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}\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 }