//分块清理,提高效率 public static OSGeo.OGR.Layer cleanLayer_Cut(OSGeo.OGR.Layer pdLayer, double minArea, double maxArea, double maxCha = 1) { List <CutBox> Tree = buildTree(pdLayer); shpDataSet.deleteLayerByName("pdClear"); OSGeo.OGR.Layer outLayer = shpDataSet.CreateLayer("pdClear", pdLayer.GetSpatialRef(), pdLayer.GetGeomType(), null); OSGeo.OGR.Envelope oriEnve = new OSGeo.OGR.Envelope(); OSGeo.OGR.Envelope nextEnve = new OSGeo.OGR.Envelope(); StaticTools.msgLine("clean SlopeLine..."); for (int c = 0; c < Tree.Count; c++) { CutBox cb = Tree[c]; int featCount = cb.pdxIDs.Count; for (int i = 0; i < featCount - 1; i++) { bool isOnly = true; OSGeo.OGR.Feature ori = pdLayer.GetFeature(cb.pdxIDs[i]); double oriArea = ori.GetGeometryRef().GetArea(); if (oriArea < minArea || oriArea > maxArea) { //判断当前要素的面积,过小或过大时,认为其有相同的图形,不加入新的Layer isOnly = false; } else { //判断当前要素与其它要素的包围盒的对应边,差值都小于阈值时,认为是相同的图形,需要跳过 //没有相同的图型时,isOnly为true ,塞到新的layer里 ori.GetGeometryRef().GetEnvelope(oriEnve); for (int j = i + 1; j < featCount; j++) { pdLayer.GetFeature(cb.pdxIDs[j]).GetGeometryRef().GetEnvelope(nextEnve); if (Math.Abs(oriEnve.MaxX - nextEnve.MaxX) < maxCha && Math.Abs(oriEnve.MaxY - nextEnve.MaxY) < maxCha && Math.Abs(oriEnve.MinX - nextEnve.MinX) < maxCha && Math.Abs(oriEnve.MinY - nextEnve.MinY) < maxCha) { isOnly = false; break; } } } if (isOnly) { outLayer.CreateFeature(ori); } StaticTools.progress((i + 2) * 100 / featCount, $"{i + 1} / {featCount}"); } } if (IsDelete) { shpDataSet.deleteLayerByName(pdLayer.GetName()); } return(outLayer); }
/// <summary> /// 根据区块范围,获取对应的pdx,dzx /// </summary> /// <param name="pdLayer"></param> /// <param name="dzxlayer"></param> /// <returns></returns> static List <CutBox> buildTree(OSGeo.OGR.Layer pdLayer, OSGeo.OGR.Layer dzxlayer = null) { StaticTools.msgLine("buildTree..."); OSGeo.OGR.Layer cutLayer = createCutLayer(3000); //用 cutLayer 中的 Featuers 创建一个容器,容器中是对应 Featuer 的 cutBox List <CutBox> allBoxes = new List <CutBox>(); int cutFeatCount = cutLayer.GetFeatureCount(0); int pdFeatCount = pdLayer.GetFeatureCount(0); if (dzxlayer != null) { int dzFeatCount = dzxlayer.GetFeatureCount(0); for (int cuti = 0; cuti < cutFeatCount; cuti++) { CutBox cb = new CutBox(); //把与盒子相交的等值线塞入盒子,向外Buffer一定距离,避免尴尬 OSGeo.OGR.Geometry cutGeom = cutLayer.GetFeature(cuti).GetGeometryRef().Buffer(5, 0); for (int dzi = 0; dzi < dzFeatCount; dzi++) { if (cutGeom.Intersect(dzxlayer.GetFeature(dzi).GetGeometryRef())) { cb.dzxIDs.Add(dzi); } } allBoxes.Add(cb); StaticTools.progress((cuti + 1) * 100 / cutFeatCount, $"{cuti}/{cutFeatCount}"); } } //遍历坡度线,放入对应的cutBox //不会重复,要素只会放入第一个匹配上的盒子里 for (int pdi = 0; pdi < pdFeatCount; pdi++) { //拿出一个坡度要素 OSGeo.OGR.Geometry aGeom = pdLayer.GetFeature(pdi).GetGeometryRef(); for (int cuti = 0; cuti < cutFeatCount; cuti++) { //拿出一个盒子,与要素求交 OSGeo.OGR.Geometry cutGeom = cutLayer.GetFeature(cuti).GetGeometryRef(); if (aGeom.Intersects(cutGeom)) { //塞入盒子,盒子ID ,坡度线ID allBoxes[cuti].pdxIDs.Add(pdi); break; } } StaticTools.progress((pdi + 1) * 100 / pdFeatCount, $"{pdi}/{pdFeatCount}"); } if (IsDelete) { shpDataSet.deleteLayerByName(cutLayer.GetName()); } return(allBoxes); }
/// <summary> /// 通过slope的位置和面积筛选dzxPoly /// </summary> /// <param name="slopePolyLayer"></param> /// <param name="dzxPolyLayer"></param> /// <returns></returns> static OSGeo.OGR.Layer selectionFeatuers(OSGeo.OGR.Layer slopePolyLayer, OSGeo.OGR.Layer dzxPolyLayer) { shpDataSet.deleteLayerByName("resLayer"); OSGeo.OGR.Layer resLayer = shpDataSet.CreateLayer("resLayer", srs, dzxPolyLayer.GetGeomType(), null); List <CutBox> selectTree = buildTree(slopePolyLayer, dzxPolyLayer); StaticTools.msgLine("selection..."); for (int i = 0; i < selectTree.Count; i++) { CutBox abox = selectTree[i]; for (int pdi = 0; pdi < abox.pdxIDs.Count; pdi++) { int ff = abox.pdxIDs[pdi]; OSGeo.OGR.Geometry pdGeom = slopePolyLayer.GetFeature(ff).GetGeometryRef(); double pdArea = pdGeom.GetArea(); double afterCha = double.MaxValue; int yesID = -1; for (int dzi = 0; dzi < abox.dzxIDs.Count; dzi++) { int tt = abox.dzxIDs[dzi]; OSGeo.OGR.Geometry dzGeom = dzxPolyLayer.GetFeature(tt).GetGeometryRef(); if (pdGeom.Intersect(dzGeom)) { double cha = Math.Abs(dzGeom.GetArea() - pdArea); if (cha < afterCha) { afterCha = cha; yesID = tt; } } } if (yesID != -1) { resLayer.CreateFeature(dzxPolyLayer.GetFeature(yesID)); } StaticTools.progress((pdi + 1) * 100 / abox.pdxIDs.Count, $"{pdi}/{abox.pdxIDs.Count} @ {i + 1} / {selectTree.Count}"); } } if (IsDelete) { shpDataSet.deleteLayerByName(slopePolyLayer.GetName()); shpDataSet.deleteLayerByName(dzxPolyLayer.GetName()); } return(resLayer); }