public static void MatchCpg(ref List <CPolygon> pLSCPgLt, ref List <CPolygon> pSSCPgLt, ref List <CPolygon> InterLSAttentionCPgLt, ref List <CPolygon> SSAttentionCPgLt) { //for a SSCPg, we calculate the intersect area with each exsiting InterLSCPg, and calcuate the intersect area foreach (var cpg in pLSCPgLt) { cpg.isMatched = false; } foreach (var pSSCPg in pSSCPgLt) { pSSCPg.CorrCGeoLt = new List <CGeoBase>(); ITopologicalOperator pSSCPgTop = pSSCPg.pPolygon as ITopologicalOperator; foreach (var cpg in pLSCPgLt) { if (cpg.isMatched == false) { //Console.WriteLine(pSSCPg.CptLt[0].X); //Console.WriteLine(pSSCPg.CptLt[0].Y); //Console.WriteLine(cpg.CptLt[0].X); //Console.WriteLine(cpg.CptLt[0].Y); IPolygon4 ipg = cpg.pPolygon; double dblIntersectArea = (pSSCPgTop.Intersect(ipg as IGeometry, esriGeometryDimension.esriGeometry2Dimension) as IArea).Area; double dblIntersectRatio = dblIntersectArea / (ipg as IArea).Area; if (dblIntersectRatio > 0.5) { pSSCPg.CorrCGeoLt.Add(cpg); cpg.isMatched = true; } } } if (pSSCPg.CorrCGeoLt.Count == 0) { SSAttentionCPgLt.Add(pSSCPg); } } //InterLSAttentionCPgLt foreach (var lscpg in pLSCPgLt) { if (lscpg.isMatched == false) { InterLSAttentionCPgLt.Add(lscpg); } } }
/// <summary> /// This function will return a point collection for intersections along a curve /// </summary> /// <param name="inFeature">the feature to intersect</param> /// <param name="inTopOp">the curve to use to intersect the feature</param> /// <returns>a point collection of intersecting points along the infeature</returns> public static IPointCollection PerformTopologicalIntersect(IFeature inFeature, ITopologicalOperator inTopOp) { try { IPolycurve pFeatureShape = inFeature.Shape as IPolycurve; IMultipoint pIntersection = (IMultipoint)inTopOp.Intersect(pFeatureShape, esriGeometryDimension.esriGeometry0Dimension); return((IPointCollection)pIntersection); } catch (Exception ex) { throw new Exception(ex.Message); } }
private IPoint GetIntersectPoint(IPolyline line1, IPolyline line2) { IPoint pnt = null; ITopologicalOperator topo = line1 as ITopologicalOperator; IGeometry geo = topo.Intersect(line2, esriGeometryDimension.esriGeometry0Dimension); IMultipoint mulpoint = geo as IMultipoint; IPointCollection pntcol = mulpoint as IPointCollection; if (pntcol != null) { pnt = pntcol.get_Point(0); } return(pnt); }
/// 粗略判断一个已知点是否在线上 private bool isPointOnLine(IPoint pPoint, IPolyline myLine) { ITopologicalOperator topo = pPoint as ITopologicalOperator; IGeometry buffer = topo.Buffer(0.00001); //缓冲一个极小的距离 topo = buffer as ITopologicalOperator; IGeometryCollection pgeo = topo.Intersect(myLine, esriGeometryDimension.esriGeometry0Dimension) as IGeometryCollection; bool result = false; if (pgeo.GeometryCount > 0) { result = true; } return(result); }
/// <summary> /// 获取两个几何形状的交集,并传出相交后的几何形状和错误信息。 /// </summary> /// <param name="geometry1">待相交的几何形状1</param> /// <param name="geometry2">待相交的几何形状2</param> /// <param name="Intersected">相交后的几何形状</param> /// <param name="ErrMsg">错误信息</param> public static void Intersect(IGeometry geometry1, IGeometry geometry2, out IGeometry Intersected, out string ErrMsg) { ErrMsg = ""; Intersected = null; if (GeometryUtility.IsHighLevelGeometry(geometry1) && GeometryUtility.IsHighLevelGeometry(geometry2)) { if (!RelationalOperator.Disjoint(geometry1, geometry2)) { esriGeometryDimension resultDimension = esriGeometryDimension.esriGeometryNoDimension; if (geometry1.Dimension <= geometry2.Dimension) { resultDimension = geometry1.Dimension; } else { resultDimension = geometry2.Dimension; } ITopologicalOperator topoOp = (ITopologicalOperator)geometry1; IGeometry geometry = topoOp.Intersect(geometry2, resultDimension); if (GeometryUtility.IsValidGeometry(geometry)) { try { Simplify(geometry); Intersected = geometry; } catch (Exception ex) { ErrMsg = ex.Message; } } else { ErrMsg = "传入的几何形状获取交集失败。"; } } else { ErrMsg = "传入的几何形状没有交集。"; } } else { ErrMsg = "传入的几何形状不是高级几何形状,不能获取交集。"; } }
/// <summary> /// 根据当前绘制的线段判断在中心线分段图层中与之相交的线段, /// 根据z值判断上下层关系,返回对应的Id属性信息 /// </summary> /// <param name="plin">要绘制的中心线</param> /// <param name="centlyr">中心线图层</param> /// <param name="HdId">巷道Id</param> /// <returns>返回线对象的Id值,决定显示效果</returns> public int SearchHdByLine(IPolyline plin, string HdId, IFeatureLayer centlyr) { int ires = 0; string sql = "\"" + GIS_Const.FIELD_HDID + "\"<>'" + HdId + "'"; IFeatureCursor crosslines = SpatialSearch(plin, sql, centlyr); if (crosslines != null) { int fldindex = centlyr.FeatureClass.FindField(GIS_Const.FIELD_ID); IFeature fea = crosslines.NextFeature(); while (fea != null) { int IdVal = Convert.ToInt16(fea.get_Value(fldindex)); IPolyline polyline = fea.Shape as IPolyline; ITopologicalOperator toplogical = (ITopologicalOperator)plin; IGeometry geo = toplogical.Intersect(polyline, esriGeometryDimension.esriGeometry0Dimension); IMultipoint mulpoint = geo as IMultipoint; IPointCollection pntcol = mulpoint as IPointCollection; if (pntcol != null && pntcol.PointCount > 0) { // 交点 IPoint pntjd = pntcol.get_Point(0); if (pntjd != null) { // 巷道高度判断 int res = CheckHdGd(plin, polyline, pntjd); if (res == 0)//同一层 { ires = 0; } else if (res == -1)//下一层 { ires = -1; } else//在上一层 { ires = 1; } } } fea = crosslines.NextFeature(); } } return(ires); }
public void InsertPointAtIntersection(ref IPolyline pPolyline, IGeometry pOther, double hmgetal) { bool SplitHappened = false; int newPartIndex = 0; int newSegmentIndex = 0; int index = 0; List <int> indices; IPoint Point = null; IClone pClone = pPolyline.SpatialReference as IClone; if (pClone.IsEqual(pOther.SpatialReference as IClone) == false) { pOther.Project(pPolyline.SpatialReference); } ITopologicalOperator pTopoOp = pOther as ITopologicalOperator; pTopoOp.Simplify(); pTopoOp = pPolyline as ITopologicalOperator; IGeometry pGeomResult = pTopoOp.Intersect(pOther, esriGeometryDimension.esriGeometry0Dimension); indices = new List <int>(); if ((pGeomResult is IPointCollection) && ((pGeomResult as IPointCollection).PointCount > 0)) { for (int i = 0; i < (pGeomResult as IPointCollection).PointCount; i++) { (pPolyline as IPolycurve2).SplitAtPoint((pGeomResult as IPointCollection).get_Point(i), true, false, out SplitHappened, out newPartIndex, out newSegmentIndex); //TODO Zet de measure op het ingevoegde punt, houdt rekening met partindex en segmentindex for (int j = 0; j < newPartIndex; j++) { index += ((pPolyline as IGeometryCollection).get_Geometry(j) as IPointCollection).PointCount; } index += newSegmentIndex; Point = (pPolyline as IPointCollection).get_Point(index); Point.M = hmgetal; (pPolyline as IPointCollection).UpdatePoint(index, Point); } } (pPolyline as ITopologicalOperator2).IsKnownSimple_2 = false; (pPolyline as IPolyline4).SimplifyEx(true); }
/// <summary> /// 如果是Polygon,进行自重叠检查 /// </summary> /// <returns></returns> public bool CheckSelfOverlap(List <FeatureObject> featureList, out string outMsg) { bool result = false; outMsg = string.Empty; try { for (int i = 0; i < featureList.Count; i++) { FeatureObject foi = featureList[i]; if (foi.geometry == null || foi.geometry.IsEmpty) { continue; } ITopologicalOperator pITop = (ITopologicalOperator)foi.geometry; for (int j = i + 1; j < featureList.Count; j++) { FeatureObject foj = featureList[j]; if (foj.geometry == null || foj.geometry.IsEmpty) { continue; } IGeometry overlapGeo = pITop.Intersect(foj.geometry, esriGeometryDimension.esriGeometry2Dimension); if (overlapGeo != null && !overlapGeo.IsEmpty) { result = true; int i_int = i + 1; int j_int = j + 1; outMsg += string.Format("传入的地块集合中第{0}和第{1}个地块是相互重叠的;", i_int, j_int); } } } } catch (Exception ex) { outMsg += ex.Message; result = true; } return(result); }
private IPolygon intersectWithRasterEnvelope() { try { IRasterProps pRasterProps = m_pSrcRaster as IRasterProps; IEnvelope pSrcEnvelope = pRasterProps.Extent; ITopologicalOperator pTopologicalOp = m_pClipPolygon as ITopologicalOperator; IGeometry pDstGeometry = pTopologicalOp.Intersect(pSrcEnvelope as IGeometry, esriGeometryDimension.esriGeometry2Dimension); IPolygon pResultPolygon = pDstGeometry as IPolygon; return(pResultPolygon); } catch (System.Exception ex) { return(null); } }
/// <summary> /// 将line1延长与line2相交后求交点 /// </summary> /// <params name="line1"></params> /// <params name="line2"></params> /// <returns></returns> private IPoint GetIntersectPointExtend(IPolyline line1, IPolyline line2) { IPoint pnt = null; IConstructCurve constructCurve = new PolylineClass(); bool isExtensionPerfomed = false; constructCurve.ConstructExtended(line1, line2, (int)esriCurveExtension.esriDefaultCurveExtension, ref isExtensionPerfomed); ITopologicalOperator topo = constructCurve as ITopologicalOperator; IGeometry geo = topo.Intersect(line2, esriGeometryDimension.esriGeometry0Dimension); IMultipoint mulpoint = geo as IMultipoint; IPointCollection pntcol = mulpoint as IPointCollection; if (pntcol != null && pntcol.PointCount > 0) { pnt = pntcol.get_Point(0); } return(pnt); }
/* * THIS FUNCTION IS used to choose which bigger polygons in layer * is suitable for specific features in SelectionSet to Merge * UNDER privilige : same previous type && same region && longest public side */ public static void Processing(IFeatureSelection selectedfeatureselection, ILayer layer) { /*Initialize inner loop for every feature in the layer*/ IFeatureLayer featurelayer = layer as IFeatureLayer; IFeatureCursor featurecursor = featurelayer.Search(null, false); IFeature feature = featurecursor.NextFeature(); /*Initialize outter loop for features in selectionset*/ ISelectionSet selectionset = selectedfeatureselection.SelectionSet; ICursor cursor; selectionset.Search(null, false, out cursor); IFeatureCursor selectedfeaturecursor = cursor as IFeatureCursor; IFeature selectedfeature = selectedfeaturecursor.NextFeature(); IFeatureCursor mark; while (selectedfeature != null) { IGeometry selectedgeom = selectedfeature.Shape; double maxcommonside = 0; while (feature != null) { if (Is_Touch(selectedgeom, feature.Shape)) { ITopologicalOperator intersectOp = feature.Shape as ITopologicalOperator; IPolycurve commonside = (IPolycurve)intersectOp.Intersect(selectedgeom, esriGeometryDimension.esriGeometry1Dimension); /*THIS can be replaced by any other comparing model*/ if (commonside.Length > maxcommonside) { maxcommonside = commonside.Length; mark = featurecursor; } } feature = featurecursor.NextFeature(); } selectedfeature = selectedfeaturecursor.NextFeature(); } }
/// <summary> /// 得到Geometry和Polyline的交点 /// </summary> /// <param name="vIntersect"></param> /// <param name="vOther"></param> /// <returns></returns> private IGeometry GetIntersection(IGeometry vIntersect, IPolyline vOther) { //判断这两个是否有交点 IEnvelope pEnvIntersect = vIntersect.Envelope; IEnvelope pEnvOther = vOther.Envelope; if (pEnvIntersect.XMax < pEnvOther.XMin || pEnvIntersect.XMin > pEnvOther.XMax || pEnvIntersect.YMax < pEnvOther.YMin || pEnvIntersect.YMin > pEnvOther.YMax) { return(null); } if (vIntersect.SpatialReference != null && !vIntersect.SpatialReference.Equals(vOther.SpatialReference)) { vOther.Project(vIntersect.SpatialReference); } ITopologicalOperator vTopoOp = vIntersect as ITopologicalOperator; vTopoOp.Simplify(); IGeometry vGeomResult = vTopoOp.Intersect(vOther, esriGeometryDimension.esriGeometry0Dimension); if (vGeomResult == null) { return(null); } if (vGeomResult is IPointCollection) { if (!((vGeomResult as IPointCollection).PointCount >= 1)) { return(null); } } if (!(vGeomResult.GeometryType == esriGeometryType.esriGeometryMultipoint)) { return(null); } return(vGeomResult); }
private static IPointCollection GetIntersection(IGeometry pIntersect, IPolyline pPolyline) { if (pIntersect.SpatialReference.SpatialReferenceImpl != pPolyline.SpatialReference.SpatialReferenceImpl) { pPolyline.Project(pIntersect.SpatialReference); } ITopologicalOperator pTopoOp = pIntersect as ITopologicalOperator; pTopoOp.Simplify(); IGeometry pGeomResult = pTopoOp.Intersect(pPolyline, esriGeometryDimension.esriGeometry0Dimension); if (pGeomResult == null) { return(null); } IPointCollection pPointCollection = pGeomResult as IPointCollection; return(pPointCollection); }
private bool GetDriveCenterlineIntersection(IPolyline drive) { try { ISpatialFilter sp = new SpatialFilterClass(); sp.Geometry = drive; sp.GeometryField = Globals.CenterlineLayer.FeatureClass.ShapeFieldName; sp.SearchOrder = esriSearchOrder.esriSearchOrderSpatial; sp.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IFeatureSelection fs = (IFeatureSelection)Globals.CenterlineLayer; fs.SelectFeatures(sp, esriSelectionResultEnum.esriSelectionResultNew, true); ISelectionSet selset = fs.SelectionSet; if (selset.Count < 1) { return(false); } else { IEnumIDs penum = selset.IDs; int xid = penum.Next(); IFeature f = Globals.CenterlineLayer.FeatureClass.GetFeature(xid); Centerline = f; ITopologicalOperator to = (ITopologicalOperator)drive; IGeometry g = to.Intersect(f.Shape, esriGeometryDimension.esriGeometry0Dimension); IMultipoint mp = (IMultipoint)g; IPointCollection pc = (IPointCollection)mp; IPoint p = pc.get_Point(0); //IPoint p = (IPoint)g; intersectionPoint = p; return(true); } } catch (Exception ex) { log.WriteError(ex, TAG, System.Security.Principal.WindowsIdentity.GetCurrent().Name, null); return(false); } }
public virtual IGeometry IntersectsSameDim(IGeometry byGeo, IGeometry pGeo, esriGeometryDimension pesriGeometryDimension) { IGeometry retGeo = null; IGeometry TopGeometry1 = byGeo; IGeometry TopGeometry2 = pGeo; if (TopGeometry1 == null || TopGeometry2 == null || TopGeometry1.IsEmpty == true || TopGeometry2.IsEmpty == true) { retGeo = null; MessageBox.Show("空间叠加有一对象为空", "空间分析错误"); return(retGeo); } if (TopGeometry1.Dimension != TopGeometry2.Dimension) { retGeo = null; MessageBox.Show("空间叠加两对象维数不同不能空间叠加分析", "空间分析错误"); return(retGeo); } if (!(TopGeometry1 is ITopologicalOperator) && !(TopGeometry2 is ITopologicalOperator)) { retGeo = null; MessageBox.Show("空间叠加有一对象不是高级对象(Point,Polygon,Polyline,MuliPoint,GemetryBag)", "空间分析错误"); return(retGeo); } Topoperator = (ITopologicalOperator)TopGeometry2; Topoperator.Simplify(); Topoperator = (ITopologicalOperator)TopGeometry1; Topoperator.Simplify(); try { retGeo = Topoperator.Intersect(TopGeometry2, pesriGeometryDimension); } catch (Exception ee) { retGeo = null; System.Diagnostics.Debug.WriteLine(ee.ToString()); } return(retGeo); }
public IGeometry GetSubGeometry() { try { if (m_pIFeature == null) return null; if (m_CutGeometry == null) return (m_pIFeature as IFeature).Shape; IGeometry pFeatureShape = (m_pIFeature as IFeature).Shape; ITopologicalOperator pTop = m_CutGeometry as ITopologicalOperator; //if (pFeatureShape.GeometryType == esriGeometryType.esriGeometryLine||pFeatureShape.GeometryType == esriGeometryType.esriGeometryPolyline) // return pTop.Intersect(pFeatureShape, esriGeometryDimension.esriGeometry0Dimension); //else if (pFeatureShape.GeometryType == esriGeometryType.esriGeometryPolygon) //{ // return pTop.Intersect(pFeatureShape, esriGeometryDimension.esriGeometry2Dimension); //} return pTop.Intersect(pFeatureShape, pFeatureShape.Dimension); } catch(Exception ex) { Logger.WriteLog("裁剪要素【"+(m_pIFeature.Table as IDataset).BrowseName+"】时出错!\r\n"); return null; } }
/// <summary /// 删除线或面在接边儿线处的多余点 2013.8.23 TianKuo 添加 /// </summary> /// <param name="pFCursor">接边儿要素集合对象</param> /// <param name="pGeo">接边面边界</param> private static void DeleteJieBianPoint(ref IGeometry pGeoDelPoint, IGeometry pGeo) { IPointCollection pPointCBuFen; IGeometryCollection pGeoCollection; IPoint pPt, pPoint; ITopologicalOperator pTopoOp = pGeo as ITopologicalOperator; ITopologicalOperator pTopoOp1; bool isFind = false; IPointCollection pPointIntersect = null; pTopoOp1 = pGeoDelPoint as ITopologicalOperator; //pTopoOp1.Simplify(); pGeoDelPoint.SnapToSpatialReference(); try { pPointIntersect = pTopoOp.Intersect((IGeometry)pTopoOp1, esriGeometryDimension.esriGeometry0Dimension) as IPointCollection; } catch { Console.WriteLine("空间查询出错!"); } if (pPointIntersect.PointCount > 0) { for (int i = 0; i < pPointIntersect.PointCount; i++) //循环每一个交点 { pPt = pPointIntersect.get_Point(i); isFind = false; pGeoCollection = pGeoDelPoint as IGeometryCollection; for (int k = 0; k < pGeoCollection.GeometryCount; k++) //循环每一个部件 { pPointCBuFen = pGeoCollection.get_Geometry(k) as IPointCollection; if (pGeoDelPoint.GeometryType == esriGeometryType.esriGeometryPolygon) { for (int j = 0; j < pPointCBuFen.PointCount; j++) //面的起点或终点可以删除 { pPoint = pPointCBuFen.get_Point(j); if (Math.Abs(pPt.X - pPoint.X) < 0.005 && Math.Abs(pPt.Y - pPoint.Y) < 0.005) { pPointCBuFen.RemovePoints(j, 1); //删除接边儿点 isFind = true; break; } } } else { for (int j = 1; j < pPointCBuFen.PointCount - 1; j++) //线的起点和终点即使是接边儿点儿,也不能删除 { pPoint = pPointCBuFen.get_Point(j); if (Math.Abs(pPt.X - pPoint.X) < 0.005 && Math.Abs(pPt.Y - pPoint.Y) < 0.005) { pPointCBuFen.RemovePoints(j, 1); //删除接边儿点 isFind = true; break; } } } if (isFind) { break; } } } } }
/// <summary> /// Summarise the features of an input feature class that fall within an input polygon. /// Input features can be points, lines, or polygons. A value field and a category field can be provided. /// If a category field is provided then this will be used like a GROUP BY clause in SQL and return will be broken down by /// category, in addition to the overall totals. /// If a value field is provided then it will be totalled (by category if provided), e.g. population in a polygon. /// But as some line / polygon features may be only partially contained we need to decide how to handle the values on those. /// Currently we just scale based on the proportion of the original feature that is included but there would be /// alternatives: count all or nothing based on inclusion of majority of feature, or centre of feature. Not yet implemented. /// </summary> /// <param name="pInputPolygon"> /// The IPolygon which will be used to clip and summarise the features from the second parameter /// </param> /// <param name="pInputFeatures"> /// The features which will be clipped and summarised. IFeatureClass that must be of ShapeType /// esriGeometryPoint, esriGeometryPolyline or esriGeometryPolygon /// </param> /// <param name="pCategoryFieldNum"> /// ID (integer) of a field in the feature class containing values by which the results should be grouped. Can be /// any field type but integer, string, etc are recommended. Value of -1 means no summation by category will occur. /// Set to -1 to not do this summary /// </param> /// <param name="pValueFieldNum"> /// ID (integer of a field in the feature class containing values by which the results should be totalled. For example /// population of counties, value of land parcels. Done in addition to totalling area / length / count. /// Set to -1 to not do this summary /// </param> /// <param name="pMeasureFieldNum"> /// ID (integer) of a field in the feature class containing pre-calculated values for area (polygons) or length (lines). /// Can be used to speed calculation of these properties. They will be calculated manually for features partially /// within the input polygon. /// </param> /// <returns> /// FeatureExtractionResult object containing: /// total feature count, /// total feature length / area (for lines / polygons), /// total feature value (from value field if provided), /// plus each of the above broken down by category if a category field is provided /// category results are each a dictionary of key=category value (as string), value=int or double /// </returns> internal static FeatureExtractionResult SummariseFeatures(IPolygon pInputPolygon, ExtractionLayerConfig pExtractionLayerConfig) //IFeatureClass pInputFeatures,int pCategoryFieldNum, int pValueFieldNum, int pMeasureFieldNum) { // use cast rather than as to make sure it blows up if the geodataset isn't // a feature class IFeatureClass pInputFeatures = (IFeatureClass)pExtractionLayerConfig.LayerDataset; esriGeometryType tFCType = pInputFeatures.ShapeType; // set up variables to build results Dictionary <string, int> tCategoryCounts = new Dictionary <string, int>(); Dictionary <string, double> tCategoryTotals = new Dictionary <string, double>(), tCategoryMeasures = new Dictionary <string, double>(); double tTotalMeasure = 0, tTotalValue = 0; int tTotalCount = 0; // variables to control search bool hasCategories = pExtractionLayerConfig.HasCategories; bool hasMeasures = pExtractionLayerConfig.HasMeasures; bool hasPreCalcMeasures = hasMeasures && (pExtractionLayerConfig.MeasureField != -1); bool hasValues = false; if (pExtractionLayerConfig.HasValues && pExtractionLayerConfig.ValueField != -1) { // only numeric fields will be totalled //esriFieldType tValueFieldType = pInputFeatures.Fields.get_Field(pValueFieldNum).Type; esriFieldType tValueFieldType = pInputFeatures.Fields.get_Field(pExtractionLayerConfig.ValueField) .Type; if (tValueFieldType == esriFieldType.esriFieldTypeDouble || tValueFieldType == esriFieldType.esriFieldTypeInteger || tValueFieldType == esriFieldType.esriFieldTypeSingle || tValueFieldType == esriFieldType.esriFieldTypeSmallInteger) { hasValues = true; } } // use a spatial filter to do the geographic selection ISpatialFilter tSpatialFilter = new SpatialFilterClass(); tSpatialFilter.Geometry = pInputPolygon as IGeometry; // first we will select all features wholly within the polygon. We don't need to do anything special with these // just use them as is. This applies for points, lines and polys. It is the only thing required for points. tSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains; tSpatialFilter.GeometryField = "SHAPE"; // safe to use a recycling cursor: we are not maintaining a reference to features across multiple calls to NextFeature IFeatureCursor tFeatureCursor = pInputFeatures.Search(tSpatialFilter, true); IFeature tThisFeature = tFeatureCursor.NextFeature(); try { while (tThisFeature != null) { tTotalCount += 1; double tMeasure = 0; if (hasPreCalcMeasures) { try { //tMeasure = (double)tThisFeature.get_Value(pMeasureFieldNum); tMeasure = (double)tThisFeature.get_Value(pExtractionLayerConfig.MeasureField); } catch { hasPreCalcMeasures = false; if (tFCType == esriGeometryType.esriGeometryPolyline) { IPolyline tFeatureAsLine = tThisFeature.Shape as IPolyline; tMeasure = tFeatureAsLine.Length; } else if (tFCType == esriGeometryType.esriGeometryPolygon) { IArea tFeatureAsArea = tThisFeature.Shape as IArea; tMeasure = tFeatureAsArea.Area; } } } else { if (tFCType == esriGeometryType.esriGeometryPolyline) { IPolyline tFeatureAsLine = tThisFeature.Shape as IPolyline; tMeasure = tFeatureAsLine.Length; } else if (tFCType == esriGeometryType.esriGeometryPolygon) { IArea tFeatureAsArea = tThisFeature.Shape as IArea; tMeasure = tFeatureAsArea.Area; } } tTotalMeasure += tMeasure; if (hasCategories) { // get the category / class of this featue string tCategory = tThisFeature.get_Value(pExtractionLayerConfig.CategoryField).ToString(); // placeholders for the dictionary lookups (out variables) int tCurrentCategoryCount; double tCurrentCategoryMeasure; // add 1 to the appropriate category count in the category counts dictionary if (tCategoryCounts.TryGetValue(tCategory, out tCurrentCategoryCount)) { tCategoryCounts[tCategory] = tCurrentCategoryCount + 1; } else { tCategoryCounts[tCategory] = 1; } if (tCategoryMeasures.TryGetValue(tCategory, out tCurrentCategoryMeasure)) { tCategoryMeasures[tCategory] = tCurrentCategoryMeasure + tMeasure; } else { tCategoryMeasures[tCategory] = tMeasure; } if (hasValues) { // i.e. look up the value from another field, other than just the feature's length/area and count double tCurrentCategoryTotal; //double tCurrentArcValue = (double)tThisFeature.get_Value(pValueFieldNum); double tCurrentArcValue = (double)tThisFeature.get_Value(pExtractionLayerConfig.ValueField); tTotalValue += tCurrentArcValue; if (tCategoryTotals.TryGetValue(tCategory, out tCurrentCategoryTotal)) { tCategoryTotals[tCategory] = tCurrentCategoryTotal + tCurrentArcValue; } else { tCategoryTotals[tCategory] = tCurrentArcValue; } } } else if (hasValues) { //double tCurrentArcValue = (double)tThisFeature.get_Value(pValueFieldNum); double tCurrentArcValue = (double)tThisFeature.get_Value(pExtractionLayerConfig.ValueField); tTotalValue += tCurrentArcValue; } tThisFeature = tFeatureCursor.NextFeature(); } // now for lines and polygons we need to process the features that are partially inside the polygon. // this process would work on all the features but there is no point doing expensive intersections where we // don't need to, so we did the wholly-contained features separately // we need to find the features where there is an intersection between the polygon boundary and the feature's // interior. Could use shape description language but this is covered by available spatialrelenum values bool doPartialFeatures = ((tFCType == esriGeometryType.esriGeometryPolyline || tFCType == esriGeometryType.esriGeometryPolygon)); // a point is either in or out! // not yet implemented: control how partially-intersecting features are handled //&& pFeatureIntersectionMode != IntersectingFeatureSelectionMode.SelectNoPartialFeatures); if (doPartialFeatures) { if (tFCType == esriGeometryType.esriGeometryPolyline) { // "A polyline and a polygon cross if they share a polyline or a point (for vertical line) in common on the // interior of the polygon which is not equivalent to the entire polyline." tSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; } else if (tFCType == esriGeometryType.esriGeometryPolygon) { // "Two geometries overlap if the region of their intersection is of the same dimension as the geometries involved // and is not equivalent to either of the geometries." tSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps; } // no longer safe to use recycling cursor as we're going to tinker with the features returned tFeatureCursor = pInputFeatures.Search(tSpatialFilter, false); tThisFeature = tFeatureCursor.NextFeature(); ITopologicalOperator tInputAsTopoOp = pInputPolygon as ITopologicalOperator; int tNumberCrossingBoundary = 0; while (tThisFeature != null) { // return (so track) the number of partially-included features separately from the overall total tNumberCrossingBoundary += 1; tTotalCount += 1; // either the length or area of the intersected feature: double tMeasure = 0; // either the length or area of entire original intersected feature // (to get proportion that's included): double tOriginalMeasure = 0; // do the IGeometry tFeatureGeometry = tThisFeature.ShapeCopy; if (tFCType == esriGeometryType.esriGeometryPolyline) { IPolyline tArcEntire = tFeatureGeometry as IPolyline; tOriginalMeasure = tArcEntire.Length; IPolyline tArcInside = tInputAsTopoOp.Intersect(tFeatureGeometry, esriGeometryDimension.esriGeometry1Dimension) as IPolyline; tMeasure = tArcInside.Length; } else { IArea tAreaEntire = tFeatureGeometry as IArea; tOriginalMeasure = tAreaEntire.Area; IArea tAreaInside = tInputAsTopoOp.Intersect(tFeatureGeometry, esriGeometryDimension.esriGeometry2Dimension) as IArea; tMeasure = tAreaInside.Area; } tTotalMeasure += tMeasure; if (hasCategories) { //string tCategory = tThisFeature.get_Value(pCategoryFieldNum).ToString(); string tCategory = tThisFeature.get_Value(pExtractionLayerConfig.CategoryField).ToString(); int tCurrentCategoryCount; double tCurrentCategoryMeasure; if (tCategoryCounts.TryGetValue(tCategory, out tCurrentCategoryCount)) { tCategoryCounts[tCategory] = tCurrentCategoryCount + 1; } else { tCategoryCounts[tCategory] = 1; } if (tCategoryMeasures.TryGetValue(tCategory, out tCurrentCategoryMeasure)) { tCategoryMeasures[tCategory] = tCurrentCategoryMeasure + tMeasure; } else { tCategoryMeasures[tCategory] = tMeasure; } if (hasValues) { // how should we handle a value field in an intersected feature? we can't, for certain, // as we don't know what they mean. We'll just assume that it scales proportionally with the // proportion of the original feature's length / area that is included. // The raster equivalent is to count all or none based on cell centre, so maybe we should count // all or none based on centroid?? double tCurrentCategoryTotal; //double tCurrentFeatureValue = (double)tThisFeature.get_Value(pValueFieldNum); double tCurrentFeatureValue = (double)tThisFeature.get_Value( pExtractionLayerConfig.ValueField); double tScaledFeatureValue = (tMeasure / tOriginalMeasure) * tCurrentFeatureValue; tTotalValue += tScaledFeatureValue; if (tCategoryTotals.TryGetValue(tCategory, out tCurrentCategoryTotal)) { tCategoryTotals[tCategory] = tCurrentCategoryTotal + tScaledFeatureValue; } else { tCategoryTotals[tCategory] = tScaledFeatureValue; } } } else if (hasValues) { //double tCurrentFeatureValue = (double)tThisFeature.get_Value(pValueFieldNum); double tCurrentFeatureValue = (double)tThisFeature.get_Value(pExtractionLayerConfig.ValueField); double tScaledFeatureValue = (tMeasure / tOriginalMeasure) * tCurrentFeatureValue; tTotalValue += tScaledFeatureValue; } tThisFeature = tFeatureCursor.NextFeature(); } } double?outMeasure; double?outValue; if (hasMeasures) { outMeasure = tTotalMeasure; } else { outMeasure = null; } if (hasValues) { outValue = tTotalValue; } else { outValue = null; } FeatureExtractionResult tResult = new FeatureExtractionResult( pExtractionLayerConfig.ParamName, tTotalCount, outMeasure, outValue, tCategoryCounts, tCategoryMeasures, tCategoryTotals, pInputFeatures.ShapeType ); return(tResult); } catch (Exception ex) { logger.LogMessage(ServerLogger.msgType.debug, "process features", 99, "error summarising features in " + pInputFeatures.AliasName + " Detail: " + ex.StackTrace + " " + ex.Message); return(new FeatureExtractionResult("An error occurred with extraction from " + pInputFeatures.AliasName, pExtractionLayerConfig.ParamName)); } }
/// <summary> /// 获取交点 /// </summary> /// <param name="TaskAreas"></param> /// <param name="map"></param> public static void getIntersect(ESRI.ArcGIS.Controls.AxMapControl pMapCtr) { Core.Map.MapHelper map = new Core.Map.MapHelper(pMapCtr); Core.Generic.myXML xml = new Core.Generic.myXML(System.Windows.Forms.Application.StartupPath + "\\Setting.xml"); try { IFeatureClass pFeatureClass = null; Core.Model.DisaCrossPoint gatherPoint = new Core.Model.DisaCrossPoint(); Core.DAL.DisaCrossPoint dal = new Core.DAL.DisaCrossPoint(); //删除以前生成的交点 dal.Deletes(list_model[0].PID); map.getNetWorkData(ref pFeatureClass); if (list_model.Count == 0) { MessageBox.Show("该灾区尚未生成任务区!"); return; } //pIntersectPoint = new List<IPoint>(); string Roadtype = xml.GetElement("FilterPara", "RoadType"); string[] typeArray = Roadtype.Split(','); string whereclause = ""; if (Roadtype != null) { for (int i = 0; i < typeArray.Length; i++) { if (i != (typeArray.Length - 1)) { whereclause += "Type=" + typeArray[i] + " or "; } else { whereclause += "Type=" + typeArray[i]; } } } foreach (Core.Model.TaskAreas taskarea in list_model) { IPolygon pPolygon = CoScheduling.Core.Generic.Convertor.ToPolygon(taskarea.PolygonString); //过滤道路网 IGeometry pGeometry = pPolygon as IGeometry; ISpatialFilter pSpatialfilter = new SpatialFilterClass(); pSpatialfilter.Geometry = pGeometry; pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatialfilter.WhereClause = whereclause; pSpatialfilter.GeometryField = "Shape"; IFeatureCursor FeatureCursor = pFeatureClass.Search(pSpatialfilter, false); IFeature pFeature = FeatureCursor.NextFeature(); int count = 1; while (pFeature != null) { IPolyline pPolyline = pFeature.ShapeCopy as IPolyline; ITopologicalOperator pTopologicalOperator = pPolyline as ITopologicalOperator; IGeometry pGeometry1 = pTopologicalOperator.Intersect(pPolygon, esriGeometryDimension.esriGeometry0Dimension) as IGeometry; if (!pGeometry1.IsEmpty) { IPointCollection Pc = pGeometry1 as IPointCollection; ISymbol symbol = map.CreateSimpleSymbol(Color.Red, 8, ESRI.ArcGIS.Display.esriSimpleMarkerStyle.esriSMSCircle); for (int i = 0; i < Pc.PointCount; i++) { //将交点显示在地图上 IPoint point = Pc.get_Point(i); map.AddElement(Pc.get_Point(i), symbol, "Intersect|" + taskarea.ID + "|" + taskarea.PID); //将交点存储到数据库中 gatherPoint.LON = point.X; gatherPoint.LAT = point.Y; gatherPoint.PID = taskarea.ID; gatherPoint.PName = "交点(" + count++ + ")"; dal.Add(gatherPoint); //pIntersectPoint.Add(Pc.get_Point(i)); } } pFeature = FeatureCursor.NextFeature(); } } } catch (Exception ex) { throw ex; } finally { TaskAreas = null; } }
/// <summary> /// 获取交点 /// </summary> /// <param name="pMapCtr"></param> /// <param name="id"></param> public static void getIntersect(ESRI.ArcGIS.Controls.AxMapControl pMapCtr, int id) { Core.Map.MapHelper map = new Core.Map.MapHelper(pMapCtr); Core.Generic.myXML xml = new Core.Generic.myXML(System.Windows.Forms.Application.StartupPath + "\\Setting.xml"); try { IFeatureClass pFeatureClass = null; Core.Model.DisaAreaInfo model = new Core.Model.DisaAreaInfo(); Core.DAL.DisaAreaInfo dal0 = new Core.DAL.DisaAreaInfo(); Core.Model.DisaCrossPoint gatherPoint = new Core.Model.DisaCrossPoint(); Core.DAL.DisaCrossPoint dal = new Core.DAL.DisaCrossPoint(); //删除以前生成的交点 dal.Deletes(id); map.getNetWorkData(ref pFeatureClass); //pIntersectPoint = new List<IPoint>(); string Roadtype = xml.GetElement("FilterPara", "RoadType"); string[] typeArray = Roadtype.Split(','); string whereclause = ""; if (Roadtype != null) { for (int i = 0; i < typeArray.Length; i++) { if (i != (typeArray.Length - 1)) { whereclause += "Type=" + typeArray[i] + " or "; } else { whereclause += "Type=" + typeArray[i]; } } } //生成灾区影响范围Geometry model = dal0.GetModel(id); IPoint pPoint = new PointClass(); pPoint.PutCoords(model.LON, model.LAT); ITopologicalOperator pTopoOp = default(ITopologicalOperator); IGeometry geoBuffer = null; pTopoOp = pPoint as ITopologicalOperator; geoBuffer = pTopoOp.Buffer(model.AffectedRadius / Core.Generic.SysEnviriment.LengthPerRad); ISpatialFilter pSpatialfilter = new SpatialFilterClass(); pSpatialfilter.Geometry = geoBuffer; pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; pSpatialfilter.WhereClause = whereclause; pSpatialfilter.GeometryField = "Shape"; IFeatureCursor FeatureCursor = pFeatureClass.Search(pSpatialfilter, false); IFeature pFeature = FeatureCursor.NextFeature(); int count = 1; while (pFeature != null) { IPolyline pPolyline = pFeature.ShapeCopy as IPolyline; ITopologicalOperator pTopologicalOperator = pPolyline as ITopologicalOperator; IGeometry pGeometry1 = pTopologicalOperator.Intersect(geoBuffer as IPolygon, esriGeometryDimension.esriGeometry0Dimension) as IGeometry; if (!pGeometry1.IsEmpty) { IPointCollection Pc = pGeometry1 as IPointCollection; ISymbol symbol = map.CreateSimpleSymbol(Color.Red, 8, ESRI.ArcGIS.Display.esriSimpleMarkerStyle.esriSMSCircle); for (int i = 0; i < Pc.PointCount; i++) { //将交点显示在地图上 IPoint point = Pc.get_Point(i); map.AddElement(Pc.get_Point(i), symbol, "Intersect|" + id); //将交点存储到数据库中 gatherPoint.LON = point.X; gatherPoint.LAT = point.Y; gatherPoint.PID = id; gatherPoint.PName = "交点(" + count++ + ")"; dal.Add(gatherPoint); //pIntersectPoint.Add(Pc.get_Point(i)); } } pFeature = FeatureCursor.NextFeature(); } pMapCtr.ActiveView.Refresh(); } catch (Exception ex) { throw ex; } finally { TaskAreas = null; } }
private void dToolStripMenuItem_Click(object sender, EventArgs e) { IGeometry buffer; ISelection pSeletion = axMapControl1.Map.FeatureSelection; IEnumFeature pEnumFeature = (IEnumFeature)pSeletion; //IGraphicsContainer graphicsContainer = axMapControl1.ActiveView.GraphicsContainer; //graphicsContainer.DeleteAllElements(); IFeature pFeature = pEnumFeature.Next();//自己 double bufferDistance = GlobalData.dist; if (bufferDistance <= 0.0) { MessageBox.Show("距离设置错误"); return; } if (pFeature != null) { axMapControl1.Map.ClearSelection(); ITopologicalOperator topoOperator = pFeature.Shape as ITopologicalOperator; buffer = topoOperator.Buffer(bufferDistance); ISpatialFilter spatilaFilter = new SpatialFilterClass(); //在缓冲区内 spatilaFilter.Geometry = buffer; spatilaFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains; int iIndex; object o = Type.Missing; IPoint pt0 = pFeature.Shape as IPoint; for (iIndex = 0; iIndex < axMapControl1.LayerCount; iIndex++) { ILayer pLayer = axMapControl1.get_Layer(iIndex); IFeatureLayer pFLayer = pLayer as IFeatureLayer; IFeatureClass pFClass = pFLayer.FeatureClass; ILayer lineLayer = axMapControl1.get_Layer(axMapControl1.LayerCount - 1 - iIndex); IFeatureLayer lineFLayer = lineLayer as IFeatureLayer; IFeatureClass lineFClass = lineFLayer.FeatureClass; if (pFClass.ShapeType == esriGeometryType.esriGeometryPoint) //点图层 { //IWorkspaceFactory pWSF=new IFeatureCursor featureCursor = pFClass.Search(spatilaFilter, true);//圈内的点 IFeature oFeature = featureCursor.NextFeature(); while (oFeature != null) { if (oFeature.OID != pFeature.OID) { IFeatureCursor polygonCursor = lineFClass.Search(spatilaFilter, true); IFeature polyFeature = polygonCursor.NextFeature(); IGeometryCollection polyline = new PolylineClass(); IPoint pt1 = oFeature.Shape as IPoint; IPointCollection pPath = new PathClass(); pPath.AddPoint(pt0, ref o, ref o); pPath.AddPoint(pt1, ref o, ref o); polyline.AddGeometry(pPath as IGeometry); ITopologicalOperator pTopoOperator = polyline as ITopologicalOperator; while (polyFeature != null) { IPolyline pPolylineresult = pTopoOperator.Intersect(polyFeature.Shape, esriGeometryDimension.esriGeometry1Dimension) as IPolyline; if (pPolylineresult.Length != 0) { break; } polyFeature = polygonCursor.NextFeature(); } if (polyFeature == null) //normal end { axMapControl1.Map.SelectFeature(pLayer, oFeature); //找出处自己之外的伙伴 } } oFeature = featureCursor.NextFeature(); } break; } } axMapControl1.Refresh(); } }
protected IArray SplitLine(IGeometryBag igeometryBag_0) { int i; IPolyline geometry; int j; IPointCollection pointCollection; IGeometryCollection igeometryBag0 = (IGeometryCollection)igeometryBag_0; IPointCollection[] multipointClass = new IPointCollection[igeometryBag0.GeometryCount]; for (i = 0; i < igeometryBag0.GeometryCount; i++) { multipointClass[i] = new Multipoint(); } for (i = 0; i < igeometryBag0.GeometryCount; i++) { geometry = igeometryBag0.Geometry[i] as IPolyline; if (geometry != null) { for (j = i + 1; j < igeometryBag0.GeometryCount; j++) { IPolyline polyline = igeometryBag0.Geometry[j] as IPolyline; if (polyline != null) { IRelationalOperator relationalOperator = (IRelationalOperator)geometry; ITopologicalOperator topologicalOperator = (ITopologicalOperator)geometry; if (relationalOperator.Crosses(polyline)) { IGeometry geometry1 = topologicalOperator.Intersect(polyline, esriGeometryDimension.esriGeometry0Dimension); if (geometry1 != null && geometry1 is IPointCollection) { pointCollection = multipointClass[i]; pointCollection.AddPointCollection((IPointCollection)geometry1); pointCollection = multipointClass[j]; pointCollection.AddPointCollection((IPointCollection)geometry1); } } } } } } IArray arrayClass = new Array(); try { for (i = 0; i < igeometryBag0.GeometryCount; i++) { geometry = igeometryBag0.Geometry[i] as IPolyline; if (geometry != null) { pointCollection = multipointClass[i]; if (pointCollection.PointCount != 0) { ((IPolycurve2)geometry).SplitAtPoints(pointCollection.EnumVertices, true, true, -1); IGeometryCollection geometryCollection = (IGeometryCollection)geometry; for (j = 0; j < geometryCollection.GeometryCount; j++) { IGeometry geometry2 = geometryCollection.Geometry[j]; IGeometryCollection polylineClass = new Polyline() as IGeometryCollection; polylineClass.AddGeometries(1, ref geometry2); if (!((ITopologicalOperator)polylineClass).IsSimple) { ((ITopologicalOperator)polylineClass).Simplify(); } this.method_0(arrayClass, polylineClass as IGeometry); } } else if (geometry.IsClosed) { this.method_0(arrayClass, geometry); } } } } catch { } return(arrayClass); }
public override void OnMouseDown(int button, int shift, int x, int y, double mapX, double mapY) { DF2DApplication app = DF2DApplication.Application; if (app == null || app.Current2DMapControl == null) { return; } IActiveView m_ActiveView = app.Current2DMapControl.ActiveView; IScreenDisplay m_Display = app.Current2DMapControl.ActiveView.ScreenDisplay; IGeometry pGeo = null; try { if (button == 1) { ISimpleLineSymbol pLineSym = new SimpleLineSymbol(); IRgbColor pColor = new RgbColorClass(); pColor.Red = 255; pColor.Green = 255; pColor.Blue = 0; pLineSym.Color = pColor; pLineSym.Style = esriSimpleLineStyle.esriSLSSolid; pLineSym.Width = 2; IRubberBand pRubberBand; pRubberBand = new RubberLineClass(); IGeometry pLine = pRubberBand.TrackNew(m_Display, null); object symbol = pLineSym as object; app.Current2DMapControl.DrawShape(pLine, ref symbol); if ((pLine as IPolyline).Length > 500) { XtraMessageBox.Show("横断面线超过500米,分析效率很低,请重新绘制", "提示"); return; } WaitForm.Start("正在进行横断面分析...", "请稍后"); pGeo = pLine; if (pGeo == null) { return; } string road1 = ""; string road2 = ""; bool bAlert = false; double hmax = double.MinValue; double hmin = double.MaxValue; List <PPLine2D> pplines = new List <PPLine2D>(); IFeatureCursor pFeatureCursor = null; IFeature pFeature = null; foreach (MajorClass mc in LogicDataStructureManage2D.Instance.GetAllMajorClass()) { foreach (SubClass sc in mc.SubClasses) { if (!sc.Visible2D) { continue; } string[] arrFc2DId = mc.Fc2D.Split(';'); if (arrFc2DId == null) { continue; } foreach (string fc2DId in arrFc2DId) { DF2DFeatureClass dffc = DF2DFeatureClassManager.Instance.GetFeatureClassByID(fc2DId); if (dffc == null) { continue; } IFeatureClass fc = dffc.GetFeatureClass(); if (fc == null) { continue; } FacilityClass facc = dffc.GetFacilityClass(); if (facc.Name != "PipeLine") { continue; } //查找管径长宽字段,获得该要素类下字段索引值,若为圆管,则长宽相等 DFDataConfig.Class.FieldInfo fiDia = facc.GetFieldInfoBySystemName("Diameter"); DFDataConfig.Class.FieldInfo fiDia1 = facc.GetFieldInfoBySystemName("Diameter1"); DFDataConfig.Class.FieldInfo fiDia2 = facc.GetFieldInfoBySystemName("Diameter2"); int indexDia = fc.Fields.FindField(fiDia.Name); int indexDiaWith = fc.Fields.FindField(fiDia1.Name); int indexDiaHeight = fc.Fields.FindField(fiDia2.Name); if (indexDiaWith == -1 || indexDiaHeight == -1 || indexDia == -1) { continue; } //查找道路字段索引 DFDataConfig.Class.FieldInfo fiRoad = facc.GetFieldInfoBySystemName("Road"); int indexRoad = fc.Fields.FindField(fiRoad.Name); //查找管线高类别索引 DFDataConfig.Class.FieldInfo fiHLB = facc.GetFieldInfoBySystemName("HLB"); int indexHLB = fc.Fields.FindField(fiHLB.Name); //二级分类名索引 int indexClassify = fc.Fields.FindField(mc.ClassifyField); ISpatialFilter pSpatialFilter = new SpatialFilter(); pSpatialFilter.Geometry = pGeo; pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatialFilter.WhereClause = UpOrDown.DecorateWhereClasuse(fc) + mc.ClassifyField + " = '" + sc.Name + "'"; int count = fc.FeatureCount(pSpatialFilter); if (count == 0) { continue; } pFeatureCursor = fc.Search(pSpatialFilter, true); while ((pFeature = pFeatureCursor.NextFeature()) != null) { if (indexRoad != -1) { if (road2 == "") { road1 = pFeature.get_Value(indexRoad).ToString(); road2 = pFeature.get_Value(indexRoad).ToString(); } else { road1 = pFeature.get_Value(indexRoad).ToString(); if (road1 != road2) { if (!bAlert) { XtraMessageBox.Show("横断面线跨越多条道路,当前只绘制在【" + road2 + "】上的管线横断面图。", "提示"); bAlert = true; } continue; } } } //查找管线的起点终点地面高 double startSurfHeight = double.MaxValue; double endSurfHeight = double.MaxValue; DFDataConfig.Class.FieldInfo fiStartSurfHeight = facc.GetFieldInfoBySystemName("StartSurfH"); if (fiStartSurfHeight == null) { continue; } int indexStartSurfHeight = pFeature.Fields.FindField(fiStartSurfHeight.Name); if (indexStartSurfHeight == -1) { continue; } DFDataConfig.Class.FieldInfo fiEndSurfHeight = facc.GetFieldInfoBySystemName("EndSurfH"); if (fiEndSurfHeight == null) { continue; } int indexEndSurfHeight = pFeature.Fields.FindField(fiEndSurfHeight.Name); if (indexEndSurfHeight == -1) { continue; } //若管线属性地面高字段为null,则从DEM取值 if (pFeature.get_Value(indexStartSurfHeight).ToString() == "" || pFeature.get_Value(indexEndSurfHeight).ToString() == "") { startSurfHeight = ReadDemRaster.GetH((pFeature.Shape as IPolyline).FromPoint); endSurfHeight = ReadDemRaster.GetH((pFeature.Shape as IPolyline).ToPoint); } else { startSurfHeight = Convert.ToDouble(pFeature.get_Value(indexStartSurfHeight).ToString()); endSurfHeight = Convert.ToDouble(pFeature.get_Value(indexEndSurfHeight).ToString()); } //查找管线起点高程和终点高程 double startDepthHeight = double.MaxValue; double endDepthHeight = double.MaxValue; DFDataConfig.Class.FieldInfo fiStartDepthHeight = facc.GetFieldInfoBySystemName("StartHeight2D"); if (fiStartDepthHeight == null) { continue; } int indexStartDepthHeight = pFeature.Fields.FindField(fiStartDepthHeight.Name); if (indexStartDepthHeight == -1) { continue; } DFDataConfig.Class.FieldInfo fiEndDepthHeight = facc.GetFieldInfoBySystemName("EndHeight"); if (fiEndDepthHeight == null) { continue; } int indexEndDepthHeight = pFeature.Fields.FindField(fiEndDepthHeight.Name); if (indexEndDepthHeight == -1) { continue; } startDepthHeight = Convert.ToDouble(pFeature.get_Value(indexStartDepthHeight).ToString()); endDepthHeight = Convert.ToDouble(pFeature.get_Value(indexEndDepthHeight).ToString()); //计算管线和断面的交点 IGeometry ppGeo = pFeature.Shape; ITopologicalOperator pTopo = ppGeo as ITopologicalOperator; IGeometry geoIntersect = pTopo.Intersect(pGeo, esriGeometryDimension.esriGeometry0Dimension); if (geoIntersect == null) { continue; } PPLine2D ppline = new PPLine2D(); if (indexClassify == -1) { ppline.facType = mc.Name; } else { ppline.facType = pFeature.get_Value(indexClassify).ToString(); } //查找管线的管径,判断其是方管还是圆管 string diameter = pFeature.get_Value(indexDia).ToString(); string diameter1 = pFeature.get_Value(indexDiaWith).ToString(); string diameter2 = pFeature.get_Value(indexDiaHeight).ToString(); if (diameter.Trim() == "") { continue; } ppline.dia = diameter; int indexSplit = diameter.IndexOf('*'); if (indexSplit != -1) { ppline.isrect = true; int iDia1; bool bDia1 = int.TryParse(diameter.Substring(0, indexSplit), out iDia1); if (!bDia1) { continue; } int iDia2; bool bDia2 = int.TryParse(diameter.Substring(indexSplit + 1, diameter.Length - indexSplit - 1), out iDia2); if (!bDia2) { continue; } ppline.gj.Add(iDia1); ppline.gj.Add(iDia2); } else { ppline.isrect = false; int iDia; bool bDia = int.TryParse(diameter, out iDia); if (!bDia) { continue; } ppline.gj.Add(iDia); ppline.gj.Add(iDia); } //判断管线高方式 int hlb = 0; if (indexHLB != -1) { string strhlb = pFeature.get_Value(indexHLB).ToString(); if (strhlb.Contains("内")) { hlb = 1; } else if (strhlb.Contains("外")) { hlb = -1; } else { hlb = 0; } ppline.hlb = hlb; } #region 交点为一个 if (geoIntersect.GeometryType == esriGeometryType.esriGeometryPoint) { IPolyline polyline = pFeature.Shape as IPolyline; IPoint ptIntersect = geoIntersect as IPoint; ppline.interPoint = new PPPoint(ptIntersect.X, ptIntersect.Y); ppline.clh = GetInterPointHeight(ptIntersect, polyline, startDepthHeight, endDepthHeight); if (ppline.clh > hmax) { hmax = ppline.clh; } if (ppline.clh < hmin) { hmin = ppline.clh; } ppline.cgh = startSurfHeight + (endSurfHeight - startSurfHeight) * Math.Sqrt((polyline.FromPoint.X - ptIntersect.X) * (polyline.FromPoint.X - ptIntersect.X) + (polyline.FromPoint.Y - ptIntersect.Y) * (polyline.FromPoint.Y - ptIntersect.Y)) / polyline.Length; if (ppline.cgh > hmax) { hmax = ppline.cgh; } if (ppline.cgh < hmin) { hmin = ppline.cgh; } // 辅助画图 IPolyline l = pGeo as IPolyline; ppline.startPt = new PPPoint(l.FromPoint.X, l.FromPoint.Y); pplines.Add(ppline); } #endregion #region 交点为多个 else if (geoIntersect.GeometryType == esriGeometryType.esriGeometryMultipoint) { IPolyline polyline = pFeature.Shape as IPolyline; IPointCollection geoCol = geoIntersect as IPointCollection; for (int i = 0; i < geoCol.PointCount; i++) { IPoint ptIntersect = geoCol.get_Point(i); ppline.interPoint = new PPPoint(ptIntersect.X, ptIntersect.Y); ppline.clh = GetInterPointHeight(ptIntersect, polyline, startDepthHeight, endDepthHeight); if (ppline.clh > hmax) { hmax = ppline.clh; } if (ppline.clh < hmin) { hmin = ppline.clh; } ppline.cgh = startSurfHeight + (endSurfHeight - startSurfHeight) * Math.Sqrt((polyline.FromPoint.X - ptIntersect.X) * (polyline.FromPoint.X - ptIntersect.X) + (polyline.FromPoint.Y - ptIntersect.Y) * (polyline.FromPoint.Y - ptIntersect.Y)) / polyline.Length; if (ppline.cgh > hmax) { hmax = ppline.cgh; } if (ppline.cgh < hmin) { hmin = ppline.cgh; } // 辅助画图 IPolyline l = pGeo as IPolyline; ppline.startPt = new PPPoint(l.FromPoint.X, l.FromPoint.Y); pplines.Add(ppline); } } else { continue; } #endregion } } } } WaitForm.Stop(); if (pplines.Count < 2) { XtraMessageBox.Show("相交管线少于2个", "提示"); return; } pplines.Sort(new PPLineCompare2D()); double spacesum = 0.0; for (int i = 1; i < pplines.Count; i++) { PPLine2D line1 = pplines[i - 1]; PPLine2D line2 = pplines[i]; line2.space = Math.Sqrt((line1.interPoint.X - line2.interPoint.X) * (line1.interPoint.X - line2.interPoint.X) + (line1.interPoint.Y - line2.interPoint.Y) * (line1.interPoint.Y - line2.interPoint.Y)); spacesum += line2.space; } ; var str1 = (pplines[0].interPoint.X / 1000).ToString("0.00"); var str2 = (pplines[0].interPoint.Y / 1000).ToString("0.00"); string mapNum = str2 + "-" + str1; string mapName = SystemInfo.Instance.SystemFullName + "横断面图"; FrmSectionAnalysis dialog = new FrmSectionAnalysis("横断面分析结果", 0); dialog.SetInfo(mapName, mapNum, pplines, hmax, hmin, spacesum, road2); dialog.Show(); } } catch { WaitForm.Stop(); } }
private static void InsertFeature(IFeatureCursor ifeatureCursor_0, IFeatureBuffer ifeatureBuffer_0, IFields ifields_0, IFeature ifeature_0, IGeometry igeometry_0, IGeometry igeometry_1) { IFields fields = ifeatureBuffer_0.Fields; IFields field = ifeature_0.Fields; for (int i = 0; i < field.FieldCount; i++) { IField field1 = field.Field[i]; if ((field1.Type == esriFieldType.esriFieldTypeGeometry ? false : field1.Type != esriFieldType.esriFieldTypeOID)) { int value = fields.FindField(ifields_0.Field[i].Name); if (value != -1) { field1 = ifeatureBuffer_0.Fields.Field[value]; if ((field1.Type == esriFieldType.esriFieldTypeGeometry || field1.Type == esriFieldType.esriFieldTypeOID ? false : field1.Editable)) { try { ifeatureBuffer_0.Value[value] = ifeature_0.Value[i]; } catch (Exception exception) { Logger.Current.Error("", exception, ""); } } } } } try { IGeometry zAware = null; if (igeometry_1 != null) { bool flag = false; try { flag = (igeometry_1 as IRelationalOperator).Contains(igeometry_0); } catch { } if (!flag) { ITopologicalOperator igeometry1 = (ITopologicalOperator)igeometry_1; if (igeometry_0.GeometryType == esriGeometryType.esriGeometryMultipoint) { zAware = igeometry1.Intersect(igeometry_0, esriGeometryDimension.esriGeometry0Dimension); (zAware as IZAware).ZAware = (igeometry_0 as IZAware).ZAware; (zAware as IMAware).MAware = (igeometry_0 as IMAware).MAware; } else if (igeometry_0.GeometryType == esriGeometryType.esriGeometryPolygon) { zAware = igeometry1.Intersect(igeometry_0, esriGeometryDimension.esriGeometry2Dimension); (zAware as IZAware).ZAware = (igeometry_0 as IZAware).ZAware; if ((zAware as IZAware).ZAware) { (zAware as IZ).SetConstantZ((igeometry_0 as IZ).ZMin); } (zAware as IMAware).MAware = (igeometry_0 as IMAware).MAware; } else if (igeometry_0.GeometryType != esriGeometryType.esriGeometryPolyline) { zAware = igeometry_0; } else { try { zAware = igeometry1.Intersect(igeometry_0, esriGeometryDimension.esriGeometry1Dimension); (zAware as IZAware).ZAware = (igeometry_0 as IZAware).ZAware; (zAware as IMAware).MAware = (igeometry_0 as IMAware).MAware; } catch (Exception exception1) { zAware = igeometry_0; } } } else { zAware = igeometry_0; } } else { zAware = igeometry_0; } ifeatureBuffer_0.Shape = zAware; ifeatureCursor_0.InsertFeature(ifeatureBuffer_0); } catch (Exception exception2) { Logger.Current.Error("", exception2, ""); } }
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 int CalculateHouseNumber(IPoint p) { try { ITopologicalOperator to = (ITopologicalOperator)p; double buffsize = .01 * mDoc.FocusMap.MapScale; IGeometry g = to.Buffer(buffsize); FlashGeometry(g); mMap.SelectByShape(g, ArcMap.ThisApplication.SelectionEnvironment, true); IFeatureSelection fsel = Globals.CenterlineLayer as IFeatureSelection; if (fsel.SelectionSet.Count > 0) { IEnumIDs pEnum = fsel.SelectionSet.IDs; int oid = pEnum.Next(); IFeature feat = Globals.CenterlineLayer.FeatureClass.GetFeature(oid); Centerline = feat; IPolyline pline = feat.Shape as IPolyline; ICurve curve = pline as ICurve; esriSegmentExtension segEx = esriSegmentExtension.esriNoExtension; ITopologicalOperator to2 = g as ITopologicalOperator; IMultipoint mp = to2.Intersect(curve, esriGeometryDimension.esriGeometry0Dimension) as IMultipoint; IPointCollection pc = mp as IPointCollection; IPoint ObservationPoint = p; IPoint inPoint = pc.get_Point(0); IPoint outPoint = new PointClass(); double distance = 0.0d; double distancefrom = 0.0d; bool onright = false; curve.QueryPointAndDistance(segEx, ObservationPoint, false, outPoint, ref distance, ref distancefrom, ref onright); intersectionPoint = outPoint; //double a = GetAreaOfTriangle(pline.FromPoint, pline.ToPoint, inPoint, outPoint, distancefrom); //double a = GetThreePointAngle(pline.FromPoint.X, pline.FromPoint.Y, pline.ToPoint.X, pline.ToPoint.Y, inPoint.X, inPoint.Y); //onright = (a > 0); int start_number = 0; int n1 = Convert.ToInt32(Centerline.get_Value(Globals.CenterlineFields.FromLeft).ToString()); int n2 = Convert.ToInt32(Centerline.get_Value(Globals.CenterlineFields.FromRight).ToString()); start_number = Math.Min(n1, n2); int n3 = Convert.ToInt32(Centerline.get_Value(Globals.CenterlineFields.ToLeft).ToString()); int n4 = Convert.ToInt32(Centerline.get_Value(Globals.CenterlineFields.ToRight).ToString()); int end_number = 0; end_number = Math.Max(n3, n4); int total_addresses = end_number - start_number; double apu = curve.Length / total_addresses; double lengthIndex = Math.Abs(distance / apu); int housenumberstoadd = Convert.ToInt32(Math.Round(lengthIndex, 0)); IPolyline pline1 = (IPolyline)feat.Shape; FlashGeometry(ObservationPoint); int hn = 0; if (onright == false) { int x = start_number + housenumberstoadd; if (x % 2 == 0) { hn = x - 1; } else { hn = x; } } else { int x = start_number + housenumberstoadd; if (x % 2 == 0) { hn = x; } else { hn = x - 1; } } return(hn); } else { return(0); } } catch (Exception ex) { log.WriteError(ex, TAG, System.Security.Principal.WindowsIdentity.GetCurrent().Name, null); return(0); } }
public override void OnMouseDown(int button, int shift, int x, int y, double mapX, double mapY) { IScreenDisplay pScr = m_pActiveView.ScreenDisplay; //跟踪画线 IRubberBand pRB = new RubberLineClass(); m_pGeoTrack = pRB.TrackNew(pScr, null); if ((m_pGeoTrack as IPointCollection).PointCount != 2) { XtraMessageBox.Show("请使用鼠标制定两点确定扯旗的管线"); return; } Element.DeleteElement(m_pActiveView.GraphicsContainer, "cq"); Element.AddGraphics(m_pActiveView.GraphicsContainer, m_pGeoTrack, GetDefaultSymbol(esriGeometryType.esriGeometryPolyline), "dmx"); IElement pElement = Element.GetElementByName(m_pMapControl.ActiveView.GraphicsContainer, "cq"); if (pElement != null) { m_pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } IFeature pFeature; IGeometry pGeo; IGeometry pPipeLineGeo; IFeatureClass pFeatureClass; IFeatureCursor pFeaCur; ITopologicalOperator pTopo; string classify = ""; string startNo = ""; string endNo = ""; string material = ""; string coverstyle = ""; string diameter = ""; string road = ""; double distance; m_IntersectPipes = new List <IntersectPipe>(); string[] sysFields = new string[] { "Classify", "StartNo", "EndNo", "Material", "CoverStyle", "Diameter", "Road" }; string[] fields = new string[] { "类别", "起点号", "终点号", "材质", "埋设方式", "管径", "所在道路" }; try { foreach (MajorClass mc in LogicDataStructureManage2D.Instance.GetAllMajorClass()) { WaitForm.Start("正在查询...", "请稍后"); string[] arrFc2DId = mc.Fc2D.Split(';');//将二级大类所对应的要素类ID转换为数组 if (arrFc2DId == null) { continue; } foreach (SubClass sc in mc.SubClasses) { if (!sc.Visible2D) { continue; } foreach (string fc2DId in arrFc2DId) //遍历二级子类所对应的要素类ID { DF2DFeatureClass dffc = DF2DFeatureClassManager.Instance.GetFeatureClassByID(fc2DId); //根据要素类ID得到DF2DFC if (dffc == null) { continue; } FacilityClass fcc = dffc.GetFacilityClass(); if (fcc.Name != "PipeLine") { continue; } IFeatureLayer fl = dffc.GetFeatureLayer(); ISpatialFilter pSpatialFilter = new SpatialFilterClass(); pSpatialFilter.Geometry = m_pGeoTrack; pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatialFilter.WhereClause = "SMSCODE = '" + sc.Name + "'"; IFeatureClass fc = dffc.GetFeatureClass(); pFeaCur = fc.Search(pSpatialFilter, false); while ((pFeature = pFeaCur.NextFeature()) != null) { foreach (string field in sysFields) { DFDataConfig.Class.FieldInfo fi = fcc.GetFieldInfoBySystemName(field); if (fi == null) { continue; } int index = fc.Fields.FindField(fi.Name); object obj = pFeature.get_Value(index); switch (field) { case "Classify": classify = obj.ToString(); break; case "StartNo": startNo = obj.ToString(); break; case "EndNo": endNo = obj.ToString(); break; case "Material": material = obj.ToString(); break; case "CoverStyle": coverstyle = obj.ToString(); break; case "Diameter": diameter = obj.ToString(); break; case "Road": road = obj.ToString(); break; } } IPolyline pline = m_pGeoTrack as IPolyline; IPoint point1 = pline.ToPoint; ITopologicalOperator topo = pFeature.Shape as ITopologicalOperator; IGeometry geo = topo.Intersect(m_pGeoTrack, esriGeometryDimension.esriGeometry0Dimension); IPointCollection pointCol = geo as IPointCollection; IPoint point2 = pointCol.get_Point(pointCol.PointCount - 1); distance = GetDistanceOfTwoPoints(point1, point2); IntersectPipe interPipe = new IntersectPipe(pFeature, fl, distance, classify, startNo, endNo, material, coverstyle, diameter, road); m_IntersectPipes.Add(interPipe); } } } } if (m_IntersectPipes.Count == 0) { return; } List <IntersectPipe> orderList = m_IntersectPipes.OrderBy(i => i.Distance).ToList <IntersectPipe>(); DrawPipeLabels(); int n = 0; foreach (IntersectPipe interPipe in orderList) { WaitForm.SetCaption("正在输出属性,请稍后..."); DrawPipeInfo(interPipe, n); ++n; } WaitForm.Stop(); } catch (System.Exception ex) { WaitForm.Stop(); } }
/// <summary> /// 根据输入的一系列点计算voronoi图 /// </summary> /// <param name="points">一系列点</param> /// <returns>一系列多变形</returns> public static IList <IGeometry> GeometryVoronoi(List <IPoint> points) { // 判断点的数量是否合法 if (points.Count < 3) { throw new ArgumentException("Input must be a MultiPoint containing at least three points"); } // 初始化顶点列表 List <SimplePoint> vertices = new List <SimplePoint>(); // 加入所有初始提供的点 for (int i = 0; i < points.Count; i++) { SimplePoint point = new SimplePoint(points[i].X, points[i].Y); // 除掉所有的多点,因为三角剖分算法不支持多点的引入 if (!vertices.Contains(point)) { vertices.Add(point); } } // 计算点集的数量,此时应该已经除掉了所有的重复点 int numPoints = vertices.Count; // 判断点的数量是否合法 if (numPoints < 3) { throw new ArgumentException("Input must be a list of points containing at least three points"); } // 基于vertices中的顶点x坐标对indices进行sort vertices.Sort(); IPointCollection pointCollection = new MultipointClass(); foreach (SimplePoint p in vertices) { pointCollection.AddPoint(new PointClass() { X = p.X, Y = p.Y }); } IEnvelope envelope = (pointCollection as IGeometry).Envelope; // Width double dx = envelope.Width; // Height double dy = envelope.Height; // Maximum dimension double dmax = (dx > dy) ? dx : dy; // Centre double avgx = ((envelope.XMax - envelope.XMin) / 2) + envelope.XMin; double avgy = ((envelope.YMax - envelope.YMin) / 2) + envelope.YMin; // Create the points at corners of the supertriangle SimplePoint a = new SimplePoint(avgx - (2 * dmax), avgy - dmax); SimplePoint b = new SimplePoint(avgx + (2 * dmax), avgy - dmax); SimplePoint c = new SimplePoint(avgx, avgy + (2 * dmax)); // Add the supertriangle vertices to the end of the vertex array vertices.Add(a); vertices.Add(b); vertices.Add(c); double radius; SimplePoint circumcentre; Triangulation.CalculateCircumcircle(a, b, c, out circumcentre, out radius); // 确定超级三角形,这个三角形应该包含所有点 SimpleTriangle superTriangle = new SimpleTriangle(numPoints, numPoints + 1, numPoints + 2, circumcentre, radius); // 将超级三角形push到triangles列表 List <SimpleTriangle> triangles = new List <SimpleTriangle>(); triangles.Add(superTriangle); List <SimpleTriangle> completedTriangles = new List <SimpleTriangle>(); // 遍历基于indecies顺序的vertices中的每一个点 for (int i = 0; i < numPoints; i++) { // 初始化边缓存数组 List <int[]> edges = new List <int[]>(); // 遍历temp triangles中的每一个三角形 for (int j = triangles.Count - 1; j >= 0; j--) { // 如果该点在外接圆内 if (Distance(triangles[j].CircumCentre, vertices[i]) < triangles[j].Radius) { // 则该三角形不为Delaunay三角形,将三边保存至edge buffer edges.Add(new int[] { triangles[j].A, triangles[j].B }); edges.Add(new int[] { triangles[j].B, triangles[j].C }); edges.Add(new int[] { triangles[j].C, triangles[j].A }); // 在temp中除掉该三角形 triangles.RemoveAt(j); } else if (vertices[i].X > triangles[j].CircumCentre.X + triangles[j].Radius) { { completedTriangles.Add(triangles[j]); } triangles.RemoveAt(j); } } // 对edgebuffer进行去重 for (int j = edges.Count - 1; j > 0; j--) { for (int k = j - 1; k >= 0; k--) { // Compare if this edge match in either direction if (edges[j][0].Equals(edges[k][1]) && edges[j][1].Equals(edges[k][0])) { // 去重 edges.RemoveAt(j); edges.RemoveAt(k); // We've removed an item from lower down the list than where j is now, so update j j--; break; } } } // Create new triangles for the current point for (int j = 0; j < edges.Count; j++) { Triangulation.CalculateCircumcircle(vertices[edges[j][0]], vertices[edges[j][1]], vertices[i], out circumcentre, out radius); SimpleTriangle t = new SimpleTriangle(edges[j][0], edges[j][1], i, circumcentre, radius); triangles.Add(t); } } // 我们已经完成了三角剖分部分,接下来就是要完成构建voronoi图的过程 completedTriangles.AddRange(triangles); IList <IGeometry> voronoiPolygon = new List <IGeometry>(); for (var i = 0; i < vertices.Count; i++) { // 新建一个IGeometry来存放voronoi图 IPointCollection mp = new MultipointClass(); // 遍历所有三角形 foreach (SimpleTriangle tri in completedTriangles) { // If the triangle intersects this point if (tri.A == i || tri.B == i || tri.C == i) { mp.AddPoint(new PointClass() { X = tri.CircumCentre.X, Y = tri.CircumCentre.Y }); } } // Create the voronoi polygon from the convex hull of the circumcentres of intersecting triangles ITopologicalOperator topologicalOperator = mp as ITopologicalOperator; IGeometry polygon = topologicalOperator.ConvexHull(); topologicalOperator = polygon as ITopologicalOperator; IGeometry result = topologicalOperator.Intersect(envelope, esriGeometryDimension.esriGeometry2Dimension); if ((result != null) && (!result.IsEmpty)) { voronoiPolygon.Add(result); } } return(voronoiPolygon); }
private byte[] QueryPoint(ESRI.ArcGIS.Geometry.IPoint location, double distance) { if (distance <= 0.0) { throw new ArgumentOutOfRangeException("distance"); } // Buffer the point. ITopologicalOperator topologicalOperator = (ESRI.ArcGIS.Geometry.ITopologicalOperator)location; IGeometry queryGeometry = topologicalOperator.Buffer(distance); // Query the feature class. ISpatialFilter spatialFilter = new ESRI.ArcGIS.Geodatabase.SpatialFilter(); spatialFilter.Geometry = queryGeometry; spatialFilter.SpatialRel = ESRI.ArcGIS.Geodatabase.esriSpatialRelEnum.esriSpatialRelIntersects; spatialFilter.GeometryField = m_fcToQuery.ShapeFieldName; IFeatureCursor resultsFeatureCursor = m_fcToQuery.Search(spatialFilter, true); // Loop through the features, clip each geometry to the buffer // and total areas by attribute value. topologicalOperator = (ESRI.ArcGIS.Geometry.ITopologicalOperator)queryGeometry; int classFieldIndex = m_fcToQuery.FindField(m_mapFieldToQuery); // System.Collections.Specialized.ListDictionary summaryStatsDictionary = new System.Collections.Specialized.ListDictionary(); Dictionary <string, double> summaryStatsDictionary = new Dictionary <string, double>(); // Initialize a list to hold JSON geometries. List <JsonObject> jsonGeometries = new List <JsonObject>(); IFeature resultsFeature = null; while ((resultsFeature = resultsFeatureCursor.NextFeature()) != null) { // Clip the geometry. IPolygon clippedResultsGeometry = (IPolygon)topologicalOperator.Intersect(resultsFeature.Shape, ESRI.ArcGIS.Geometry.esriGeometryDimension.esriGeometry2Dimension); clippedResultsGeometry.Densify(0, 0); // Densify to maintain curved appearance when converted to JSON. // Convert the geometry to JSON and add it to the list. JsonObject jsonClippedResultsGeometry = Conversion.ToJsonObject(clippedResultsGeometry); jsonGeometries.Add(jsonClippedResultsGeometry); // Get statistics. IArea area = (IArea)clippedResultsGeometry; string resultsClass = resultsFeature.get_Value(classFieldIndex) as string; // If the class is already in the dictionary, add the current feature's area to the existing entry. if (summaryStatsDictionary.ContainsKey(resultsClass)) { summaryStatsDictionary[resultsClass] = (double)summaryStatsDictionary[resultsClass] + area.Area; } else { summaryStatsDictionary[resultsClass] = area.Area; } } // Use a helper method to get a JSON array of area records. JsonObject[] areaResultJson = CreateJsonRecords(summaryStatsDictionary) as JsonObject[]; // Create a JSON object of the geometry results and the area records. JsonObject resultJsonObject = new JsonObject(); resultJsonObject.AddArray("geometries", jsonGeometries.ToArray()); resultJsonObject.AddArray("records", areaResultJson); // Get byte array of json and return results. byte[] result = Encoding.UTF8.GetBytes(resultJsonObject.ToJson()); return(result); }
private void DWIntersect(CPolyline pBSCpl, ref List <CPoint> cptlt, double dblIgnorableDis) { IPointCollection4 pCol = new PolylineClass(); for (int i = 0; i < cptlt.Count; i++) { cptlt[i].SetPoint(); pCol.AddPoint(cptlt[i].pPoint); } IPolyline5 ipl = pCol as IPolyline5; pBSCpl.SetPolyline(); IRelationalOperator pRel = pBSCpl.pPolyline as IRelationalOperator; bool isCrosses = pRel.Crosses(ipl); if (isCrosses == true) { ITopologicalOperator pTop = pBSCpl.pPolyline as ITopologicalOperator; IGeometry pGeoIntersect = pTop.Intersect(ipl, esriGeometryDimension.esriGeometry0Dimension); IPointCollection4 pColIntersect = pGeoIntersect as IPointCollection4; double dblMaxDis = 0; for (int j = 0; j < pColIntersect.PointCount; j++) { double dblDis = CGeoFunc.CalDistanceFromStartPoint(ipl, pColIntersect.get_Point(j), false); if (dblDis > dblMaxDis) { dblMaxDis = dblDis; } } ICurve pSubCurve; ipl.GetSubcurve(dblMaxDis, ipl.Length, false, out pSubCurve); //IPolyline5 Cutipl = pSubCurve as IPolyline5; IPointCollection4 iplCutCol = pSubCurve as IPointCollection4; //the new first segment IPointCollection4 pSegCol = new PolylineClass(); pSegCol.AddPoint(ipl.FromPoint, _Missing, _Missing); pSegCol.AddPoint(iplCutCol.get_Point(1), _Missing, _Missing); IPolyline5 seg = pSegCol as IPolyline5; bool isCrossesSeg; int intIndex = 0; while (intIndex < iplCutCol.PointCount - 1) { intIndex++; pSegCol.UpdatePoint(1, iplCutCol.get_Point(intIndex)); isCrossesSeg = pRel.Crosses(seg); if (isCrossesSeg == false) { iplCutCol.RemovePoints(1, intIndex - 1); iplCutCol.UpdatePoint(0, ipl.FromPoint); break; } if (seg.Length >= dblIgnorableDis) { double dblOriginalIntersectionDis = CGeoFunc.CalDistanceFromStartPoint(pBSCpl.pPolyline, pCol.get_Point(0), false); double dblRealisticIntersectionDis = CGeoFunc.CalDistanceFromStartPoint(pBSCpl.pPolyline, iplCutCol.get_Point(0), false); IPointCollection4 pColBSCpl = pBSCpl.pPolyline as IPointCollection4; double dblSumDis = 0; for (int i = 0; i < pColBSCpl.PointCount - 1; i++) { double dblDis = CGeoFunc.CalDis(pColBSCpl.get_Point(i), pColBSCpl.get_Point(i + 1)); dblSumDis += dblDis; if (dblSumDis >= dblRealisticIntersectionDis) { double dblDisPre = Math.Abs(dblSumDis - dblDis - dblOriginalIntersectionDis); double dblDisNext = Math.Abs(dblSumDis - dblOriginalIntersectionDis); IPoint intersectpt = new PointClass(); if (dblDisPre <= dblDisNext) { intersectpt = pColBSCpl.get_Point(i); } else { intersectpt = pColBSCpl.get_Point(i + 1); } iplCutCol.UpdatePoint(0, intersectpt); break; } } break; } } cptlt = CHelpFunc.GetCptEbByICol(iplCutCol).ToList(); } }