private IPolygon DissolvePolygon(ISpatialReference spatialRef, Dictionary <string, IPolygon> originPolygonDict, string[] originStrArr) { IGeometry geometryBag = new GeometryBagClass(); var geoCollection = (IGeometryCollection)geometryBag; ((IGeometry)geoCollection).SpatialReference = spatialRef; for (int i = 0; i < originStrArr.Length; i++) { var originStr = originStrArr[i]; object missing = Type.Missing; //var polygon = (IPolygon)((IClone)originPolygonDict[originStr]).Clone(); geoCollection.AddGeometry(originPolygonDict[originStr], ref missing, ref missing); } // 找到的要素合并为一个要素 IPolygon outPolygon = new PolygonClass(); ITopologicalOperator topologicalOperator = (ITopologicalOperator)outPolygon; topologicalOperator.ConstructUnion((IEnumGeometry)geometryBag); return(outPolygon); }
private IGeometry BufferExtAndIntBoundary(IPolygon4 polygon, double bufferDistance, bool draw) { IGeometry bndBuffer; object obj = Type.Missing; IGeometryCollection bufferGeometries = new GeometryBagClass() as IGeometryCollection; IGeometryBag exteriorRings = polygon.ExteriorRingBag; IEnumGeometry exteriorRingsEnum = exteriorRings as IEnumGeometry; exteriorRingsEnum.Reset(); IRing currentExteriorRing = exteriorRingsEnum.Next() as IRing; while (currentExteriorRing != null) { bndBuffer = BufferBoundary(currentExteriorRing, bufferDistance, false); bufferGeometries.AddGeometry(bndBuffer, ref obj, ref obj); //IPolygon4.get_InteriorRingBag should be used instead of IPolygon.QueryInteriorRings, //which does not work in .NET because of C-Style Arrays IGeometryBag interiorRings = polygon.get_InteriorRingBag(currentExteriorRing); IEnumGeometry interiorRingsEnum = interiorRings as IEnumGeometry; interiorRingsEnum.Reset(); IRing currentInteriorRing = interiorRingsEnum.Next() as IRing; while (currentInteriorRing != null) { bndBuffer = BufferBoundary(currentInteriorRing, bufferDistance, false); bufferGeometries.AddGeometry(bndBuffer, ref obj, ref obj); currentInteriorRing = interiorRingsEnum.Next() as IRing; } currentExteriorRing = exteriorRingsEnum.Next() as IRing; } ITopologicalOperator topoBufferGeometries = bufferGeometries as ITopologicalOperator; topoBufferGeometries.Simplify(); IPolygon buffPolygon = new PolygonClass(); ITopologicalOperator topoPolygon = buffPolygon as ITopologicalOperator; IEnumGeometry enumGeometry = bufferGeometries as IEnumGeometry; topoPolygon.ConstructUnion(enumGeometry); if (draw) { DrawGraphics(buffPolygon as IGeometry); } return(buffPolygon as IGeometry); }
private void SetPINValue() { //The Theory. //Select polygons that intersect the sketch. //Construct one polyline from the boundaries and intersect with sketch. //Sort resulting intersection locations (multipoint) by distance of the intersect // from the start of the sketch and create new ordered multipoint. //Loop through new ordered multipoint, select underlying parcel and calc pin. IFeatureLayer featLayer = m_editLayers.CurrentLayer; m_curve = m_edSketch.Geometry as IPolyline; //Search parcel polys by graphic to get feature cursor ISpatialFilter spatialFilter = new SpatialFilter(); spatialFilter.Geometry = m_curve; spatialFilter.GeometryField = m_editLayers.CurrentLayer.FeatureClass.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; IFeatureCursor featCursor = featLayer.Search(spatialFilter, true); IFeature feature = featCursor.NextFeature(); //If we have no intersects then exit if (feature == null) { return; } //Make a GeomBag of the polygons boundaries (polylines) IGeometryCollection geomBag = new GeometryBagClass(); object missing = Type.Missing; while (feature != null) { ITopologicalOperator poly = feature.Shape as ITopologicalOperator; geomBag.AddGeometry(poly.Boundary, ref missing, ref missing); feature = featCursor.NextFeature(); } //Make one polyline from the boundaries IPolyline polyLineU = new PolylineClass(); ITopologicalOperator topoOp = polyLineU as ITopologicalOperator; topoOp.ConstructUnion(geomBag as IEnumGeometry); //Get the intersections of the boundaries and the curve IPointCollection pointCol = topoOp.Intersect(m_curve, esriGeometryDimension.esriGeometry0Dimension) as IPointCollection; //The point collection is not ordered by distance along the curve so //need to create a new collection with this info int[] pointOrder = new int[pointCol.PointCount]; double dac = 0, dfc = 0; bool bRS = false; for (int i = 0; i < pointCol.PointCount; i++) { IPoint queryPoint = new PointClass(); pointCol.QueryPoint(i, queryPoint); m_curve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, queryPoint, false, null, ref dac, ref dfc, ref bRS); pointOrder[i] = (int)dac; } //use built in bubble sort System.Array.Sort(pointOrder); //Loop through the sorted array and calc midpoint between parcel boundaries IPointCollection midPoints = new MultipointClass(); for (int i = 0; i < pointOrder.Length - 1; i++) { //Get the midpoint distance double midPointDist = (pointOrder[i] + pointOrder[i + 1]) / 2; //create a point at the distance and store in point collection IPoint queryPoint = new PointClass(); m_curve.QueryPoint(esriSegmentExtension.esriNoExtension, midPointDist, false, queryPoint); midPoints.AddPoint(queryPoint, ref missing, ref missing); } //If ends of sketch are included then add them as points if (chkEnds.Checked) { object before = 0 as object; midPoints.AddPoint(m_curve.FromPoint, ref before, ref missing); midPoints.AddPoint(m_curve.ToPoint, ref missing, ref missing); } m_editor.StartOperation(); //Loop through calculated midpoints, select polygon and calc pin for (int i = 0; i < midPoints.PointCount; i++) { IPoint midPoint = midPoints.get_Point(i); spatialFilter = new SpatialFilter(); spatialFilter.Geometry = midPoint; spatialFilter.GeometryField = m_editLayers.CurrentLayer.FeatureClass.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin; featCursor = featLayer.Search(spatialFilter, false); while ((feature = featCursor.NextFeature()) != null) { feature.set_Value(feature.Fields.FindField(cmbPINField.Text), m_lotNum); feature.Store(); m_lotNum += int.Parse(txtlotinc.Text); } } m_editor.StopOperation("ViperPIN"); txtlot.Text = m_lotNum.ToString(); }
private bool AddEditArea(IServerObject serverObject, string creator, string versionName, int editCount, IEnvelope editZone, bool autoExpandZone = true) { bool isOk = false; IFeatureClass editAreasFC = null; try { // Open edit areas feature class in default workspace editAreasFC = GetEditAreaFeatureClass(serverObject); // Get field indices int creatorFIdx = editAreasFC.FindField(_creatorFName); int creationDateFIdx = editAreasFC.FindField(_creationDateFName); int lastUpdateFIdx = editAreasFC.FindField(_lastUpdateFName); int editCountFIdx = editAreasFC.FindField(_editCountFName); int versionNameFIdx = editAreasFC.FindField(_versionNameFName); DateTime currentTime = DateTime.Now; // Expand zone to make it more visible if (autoExpandZone) { double expandRatio = (editCount <= 3) ? 1.5 : 1.15; editZone.Expand(expandRatio, expandRatio, true); } // Check if there's an existing area IFeature curFeature = null; IFeatureCursor fCursor = GetEditAreas(serverObject, versionName); if (fCursor != null && (curFeature = fCursor.NextFeature()) != null) { // Union the edit zones IPolygon curZone = (IPolygon)curFeature.Shape; IGeometry geometryBag = new GeometryBag(); geometryBag.SpatialReference = curZone.SpatialReference; IGeometryCollection geometryCollection = (IGeometryCollection)geometryBag; geometryCollection.AddGeometry(curZone); geometryCollection.AddGeometry(editZone); Polygon zoneConstructor = new Polygon(); ITopologicalOperator newZone = (ITopologicalOperator)zoneConstructor; newZone.ConstructUnion((IEnumGeometry)geometryCollection); // Update feature values curFeature.Shape = (IGeometry)newZone; curFeature.Value[lastUpdateFIdx] = currentTime; int curCount = (int)curFeature.Value[editCountFIdx]; curFeature.Value[editCountFIdx] = curCount + editCount; // Store feature curFeature.Store(); curFeature = null; } else { // Save edit zone to feature class IFeature zoneFeature = editAreasFC.CreateFeature(); zoneFeature.Value[creatorFIdx] = creator; zoneFeature.Value[creationDateFIdx] = currentTime; zoneFeature.Value[lastUpdateFIdx] = currentTime; zoneFeature.Value[versionNameFIdx] = versionName; zoneFeature.Value[editCountFIdx] = editCount; // Set geometry Polygon editAreaPoly = new Polygon(); ISegmentCollection editAreaSeg = (ISegmentCollection)editAreaPoly; editAreaSeg.SetRectangle(editZone); IZAware polyZAware = editAreaPoly as IZAware; polyZAware.ZAware = false; zoneFeature.Shape = polyZAware as IGeometry; // Store feature zoneFeature.Store(); fCursor.Flush(); fCursor = null; zoneFeature = null; } isOk = true; } catch (Exception e) { _serverLog.LogMessage(ServerLogger.msgType.infoStandard, _soiName + ".AddEditArea()", 200, "Error while adding edit are: " + e.ToString()); } finally { editAreasFC = null; } return(isOk); }
/// <summary> /// 合并多条多义线,如果合并的多义线不是简单的多义线则抛出异常 /// </summary> /// <param name="pPolylines">多义线集</param> /// <returns>多义线</returns> public static IPolyline UnionPolylines(IPolyline[] pPolylines) { // 第一条线段 int indexFirst = -1; int degree = 0; IRelationalOperator pRO = null; int nSelected = pPolylines.Length; IPolyline pRetPolyline = new PolylineClass(); ITopologicalOperator pTopoOper = (ITopologicalOperator)pRetPolyline; IGeometryCollection pGeometryCollection = new GeometryBagClass(); for (int i = 0; i < pPolylines.Length; i++) { object o = Type.Missing; pGeometryCollection.AddGeometry(pPolylines[i], ref o, ref o); } pTopoOper.ConstructUnion((IEnumGeometry)pGeometryCollection); IGeometryCollection pGeometryColl = (IGeometryCollection)pTopoOper; if (pGeometryColl.GeometryCount > 1) { throw new Exception("线段的空间连接不正确"); } return((IPolyline)pTopoOper); // AddGeometry // 数据检查 //ConstructUnion /* * double tol = GeometryHelper.ConvertPixelsToMapUnits(pActiveView, 4); * IPoint pHitPoint = null; * double hitDist = 0; * int partIndex = 0; * int vertexIndex = 0; * int vertexOffset = 0; * bool vertex = false; * if (EditHelper.HitTest(tol, _pMenuPosition, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex)) * { * * } */ for (int i = 0; i < nSelected; i++) { int nTouch = 0; pRO = (IRelationalOperator)pPolylines[i]; IHitTest hittest = (IHitTest)pRO; for (int j = 0; j < nSelected; j++) { if (i != j && pRO.Touches(pPolylines[j])) { nTouch++; } } if (nTouch == 0 || nTouch > 2) { throw new Exception("line touch error"); } else if (nTouch == 1) { if (indexFirst == -1) { indexFirst = i; } if (++degree > 2) { throw new Exception("multi patchs"); } } } // 依据第一条线topo有序 if (indexFirst == -1) { throw new Exception("line circle"); } IPolyline pTemp = pPolylines[indexFirst]; pPolylines[indexFirst] = pPolylines[0]; pPolylines[0] = pTemp; IPolyline pPolyline = new PolylineClass(); ISegmentCollection pSegments = (ISegmentCollection)pPolyline; pSegments.AddSegmentCollection((ISegmentCollection)pPolylines[0]); for (int i = 0; i < nSelected - 1; i++) { pRO = (IRelationalOperator)pPolylines[i]; for (int j = i + 1; j < nSelected; j++) { if (pRO.Touches(pPolylines[j])) { pTemp = pPolylines[j]; pPolylines[j] = pPolylines[i + 1]; pPolylines[i + 1] = pTemp; if (IdentialPoint(pPolylines[i].FromPoint, pPolylines[i + 1].ToPoint)) { //pSegments.AddSegmentCollection(); } break; } } } return(null); }