zoukankan      html  css  js  c++  java
  • NetTopologySuite 工具类

      1 using System.Threading;
      2 using System.Collections.Generic;
      3 using GeoAPI.Geometries;
      4 using NetTopologySuite.Geometries;
      5 using NetTopologySuite.Operation.Polygonize;
      6 using System.Linq;
      7 
      8 namespace Test.Workspace
      9 {
     10     public static class NTSExpend
     11     {
     12         public static IGeometry Validate(this IGeometry geometry) => NTSUtils.Instance.Validate(geometry);
     13     }
     14     public class NTSUtils
     15     {
     16         private static NTSUtils _this = null;
     17         private static object lockObj = new object();
     18 
     19         /// <summary>
     20         /// 单例创建对象
     21         /// </summary>
     22         /// <returns></returns>
     23         public static NTSUtils Instance
     24         {
     25             get
     26             {
     27                 if (_this == null)
     28                 {
     29                     lock (lockObj)
     30                     {
     31                         if (_this == null)
     32                             _this = new NTSUtils();
     33                         return _this;
     34                     }
     35                 }
     36                 else
     37                     return _this;
     38             }
     39         }
     40 
     41         /// <summary>
     42         /// 处理图形自相交
     43         /// </summary>
     44         /// <returns></returns>
     45         public IGeometry Validate(IGeometry geometry)
     46         {
     47             Polygonizer polygonizer = null;
     48             if (geometry is Polygon)
     49             {
     50                 if (geometry.IsValid)
     51                 {
     52                     geometry.Normalize();
     53                     return geometry;
     54                 }
     55                 polygonizer = new Polygonizer();
     56 
     57                 AddPolygon((Polygon)geometry, polygonizer);
     58             }
     59             else if (geometry is MultiPolygon)
     60             {
     61                 if (geometry.IsValid)
     62                 {
     63                     geometry.Normalize();
     64                     return geometry;
     65                 }
     66                 polygonizer = new Polygonizer();
     67                 for (int n = geometry.NumGeometries; n-- > 0;)
     68                 {
     69                     AddPolygon((Polygon)geometry.GetGeometryN(n), polygonizer);
     70                 }
     71             }
     72             else if (geometry is GeometryCollection)
     73             {
     74                 if (geometry.IsValid)
     75                 {
     76                     geometry.Normalize();
     77                     return geometry;
     78                 }
     79                 polygonizer = new Polygonizer();
     80                 for (int n = geometry.NumGeometries; n-- > 0;)
     81                 {
     82                     IGeometry temp = geometry.GetGeometryN(n);
     83                     if (temp is Polygon)
     84                     {
     85                         AddPolygon((Polygon)temp, polygonizer);
     86                     }
     87                     else if (temp is MultiPolygon)
     88                     {
     89                         for (int m = temp.NumGeometries; m-- > 0;)
     90                         {
     91                             AddPolygon((Polygon)temp.GetGeometryN(m), polygonizer);
     92                         }
     93                     }
     94                 }
     95             }
     96             else
     97                 return geometry;
     98 
     99             return ToPolygonGeometry(polygonizer.GetPolygons(), geometry.Factory);
    100         }
    101 
    102         void AddPolygon(Polygon polygon, Polygonizer polygonizer)
    103         {
    104             AddLineString(polygon.ExteriorRing, polygonizer);
    105             for (int n = polygon.NumInteriorRings; n-- > 0;)
    106             {
    107                 AddLineString(polygon.GetInteriorRingN(n), polygonizer);
    108             }
    109         }
    110 
    111         void AddLineString(ILineString lineString, Polygonizer polygonizer)
    112         {
    113 
    114             if (lineString is LinearRing)
    115             { // LinearRings are treated differently to line strings : we need a LineString NOT a LinearRing
    116                 lineString = lineString.Factory.CreateLineString(lineString.CoordinateSequence);
    117             }
    118 
    119             // unioning the linestring with the point makes any self intersections explicit.
    120 
    121             IPoint point = lineString.Factory.CreatePoint(lineString.GetCoordinateN(0));
    122             IGeometry toAdd = lineString.Union(point);
    123 
    124             //Add result to polygonizer
    125             polygonizer.Add(toAdd);
    126         }
    127 
    128         /**
    129          * Get a geometry from a collection of polygons.
    130          * 
    131          * @param polygons collection
    132          * @param factory factory to generate MultiPolygon if required
    133          * @return null if there were no polygons, the polygon if there was only one, or a MultiPolygon containing all polygons otherwise
    134          */
    135         IGeometry ToPolygonGeometry(ICollection<IGeometry> polygons, IGeometryFactory factory)// geoSource.factory 可以创建多边形
    136         {
    137             switch (polygons.Count())
    138             {
    139                 case 0:
    140                     return null; // No valid polygons!
    141                 case 1:
    142                     return polygons.FirstOrDefault(); // single polygon - no need to wrap
    143                 default:
    144                     //polygons may still overlap! Need to sym difference them
    145                     List<IGeometry> ps = polygons.ToList();
    146                     double maxArea = ps.Select(x => x.Envelope.Area).Max();
    147                     IGeometry geometry = ps.FirstOrDefault(x => x.Envelope.Area == maxArea);
    148                     IGeometry result = geometry;
    149                     for (int i = 0; i < ps.Count; i++)
    150                     {
    151                         IGeometry currentGeo = ps[i];
    152 
    153                         //string testStr = currentGeo.ToString();
    154                         //string res = GdalShapeOperate.Instance.GetPoints(OSGeo.OGR.Ogr.CreateGeometryFromWkt(ref testStr, null));
    155                         if (currentGeo == null || currentGeo.Equals(geometry))
    156                             continue;
    157 
    158                         //1. 判断当前图形是否是多环图形
    159 
    160                         //Covers 优于 Contains  
    161                         // symDifference 并集去掉重合部分
    162                         IPolygon p = result as IPolygon;
    163                         if (p?.NumInteriorRings > 0)
    164                         {
    165                             //多环的话 需要把内部空环依次和当前图形比对 判断是否是重叠 (重叠取diff)
    166                             Polygonizer polygonizer = new Polygonizer();
    167                             for (int n = p.NumInteriorRings; n-- > 0;)
    168                             {
    169                                 AddLineString(p.GetInteriorRingN(n), polygonizer);
    170                             }
    171                             List<IGeometry> interPolygons = polygonizer.GetPolygons().ToList();
    172                             //内环存在的话 需要和当前图形比对 如果基本匹配(重合面积>90) 取差集
    173                             if (interPolygons.Count > 0)
    174                             {
    175                                 bool isIntersect = false;
    176                                 foreach (var item in interPolygons)
    177                                 {
    178                                     if (item.Intersects(currentGeo) && item.Intersection(currentGeo).Area / currentGeo.Area > 0.9)
    179                                     {
    180                                         isIntersect = true;
    181                                         break;
    182                                     }
    183                                 }
    184                                 if (isIntersect)
    185                                 {
    186                                     result = result.Difference(currentGeo);
    187                                     continue;
    188                                 }
    189                             }
    190                         }
    191 
    192                         //不是多环图形, 如果重叠 且重叠面积>当前图形面积的90%则 交集, 否则并集
    193                         if (geometry.Intersects(currentGeo) && geometry.Intersection(currentGeo).Area / currentGeo.Area > 0.9)
    194                             result = result.Difference(currentGeo);
    195                         else
    196                             result = result.Union(currentGeo);
    197 
    198                     }
    199                     return result;
    200             }
    201         }
    202 
    203         /// <summary>
    204         /// wkt转geometry
    205         /// </summary>
    206         /// <param name="wkt"></param>
    207         /// <returns></returns>
    208         public IGeometry WktToGeometry(string wkt)
    209         {
    210             NetTopologySuite.IO.WKTReader reader = new NetTopologySuite.IO.WKTReader();
    211             IGeometry geo = reader.Read(wkt);
    212             return geo;
    213         }
    214 
    215         /// <summary>
    216         /// rings 转 geometry
    217         /// </summary>
    218         /// <param name="rings"></param>
    219         /// <returns></returns>
    220         public IGeometry RingsToGeometry(string rings)
    221         {
    222             OSGeo.OGR.Geometry geometry = GdalShapeOperate.Instance.GetGeometryFromShapeJson(rings);
    223 
    224             string wkt = string.Empty;
    225             while (wkt == string.Empty)
    226             {
    227                 wkt = GdalShapeOperate.Instance.ExportToWkt(geometry);
    228                 Thread.Sleep(50);
    229             }
    230             return WktToGeometry(wkt);
    231         }
    232 
    233         public string WktToRings(string wkt) => GdalShapeOperate.Instance.GetPoints(OSGeo.OGR.Geometry.CreateFromWkt(wkt));
    234 
    235         public string GeometryToRings(Geometry geo) => GdalShapeOperate.Instance.GetPoints(OSGeo.OGR.Geometry.CreateFromWkt(geo.ToString()));
    236     }
    237 }
  • 相关阅读:
    ButterKnife 原理解析
    有关java之反射的使用
    Integer 与 int 中的 ==
    下拉框、多选框、单选框 通过TagHelper绑定数据
    动态构建视图表单
    添加我的应用中的后台图标
    标准服务接口示例代码
    .net Core下的 常用方法
    使用Redirect跳转
    标准表单提交示例代码
  • 原文地址:https://www.cnblogs.com/Jason1019/p/13470896.html
Copyright © 2011-2022 走看看