C#建立Oracle中的幾何對象:點、線、面

來源:互聯網
上載者:User

標籤:

最初寫這個程式是應老大的要求解決“更新Oracle中的空間資料時會因為wkt字串太長而報錯”這個問題,之前的更新都是在程式中插入一條SQL語句來進行更新,由於SQL語句本身的一些限制,在wkt字串中包含幾萬個以上的點時就會報“ORA-01074:字串文字太長”錯誤,這裡提出了兩種解決方案:

第一種:將之前傳入簡單的SQL更新語句,改為傳入預存程序;

DECLARE
geom sdo_geometry;

BEGIN

geom:=sdo_geometry
(2003,
null,
null,
sdo_elem_info_array(1,1003,1),
sdo_ordinate_array(58184.2949999999, 39390.5210000016, 58208.6500000013, 39291.8900000025, 58499.0099999998, 39310.700000003, 58482.4699999997, 39409.8360000011, 58184.2949999999, 39390.5210000016)
);

execute immediate ‘update zd_test set shape=:gm where objectid=242137‘ using geom;

END;


select objectid,shape from zd_test

select objectid,SDO_UTIL.TO_WKTGEOMETRY(shape) as ShapeString from zd_test where objectid=242137

第二種:使用參數方法進行傳值

這種方法主要是參考了http://www.cnblogs.com/Anders888/p/3542288.html這篇文章,最終問題解決,代碼如下:

這裡SdoGeometry 、SdoPoint都已經經過封裝,可參考http://blog.csdn.net/rrrrssss00/article/details/22879719

最終傳參使用:

//單點
string wkt = "POINT (63918.6936862222 39311.6724619204)";
string conn_str = "Data Source=ORCL162; User ID = gttest; Password = gttest";//串連Oracle資料庫的字串
GeoneOracleGeometry geo = new GeoneOracleGeometry();
geo.UpdateGeometryData(conn_str, "zd_test", "objectid", "230361", "shape", wkt);

一、根據wkt建立幾何對象:點、線、面

#region 建立幾何對象:點、線、面

private SdoGeometry CreateGeometryByWkt(string wkt)
{
if (wkt.Contains("POLYGON"))
{
if (wkt.Contains("MULTIPOLYGON"))
{
//多邊形:多個面
SdoGeometry MultiPolygon = new SdoGeometry();
MultiPolygon.Sdo_Gtype = 2007;
MultiPolygon.Sdo_Srid = null;
MultiPolygon.Point = null;
MultiPolygon.ElemArray = CreateMultiPolygonArray(wkt);
MultiPolygon.OrdinatesArray = ConvertPointToArray(wkt);
return MultiPolygon;
}
else if (wkt.Contains("),"))
{
//多邊形:環(有島多邊形)
SdoGeometry CirculPolygon = new SdoGeometry();
CirculPolygon.Sdo_Gtype = 2003;
CirculPolygon.Sdo_Srid = null;
CirculPolygon.Point = null;
CirculPolygon.ElemArray = CreateCurArray(wkt);
CirculPolygon.OrdinatesArray = ConvertPointToArray(wkt);
return CirculPolygon;
}
else
{
//多邊形:簡單面
SdoGeometry SimplePolygon = new SdoGeometry();
SimplePolygon.Sdo_Gtype = 2003;
SimplePolygon.Sdo_Srid = null;
SimplePolygon.Point = null;
SimplePolygon.ElemArray = new decimal[] { 1, 1003, 1 };
SimplePolygon.OrdinatesArray = ConvertPointToArray(wkt);
return SimplePolygon;
}
}
else if (wkt.Contains("LINESTRING"))
{
//直線
SdoGeometry SimpleLine = new SdoGeometry();
SimpleLine.Sdo_Gtype = 2002;
SimpleLine.Sdo_Srid = null;
decimal[] dest = ConvertPointToArray(wkt);
SimpleLine.Point = null;
SimpleLine.ElemArray = new decimal[] { 1, 2, 1 };
SimpleLine.OrdinatesArray = dest;
return SimpleLine;
}
else if (wkt.Contains("CIRCULARSTRING"))
{
//曲線
SdoGeometry CirculLine = new SdoGeometry();
CirculLine.Sdo_Gtype = 2002;
CirculLine.Sdo_Srid = null;
decimal[] dest = ConvertPointToArray(wkt);
CirculLine.Point = null;
CirculLine.ElemArray = new decimal[] { 1, 2, 2 };
CirculLine.OrdinatesArray = dest;
return CirculLine;
}
else if (wkt.Contains("POINT"))
{
if (wkt.Contains("MULTIPOINT "))
{
//多點
SdoGeometry MultiPoint = new SdoGeometry();
MultiPoint.Sdo_Gtype = 2005;
MultiPoint.Sdo_Srid = null;
decimal[] dest = ConvertPointToArray(wkt);
MultiPoint.Point = null;
MultiPoint.ElemArray = new decimal[] { 1, 1, dest .Length/ 2 };
MultiPoint.OrdinatesArray = dest;
return MultiPoint;
}
else
{
//單點
SdoGeometry SimplePoint = new SdoGeometry();
SimplePoint.Sdo_Gtype = 2001;
SimplePoint.Sdo_Srid = null;
decimal[] dest = ConvertPointToArray(wkt);
SimplePoint.Point = new SdoPoint();
SimplePoint.Point.X = dest[0];
SimplePoint.Point.Y = dest[1];
SimplePoint.Point.Z = null;
SimplePoint.ElemArray = null;
SimplePoint.OrdinatesArray = null;
return SimplePoint;
}
}
return null;
}

