/// <summary> /// Creates a <see cref="Polygon" /> using the next token in the stream. /// </summary> /// <param name="tokenizer"> /// tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a MultiPolygon. /// </param> /// <returns> /// a <code>MultiPolygon</code> specified by the next token in the /// stream, or if if the coordinates used to create the <see cref="Polygon" /> /// shells and holes do not form closed linestrings. /// </returns> private static Polygon ReadMultiPolygonText(WktStreamTokenizer tokenizer) { var nextToken = GetNextEmptyOrOpener(tokenizer); if (nextToken == "EMPTY") { throw new Exception("Empty MultiPolygon"); } var polygon = ReadPolygonText(tokenizer); var polygons = new PolygonBuilder(polygon); var exteriorRingCcw = false; // Need to pay attention to whether or not the first exterior ring is CW or CCW, so // the other exterior rings match. if (polygon.Parts.Count > 0) { exteriorRingCcw = Algorithms.IsCcw(polygon.Parts[0]); } nextToken = GetNextCloserOrComma(tokenizer); while (nextToken == ",") { polygon = ReadPolygonText(tokenizer, exteriorRingCcw, true); polygons.AddParts(polygon.Parts); nextToken = GetNextCloserOrComma(tokenizer); } return(polygons.ToGeometry()); }
private static Polygon CreateWkbMultiPolygon(BinaryReader reader, WkbByteOrder byteOrder) { // Get the number of Polygons. var numPolygons = (int)ReadUInt32(reader, byteOrder); if (numPolygons < 1) { throw new Exception("Could not create MultiPolygon"); } // Read linestring header reader.ReadByte(); ReadUInt32(reader, byteOrder); // Create a new array for the Polygons. var polygons = new PolygonBuilder(CreateWkbPolygon(reader, byteOrder)); // Loop on the number of polygons. for (var i = 1; i < numPolygons; i++) { // read polygon header reader.ReadByte(); ReadUInt32(reader, byteOrder); // TODO: Validate type polygons.AddParts(CreateWkbPolygon(reader, byteOrder).Parts); } //Create and return the MultiPolygon. return(polygons.ToGeometry()); }
/// <summary> /// The methods retrieves the outer ring(s) of the input polygon. /// This method must be called on the MCT. Use QueuedTask.Run. /// </summary> /// <param name="inputPolygon">Input Polygon.</param> /// <returns>The outer most (exterior, clockwise) ring(s) of the polygon. If the input is null or empty, a null pointer is returned.</returns> /// <remarks>This method must be called on the MCT. Use QueuedTask.Run.</remarks> public Polygon GetOutermostRings(Polygon inputPolygon) { if (inputPolygon == null || inputPolygon.IsEmpty) { return(null); } PolygonBuilder outerRings = new PolygonBuilder(); List <Polygon> internalRings = new List <Polygon>(); // explode the parts of the polygon into a list of individual geometries var parts = MultipartToSinglePart(inputPolygon); // get an enumeration of clockwise geometries (area > 0) ordered by the area var clockwiseParts = parts.Where(geom => ((Polygon)geom).Area > 0).OrderByDescending(geom => ((Polygon)geom).Area); // for each of the exterior rings foreach (var part in clockwiseParts) { // add the first (the largest) ring into the internal collection if (internalRings.Count == 0) { internalRings.Add(part as Polygon); } // use flag to indicate if current part is within the already selection polygons bool isWithin = false; foreach (var item in internalRings) { if (GeometryEngine.Within(part, item)) { isWithin = true; } } // if the current polygon is not within any polygon of the internal collection // then it is disjoint and needs to be added to if (isWithin == false) { internalRings.Add(part as Polygon); } } // now assemble a new polygon geometry based on the internal polygon collection foreach (var ring in internalRings) { outerRings.AddParts(ring.Parts); } // return the final geometry of the outer rings return(outerRings.ToGeometry()); }
private void AddShapeLayer(List <IGeoInfo> shapeList, Layer layer) { foreach (ShapeGeoInfo shape in shapeList) { if (shape.Polygons.Values.Count == 0) { continue; } PolygonBuilder builder = new PolygonBuilder(SpatialReferences.Wgs84); shape.Polygons.Values.ToList().ForEach(p => builder.AddParts(p.Parts)); Polygon polygon = builder.ToGeometry(); Dictionary <string, object> attr = new Dictionary <string, object>(shape.AttrList); attr[KEY_CODE] = shape.KeyCode; layer.GraphicsLayer.Graphics.Add(new Graphic(polygon, attr, MapShapeLayer.GetSymbol(GeoMarkerType.Fill, GeoStatus.Normal))); _shapeList.Add(polygon.Extent); layer.GraphicsLayer.Graphics.Add(new Graphic(polygon.Extent.GetCenter(), attr, MapShapeLayer.GetSymbol(GeoMarkerType.Point, GeoStatus.Normal))); } }
/// <summary> /// The methods retrieves the outer ring(s) of the input polygon. /// This method must be called on the MCT. Use QueuedTask.Run. /// </summary> /// <param name="inputPolygon">Input Polygon.</param> /// <returns>The outer most (exterior, clockwise) ring(s) of the polygon. If the input is null or empty, a null pointer is returned.</returns> /// <remarks>This method must be called on the MCT. Use QueuedTask.Run.</remarks> public Polygon GetOutermostRings(Polygon inputPolygon) { if (inputPolygon == null || inputPolygon.IsEmpty) return null; PolygonBuilder outerRings = new PolygonBuilder(); List<Polygon> internalRings = new List<Polygon>(); // explode the parts of the polygon into a list of individual geometries var parts = MultipartToSinglePart(inputPolygon); // get an enumeration of clockwise geometries (area > 0) ordered by the area var clockwiseParts = parts.Where(geom => ((Polygon)geom).Area > 0).OrderByDescending(geom => ((Polygon)geom).Area); // for each of the exterior rings foreach (var part in clockwiseParts) { // add the first (the largest) ring into the internal collection if (internalRings.Count == 0) internalRings.Add(part as Polygon); // use flag to indicate if current part is within the already selection polygons bool isWithin = false; foreach (var item in internalRings) { if (GeometryEngine.Within(part, item)) isWithin = true; } // if the current polygon is not within any polygon of the internal collection // then it is disjoint and needs to be added to if (isWithin == false) internalRings.Add(part as Polygon); } // now assemble a new polygon geometry based on the internal polygon collection foreach (var ring in internalRings) { outerRings.AddParts(ring.Parts); } // return the final geometry of the outer rings return outerRings.ToGeometry(); }