目前大多數數據庫已支持空間數據存儲,我本人用過mysql,Oracle,SqlServer三種數據庫,常見利用數據庫Geometry類型,存儲面狀圖形,但在繪制過程中會經常出現自相交的微小面,如下圖所示 ,在arcmap中打開這種微小面,會報自相交錯誤
經過一番查閱資料,發現網友有相似經歷,網上也有JAVA的解決方案,本人將其轉化為.net版,以方便以后遇到類似問題的同志們。大致過程如下,利用GeoAPI,NetTopologySuite 可以將GeoJson,轉化為oracle,sqlserver,mysql格式的Geometry,利用ORM保存。
GeoAPI,NetTopologySuite 網上有開源代碼,有興趣的可以自己下載來看。
引用的類庫:
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;
using NetTopologySuite.Operation.Polygonize;
public class GeometryRepair { /// <summary> /// 驗證圖形是否自相交 /// </summary> /// <param name="geom"></param> /// <returns></returns> public static IGeometry validateGeometry(IGeometry geom) { if (geom is Polygon) { if (geom.IsValid) { geom.Normalize(); return geom; } Polygonizer polygonizer = new Polygonizer(); addPolygon((Polygon)geom, polygonizer); return toPolygonGeometry(polygonizer.GetPolygons(), geom.Factory as IGeometryFactory); } else if (geom is MultiPolygon) { if (geom.IsValid) { geom.Normalize(); return geom; } Polygonizer polygonizer = new Polygonizer(); for (int n = geom.NumGeometries; n-- > 0;) { addPolygon((Polygon)geom.GetGeometryN(n), polygonizer); } return toPolygonGeometry(polygonizer.GetPolygons(), geom.Factory as IGeometryFactory); } else { return geom; } } /// <summary> /// 添加多邊形 /// </summary> /// <param name="polygon"></param> /// <param name="polygonizer"></param> static void addPolygon(Polygon polygon, Polygonizer polygonizer) { addLineString(polygon.ExteriorRing as LineString, polygonizer); for (int n = polygon.NumInteriorRings; n-- > 0;) { var line = polygon.GetInteriorRingN(n) as LineString; addLineString(line, polygonizer); } } /// <summary> /// 添加線 /// </summary> /// <param name="lineString"></param> /// <param name="polygonizer"></param> static void addLineString(LineString lineString, Polygonizer polygonizer) { if (lineString is LinearRing) { lineString = lineString.Factory.CreateLineString(lineString.CoordinateSequence) as LineString; } Point point = lineString.Factory.CreatePoint(lineString.GetCoordinateN(0)) as Point; IGeometry toAdd = lineString.Union(point); polygonizer.Add(toAdd); } /// <summary> /// 將面對象轉化為一個多面 /// </summary> /// <param name="polygons"></param> /// <param name="factory"></param> /// <returns></returns> static IGeometry toPolygonGeometry(ICollection<IGeometry> polygons, IGeometryFactory factory) { switch (polygons.Count) { case 0: return null; case 1: return polygons.First(); default: List<IPolygon> mPolygons = new List<IPolygon>(); foreach (IGeometry g in polygons) { mPolygons.Add(g as IPolygon); } return factory.CreateMultiPolygon(mPolygons.ToArray()) as MultiPolygon; } } }
更多GIS開發相關問題請加入 GIS開發學習QQ交流群 192251607 共同交流學習!