二、讀取wkt字串並轉換為數組

#region 讀取wkt字串並轉換為數組

public decimal[] ConvertPointToArray(string wkt)
{
string RegExp = @"(\d+\.\d+|\d+)\s(\d+\.\d+|\d+)";
Regex regex = new Regex(RegExp, RegexOptions.Singleline | RegexOptions.IgnoreCase);
Match m = regex.Match(wkt);
int count = 0;
while (m.Success)
{
count++;
m = m.NextMatch();
}
count *= 2;
decimal[] dest = new decimal[count];
m = regex.Match(wkt);
int arrayIndex = 0;
while (m.Success)
{
string[] arr = m.Value.Trim().Split(new Char[] { ‘ ‘ });

decimal x0 = Convert.ToDecimal(arr[0]);
decimal y0 = Convert.ToDecimal(arr[1]);

dest[arrayIndex++] = x0;
dest[arrayIndex++] = y0;

m = m.NextMatch();
}
return dest;
}

#endregion

三、多邊形:環 類型數組

#region 多邊形:環 類型數組

public decimal[] CreateCurArray(string wkt)
{
string[] aa = wkt.Replace("),", "@").Split(‘@‘);
decimal[] bb = new decimal[aa.Length * 3];
bb[0] = 1;
bb[1] = 1003;
bb[2] = 1;
for (int i = 1; i < aa.Length; i++)
{
int length = aa[i - 1].Length - aa[i - 1].Replace(",", "").Length + 1;
bb[i * 3] = length * 2 + 1;
bb[i * 3 + 1] = 2003;
bb[i * 3 + 2] = 1;
}
return bb;
}

#endregion

四、多邊形:多面 類型數組

#region 多邊形:多面 類型數組
public decimal[] CreateMultiPolygonArray(string wkt)
{
string[] aa = wkt.Replace(")),", "@").Split(‘@‘);
decimal[] bb = new decimal[aa.Length * 3];
bb[0] = 1;
bb[1] = 1003;
bb[2] = 1;
int s = 0;
for (int i = 1; i < aa.Length; i++)
{
int length= aa[i-1].Length - aa[i-1].Replace("," , "").Length+1 ;
s = s + length;
bb[i* 3] = s * 2 + 1;
bb[i* 3 + 1] = 1003;
bb[i* 3 + 2] = 1;
}
return bb;
}

#endregion

五、更新幾何對象:點、線、面

#region 更新幾何對象:點、線、面

public string UpdateGeometryData(string conn_str, string tableName, string keyId, string KeyValuePar, string shapeId,string wkt)
{
try
{
OracleConnection conn = new OracleConnection(conn_str);
conn.Open();

string sql = string.Format("update {0} set {1}=:shape where {3}=:objectid", tableName, shapeId, wkt, keyId, KeyValuePar);

OracleCommand cmd = new OracleCommand(sql, conn);
//圖形參數
OracleParameter pra = new OracleParameter();
pra.OracleDbType = OracleDbType.Object;
pra.UdtTypeName = "MDSYS.SDO_GEOMETRY";
//圖形
pra.Value = CreateGeometryByWkt(wkt);
cmd.Parameters.Add(pra);
//關鍵字參數
OracleParameter prc = new OracleParameter(":objectid", KeyValuePar);
cmd.Parameters.Add(prc);
cmd.ExecuteNonQuery();
conn.Close();
cmd.Dispose();
}
catch (Exception ex)
{
throw ex;
}

return null;
}

#endregion

C#建立Oracle中的幾何對象:點、線、面

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.