GDAL 工具类

  1 using OSGeo.GDAL;
  2 using OSGeo.OGR;
  3 using System;
  4 using System.Collections.Generic;
  5 using System.IO;
  6 using System.Runtime.Serialization.Json;
  7 using System.Text;
  8 
  9 namespace Test.Workspace
 10 {
 11     public class GdalShapeOperate
 12     {
 13         private static GdalShapeOperate _instance = null;
 14 
 15         public static GdalShapeOperate Instance
 16         {
 17             get
 18             {
 19                 if (_instance == null)
 20                     _instance = new GdalShapeOperate();
 21                 return _instance;
 22             }
 23         }
 24 
 25         [System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions]
 26         public string ExportToWkt(Geometry geo)
 27         {
 28             string wkt = string.Empty;
 29             try
 30             {
 31                 geo.ExportToWkt(out wkt);
 32             }
 33             catch (AccessViolationException)
 34             {
 35                 return string.Empty;
 36             }
 37             return wkt;
 38         }
 39 
 40         private System.Data.DataTable tableRst = null;
 41 
 42         public System.Data.DataTable ShapeToDataTable(string shapePath, string layerName = null, bool isEsriRing = true)
 43         {
 44             // 注册所有的驱动
 45             Ogr.RegisterAll();
 46             // 为了支持中文路径,请添加下面这句代码
 47             //Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
 48             // 为了使属性表字段支持中文,请添加下面这句
 49             //Gdal.SetConfigOption("SHAPE_ENCODING", "NO");
 50             OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
 51             OSGeo.GDAL.Gdal.SetConfigOption("KENCODING", System.IO.Path.GetExtension(shapePath).ToUpper() == ".MDB" ? "True" : null);
 52             //OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
 53             //OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
 54             //打开数据
 55             using (DataSource ds = Ogr.Open(shapePath, 0))
 56             {
 57                 if (ds == null || ds.GetLayerCount() <= 0)
 58                 {
 59                     return null;
 60                 }
 61                 Layer layer = null;
 62                 if (string.IsNullOrWhiteSpace(layerName))
 63                 {
 64                     layer = ds.GetLayerByIndex(0);
 65                 }
 66                 else
 67                 {
 68                     layer = ds.GetLayerByName(layerName);
 69                 }
 70 
 71                 if (layer == null)
 72                 {
 73                     return null;
 74                 }
 75                 OSGeo.OGR.Feature feature = null;
 76                 tableRst = GetDataTable(layer.GetLayerDefn(), isEsriRing);
 77                 if (!tableRst.Columns.Contains("SHAPESTR"))
 78                 {
 79                     tableRst.Columns.Add("SHAPESTR", typeof(string));
 80                 }
 81                 wkbGeometryType layerGeometryType = layer.GetGeomType();
 82                 while ((feature = layer.GetNextFeature()) != null)
 83                 {
 84                     System.Data.DataRow drNewRow = NewDataRow(feature);
 85                     OSGeo.OGR.Geometry geometry = feature.GetGeometryRef();
 86                     if (isEsriRing)
 87                     {
 88                         if (geometry == null) continue;
 89                         drNewRow["SHAPE"] = GetPoints(geometry);
 90                         if (tableRst.Columns.Contains("SHAPESTR"))
 91                         {
 92                             drNewRow["SHAPESTR"] = drNewRow["SHAPE"];
 93                         }
 94                     }
 95                     else
 96                     {
 97                         drNewRow["SHAPE"] = geometry;
 98                     }
 99                     tableRst.Rows.Add(drNewRow);
100                 }
101                 return tableRst;
102             }
103         }
104 
105         public string GetRing(string wkt)
106         {
107             OSGeo.OGR.Geometry geo = OSGeo.OGR.Geometry.CreateFromWkt(wkt);
108             return GetPoints(geo);
109         }
110 
111         public System.Data.DataTable ShapeToDataTableTemp(string shapePath, string layerName = null)
112         {
113             // 注册所有的驱动
114             Ogr.RegisterAll();
115             // 为了支持中文路径,请添加下面这句代码
116             Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
117             // 为了使属性表字段支持中文,请添加下面这句
118             Gdal.SetConfigOption("SHAPE_ENCODING", "NO");
119 
120             //打开数据
121             DataSource ds = Ogr.Open(shapePath, 0);
122             if (ds == null || ds.GetLayerCount() <= 0) return null;
123             Layer layer = null;
124             if (string.IsNullOrWhiteSpace(layerName))
125             {
126                 layer = ds.GetLayerByIndex(0);
127             }
128             else
129             {
130                 layer = ds.GetLayerByName(layerName);
131             }
132 
133             if (layer == null) return null;
134             OSGeo.OGR.Feature feature = null;
135             tableRst = GetDataTable(layer.GetLayerDefn());
136             wkbGeometryType layerGeometryType = layer.GetGeomType();
137             while ((feature = layer.GetNextFeature()) != null)
138             {
139                 System.Data.DataRow drNewRow = NewDataRow(feature);
140                 OSGeo.OGR.Geometry geometry = feature.GetGeometryRef();
141                 if (geometry == null) continue;
142                 drNewRow["SHAPE"] = @"{""x"":" + geometry.Centroid().GetX(0) + @",""y"":" + geometry.Centroid().GetY(0) + "}";//GetPoints(geometry);
143                 tableRst.Rows.Add(drNewRow);
144             }
145             return tableRst;
146         }
147 
148         /// <summary>
149         /// 创建table
150         /// </summary>
151         /// <param name="oDefn"></param>
152         /// <returns></returns>
153         private System.Data.DataTable GetDataTable(FeatureDefn oDefn, bool isShapeStr = true)
154         {
155             System.Data.DataTable dtNew = new System.Data.DataTable();
156             int iFieldCount = oDefn.GetFieldCount();
157             for (int i = 0; i < iFieldCount; i++)
158             {
159                 FieldDefn oField = oDefn.GetFieldDefn(i);
160                 FieldType type = oField.GetFieldType();
161                 string name = oField.GetNameRef();
162                 if (name.ToUpper() == "SHAPE" || name.ToUpper() == "OBJECTID" || name.ToUpper() == "FID") continue;
163                 string colName = name.ToUpper();
164                 if (colName == "SHAPE_AREA")
165                     colName = "SHAPEAREA";
166                 else if (colName == "SHAPE_LENGTH")
167                 {
168                     colName = "SHAPELENGTH";
169                 }
170                 switch (type)
171                 {
172                     case FieldType.OFTInteger:
173                         dtNew.Columns.Add(colName, typeof(Int32));
174                         break;
175 
176                     case FieldType.OFTReal:
177                         dtNew.Columns.Add(colName, typeof(double));
178                         break;
179 
180                     case FieldType.OFTString:
181                         dtNew.Columns.Add(colName, typeof(string));
182                         break;
183 
184                     default:
185                         dtNew.Columns.Add(colName, typeof(string));
186                         break;
187                 }
188 
189                 //Console.WriteLine("{0}:{1} ({2}.{3})", oField.GetNameRef(),
190                 //            oField.GetFieldTypeName(oField.GetFieldType()),
191                 //            oField.GetWidth(), oField.GetPrecision());
192             }
193             if (isShapeStr)
194             {
195                 dtNew.Columns.Add("SHAPE");
196             }
197             else
198             {
199                 dtNew.Columns.Add("SHAPE", typeof(Geometry));
200             }
201             return dtNew;
202         }
203 
204         /// <summary>
205         /// 创建新行
206         /// </summary>
207         /// <param name="feature"></param>
208         /// <returns></returns>
209         private System.Data.DataRow NewDataRow(Feature feature)
210         {
211             if (tableRst == null) return null;
212             System.Data.DataRow newRow = tableRst.NewRow();
213             FeatureDefn oDefn = feature.GetDefnRef();
214             for (int iField = 0; iField < feature.GetFieldCount(); iField++)
215             {
216                 FieldDefn oFieldDefn = oDefn.GetFieldDefn(iField);
217                 FieldType type = oFieldDefn.GetFieldType();
218                 string name = oFieldDefn.GetName().ToUpper();
219                 if (name == "SHAPE" || name == "OBJECTID" || name == "FID") continue;
220                 if (name == "SHAPE_AREA")
221                     name = "SHAPEAREA";
222                 else if (name == "SHAPE_LENGTH")
223                 {
224                     name = "SHAPELENGTH";
225                 }
226                 switch (type)
227                 {
228                     //case FieldType.OFTBinary:
229                     //    break;
230                     //case FieldType.OFTDate:
231                     //    //feature.GetFieldAsDateTime(i,
232                     //    break;
233                     //case FieldType.OFTDateTime:
234                     //    break;
235                     //case FieldType.OFTIntegerList:
236                     //    break;
237                     //case FieldType.OFTRealList:
238                     //    break;
239                     //case FieldType.OFTStringList:
240                     //    break;
241                     //case FieldType.OFTTime:
242                     //    break;
243                     //case FieldType.OFTWideString:
244                     //    break;
245                     //case FieldType.OFTWideStringList:
246                     //    break;
247                     case FieldType.OFTInteger:
248                         newRow[name] = feature.GetFieldAsInteger(iField);
249                         break;
250 
251                     case FieldType.OFTReal:
252                         newRow[name] = feature.GetFieldAsDouble(iField);
253                         break;
254 
255                     case FieldType.OFTString:
256                         newRow[name] = feature.GetFieldAsString(iField);
257                         break;
258 
259                     default:
260                         newRow[name] = feature.GetFieldAsString(iField);
261                         break;
262                 }
263 
264                 //switch (type)
265                 //{
266                 // case caseFieldType.OFTString:
267                 //         Console.WriteLine("{0}	",feature.GetFieldAsString(iField));
268                 //         break;
269                 //caseFieldType.OFTReal:
270                 //         Console.WriteLine("{0}	",feature.GetFieldAsDouble(iField));
271                 //         break;
272                 //caseFieldType.OFTInteger:
273                 //         Console.WriteLine("{0}	",feature.GetFieldAsInteger(iField));
274                 //         break;
275                 //default:
276                 //         Console.WriteLine("{0}	",feature.GetFieldAsString(iField));
277                 //         break;
278                 //}
279             }
280             return newRow;
281         }
282 
283         public string GetPoints(OSGeo.OGR.Geometry geometry)
284         {
285             StringBuilder sb = new StringBuilder("{");
286             switch (geometry.GetGeometryType())
287             {
288                 case wkbGeometryType.wkbGeometryCollection:
289                     break;
290 
291                 case wkbGeometryType.wkbGeometryCollection25D:
292                     break;
293 
294                 case wkbGeometryType.wkbLineString:
295                     break;
296 
297                 case wkbGeometryType.wkbLineString25D:
298                     break;
299 
300                 case wkbGeometryType.wkbLinearRing:
301                     break;
302 
303                 case wkbGeometryType.wkbMultiLineString:
304                     break;
305 
306                 case wkbGeometryType.wkbMultiLineString25D:
307                     break;
308 
309                 case wkbGeometryType.wkbMultiPoint:
310                     break;
311 
312                 case wkbGeometryType.wkbMultiPoint25D:
313                     break;
314 
315                 case wkbGeometryType.wkbMultiPolygon25D:
316                     break;
317 
318                 case wkbGeometryType.wkbNone:
319                     break;
320 
321                 case wkbGeometryType.wkbPoint:
322                     string json = @"""x"":" + geometry.GetX(0) + @",""y"":" + geometry.GetY(0) + "";
323                     sb.Append(json);
324                     break;
325 
326                 case wkbGeometryType.wkbPoint25D:
327                     break;
328 
329                 case wkbGeometryType.wkbMultiPolygon:
330                 case wkbGeometryType.wkbPolygon:
331                     int geometryCount = geometry.GetGeometryCount();
332                     if (geometryCount > 0)
333                     {
334                         sb.Append(@"""rings"":[");
335 
336                         for (int i = 0; i < geometryCount; i++)
337                         {
338                             Geometry ge = geometry.GetGeometryRef(i);
339                             int subGeoCount = ge.GetGeometryCount();
340                             if (subGeoCount > 0)
341                             {
342                                 for (int j = 0; j < subGeoCount; j++)
343                                 {
344                                     sb.Append(GetSingleGeometry(ge.GetGeometryRef(j)));
345                                 }
346                             }
347                             else
348                             {
349                                 sb.Append(GetSingleGeometry(ge));
350                             }
351                             //sb.Append("[");
352                             //Geometry ge = geometry.GetGeometryRef(i);
353                             //int count = ge.GetPointCount();
354                             //for (int j = 0; j < count; j++)
355                             //{
356                             //    sb.Append("[" + ge.GetX(j) + "," + ge.GetY(j) + "],");
357                             //}
358                             //sb.Remove(sb.Length - 1, 1);
359                             //sb.Append("],");
360                         }
361                         sb.Replace(',', ']', sb.Length - 1, 1);
362                     }
363                     break;
364 
365                 case wkbGeometryType.wkbPolygon25D:
366                     break;
367 
368                 case wkbGeometryType.wkbUnknown:
369                     break;
370 
371                 default:
372                     break;
373             }
374             sb.Append("}");
375             return sb.ToString();
376         }
377 
378         /// <summary>
379         /// 计算 Geometry 的面积(单位:亩)
380         /// </summary>
381         /// <param name="geo"></param>
382         /// <param name="area"></param>
383         /// <returns></returns>
384         public bool TryGetAreaFromGeometry(Geometry geo, ref double area, int dh = -1)
385         {
386             try
387             {
388                 OSGeo.OSR.SpatialReference tagt = new OSGeo.OSR.SpatialReference("");
389                 //如果没有指定代号, 按照当前经度来直接获取面积  如果指定代号 按照3度带来计算
390                 tagt.SetTM(0, dh == -1 ? geo.Centroid().GetX(0) : dh * 3, 1, 0, 0);//高斯克吕格投影,fe应该有值,但不影响计算,用0替代
391                 OSGeo.OSR.SpatialReference src = new OSGeo.OSR.SpatialReference("");
392                 src.SetWellKnownGeogCS("WGS84");//WSG地理坐标
393                 //sr2.SetGeogCS("GCS_China_Geodetic_Coordinate_System_2000", "D_China_2000", " CGCS2000", 6378137.0, 298.25722210100002, "Degree", 0, "rad", 0.017453292519943295);
394                 //投影
395                 OSGeo.OSR.CoordinateTransformation tranform = new OSGeo.OSR.CoordinateTransformation(src, tagt);
396                 geo.Transform(tranform);
397 
398                 area = geo.Area() * 0.0015;//平方米转亩
399             }
400             catch (Exception ex)
401             {
402                 area = geo.Area() * 0.0015;//平方米转亩
403                
404                 return false;
405             }
406             return true;
407         }
408 
409         private string GetSingleGeometry(Geometry geo)
410         {
411             StringBuilder sb = new StringBuilder();
412             sb.Append("[");
413             //Geometry ge = geo.GetGeometryRef(i);
414             int count = geo.GetPointCount();
415             for (int j = 0; j < count; j++)
416             {
417                 sb.Append("[" + geo.GetX(j) + "," + geo.GetY(j) + "],");
418             }
419             sb.Remove(sb.Length - 1, 1);
420             sb.Append("],");
421             return sb.ToString();
422         }
423 
424         /// <summary>
425         /// 获取多边形的最小外接矩形坐标串
426         /// </summary>
427         /// <param name="shapeJson">多边形坐标串</param>
428         /// <returns></returns>
429         public string GetRectangleStrFromShapeJson(string shapeJson)
430         {
431             // 注册所有的驱动
432             Ogr.RegisterAll();
433             // 为了支持中文路径,请添加下面这句代码
434             Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
435             // 为了使属性表字段支持中文,请添加下面这句
436             Gdal.SetConfigOption("SHAPE_ENCODING", "NO");
437 
438             JsonRings shapeJsonStr = JsonRings.FromJson(shapeJson);
439             if (shapeJsonStr == null || shapeJsonStr.rings.Count == 0)
440             {
441                 return null;
442             }
443 
444             OSGeo.OGR.Geometry ring = new OSGeo.OGR.Geometry(OSGeo.OGR.wkbGeometryType.wkbLinearRing);
445             foreach (List<double[]> ringStr in shapeJsonStr.rings)
446             {
447                 foreach (double[] pointStr in ringStr)
448                 {
449                     double x = Convert.ToDouble(pointStr[0]);
450                     double y = Convert.ToDouble(pointStr[1]);
451                     ring.AddPoint_2D(x, y);
452                 }
453             }
454 
455             Geometry geo = new Geometry(wkbGeometryType.wkbPolygon);
456             geo.AddGeometry(ring);
457 
458             var convexHullGeo = geo.ConvexHull();//ConvexHull():计算最小凸外多边形
459             var convexHullGeoPoints = GetPoints(convexHullGeo);
460             JsonRings convexHullJsonStr = JsonRings.FromJson(convexHullGeoPoints);
461 
462             double minX = 0.00;
463             double minY = 0.00;
464             double maxX = 0.00;
465             double maxY = 0.00;
466 
467             foreach (List<double[]> ringStr in convexHullJsonStr.rings)
468             {
469                 for (int i = 0; i < ringStr.Count; i++)
470                 {
471                     double x = Convert.ToDouble(ringStr[i][0]);
472                     double y = Convert.ToDouble(ringStr[i][1]);
473                     if (i == 0)
474                     {
475                         minX = x;
476                         minY = y;
477                         maxX = x;
478                         maxY = y;
479                     }
480                     if (x < minX)
481                     {
482                         minX = x;
483                     }
484                     if (y < minY)
485                     {
486                         minY = y;
487                     }
488                     if (x > maxX)
489                     {
490                         maxX = x;
491                     }
492                     if (y > maxY)
493                     {
494                         maxY = y;
495                     }
496                 }
497             }
498 
499             OSGeo.OGR.Geometry rectangleRing = new OSGeo.OGR.Geometry(OSGeo.OGR.wkbGeometryType.wkbLinearRing);
500             rectangleRing.AddPoint_2D(minX, maxY);
501             rectangleRing.AddPoint_2D(maxX, maxY);
502             rectangleRing.AddPoint_2D(maxX, minY);
503             rectangleRing.AddPoint_2D(minX, minY);
504             rectangleRing.AddPoint_2D(minX, maxY);
505 
506             Geometry rectangleGeo = new Geometry(wkbGeometryType.wkbPolygon);
507             rectangleGeo.AddGeometry(rectangleRing);
508 
509             return GetPoints(rectangleGeo);
510         }
511 
512         /// <summary>
513         /// 获取多边形shape的四至
514         /// </summary>
515         /// <param name="shapeJson">多边形坐标串</param>
516         /// <returns></returns>
517         public FourParam GetFourParamFromShapeJson(string shapeJson)
518         {
519             // 注册所有的驱动
520             Ogr.RegisterAll();
521             // 为了支持中文路径,请添加下面这句代码
522             Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
523             // 为了使属性表字段支持中文,请添加下面这句
524             Gdal.SetConfigOption("SHAPE_ENCODING", "NO");
525 
526             JsonRings shapeJsonStr = JsonRings.FromJson(shapeJson);
527             if (shapeJsonStr == null || shapeJsonStr.rings == null || shapeJsonStr.rings.Count == 0)
528             {
529                 return null;
530             }
531 
532             if (shapeJsonStr.rings[0] == null || shapeJsonStr.rings[0].Count <= 0)
533             {
534                 return null;
535             }
536 
537             double minX = shapeJsonStr.rings[0][0][0];
538             double minY = shapeJsonStr.rings[0][0][1];
539             double maxX = shapeJsonStr.rings[0][1][0];
540             double maxY = shapeJsonStr.rings[0][1][1];
541 
542             foreach (List<double[]> ringStr in shapeJsonStr.rings)
543             {
544                 for (int i = 0; i < ringStr.Count; i++)
545                 {
546                     double x = Convert.ToDouble(ringStr[i][0]);
547                     double y = Convert.ToDouble(ringStr[i][1]);
548                     if (x < minX)
549                     {
550                         minX = x;
551                     }
552                     if (y < minY)
553                     {
554                         minY = y;
555                     }
556                     if (x > maxX)
557                     {
558                         maxX = x;
559                     }
560                     if (y > maxY)
561                     {
562                         maxY = y;
563                     }
564                 }
565             }
566 
567             FourParam fourParam = new FourParam
568             {
569                 MinX = minX,
570                 MinY = minY,
571                 MaxX = maxX,
572                 MaxY = maxY
573             };
574 
575             return fourParam;
576         }
577 
578         public class JsonRings
579         {
580             public List<List<double[]>> rings;
581 
582             public static JsonRings GetTemp()
583             {
584                 JsonRings jr = new JsonRings() { rings = new List<List<double[]>>() };
585                 for (int i = 0; i < 10; i++)
586                 {
587                     List<double[]> ring = new List<double[]>();
588                     for (int j = 0; j < 10; j++)
589                     {
590                         ring.Add(new double[] { 1111, 1111 });
591                     }
592                     jr.rings.Add(ring);
593                 }
594                 return jr;
595             }
596 
597             public string GetJsonString()
598             {
599                 var serializer = new DataContractJsonSerializer(this.GetType());
600                 var stream = new MemoryStream();
601                 serializer.WriteObject(stream, this);
602                 byte[] dataBytes = new byte[stream.Length];
603                 stream.Position = 0;
604                 stream.Read(dataBytes, 0, (int)stream.Length);
605                 return Encoding.UTF8.GetString(dataBytes);
606             }
607 
608             public static JsonRings FromJson(string json)
609             {
610                 try
611                 {
612                     if (string.IsNullOrWhiteSpace(json)) return null;
613                     var serializer = new DataContractJsonSerializer(typeof(JsonRings));
614                     var mStream = new MemoryStream(Encoding.Default.GetBytes(json));
615                     return (JsonRings)serializer.ReadObject(mStream);
616                 }
617                 catch
618                 {
619                     return null;
620                 }
621             }
622         }
623 
624         public ESRI.ArcGIS.Client.Geometry.MapPoint GetCenterMapPointByShapeJson(string shapeJson)
625         {
626             string shapeWKT = string.Empty;
627             if (!string.IsNullOrWhiteSpace(shapeJson))
628             {
629                 ESRI.ArcGIS.Client.Geometry.Polygon polygon = (ESRI.ArcGIS.Client.Geometry.Polygon)ESRI.ArcGIS.Client.Geometry.Geometry.FromJson(shapeJson);
630                 return polygon.Extent.GetCenter();
631             }
632             else
633             {
634                 return new ESRI.ArcGIS.Client.Geometry.MapPoint() { X = 0, Z = 0, Y = 0 };
635             }
636         }
637 
638         /// <summary>
639         /// 根据 shapeJson 获取 Geometry 对象
640         /// </summary>
641         /// <param name="shapeJson"></param>
642         /// <returns></returns>
643         public Geometry GetGeometryFromShapeJson(string shapeJson)
644         {
645             // 注册所有的驱动
646             Ogr.RegisterAll();
647             // 为了支持中文路径,请添加下面这句代码
648             Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
649             // 为了使属性表字段支持中文,请添加下面这句
650             Gdal.SetConfigOption("SHAPE_ENCODING", "NO");
651 
652             JsonRings shapeJsonStr = JsonRings.FromJson(shapeJson);
653             if (shapeJsonStr == null || shapeJsonStr.rings.Count == 0)
654             {
655                 return null;
656             }
657 
658             Geometry geo = new Geometry(wkbGeometryType.wkbPolygon);
659             foreach (List<double[]> ringStr in shapeJsonStr.rings)
660             {
661                 OSGeo.OGR.Geometry ring = new OSGeo.OGR.Geometry(OSGeo.OGR.wkbGeometryType.wkbLinearRing);
662                 foreach (double[] pointStr in ringStr)
663                 {
664                     double x = Convert.ToDouble(pointStr[0]);
665                     double y = Convert.ToDouble(pointStr[1]);
666                     ring.AddPoint_2D(x, y);
667                 }
668                 geo.AddGeometry(ring);
669             }
670             return geo;
671         }
672 
673         const double tolerance = 0.00000001;//容差(要求ShapeJson是经纬度坐标)//这里不能设置很小, 如果一个图形自相交,一边图形很大,另一边很小, 可能会把大的面积给裁切掉
674 
675         /// <summary>
676         /// 获取两个图像的重合部分
677         /// </summary>
678         /// <param name="baseShapeJson">基础图形</param>
679         /// <param name="needIntersectedShape">需要判断重合的图形</param>
680         /// <returns></returns>
681         public Geometry GetIntersectedGeometry(string baseShapeJson, string needIntersectedShape)
682         {
683             #region old
684             //Geometry intersectedGeometry = null;
685             //Geometry baseGeo = GetGeometryFromShapeJson(baseShapeJson);
686             //Geometry needIntersectedGeo = GetGeometryFromShapeJson(needIntersectedShape);
687             //int baseRingsCnt = baseGeo.GetGeometryCount();
688             //int needRingsCnt = needIntersectedGeo.GetGeometryCount();
689             //bool hasResult = false;
690             //if (baseRingsCnt > 0 && needRingsCnt > 0)
691             //{
692             //    intersectedGeometry = new Geometry(wkbGeometryType.wkbMultiPolygon);
693             //    for (int i = 0; i < baseRingsCnt; i++)
694             //    {
695             //        Geometry baseRing = baseRingsCnt == 1 ? baseGeo : baseGeo.GetGeometryRef(i);
696             //        baseRing = ToPolygon(baseRing);
697             //        for (int j = 0; j < needRingsCnt; j++)
698             //        {
699             //            Geometry needRing = needRingsCnt == 1 ? needIntersectedGeo : needIntersectedGeo.GetGeometryRef(i);
700             //            needRing = ToPolygon(needRing);
701 
702             //            if (baseRing.Intersects(needRing))
703             //            {
704             //                Geometry result = baseRing.Intersection(needRing);
705             //                if (result.GetGeometryCount() <= 0)
706             //                {
707             //                    continue;
708             //                }
709             //                if (result.GetGeometryType() == wkbGeometryType.wkbMultiPolygon)
710             //                {
711             //                    int resuntRingsCnt = result.GetGeometryCount();
712             //                    for (int z = 0; z < resuntRingsCnt; z++)
713             //                    {
714             //                        Geometry geoTemp = result.GetGeometryRef(z);
715             //                        geoTemp = ToPolygon(geoTemp);
716             //                        intersectedGeometry.AddGeometry(geoTemp);
717             //                    }
718             //                }
719             //                else
720             //                {
721             //                    intersectedGeometry.AddGeometry(result);
722             //                }
723             //                hasResult = true;
724             //            }
725             //        }
726             //    }
727             //}
728             //if (!hasResult || (intersectedGeometry != null && intersectedGeometry.GetGeometryCount() <= 0))
729             //{
730             //    intersectedGeometry = null;
731             //}
732             //return intersectedGeometry;
733             #endregion
734 
735             Geometry intersectedGeometry = null;
736             Geometry baseGeo = GetGeometryFromShapeJson(baseShapeJson);
737             if (baseGeo == null) return null;
738   
739 
740             Geometry needIntersectedGeo = GetGeometryFromShapeJson(needIntersectedShape);
741         
742 
743             //判断是否是环形
744             //if (baseGeo.GetGeometryCount()> 0)
745             //{
746             //    baseGeo = GetErasedGeometry(baseGeo);
747             //}
748             ////判断是否是环形
749             //if (needIntersectedGeo.GetGeometryCount() > 0)
750             //{
751             //    needIntersectedGeo = GetErasedGeometry(needIntersectedGeo);
752             //}
753 
754             if (baseGeo.Intersects(needIntersectedGeo))
755             {
756                 intersectedGeometry = baseGeo.Intersection(needIntersectedGeo);
757             }
758 
759             return intersectedGeometry;
760         }
761 
762 
763         public Geometry GetErasedGeometry(Geometry baseGeo, string needEraseShape)
764         {
765             Geometry result = null;
766             if (baseGeo == null) return null;
767             if (!baseGeo.IsValid()) baseGeo = baseGeo.Simplify(tolerance);
768 
769             Geometry needEraseGeo = GetGeometryFromShapeJson(needEraseShape);
770             if (!needEraseGeo.IsValid()) needEraseGeo = needEraseGeo.Simplify(tolerance);
771 
772             if (baseGeo.Intersects(needEraseGeo)) result = baseGeo.Difference(needEraseGeo);
773             return result;
774         }
775 
776         public Geometry GetErasedGeometry(Geometry baseGeo, Geometry needEraseGeo)
777         {
778             Geometry result = null;
779             if (baseGeo == null) return null;
780             if (!baseGeo.IsValid()) baseGeo = baseGeo.Simplify(tolerance);
781 
782             if (!needEraseGeo.IsValid()) needEraseGeo = needEraseGeo.Simplify(tolerance);
783 
784             if (baseGeo.Intersects(needEraseGeo)) result = baseGeo.Difference(needEraseGeo);
785             return result;
786         }
787         /// <summary>
788         /// 镂空里面的图形合成一个Geometry
789         /// </summary>
790         /// <param name="baseGeo"></param>
791         /// <returns></returns>
792         public Geometry GetErasedGeometry(Geometry baseGeo)
793         {
794             Geometry result = null;
795             if (baseGeo == null) return null;
796             if (!baseGeo.IsValid()) baseGeo = baseGeo.Simplify(tolerance);
797 
798             result= baseGeo.GetGeometryRef(0).Clone();
799 
800             for (int i=1; i<baseGeo.GetGeometryCount(); i++)
801             {
802                 result.Difference(baseGeo.GetGeometryRef(i));
803             }
804             return result;
805         }
806     }
807 
808     public class FourParam
809     {
810         public double MinX { set; get; }
811         public double MinY { set; get; }
812         public double MaxX { set; get; }
813         public double MaxY { set; get; }
814     }
815 }
原文地址:https://www.cnblogs.com/Jason1019/p/13470880.html