/// <summary> /// Converts an Esri enumerable interface to a DotNet IEnumerable. /// </summary> /// <param name="esriEnum">An enumerable Esri interface.</param> /// <returns>The adapted dotnet enumeration.</returns> public static IEnumerable <IPoint> Enumerate(this IEnumVertex esriEnum) { IPoint point; int partIndex; int vertexIndex; esriEnum.Reset(); esriEnum.Next(out point, out partIndex, out vertexIndex); while (point != null) { yield return(point); esriEnum.Next(out point, out partIndex, out vertexIndex); } }
static private IPoint nextPoint(IEnumVertex vertices, out int partIndex, out int vertexIndex) { IPoint p; vertices.Next(out p, out partIndex, out vertexIndex); return(p); }
/// <summary> /// INTERPOLATE ELEVATION VALUES FOR VERTICES /// </summary> /// <param name="analysisSurface">Analysis surface</param> /// <param name="vertices">Enumeration of vertices</param> internal static void InterpolateVertices(AnalysisSurface analysisSurface, IEnumVertex vertices) { // RESET ENUM vertices.Reset(); // ITERATE VERTICES IPoint outVertex; int partIndex; int vertexIndex; vertices.Next(out outVertex, out partIndex, out vertexIndex); while (outVertex != null) { // GET ELEVATION AT POINT LOCATION double elev = Helper.GetSurfaceElevation(analysisSurface, outVertex); // ASSIGN Z USING ELEVATION outVertex.Z = elev; // GET NEXT VERTEX vertices.Next(out outVertex, out partIndex, out vertexIndex); } }
private static IPoint nextPoint(IEnumVertex vertices, out int partIndex, out int vertexIndex) { IPoint p; vertices.Next(out p, out partIndex, out vertexIndex); return p; }
// Execute: Execute the function given the array of the parameters public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message) { IFeatureClass outputFeatureClass = null; try { // get the input feature class IGPMultiValue inputFeatureClasses_Parameter = (IGPMultiValue)m_GPUtilities.UnpackGPValue(paramvalues.get_Element(0)); layer[] input_featureClasses = new layer[inputFeatureClasses_Parameter.Count]; for (int i = 0; i < inputFeatureClasses_Parameter.Count; i++) { IGPValue inputFeatureClass_Parameter = inputFeatureClasses_Parameter.get_Value(i); IFeatureClass inputFeatureClass; IQueryFilter inputQF; m_GPUtilities.DecodeFeatureLayer(inputFeatureClass_Parameter, out inputFeatureClass, out inputQF); input_featureClasses[i] = new layer() { featureclass = inputFeatureClass, qFilter = inputQF }; } if (input_featureClasses.Length == 0 || input_featureClasses.Any(w => w.featureclass == null)) { message.AddError(2, "Could not open one or more input dataset."); return; } //IFields additionalFields = new FieldsClass(); //additionalFields.AddField(FEATURE_SOURCE_FIELD_NAME, esriFieldType.esriFieldTypeString); //additionalFields.AddField(FEATURE_ID_FIELD_NAME, esriFieldType.esriFieldTypeInteger); //additionalFields.AddField( // input_featureClasses[0].featureclass.Fields.get_Field( // input_featureClasses[0].featureclass.Fields.FindField( // input_featureClasses[0].featureclass.ShapeFieldName))); // create the output feature class IGPValue outputFeatureClass_Parameter = m_GPUtilities.UnpackGPValue(paramvalues.get_Element(1)); outputFeatureClass = GPHelperFunctions.CreateFeatureClass(outputFeatureClass_Parameter, envMgr); if (outputFeatureClass == null) { message.AddError(2, "Could not create output dataset."); return; } IGPString curveTypeParameter = (IGPString)m_GPUtilities.UnpackGPValue(paramvalues.get_Element(2)); ArcConstructionMethods method; if (!Enum.TryParse <ArcConstructionMethods>(curveTypeParameter.Value, true, out method)) { message.AddError(2, string.Format("The value {0} is not expected. Expected values are: {1}.", curveTypeParameter.Value, string.Join(",", Enum.GetNames(typeof(ArcConstructionMethods))))); return; } IStepProgressor stepPro = (IStepProgressor)trackcancel; GPHelperFunctions.dropSpatialIndex(outputFeatureClass); BoostVoronoi bv = new BoostVoronoi(100); double minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; List <site_key> point_sites = new List <site_key>(); List <site_key> segment_sites = new List <site_key>(); for (short i = 0; i < input_featureClasses.Length; i++) { layer l = input_featureClasses[i]; int featcount = l.featureclass.FeatureCount(l.qFilter); stepPro.MinRange = 0; stepPro.MaxRange = featcount; stepPro.StepValue = (1); stepPro.Message = "Reading features"; stepPro.Position = 0; stepPro.Show(); IFeatureCursor cursor = null; IFeature row = null; try { cursor = l.featureclass.Search(l.qFilter, false); while ((row = cursor.NextFeature()) != null) { stepPro.Step(); IPoint point = row.Shape as IPoint; if (point != null) { double X = point.X; double Y = point.Y; minX = Math.Min(minX, X); maxX = Math.Max(maxX, X); minY = Math.Min(minY, Y); maxY = Math.Max(maxY, Y); bv.AddPoint(point.X, point.Y); point_sites.Add(new site_key(i, row.OID)); } IMultipoint multipoint = row.Shape as IMultipoint; if (multipoint != null) { IPointCollection pointCollection = (IPointCollection)multipoint; IEnumVertex vertices = pointCollection.EnumVertices; IPoint vertex = null; int part, index; vertices.Next(out vertex, out part, out index); minX = Math.Min(minX, multipoint.Envelope.XMin); maxX = Math.Max(maxX, multipoint.Envelope.XMax); minY = Math.Min(minY, multipoint.Envelope.YMin); maxY = Math.Max(maxY, multipoint.Envelope.YMax); while (vertex != null) { bv.AddPoint(vertex.X, vertex.Y); point_sites.Add(new site_key(i, row.OID)); vertices.Next(out vertex, out part, out index); } } IPolyline polyline = row.Shape as IPolyline; if (polyline != null) { double fromX = polyline.FromPoint.X; double fromY = polyline.FromPoint.Y; double toX = polyline.ToPoint.X; double toY = polyline.ToPoint.Y; if (toX < fromX) { minX = Math.Min(minX, toX); maxX = Math.Max(maxX, fromX); } else { minX = Math.Min(minX, fromX); maxX = Math.Max(maxX, toX); } if (toY < fromY) { minY = Math.Min(minY, toY); maxY = Math.Max(maxY, fromY); } else { minY = Math.Min(minY, fromY); maxY = Math.Max(maxY, toY); } bv.AddSegment( polyline.FromPoint.X, polyline.FromPoint.Y, polyline.ToPoint.X, polyline.ToPoint.Y ); segment_sites.Add(new site_key(i, row.OID)); } Marshal.ReleaseComObject(row); } } finally { if (row != null) { Marshal.ReleaseComObject(row); } if (cursor != null) { Marshal.ReleaseComObject(cursor); } stepPro.Hide(); } } message.AddMessage(String.Format("{0}, {1} -> {2}, {3}", minX, minY, maxX, maxY)); int width = Math.Max((int)((maxX - minX) * 0.1), 1); int height = Math.Max((int)((maxY - minY) * 0.1), 1); maxX = maxX + width; minX = minX - width; maxY = maxY + height; minY = minY - height; message.AddMessage(String.Format("{0}, {1} -> {2}, {3}", minX, minY, maxX, maxY)); bv.AddSegment(minX, minY, maxX, minY); segment_sites.Add(new site_key(-1, -1)); bv.AddSegment(maxX, minY, maxX, maxY); segment_sites.Add(new site_key(-1, -1)); bv.AddSegment(maxX, maxY, minX, maxY); segment_sites.Add(new site_key(-1, -1)); bv.AddSegment(minX, maxY, minX, minY); segment_sites.Add(new site_key(-1, -1)); stepPro.Message = "Solve Voronoi"; stepPro.MaxRange = 0; stepPro.MaxRange = 0; stepPro.Show(); bv.Construct(); stepPro.Hide(); int featureSourceIndx = outputFeatureClass.Fields.FindField(FEATURE_SOURCE_FIELD_NAME); int featureIDIndx = outputFeatureClass.Fields.FindField(FEATURE_ID_FIELD_NAME); IFeatureCursor inserts = null; IFeatureBuffer buffer = null; try { object missing = Type.Missing; ISpatialReference spatialReference = ((IGeoDataset)outputFeatureClass).SpatialReference; inserts = outputFeatureClass.Insert(false); buffer = outputFeatureClass.CreateFeatureBuffer(); List <Cell> cells = bv.Cells; message.AddMessage(string.Format("{0} cells calculated", cells.Count)); List <Edge> edges = bv.Edges; message.AddMessage(string.Format("{0} edges calculated", edges.Count)); List <Vertex> vertices = bv.Vertices; message.AddMessage(string.Format("{0} vertexes calculated", vertices.Count)); stepPro.Message = "Write cells"; stepPro.MaxRange = 0; stepPro.MaxRange = cells.Count; stepPro.Show(); for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) { try { if (cellIndex % 5000 == 0) { message.AddMessage(String.Format("{0}. {1} cells processed.", DateTime.Now, cellIndex)); } Cell cell = cells[cellIndex]; int currentSite = cell.Site; IGeometryCollection geometryCollection = new GeometryBagClass() { SpatialReference = spatialReference }; //ignores any sliver cells if (cell.IsOpen || cell.EdgesIndex.Count < 3) { continue; } ISegmentCollection segmentCollection = createSegments(cell, bv, method, spatialReference); if (((IArea)segmentCollection).Area <= 0) { message.AddMessage("A invalid geometry has been detected, try reversing the orientation."); ISegmentCollection reversed_segmentCollection = new PolygonClass() { SpatialReference = spatialReference }; for (int i = segmentCollection.SegmentCount - 1; i >= 0; i--) { ISegment segment = (ISegment)segmentCollection.get_Segment(i); segment.ReverseOrientation(); reversed_segmentCollection.AddSegment(segment); } segmentCollection = reversed_segmentCollection; } ((IPolygon)segmentCollection).SpatialReference = spatialReference; if (((IArea)segmentCollection).Area <= 0) { message.AddWarning("An empty shell has been created"); for (int i = 0; i < segmentCollection.SegmentCount; i++) { ISegment segment = (ISegment)segmentCollection.get_Segment(i); message.AddMessage(String.Format("From {0}, {1} To {2},{3}", segment.FromPoint.X, segment.FromPoint.Y, segment.ToPoint.X, segment.ToPoint.Y)); } } //set attributes site_key sk = (currentSite >= point_sites.Count) ? segment_sites[currentSite - point_sites.Count] : point_sites[currentSite]; if (!sk.isEmpty) { buffer.set_Value(featureSourceIndx, input_featureClasses[sk.featureClassIndex].featureclass.AliasName); buffer.set_Value(featureIDIndx, sk.objectID); } else { buffer.set_Value(featureSourceIndx, DBNull.Value); buffer.set_Value(featureIDIndx, DBNull.Value); } IPolygon voronoiPolygon = (IPolygon)segmentCollection; buffer.Shape = (IPolygon)voronoiPolygon; inserts.InsertFeature(buffer); } catch (Exception e) { message.AddWarning("Failed to create a cell"); } } } finally { if (buffer != null) { Marshal.ReleaseComObject(buffer); } if (inserts != null) { Marshal.ReleaseComObject(inserts); } } GPHelperFunctions.createSpatialIndex(outputFeatureClass); } catch (Exception exx) { message.AddError(2, exx.Message); message.AddMessage(exx.ToString()); } finally { if (outputFeatureClass != null) { Marshal.ReleaseComObject(outputFeatureClass); } ((IProgressor)trackcancel).Hide(); } }
private void processPolygonLayer(LayerProperties layerProps, geFolder folder) { //I have a polygon layer, and a kml folder :) IFeatureClass clasa = (layerProps.Layeru as IFeatureLayer).FeatureClass; //get acces to features IFeatureCursor featurele = clasa.Search(null, true); int nrFeature = clasa.FeatureCount(null); //if I have any features Polygon poligon; IFeature currentFeature; while ((currentFeature = featurele.NextFeature()) != null) { poligon = currentFeature.Shape as Polygon; //coordinates and vertices double coordLat; double coordLong; IEnumVertex colection = poligon.EnumVertices; IPoint polyVertex; //create coord system WGS 84 (Google earth) IGeographicCoordinateSystem gcs; SpatialReferenceEnvironment sre = new SpatialReferenceEnvironment(); gcs = sre.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984); //create spatial reference ISpatialReference pointToSpatialReference; pointToSpatialReference = gcs; #region add points to polygon //create a placemark for the line gePlacemark pmPolygon = new gePlacemark(); pmPolygon.StyleUrl = "#Shape2KMLGeneratedStyle"; List <geCoordinates> polyCoords = new List <geCoordinates>(); int index1, index2; //iterate points... while (!colection.IsLastInPart()) { //create polygon from vertices colection.Next(out polyVertex, out index1, out index2); //project point and get coordinates polyVertex.Project(pointToSpatialReference); polyVertex.QueryCoords(out coordLong, out coordLat); //add point to line try { //create points for polygon based on altitude mode. switch (layerProps.AltitudeMode) { case AltitudeMode.absolute: if (layerProps.Field == "") { //add point to line polyCoords.Add(new geCoordinates(new geAngle90(coordLat), new geAngle180(coordLong), layerProps.Altitude)); } else { int altitude; //if altitude is integer, this should work altitude = (int)currentFeature.get_Value(currentFeature.Fields.FindField(layerProps.Field)); //add point to line polyCoords.Add(new geCoordinates(new geAngle90(coordLat), new geAngle180(coordLong), layerProps.Multiplier * altitude)); } break; case AltitudeMode.clampToGround: //add point to line polyCoords.Add(new geCoordinates(new geAngle90(coordLat), new geAngle180(coordLong))); break; case AltitudeMode.relativeToGround: if (layerProps.Field == "") { //add point to line polyCoords.Add(new geCoordinates(new geAngle90(coordLat), new geAngle180(coordLong), layerProps.Altitude)); } else { float altitude; //if altitude is integer, this should work altitude = (float)currentFeature.get_Value(currentFeature.Fields.FindField(layerProps.Field)); //add point to line polyCoords.Add(new geCoordinates(new geAngle90(coordLat), new geAngle180(coordLong), layerProps.Multiplier * altitude)); } break; default: break; } } catch (Exception) { MessageBox.Show("Altitude field is not a number value"); break; } } //create line from list of coords geOuterBoundaryIs outer = new geOuterBoundaryIs(new geLinearRing(polyCoords)); gePolygon poly = new gePolygon(outer); //and add it to document switch (layerProps.AltitudeMode) { //set altitude mode... case AltitudeMode.absolute: poly.AltitudeMode = geAltitudeModeEnum.absolute; break; case AltitudeMode.clampToGround: poly.AltitudeMode = geAltitudeModeEnum.clampToGround; break; case AltitudeMode.relativeToGround: poly.AltitudeMode = geAltitudeModeEnum.relativeToGround; break; default: break; } if (layerProps.DescField != "") { pmPolygon.Description = currentFeature.get_Value(currentFeature.Fields.FindField(layerProps.DescField)).ToString(); } if (layerProps.NameField != "") { pmPolygon.Name = currentFeature.get_Value(currentFeature.Fields.FindField(layerProps.NameField)).ToString(); } pmPolygon.Geometry = poly; folder.Features.Add(pmPolygon); #endregion } }
private int CheckZRange([NotNull] IFeature feature, [NotNull] IPointCollection points) { IEnumVertex enumPoints = points.EnumVertices; enumPoints.Reset(); var errorPointsBelow = new List <IPoint>(); var errorPointsAbove = new List <IPoint>(); IPoint currentPoint; int partIndex; int segmentIndex; enumPoints.Next(out currentPoint, out partIndex, out segmentIndex); double zMax = double.MinValue; double zMin = double.MaxValue; while (currentPoint != null) { double z = currentPoint.Z; if (!IsAllowed(z)) { if (z < _minimumZValue) { errorPointsBelow.Add(GeometryFactory.Clone(currentPoint)); } else if (z > _maximumZValue) { errorPointsAbove.Add(GeometryFactory.Clone(currentPoint)); } if (z < zMin) { zMin = z; } else if (z > zMax) { zMax = z; } } enumPoints.Next(out currentPoint, out partIndex, out segmentIndex); } var errorCount = 0; if (errorPointsBelow.Count > 0) { errorCount += ReportError(GetErrorMessageBelow(errorPointsBelow, zMin), GetErrorGeometry(errorPointsBelow), null, _shapeFieldName, (IRow)feature); } if (errorPointsAbove.Count > 0) { string message = GetErrorMessageAbove(errorPointsAbove, zMax); errorCount += ReportError(message, GetErrorGeometry(errorPointsAbove), null, _shapeFieldName, (IRow)feature); } return(errorCount); }