目前大多数数据库已支持空间数据存储,我本人用过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 共同交流学习!