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}\t",feature.GetFieldAsString(iField));
268 // break;
269 //caseFieldType.OFTReal:
270 // Console.WriteLine("{0}\t",feature.GetFieldAsDouble(iField));
271 // break;
272 //caseFieldType.OFTInteger:
273 // Console.WriteLine("{0}\t",feature.GetFieldAsInteger(iField));
274 // break;
275 //default:
276 // Console.WriteLine("{0}\t",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 }