/// <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());
        }
Exemple #2
0
        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();
        }