private Feature ConvertToMultipolygon(CompleteRelation relation)
        {
            var allWaysInRelationByRole = GetAllWaysGroupedByRole(relation);
            var outerWays     = allWaysInRelationByRole.Where(kvp => kvp.Key == OUTER).SelectMany(kvp => kvp.Value).ToList();
            var outerPolygons = GetGeometriesFromWays(outerWays).OfType <Polygon>().ToList();

            outerPolygons = MergePolygons(outerPolygons);
            var innerWays     = allWaysInRelationByRole.Where(kvp => kvp.Key != OUTER).SelectMany(kvp => kvp.Value).ToList();
            var innerPolygons = GetGeometriesFromWays(innerWays).OfType <Polygon>().ToList();

            innerPolygons = MergePolygons(innerPolygons);
            MergeInnerIntoOuterPolygon(ref outerPolygons, ref innerPolygons);
            var multiPolygon = _geometryFactory.CreateMultiPolygon(outerPolygons.Union(innerPolygons).ToArray());

            return(new Feature(multiPolygon, ConvertTags(relation)));
        }
示例#2
0
        public static IGeometry FromFlatbuf(Geometry geometry, GeometryType type)
        {
            byte dimensions = 2;
            var  factory    = new GeometryFactory();

            if (type == GeometryType.Unknown)
            {
                type = geometry.Type;
            }

            switch (type)
            {
            case GeometryType.MultiPolygon:
                int       partsLength = geometry.PartsLength;
                Polygon[] polygons    = new Polygon[partsLength];
                for (int i = 0; i < geometry.PartsLength; i++)
                {
                    polygons[i] = (Polygon)FromFlatbuf(geometry.Parts(i).Value, GeometryType.Polygon);
                }
                return(factory.CreateMultiPolygon(polygons));
            }

            var coords          = geometry.GetXyArray();
            var ends            = geometry.GetEndsArray();
            var sequenceFactory = new PackedCoordinateSequenceFactory();

            switch (type)
            {
            case GeometryType.Point:
                return(factory.CreatePoint(sequenceFactory.Create(coords, dimensions)));

            case GeometryType.MultiPoint:
                return(factory.CreateMultiPoint(sequenceFactory.Create(coords, dimensions)));

            case GeometryType.LineString:
                return(factory.CreateLineString(sequenceFactory.Create(coords, dimensions)));

            case GeometryType.MultiLineString:
                return(ParseFlatbufMultiLineString(ends, coords, dimensions));

            case GeometryType.Polygon:
                return(ParseFlatbufPolygon(ends, coords, dimensions));

            default: throw new ApplicationException("FromFlatbuf: Unsupported geometry type");
            }
        }
示例#3
0
        /// <summary>
        /// CONVERSION of geometry: Polygon to Multipolygon
        /// </summary>
        public static IMultiPolygon Polygon2Multipolygon(IGeometry polygon)
        {
            if (polygon is Polygon)
            {
                var           factory      = new GeometryFactory();
                Polygon[]     polygons     = new Polygon[] { polygon as Polygon };
                IMultiPolygon multiPolygon = factory.CreateMultiPolygon(polygons);

                return(multiPolygon);
            }
            else if (polygon is MultiPolygon)
            {
                return((IMultiPolygon)polygon);
            }
            else
            {
                throw new ArgumentException($"Error: GeometryType not supported! input is of type {polygon.GeometryType}");
            }
        }
示例#4
0
        public void ParseMultipolygon()
        {
            string        multipolygon = "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7,5 5)))";
            IMultiPolygon geom         = GeometryFromWKT.Parse(multipolygon) as IMultiPolygon;

            Assert.IsNotNull(geom);
            Assert.AreEqual(2, geom.NumGeometries);
            Assert.AreEqual(GeometryFactory.CreatePoint(5, 5), geom[0].Centroid);
            Assert.AreEqual(multipolygon, geom.AsText());
            Assert.IsNotNull(GeometryFromWKT.Parse("MULTIPOLYGON EMPTY"));
            Assert.IsTrue(GeometryFromWKT.Parse("MULTIPOLYGON EMPTY").IsEmpty);
            geom = GeometryFromWKT.Parse("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),EMPTY,((5 5,7 5,7 7,5 7,5 5)))") as IMultiPolygon;
            Assert.IsNotNull(geom);
            Assert.IsTrue(geom[1].IsEmpty);
            Assert.AreEqual(GeometryFactory.CreatePoint(5, 5), (geom.Geometries[2] as IPolygon).Shell.EndPoint);
            Assert.AreEqual(GeometryFactory.CreatePoint(5, 5), (geom.Geometries[2] as IPolygon).Shell.StartPoint);
            Assert.AreEqual((geom.Geometries[2] as IPolygon).Shell.StartPoint, (geom.Geometries[2] as IPolygon).Shell.EndPoint);
            Assert.AreEqual(3, geom.NumGeometries);
            Assert.AreEqual("MULTIPOLYGON EMPTY", GeometryFactory.CreateMultiPolygon().AsText());
        }
示例#5
0
        /// <summary>
        /// Creates a multipolygon from the wkb.
        /// </summary>
        /// <returns>A geometry.</returns>
        private Geometry CreateWKBMultiPolygon()
        {
            //Get the number of Polygons.
            int numPolygons = (int)_bReader.ReadUInt32();

            //Create a new array for the Polygons.
            Polygon[] polygons = new Polygon[numPolygons];

            //Loop on the number of polygons.
            for (int i = 0; i < numPolygons; i++)
            {
                // read polygon header
                _bReader.ReadByte();
                _bReader.ReadUInt32();
                //Create the next polygon and add it to the array.
                polygons[i] = (Polygon)CreateWKBPolygon();
            }
            //Create and return the MultiPolygon.
            return(_geometryFactory.CreateMultiPolygon(polygons));
        }
        /// <summary>
        /// Creates a single Polygon with holes.
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        private Geometry CreateSingleOrMultiPolygon(CoordinateBuffer buffer)
        {
            // Support vars
            var cses         = buffer.ToSequences();
            var shellRings   = new List <LinearRing>();
            var holeRings    = new List <LinearRing>();
            var numHoleRings = new Queue <int>();

            //Sort for shells and holes
            foreach (var cs in cses)
            {
                var ring = _factory.CreateLinearRing(cs);
                if (!ring.IsCCW)
                {
                    shellRings.Add(ring);
                    numHoleRings.Enqueue(holeRings.Count);
                }
                else
                {
                    holeRings.Add(ring);
                }
            }
            numHoleRings.Enqueue(holeRings.Count);

            if (shellRings.Count == 1)
            {
                return(_factory.CreatePolygon(shellRings[0], holeRings.ToArray()));
            }

            var polygons = new Polygon[shellRings.Count];
            int offset   = numHoleRings.Dequeue();

            for (int i = 0; i < shellRings.Count; i++)
            {
                var shellRing = shellRings[i];
                int numHoles  = numHoleRings.Dequeue();
                var holes     = holeRings.GetRange(offset, numHoles - offset).ToArray();
                polygons[i] = _factory.CreatePolygon(shellRing, holes);
            }
            return(_factory.CreateMultiPolygon(polygons));
        }
示例#7
0
        private GeometryCollection EditGeometryCollection(GeometryCollection collection,
                                                          IGeometryEdit operation)
        {
            GeometryCollection newCollection =
                (GeometryCollection)operation.Edit(collection, m_objFactory);

            GeometryList geometries = new GeometryList();

            for (int i = 0; i < newCollection.NumGeometries; i++)
            {
                Geometry geometry = Edit(newCollection.GetGeometry(i), operation);

                if (geometry.IsEmpty)
                {
                    continue;
                }

                geometries.Add(geometry);
            }

            GeometryType geomType = newCollection.GeometryType;

            if (geomType == GeometryType.MultiPoint)
            {
                return(m_objFactory.CreateMultiPoint(geometries.ToPointArray()));
            }

            if (geomType == GeometryType.MultiLineString)
            {
                return(m_objFactory.CreateMultiLineString(
                           geometries.ToLineStringArray()));
            }

            if (geomType == GeometryType.MultiPolygon)
            {
                return(m_objFactory.CreateMultiPolygon(geometries.ToPolygonArray()));
            }

            return(m_objFactory.CreateGeometryCollection(geometries.ToArray()));
        }
        /// <summary>
        /// Transforms a <see cref="MultiPolygon"/> geometry.
        /// </summary>
        /// <param name="geom">The <c>MultiPolygon</c> to transform</param>
        /// <param name="parent">The parent geometry</param>
        /// <returns>A <c>MultiPolygon</c></returns>
        protected virtual Geometry TransformMultiPolygon(MultiPolygon geom, Geometry parent)
        {
            var transGeomList = new List <Geometry>();

            for (int i = 0; i < geom.NumGeometries; i++)
            {
                var transformGeom = TransformPolygon((Polygon)geom.GetGeometryN(i), geom);
                if (transformGeom == null)
                {
                    continue;
                }
                if (transformGeom.IsEmpty)
                {
                    continue;
                }
                transGeomList.Add(transformGeom);
            }
            if (transGeomList.Count == 0)
            {
                return(Factory.CreateMultiPolygon());
            }
            return(Factory.BuildGeometry(transGeomList));
        }
示例#9
0
        static IMultiPolygon ParseFlatbufMultiPolygon(uint[] lengths, uint[] ringLengths, uint[] ringCounts, double[] coords, byte dimensions)
        {
            var sequenceFactory = new PackedCoordinateSequenceFactory();
            var factory         = new GeometryFactory(sequenceFactory);
            var polygons        = new List <IPolygon>();

            if (lengths == null)
            {
                var polygon = ParseFlatbufPolygon(ringLengths, coords, dimensions);
                polygons.Add(polygon);
            }
            else
            {
                var  arraySegment = new ArraySegment <double>(coords);
                uint offset       = 0;
                uint ringOffset   = 0;
                for (int i = 0; i < lengths.Length; i++)
                {
                    var    length           = lengths[i];
                    var    ringCount        = ringCounts[i];
                    uint[] ringLengthSubset = null;
                    if (ringCount > 1)
                    {
                        var ringLengthsSegment = new ArraySegment <uint>(ringLengths).Skip((int)ringOffset).Take((int)ringCount).ToArray();
                        ringLengthSubset = ringLengths;
                    }
                    ringOffset += ringCount;

                    var linearRingCoords = arraySegment.Skip((int)offset).Take((int)length).ToArray();
                    var polygon          = ParseFlatbufPolygon(ringLengthSubset, linearRingCoords, dimensions);
                    polygons.Add(polygon);
                    offset += length;
                }
            }

            return(factory.CreateMultiPolygon(polygons.ToArray()));
        }
示例#10
0
        private static MultiPolygon CreateWKBMultiPolygon(BinaryReader reader, WkbByteOrder byteOrder, GeometryFactory factory)
        {
            // Get the number of Polygons.
            var numPolygons = (int)ReadUInt32(reader, byteOrder);

            // Create a new array for the Polygons.
            var polygons = new Polygon[numPolygons];

            // Loop on the number of polygons.
            for (var i = 0; i < numPolygons; i++)
            {
                // read polygon header
                reader.ReadByte();
                ReadUInt32(reader, byteOrder);

                // TODO: Validate type

                // Create the next polygon and add it to the array.
                polygons[i] = CreateWKBPolygon(reader, byteOrder, factory);
            }

            //Create and return the MultiPolygon.
            return(factory.CreateMultiPolygon(polygons));
        }
示例#11
0
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="file">The stream to read.</param>
        /// <param name="geometryFactory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override Geometry Read(BigEndianBinaryReader file, GeometryFactory geometryFactory)
        {
            int       shapeTypeNum = file.ReadInt32();
            ShapeType shapeType    = (ShapeType)Enum.Parse(typeof(ShapeType), shapeTypeNum.ToString());

            if (shapeType != ShapeType.Polygon)
            {
                throw new ShapefileException("Attempting to load a non-polygon as polygon.");
            }

            //read and for now ignore bounds.
            double[] box = new double[4];
            for (int i = 0; i < 4; i++)
            {
                box[i] = file.ReadDouble();
            }

            int[] partOffsets;

            int numParts  = file.ReadInt32();
            int numPoints = file.ReadInt32();

            partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = file.ReadInt32();
            }

            ArrayList shells = new ArrayList();
            ArrayList holes  = new ArrayList();

            int start, finish, length;

            for (int part = 0; part < numParts; part++)
            {
                start = partOffsets[part];
                if (part == numParts - 1)
                {
                    finish = numPoints;
                }
                else
                {
                    finish = partOffsets[part + 1];
                }
                length = finish - start;
                Coordinates points = new Coordinates();
                points.Capacity = length;
                for (int i = 0; i < length; i++)
                {
                    Coordinate external      = new Coordinate(file.ReadDouble(), file.ReadDouble());
                    Coordinate internalCoord = geometryFactory.PrecisionModel.ToInternal(external);
                    points.Add(internalCoord);
                }
                LinearRing ring = geometryFactory.CreateLinearRing(points);
                //Debug.Assert(ring.IsValid()==false,"Ring is not valid.");
                if (_cga.IsCCW(points))
                {
                    holes.Add(ring);
                }
                else
                {
                    shells.Add(ring);
                }
            }

            //now we have a list of all shells and all holes
            ArrayList holesForShells = new ArrayList(shells.Count);

            for (int i = 0; i < shells.Count; i++)
            {
                holesForShells.Add(new ArrayList());
            }
            //find homes
            for (int i = 0; i < holes.Count; i++)
            {
                LinearRing testRing = (LinearRing)holes[i];
                LinearRing minShell = null;
                Envelope   minEnv   = null;
                Envelope   testEnv  = testRing.GetEnvelopeInternal();
                Coordinate testPt   = testRing.GetCoordinateN(0);
                LinearRing tryRing;
                for (int j = 0; j < shells.Count; j++)
                {
                    tryRing = (LinearRing)shells[j];
                    Envelope tryEnv = tryRing.GetEnvelopeInternal();
                    if (minShell != null)
                    {
                        minEnv = minShell.GetEnvelopeInternal();
                    }
                    bool        isContained = false;
                    Coordinates coordList   = tryRing.GetCoordinates();
                    if (tryEnv.Contains(testEnv) &&
                        (_cga.IsPointInRing(testPt, coordList) ||
                         (PointInList(testPt, coordList))))
                    {
                        isContained = true;
                    }
                    // check if this new containing ring is smaller than the
                    // current minimum ring
                    if (isContained)
                    {
                        if (minShell == null ||
                            minEnv.Contains(tryEnv))
                        {
                            minShell = tryRing;
                        }
                    }
                }
                //if (minShell==null)
                //{
                //	throw new InvalidOperationException("Could not find shell for a hole. Try a different precision model.");
                //}
            }
            Polygon[] polygons = new Polygon[shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = geometryFactory.CreatePolygon((LinearRing)shells[i], (LinearRing[])((ArrayList)holesForShells[i]).ToArray(typeof(LinearRing)));
            }

            if (polygons.Length == 1)
            {
                return(polygons[0]);
            }
            //it's a multi part
            return(geometryFactory.CreateMultiPolygon(polygons));
        }
        private Geometry ParseGeometry(JsonReader reader, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            if (reader.TokenType != JsonToken.StartObject)
            {
                throw new JsonReaderException("Expected Start object '{' Token");
            }

            // advance
            reader.ReadOrThrow();

            GeoJsonObjectType?geometryType = null;
            List <object>     coords       = null;

            while (reader.TokenType == JsonToken.PropertyName)
            {
                //read the tokens, type may come before coordinates or geometries as pr spec
                string prop = (string)reader.Value;
                switch (prop)
                {
                case "type":
                    if (geometryType == null)
                    {
                        reader.ReadOrThrow();
                        geometryType = (GeoJsonObjectType)Enum.Parse(typeof(GeoJsonObjectType), (string)reader.Value, true);
                        reader.ReadOrThrow();
                    }

                    break;

                case "geometries":
                    //only geom collection has "geometries"
                    reader.ReadOrThrow();      //read past start array tag
                    coords = ParseGeomCollection(reader, serializer);
                    break;

                case "coordinates":
                    reader.ReadOrThrow();     //read past start array tag
                    coords = ReadCoordinates(reader);
                    break;

                case "bbox":
                    // Read, but can't do anything with it, assigning Envelopes is impossible without reflection
                    /*var bbox = */
                    serializer.Deserialize <Envelope>(reader);
                    break;

                default:
                    reader.ReadOrThrow();
                    /*var item = */
                    serializer.Deserialize(reader);
                    break;
                }

                reader.SkipComments();
            }

            if (reader.TokenType != JsonToken.EndObject)
            {
                throw new ArgumentException("Expected token '}' not found.");
            }

            switch (geometryType)
            {
            case GeoJsonObjectType.Point:
                return(CreatePoint(reader, coords));

            case GeoJsonObjectType.MultiPoint:
                return(_factory.CreateMultiPoint(coords.Select(obj => CreatePoint(reader, (List <object>)obj)).ToArray()));

            case GeoJsonObjectType.LineString:
                return(CreateLineString(reader, coords));

            case GeoJsonObjectType.MultiLineString:
                return(_factory.CreateMultiLineString(coords.Select(obj => CreateLineString(reader, (List <object>)obj)).ToArray()));

            case GeoJsonObjectType.Polygon:
                return(CreatePolygon(reader, coords));

            case GeoJsonObjectType.MultiPolygon:
                return(_factory.CreateMultiPolygon(coords.Select(obj => CreatePolygon(reader, (List <object>)obj)).ToArray()));

            case GeoJsonObjectType.GeometryCollection:
                return(_factory.CreateGeometryCollection(coords.Cast <Geometry>().ToArray()));

            default:
                return(null);
            }
        }
示例#13
0
        /// <summary>
        /// Writes a Geometry to the given binary wirter.
        /// </summary>
        /// <param name="geometry">The geometry to write.</param>
        /// <param name="file">The file stream to write to.</param>
        /// <param name="geometryFactory">The geometry factory to use.</param>
        public override void Write(IGeometry geometry, BinaryWriter file, IGeometryFactory geometryFactory)
        {
            // This check seems to be not useful and slow the operations...
            // if (!geometry.IsValid)
            // Trace.WriteLine("Invalid polygon being written.");

            IGeometryCollection multi;

            if (geometry is IGeometryCollection)
            {
                multi = (IGeometryCollection)geometry;
            }
            else
            {
                GeometryFactory gf = new GeometryFactory(geometry.PrecisionModel);
                multi = gf.CreateMultiPolygon(new[] { (IPolygon)geometry, });
            }

            file.Write(int.Parse(EnumUtility.Format(typeof(ShapeGeometryType), ShapeType, "d")));

            Envelope box    = multi.EnvelopeInternal as Envelope;
            Envelope bounds = GetEnvelopeExternal(geometryFactory.PrecisionModel, box);

            file.Write(bounds.MinX);
            file.Write(bounds.MinY);
            file.Write(bounds.MaxX);
            file.Write(bounds.MaxY);

            int numParts  = GetNumParts(multi);
            int numPoints = multi.NumPoints;

            file.Write(numParts);
            file.Write(numPoints);

            // write the offsets to the points
            int offset = 0;

            for (int part = 0; part < multi.NumGeometries; part++)
            {
                // offset to the shell points
                IPolygon polygon = (IPolygon)multi.Geometries[part];
                file.Write(offset);
                offset = offset + polygon.ExteriorRing.NumPoints;

                // offstes to the holes
                foreach (ILinearRing ring in polygon.InteriorRings)
                {
                    file.Write(offset);
                    offset = offset + ring.NumPoints;
                }
            }

            // write the points
            for (int part = 0; part < multi.NumGeometries; part++)
            {
                IPolygon     poly   = (IPolygon)multi.Geometries[part];
                Coordinate[] points = poly.ExteriorRing.Coordinates as Coordinate[];
                WriteCoords(points, file, geometryFactory);
                foreach (ILinearRing ring in poly.InteriorRings)
                {
                    Coordinate[] points2 = ring.Coordinates as Coordinate[];
                    WriteCoords(points2, file, geometryFactory);
                }
            }
        }
示例#14
0
        /// <summary>
        /// Reads and parses the geometry with ID 'oid' from the ShapeFile
        /// </summary>
        /// <remarks><see cref="FilterDelegate">Filtering</see> is not applied to this method</remarks>
        /// <param name="oid">Object ID</param>
        /// <returns>geometry</returns>
        private IGeometry ReadGeometry(uint oid)
        {
            brShapeFile.BaseStream.Seek(GetShapeIndex(oid) + 8, 0);          //Skip record number and content length
            ShapeType type = (ShapeType)brShapeFile.ReadInt32();             //Shape type

            if (type == ShapeType.Null)
            {
                return(null);
            }
            if (_ShapeType == ShapeType.Point || _ShapeType == ShapeType.PointM || _ShapeType == ShapeType.PointZ)
            {
                //SharpMap.Geometries.Point tempFeature = new SharpMap.Geometries.Point();
                return(GeometryFactory.CreatePoint(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
            }
            else if (_ShapeType == ShapeType.Multipoint || _ShapeType == ShapeType.MultiPointM || _ShapeType == ShapeType.MultiPointZ)
            {
                brShapeFile.BaseStream.Seek(32 + brShapeFile.BaseStream.Position, 0);                 //skip min/max box
                List <IPoint> feature = new List <IPoint>();
                //SharpMap.Geometries.MultiPoint feature = new SharpMap.Geometries.MultiPoint();
                int nPoints = brShapeFile.ReadInt32();                 // get the number of points
                if (nPoints == 0)
                {
                    return(null);
                }
                for (int i = 0; i < nPoints; i++)
                {
                    feature.Add(GeometryFactory.CreatePoint(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
                }


                return(GeometryFactory.CreateMultiPoint(feature.ToArray()));
            }
            else if (_ShapeType == ShapeType.PolyLine || _ShapeType == ShapeType.Polygon ||
                     _ShapeType == ShapeType.PolyLineM || _ShapeType == ShapeType.PolygonM ||
                     _ShapeType == ShapeType.PolyLineZ || _ShapeType == ShapeType.PolygonZ)
            {
                brShapeFile.BaseStream.Seek(32 + brShapeFile.BaseStream.Position, 0); //skip min/max box

                int nParts = brShapeFile.ReadInt32();                                 // get number of parts (segments)
                if (nParts == 0)
                {
                    return(null);
                }
                int nPoints = brShapeFile.ReadInt32();                 // get number of points

                int[] segments = new int[nParts + 1];
                //Read in the segment indexes
                for (int b = 0; b < nParts; b++)
                {
                    segments[b] = brShapeFile.ReadInt32();
                }
                //add end point
                segments[nParts] = nPoints;

                if ((int)_ShapeType % 10 == 3)
                {
                    //SharpMap.Geometries.MultiLineString mline = new SharpMap.Geometries.MultiLineString();
                    List <ILineString> mline = new List <ILineString>();
                    for (int LineID = 0; LineID < nParts; LineID++)
                    {
                        //SharpMap.Geometries.LineString line = new SharpMap.Geometries.LineString();
                        List <ICoordinate> line = new List <ICoordinate>();
                        for (int i = segments[LineID]; i < segments[LineID + 1]; i++)
                        {
                            line.Add(GeometryFactory.CreateCoordinate(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
                        }
                        //line.Vertices.Add(new SharpMap.Geometries.Point(
                        mline.Add(GeometryFactory.CreateLineString(line.ToArray()));
                    }
                    if (mline.Count == 1)
                    {
                        return(mline[0]);
                    }
                    return(GeometryFactory.CreateMultiLineString(mline.ToArray()));
                }
                else                 //(_ShapeType == ShapeType.Polygon etc...)
                {
                    //First read all the rings
                    //List<SharpMap.Geometries.LinearRing> rings = new List<SharpMap.Geometries.LinearRing>();
                    List <ILinearRing> rings = new List <ILinearRing>();
                    for (int RingID = 0; RingID < nParts; RingID++)
                    {
                        //SharpMap.Geometries.LinearRing ring = new SharpMap.Geometries.LinearRing();
                        List <ICoordinate> ring = new List <ICoordinate>();
                        for (int i = segments[RingID]; i < segments[RingID + 1]; i++)
                        {
                            ring.Add(GeometryFactory.CreateCoordinate(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
                        }

                        //ring.Vertices.Add(new SharpMap.Geometries.Point
                        rings.Add(GeometryFactory.CreateLinearRing(ring.ToArray()));
                    }
                    bool[] IsCounterClockWise = new bool[rings.Count];
                    int    PolygonCount       = 0;
                    for (int i = 0; i < rings.Count; i++)
                    {
                        IsCounterClockWise[i] = GeometryFactory.IsCCW(rings[i].Coordinates);
                        if (!IsCounterClockWise[i])
                        {
                            PolygonCount++;
                        }
                    }
                    if (PolygonCount == 1)                     //We only have one polygon
                    {
                        ILinearRing        shell = rings[0];
                        List <ILinearRing> holes = new List <ILinearRing>();
                        if (rings.Count > 1)
                        {
                            for (int i = 1; i < rings.Count; i++)
                            {
                                holes.Add(rings[i]);
                            }
                        }
                        return(GeometryFactory.CreatePolygon(shell, holes.ToArray()));
                    }
                    else
                    {
                        List <IPolygon>    polys = new List <IPolygon>();
                        ILinearRing        shell = rings[0];
                        List <ILinearRing> holes = new List <ILinearRing>();
                        for (int i = 1; i < rings.Count; i++)
                        {
                            if (!IsCounterClockWise[i])
                            {
                                polys.Add(GeometryFactory.CreatePolygon(shell, null));
                                shell = rings[i];
                            }
                            else
                            {
                                holes.Add(rings[i]);
                            }
                        }
                        polys.Add(GeometryFactory.CreatePolygon(shell, holes.ToArray()));
                        return(GeometryFactory.CreateMultiPolygon(polys.ToArray()));
                    }
                }
            }
            else
            {
                throw (new ApplicationException("Shapefile type " + _ShapeType.ToString() + " not supported"));
            }
        }
        /// <summary>
        /// Writes a Geometry to the given binary wirter.
        /// </summary>
        /// <param name="geometry">The geometry to write.</param>
        /// <param name="writer">The file stream to write to.</param>
        /// <param name="factory">The geometry factory to use.</param>
        public override void Write(Geometry geometry, BinaryWriter writer, GeometryFactory factory)
        {
            if (geometry == null)
            {
                throw new ArgumentNullException("geometry");
            }

            // This check seems to be not useful and slow the operations...
            // if (!geometry.IsValid)
            // Trace.WriteLine("Invalid polygon being written.");

            var multi = geometry as MultiPolygon;

            if (multi == null)
            {
                var poly = geometry as Polygon;
                if (poly == null)
                {
                    string err = string.Format("Expected geometry that implements 'MultiPolygon' or 'Polygon', but was '{0}'",
                                               geometry.GetType().Name);
                    throw new ArgumentException(err, "geometry");
                }

                var arr = new[] { poly };
                multi = factory.CreateMultiPolygon(arr);
            }

            // Write the shape type
            writer.Write((int)ShapeType);

            var box    = multi.EnvelopeInternal;
            var bounds = GetEnvelopeExternal(factory.PrecisionModel, box);

            writer.Write(bounds.MinX);
            writer.Write(bounds.MinY);
            writer.Write(bounds.MaxX);
            writer.Write(bounds.MaxY);

            int numParts  = GetNumParts(multi);
            int numPoints = multi.NumPoints;

            writer.Write(numParts);
            writer.Write(numPoints);

            // write the offsets to the points
            int offset = 0;

            for (int part = 0; part < multi.NumGeometries; part++)
            {
                // offset to the shell points
                var polygon = (Polygon)multi.Geometries[part];
                writer.Write(offset);
                offset = offset + polygon.ExteriorRing.NumPoints;

                // offses to the holes
                foreach (LinearRing ring in polygon.InteriorRings)
                {
                    writer.Write(offset);
                    offset = offset + ring.NumPoints;
                }
            }

            var zList = HasZValue() ? new List <double>() : null;
            var mList = (HasMValue() || HasZValue()) ? new List <double>() : null;

            // write the points
            for (int part = 0; part < multi.NumGeometries; part++)
            {
                var poly  = (Polygon)multi.Geometries[part];
                var shell = (LinearRing)poly.ExteriorRing;
                // shells in polygons are written clockwise
                var points = !shell.IsCCW
                    ? shell.CoordinateSequence
                    : shell.CoordinateSequence.Reversed();
                WriteCoords(points, writer, zList, mList);

                foreach (LinearRing hole in poly.InteriorRings)
                {
                    // holes in polygons are written counter-clockwise
                    points = hole.IsCCW
                        ? hole.CoordinateSequence
                        : hole.CoordinateSequence.Reversed();

                    WriteCoords(points, writer, zList, mList);
                }
            }

            //Write the z-m-values
            WriteZM(writer, multi.NumPoints, zList, mList);
        }
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="file">The stream to read.</param>
        /// <param name="totalRecordLength">Total length of the record we are about to read</param>
        /// <param name="factory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override Geometry Read(BigEndianBinaryReader file, int totalRecordLength, GeometryFactory factory)
        {
            int totalRead = 0;
            var type      = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);

            if (type == ShapeGeometryType.NullShape)
            {
                return(factory.CreatePolygon(null, null));
            }

            if (type != ShapeType)
            {
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));
            }

            // Read and for now ignore bounds.
            int bblength = GetBoundingBoxLength();

            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
            {
                boundingBox[boundingBoxIndex] = ReadDouble(file, totalRecordLength, ref totalRead);
            }

            int numParts  = ReadInt32(file, totalRecordLength, ref totalRead);
            int numPoints = ReadInt32(file, totalRecordLength, ref totalRead);

            int[] partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = ReadInt32(file, totalRecordLength, ref totalRead);
            }

            var skippedList = new HashSet <int>();

            //var allPoints = new List<Coordinate>();
            var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var pm     = factory.PrecisionModel;

            for (int part = 0; part < numParts; part++)
            {
                int start  = partOffsets[part];
                int finish = (part == numParts - 1)
                    ? numPoints
                    : partOffsets[part + 1];

                int length = finish - start;
                for (int i = 0; i < length; i++)
                {
                    double x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    double y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));

                    // Thanks to Abhay Menon!
                    if (!(Coordinate.NullOrdinate.Equals(x) || Coordinate.NullOrdinate.Equals(y)))
                    {
                        buffer.AddCoordinate(x, y);
                    }
                    else
                    {
                        skippedList.Add(start + i);
                    }
                }
                //Add a marker that we have finished one part of the geometry
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the parts, let's read optional Z and M values
            // and populate Z in the coordinate before we start manipulating the segments
            // We have to track corresponding optional M values and set them up in the
            // Geometries via CoordinateSequence further down.
            GetZMValues(file, totalRecordLength, ref totalRead, buffer, skippedList);

            // Get the resulting sequences
            var sequences = buffer.ToSequences(factory.CoordinateSequenceFactory);
            var shells    = new List <LinearRing>();
            var holes     = new List <LinearRing>();

            for (int i = 0; i < sequences.Length; i++)
            {
                //Skip garbage input data with 0 points
                if (sequences[i].Count < 1)
                {
                    continue;
                }

                var tmp  = EnsureClosedSequence(sequences[i], factory.CoordinateSequenceFactory);
                var ring = factory.CreateLinearRing(tmp);
                if (ring.IsCCW)
                {
                    holes.Add(ring);
                }
                else
                {
                    shells.Add(ring);
                }
            }

            // Ensure the ring is encoded right
            if (shells.Count == 0 && holes.Count == 1)
            {
                shells.Add(factory.CreateLinearRing(holes[0].CoordinateSequence.Reversed()));
                holes.Clear();
            }

            // Now we have lists of all shells and all holes
            var holesForShells = new List <List <LinearRing> >(shells.Count);

            for (int i = 0; i < shells.Count; i++)
            {
                holesForShells.Add(new List <LinearRing>());
            }

            //Thanks to Bruno.Labrecque
            //Sort shells by area, rings should only be added to the smallest shell, that contains the ring
            shells.Sort(ProbeLinearRing);

            // Find holes
            foreach (var testHole in holes)
            {
                var testEnv = testHole.EnvelopeInternal;
                var testPt  = testHole.GetCoordinateN(0);

                //We have the shells sorted
                for (int j = 0; j < shells.Count; j++)
                {
                    var  tryShell    = shells[j];
                    var  tryEnv      = tryShell.EnvelopeInternal;
                    bool isContained = tryEnv.Contains(testEnv) && PointLocation.IsInRing(testPt, tryShell.Coordinates);

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (isContained)
                    {
                        // Suggested by Brian Macomber and added 3/28/2006:
                        // holes were being found but never added to the holesForShells array
                        // so when converted to geometry by the factory, the inner rings were never created.
                        var holesForThisShell = holesForShells[j];
                        holesForThisShell.Add(testHole);

                        //Suggested by Bruno.Labrecque
                        //A LinearRing should only be added to one outer shell
                        break;
                    }
                }
            }

            var polygons = new Polygon[shells.Count];

            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = (factory.CreatePolygon(shells[i], holesForShells[i].ToArray()));
            }

            if (polygons.Length == 1)
            {
                geom = polygons[0];
            }
            else
            {
                geom = factory.CreateMultiPolygon(polygons);
            }

            return(geom);
        }
示例#17
0
 public Geometry CreateCollection(Geometry[] geometries, GeometryFactory geometryFactory)
 {
     return(geometryFactory.CreateMultiPolygon(GeometryFactory.ToPolygonArray(geometries)));
 }
        /**
         * Repair an invalid geometry.
         * <br/>
         * If preserveGeomDim is true, makeValid will remove degenerated geometries
         * from the result, i.e geometries which dimension is lower than the input
         * geometry dimension (except for mixed GeometryCollection).
         * <br/>
         * A multi-geometry will always produce a multi-geometry (eventually empty
         * or made of a single component). A simple geometry may produce a
         * multi-geometry (ex. polygon with self-intersection will generally produce
         * a multi-polygon). In this case, it is up to the client to explode
         * multi-geometries if he needs to.
         * <br/>
         * If preserveGeomDim is off, it is up to the client to filter degenerate
         * geometries.
         * <br/>
         * WARNING : for geometries of dimension 1 (linear), duplicate coordinates
         * are preserved as much as possible. For geometries of dimension 2 (areal),
         * duplicate coordinates are generally removed due to the use of overlay
         * operations.
         *
         * @param geometry input geometry
         * @return a valid Geometry
         */
        public NetTopologySuite.Geometries.Geometry makeValid(NetTopologySuite.Geometries.Geometry geometry)
        {
            // Input geometry is recursively exploded into a list of simple components
            List <NetTopologySuite.Geometries.Geometry> list = new(geometry.NumGeometries);

            decompose(geometry, list);

            // Each single component is made valid
            ICollection <NetTopologySuite.Geometries.Geometry> list2 = new List <NetTopologySuite.Geometries.Geometry>();

            foreach (var component in list)
            {
                if (component is Point)
                {
                    Point p = makePointValid((Point)component);
                    if (!p.IsEmpty)
                    {
                        list2.Add(p);
                    }
                }
                else if (component is LineString)
                {
                    var geom = makeLineStringValid((LineString)component);
                    for (int i = 0; i < geom.NumGeometries; i++)
                    {
                        if (!geom.GetGeometryN(i).IsEmpty)
                        {
                            list2.Add(geom.GetGeometryN(i));
                        }
                    }
                }
                else if (component is Polygon)
                {
                    var geom = makePolygonValid((Polygon)component);
                    for (int i = 0; i < geom.NumGeometries; i++)
                    {
                        if (!geom.GetGeometryN(i).IsEmpty)
                        {
                            list2.Add(geom.GetGeometryN(i));
                        }
                    }
                }
                else
                {
                    //assert false : "Should never reach here";
                }
            }

            list.Clear();
            foreach (NetTopologySuite.Geometries.Geometry g in list2)
            {
                // If preserveGeomDim is true and original input geometry is not a GeometryCollection
                // components with a lower dimension than input geometry are removed
                if (preserveGeomDim && !geometry.GeometryType.Equals(NetTopologySuite.Geometries.Geometry.TypeNameGeometryCollection))
                {
                    removeLowerDimension(g, list, geometry.Dimension);
                }
                else
                {
                    decompose(g, list);
                }
            }
            list2 = list;

            // In a MultiPolygon, polygons cannot touch or overlap each other
            // (adjacent polygons are not merged in the context of a mixed GeometryCollection)
            if (list2.Count > 1)
            {
                bool multiPolygon = true;
                foreach (var geom in list2)
                {
                    if (geom.Dimension < Dimension.Surface)
                    {
                        multiPolygon = false;
                    }
                }
                if (multiPolygon)
                {
                    list2 = unionAdjacentPolygons(list2);
                }
            }
            if (0 == list2.Count)
            {
                GeometryFactory factory = geometry.Factory;
                if (geometry is Point)
                {
                    return(factory.CreatePoint((Coordinate)null));
                }
                else if (geometry is LinearRing)
                {
                    return(factory.CreateLinearRing(EMPTY_COORD_ARRAY));
                }
                else if (geometry is LineString)
                {
                    return(factory.CreateLineString(EMPTY_COORD_ARRAY));
                }
                else if (geometry is Polygon)
                {
                    return(factory.CreatePolygon(factory.CreateLinearRing(EMPTY_COORD_ARRAY), EMPTY_RING_ARRAY));
                }
                else if (geometry is MultiPoint)
                {
                    return(factory.CreateMultiPoint(new Point[0]));
                }
                else if (geometry is MultiLineString)
                {
                    return(factory.CreateMultiLineString(new LineString[0]));
                }
                else if (geometry is MultiPolygon)
                {
                    return(factory.CreateMultiPolygon(new Polygon[0]));
                }
                else
                {
                    return(factory.CreateGeometryCollection(new NetTopologySuite.Geometries.Geometry[0]));
                }
            }
            else
            {
                CoordinateSequenceFactory csFactory = geometry.Factory.CoordinateSequenceFactory;
                // Preserve 4th coordinate dimension as much as possible if preserveCoordDim is true
                if (preserveCoordDim && csFactory is PackedCoordinateSequenceFactory
                    /*&& ((PackedCoordinateSequenceFactory)csFactory).Dimension == 4*/)
                {
                    System.Collections.Generic.Dictionary <Coordinate, Double> map = new();
                    gatherDim4(geometry, map);
                    list2 = restoreDim4(list2, map);
                }

                var result = geometry.Factory.BuildGeometry(list2);
                // If input geometry was a GeometryCollection and result is a simple geometry
                // Create a multi-geometry made of a single component
                if (geometry is GeometryCollection && !(result is GeometryCollection))
                {
                    if (geometry is MultiPoint && result is Point)
                    {
                        result = geometry.Factory.CreateMultiPoint(new Point[] { (Point)result });
                    }
                    else if (geometry is MultiLineString && result is LineString)
                    {
                        result = geometry.Factory.CreateMultiLineString(new LineString[] { (LineString)result });
                    }
                    else if (geometry is MultiPolygon && result is Polygon)
                    {
                        result = geometry.Factory.CreateMultiPolygon(new Polygon[] { (Polygon)result });
                    }
                }
                return(result);
            }
        }
示例#19
0
        /// <summary>
        /// Creates a Polygon or MultiPolygon from this Polygon shape.
        /// </summary>
        /// <param name="factory">The GeometryFactory to use to create the new Geometry.</param>
        /// <returns>The Polygon or IMultiPolygon created from this shape.</returns>
        protected Geometry FromPolygon(GeometryFactory factory)
        {
            if (factory == null)
            {
                factory = Geometry.DefaultFactory;
            }
            List <LinearRing> shells = new();
            List <LinearRing> holes  = new();

            foreach (var part in Range.Parts)
            {
                var coords = GetCoordinates(part);
                var ring   = factory.CreateLinearRing(coords.ToArray());
                if (Range.Parts.Count == 1)
                {
                    shells.Add(ring);
                }
                else
                {
                    if (ring.IsCCW)
                    {
                        holes.Add(ring);
                    }
                    else
                    {
                        shells.Add(ring);
                    }
                }
            }

            // Now we have a list of all shells and all holes
            List <LinearRing>[] holesForShells = new List <LinearRing> [shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                holesForShells[i] = new List <LinearRing>();
            }

            // Find holes
            foreach (LinearRing t in holes)
            {
                LinearRing testRing = t;
                LinearRing minShell = null;
                Envelope   minEnv   = null;
                Envelope   testEnv  = testRing.EnvelopeInternal;
                Coordinate testPt   = testRing.Coordinates[0];
                for (int j = 0; j < shells.Count; j++)
                {
                    LinearRing tryRing = shells[j];
                    Envelope   tryEnv  = tryRing.EnvelopeInternal;
                    if (minShell != null)
                    {
                        minEnv = minShell.EnvelopeInternal;
                    }
                    var isContained = tryEnv.Contains(testEnv) && (PointLocation.IsInRing(testPt, tryRing.Coordinates) || PointInList(testPt, tryRing.Coordinates));

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (isContained)
                    {
                        if (minShell == null || minEnv.Contains(tryEnv))
                        {
                            minShell = tryRing;
                        }

                        holesForShells[j].Add(t);
                    }
                }
            }

            var polygons = new Polygon[shells.Count];

            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = factory.CreatePolygon(shells[i], holesForShells[i].ToArray());
            }

            if (polygons.Length == 1)
            {
                return(polygons[0]);
            }

            // It's a multi part
            return(factory.CreateMultiPolygon(polygons));
        }
示例#20
0
        /// <summary>
        /// Writes a Geometry to the given binary wirter.
        /// </summary>
        /// <param name="geometry">The geometry to write.</param>
        /// <param name="file">The file stream to write to.</param>
        /// <param name="geometryFactory">The geometry factory to use.</param>
        public override void Write(Geometry geometry, System.IO.BinaryWriter file, GeometryFactory geometryFactory)
        {
            if (geometry.IsValid() == false)
            {
                Trace.WriteLine("Invalid polygon being written.");
            }
            GeometryCollection multi;

            if (geometry is GeometryCollection)
            {
                multi = (GeometryCollection)geometry;
            }
            else
            {
                GeometryFactory gf = new GeometryFactory(geometry.PrecisionModel, geometry.GetSRID());
                //multi = new MultiPolygon(new Polygon[]{(Polygon) geometry}, geometry.PrecisionModel, geometry.GetSRID());
                multi = gf.CreateMultiPolygon(new Polygon[] { (Polygon)geometry });
            }
            //file.setLittleEndianMode(true);
            file.Write(int.Parse(Enum.Format(typeof(ShapeType), this.ShapeType, "d")));

            Envelope box    = multi.GetEnvelopeInternal();
            Envelope bounds = ShapeHandler.GetEnvelopeExternal(geometryFactory.PrecisionModel, box);

            file.Write(bounds.MinX);
            file.Write(bounds.MinY);
            file.Write(bounds.MaxX);
            file.Write(bounds.MaxY);

            int numParts  = GetNumParts(multi);
            int numPoints = multi.GetNumPoints();

            file.Write(numParts);
            file.Write(numPoints);


            // write the offsets to the points
            int offset = 0;

            for (int part = 0; part < multi.Count; part++)
            {
                // offset to the shell points
                Polygon polygon = (Polygon)multi[part];
                file.Write(offset);
                offset = offset + polygon.Shell.GetNumPoints();
                // offstes to the holes
                foreach (LinearRing ring in polygon.Holes)
                {
                    file.Write(offset);
                    offset = offset + ring.GetNumPoints();
                }
            }


            // write the points
            for (int part = 0; part < multi.Count; part++)
            {
                Polygon     poly   = (Polygon)multi[part];
                Coordinates points = poly.Shell.GetCoordinates();
                if (_cga.IsCCW(points) == true)
                {
                    //points = points.ReverseCoordinateOrder();
                }
                WriteCoords(points, file, geometryFactory);
                foreach (LinearRing ring in poly.Holes)
                {
                    Coordinates points2 = ring.GetCoordinates();
                    if (_cga.IsCCW(points2) == false)
                    {
                        //points2 = points2.ReverseCoordinateOrder();
                    }
                    WriteCoords(points2, file, geometryFactory);
                }
            }
        }
示例#21
0
        private MultiPolygon CreateMP1()
        {
            Polygon[]    polygons = new Polygon[2];
            LineString[] rings    = new LineString[2];

            Coordinates coords = new Coordinates();
            Coordinate  coord  = new Coordinate(5, 1);

            coords.Add(coord);
            coord = new Coordinate(6, 2);
            coords.Add(coord);
            coord = new Coordinate(7, 3);
            coords.Add(coord);
            coord = new Coordinate(6, 4);
            coords.Add(coord);
            coord = new Coordinate(5, 5);
            coords.Add(coord);
            coord = new Coordinate(4, 4);
            coords.Add(coord);
            coord = new Coordinate(3, 3);
            coords.Add(coord);
            coord = new Coordinate(4, 2);
            coords.Add(coord);
            coord = new Coordinate(5, 1);
            coords.Add(coord);

            GeometryFactory gf = new GeometryFactory(_precMod, _sRID);

            LinearRing exterior1 = gf.CreateLinearRing(coords);

            polygons[0] = gf.CreatePolygon(exterior1);
            rings[0]    = exterior1 as LineString;

            coords = new Coordinates();
            coord  = new Coordinate(5, 1);
            coords.Add(coord);
            coord = new Coordinate(6, 2);
            coords.Add(coord);
            coord = new Coordinate(7, 3);
            coords.Add(coord);
            coord = new Coordinate(6, 4);
            coords.Add(coord);
            coord = new Coordinate(5, 5);
            coords.Add(coord);
            coord = new Coordinate(4, 4);
            coords.Add(coord);
            coord = new Coordinate(3, 3);
            coords.Add(coord);
            coord = new Coordinate(4, 2);
            coords.Add(coord);
            coord = new Coordinate(5, 1);
            coords.Add(coord);

            LinearRing exterior2 = gf.CreateLinearRing(coords);

            polygons[1] = gf.CreatePolygon(exterior2);
            rings[1]    = exterior2;

            _mls1 = gf.CreateMultiLineString(rings);

            return(gf.CreateMultiPolygon(polygons));
        }
示例#22
0
        private MultiPolygon CreateMP2()
        {
            Polygon[] polygons = new Polygon[2];

            GeometryFactory gf = new GeometryFactory(_precMod, _sRID);

            Coordinates coords = new Coordinates();
            Coordinate  coord  = new Coordinate(10, 13);

            coords.Add(coord);
            coord = new Coordinate(11, 13);
            coords.Add(coord);
            coord = new Coordinate(12, 13);
            coords.Add(coord);
            coord = new Coordinate(13, 14);
            coords.Add(coord);
            coord = new Coordinate(14, 15);
            coords.Add(coord);
            coord = new Coordinate(15, 16);
            coords.Add(coord);
            coord = new Coordinate(15, 17);
            coords.Add(coord);
            coord = new Coordinate(15, 18);
            coords.Add(coord);
            coord = new Coordinate(14, 19);
            coords.Add(coord);
            coord = new Coordinate(13, 20);
            coords.Add(coord);
            coord = new Coordinate(12, 21);
            coords.Add(coord);
            coord = new Coordinate(11, 21);
            coords.Add(coord);
            coord = new Coordinate(10, 21);
            coords.Add(coord);
            coord = new Coordinate(9, 20);
            coords.Add(coord);
            coord = new Coordinate(8, 19);
            coords.Add(coord);
            coord = new Coordinate(7, 18);
            coords.Add(coord);
            coord = new Coordinate(7, 17);
            coords.Add(coord);
            coord = new Coordinate(7, 16);
            coords.Add(coord);
            coord = new Coordinate(8, 15);
            coords.Add(coord);
            coord = new Coordinate(9, 14);
            coords.Add(coord);
            coord = new Coordinate(10, 13);
            coords.Add(coord);

            LinearRing exterior = gf.CreateLinearRing(coords);

            coords = new Coordinates();
            coord  = new Coordinate(10, 16);
            coords.Add(coord);
            coord = new Coordinate(11, 17);
            coords.Add(coord);
            coord = new Coordinate(10, 18);
            coords.Add(coord);
            coord = new Coordinate(9, 17);
            coords.Add(coord);
            coord = new Coordinate(10, 16);
            coords.Add(coord);

            LinearRing interior = gf.CreateLinearRing(coords);

            LinearRing[] linearRings = new LinearRing[1];
            linearRings[0] = interior;

            polygons[0] = gf.CreatePolygon(exterior, linearRings);

            coords = new Coordinates();
            coord  = new Coordinate(5, 1);
            coords.Add(coord);
            coord = new Coordinate(6, 2);
            coords.Add(coord);
            coord = new Coordinate(7, 3);
            coords.Add(coord);
            coord = new Coordinate(6, 4);
            coords.Add(coord);
            coord = new Coordinate(5, 5);
            coords.Add(coord);
            coord = new Coordinate(4, 4);
            coords.Add(coord);
            coord = new Coordinate(3, 3);
            coords.Add(coord);
            coord = new Coordinate(4, 2);
            coords.Add(coord);
            coord = new Coordinate(5, 1);
            coords.Add(coord);

            exterior    = gf.CreateLinearRing(coords);
            polygons[1] = gf.CreatePolygon(exterior);

            return(gf.CreateMultiPolygon(polygons));
        }
示例#23
0
        /// <summary>
        /// Writes a Geometry to the given binary wirter.
        /// </summary>
        /// <param name="geometry">The geometry to write.</param>
        /// <param name="file">The file stream to write to.</param>
        /// <param name="geometryFactory">The geometry factory to use.</param>
        public override void Write(IGeometry geometry, System.IO.BinaryWriter file, IGeometryFactory geometryFactory)
        {
            // Diego Guidi say's: his check seems to be not useful and slow the operations...
            //  if (!geometry.IsValid)
            //	Trace.WriteLine("Invalid polygon being written.");

            IGeometryCollection multi;

            if (geometry is IGeometryCollection ||
                geometry is IMultiLineString ||
                geometry is IMultiPoint ||
                geometry is IMultiPolygon)
            {
                multi = (IGeometryCollection)geometry;
            }
            else
            {
                IGeometryFactory gf = new GeometryFactory(new PrecisionModel(geometry.PrecisionModel));
                multi = gf.CreateMultiPolygon(new Polygon[] { (Polygon)geometry });
            }

            file.Write(int.Parse(Enum.Format(typeof(ShapeGeometryTypes), this.ShapeType, "d")));

            IEnvelope box    = multi.EnvelopeInternal;
            IEnvelope bounds = ShapeHandler.GetEnvelopeExternal(new PrecisionModel(geometryFactory.PrecisionModel), box);

            file.Write(bounds.MinX);
            file.Write(bounds.MinY);
            file.Write(bounds.MaxX);
            file.Write(bounds.MaxY);

            int numParts  = GetNumParts(multi);
            int numPoints = multi.NumPoints;

            file.Write(numParts);
            file.Write(numPoints);

            // write the offsets to the points
            int offset = 0;

            for (int part = 0; part < multi.NumGeometries; part++)
            {
                // offset to the shell points
                Polygon polygon = (Polygon)multi.Geometries[part];
                file.Write(offset);
                offset = offset + polygon.ExteriorRing.NumPoints;

                // offstes to the holes
                foreach (LinearRing ring in polygon.InteriorRings)
                {
                    file.Write(offset);
                    offset = offset + ring.NumPoints;
                }
            }

            // write the points
            for (int part = 0; part < multi.NumGeometries; part++)
            {
                Polygon       poly   = (Polygon)multi.Geometries[part];
                ICoordinate[] points = poly.ExteriorRing.Coordinates;
                WriteCoords(new CoordinateList(points), file, geometryFactory);
                foreach (LinearRing ring in poly.InteriorRings)
                {
                    ICoordinate[] points2 = ring.Coordinates;
                    WriteCoords(new CoordinateList(points2), file, geometryFactory);
                }
            }
        }
        public override object?ParseLiteral(IValueNode literal)
        {
            if (literal is NullValueNode)
            {
                return(null);
            }

            if (!(literal is ObjectValueNode obj) || obj.Fields.Count < 2)
            {
                throw ThrowHelper.InvalidInputObjectStructure(_geometryType);
            }

            (int typeIndex, int coordinateIndex, int crsIndex)indices =
                ParseLiteralHelper.GetFieldIndices(obj,
                                                   _typeFieldName,
                                                   _coordinatesFieldName,
                                                   _crsFieldName);

            if (indices.typeIndex == -1)
            {
                throw ThrowHelper.InvalidInputObjectStructure(_geometryType);
            }

            var type = (GeoJSONGeometryType)
                       _typeField.Type.ParseLiteral(obj.Fields[indices.typeIndex].Value);

            if (type != _geometryType || indices.coordinateIndex == -1)
            {
                throw ThrowHelper.InvalidInputObjectStructure(_geometryType);
            }

            var parts = (List <List <Coordinate> >)
                        _coordinatesField.Type.ParseLiteral(obj.Fields[indices.coordinateIndex].Value);

            if (parts.Count < 1)
            {
                throw ThrowHelper.InvalidInputObjectStructure(_geometryType);
            }

            var polygonCount = parts.Count;
            var geometries   = new Polygon[polygonCount];

            for (var i = 0; i < polygonCount; i++)
            {
                var pointCount  = parts[i].Count;
                var coordinates = new Coordinate[pointCount];

                for (var j = 0; j < pointCount; j++)
                {
                    coordinates[j] = new Coordinate(parts[i][j]);
                }

                var ring = new LinearRing(coordinates);

                geometries[i] = new Polygon(ring);
            }

            if (indices.crsIndex == -1)
            {
                return(new MultiPolygon(geometries));
            }

            var srid = (int)_crsField.Type.ParseLiteral(obj.Fields[indices.crsIndex].Value);

            GeometryFactory factory = NtsGeometryServices.Instance.CreateGeometryFactory(srid);

            return(factory.CreateMultiPolygon(geometries));
        }
示例#25
0
        public void testCreateEmptyGeometry()
        {
            Assert.IsTrue(geometryFactory.CreatePoint((Coordinate)null).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateLinearRing(new Coordinate[] {}).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateLineString(new Coordinate[] {}).IsEmpty);
            Assert.IsTrue(
                geometryFactory.CreatePolygon(geometryFactory.CreateLinearRing(new Coordinate[] {}), new LinearRing[] {})
                .IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiPolygon(new Polygon[] {}).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiLineString(new LineString[] {}).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiPoint(new Point[] {}).IsEmpty);

            Assert.IsTrue(geometryFactory.CreatePoint((Coordinate)null).IsSimple);
            Assert.IsTrue(geometryFactory.CreateLinearRing(new Coordinate[] {}).IsSimple);

            /**
             * @todo Enable when #isSimple implemented
             */
            //    Assert.IsTrue(geometryFactory.CreateLineString(new Coordinate[] { }).IsSimple);
            //    Assert.IsTrue(geometryFactory.CreatePolygon(geometryFactory.CreateLinearRing(new Coordinate[] { }), new LinearRing[] { }).IsSimple);
            //    Assert.IsTrue(geometryFactory.CreateMultiPolygon(new Polygon[] { }).IsSimple);
            //    Assert.IsTrue(geometryFactory.CreateMultiLineString(new LineString[] { }).IsSimple);
            //    Assert.IsTrue(geometryFactory.CreateMultiPoint(new Point[] { }).IsSimple);

            Assert.IsTrue(geometryFactory.CreatePoint((Coordinate)null).Boundary.IsEmpty);
            Assert.IsTrue(geometryFactory.CreateLinearRing(new Coordinate[] {}).Boundary.IsEmpty);
            Assert.IsTrue(geometryFactory.CreateLineString(new Coordinate[] {}).Boundary.IsEmpty);
            Assert.IsTrue(
                geometryFactory.CreatePolygon(geometryFactory.CreateLinearRing(new Coordinate[] {}), new LinearRing[] {})
                .Boundary.IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiPolygon(new Polygon[] {}).Boundary.IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiLineString(new LineString[] {}).Boundary.IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiPoint(new Point[] {}).Boundary.IsEmpty);

            Assert.IsTrue(geometryFactory.CreateLinearRing((CoordinateSequence)null).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateLineString((Coordinate[])null).IsEmpty);
            Assert.IsTrue(geometryFactory.CreatePolygon(null, null).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiPolygon(null).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiLineString(null).IsEmpty);
            Assert.IsTrue(geometryFactory.CreateMultiPoint((Point[])null).IsEmpty);

            Assert.AreEqual(-1, (int)(geometryFactory.CreatePoint((Coordinate)null)).BoundaryDimension);
            Assert.AreEqual(-1, (int)(geometryFactory.CreateLinearRing((CoordinateSequence)null)).BoundaryDimension);
            Assert.AreEqual(0, (int)(geometryFactory.CreateLineString((Coordinate[])null)).BoundaryDimension);
            Assert.AreEqual(1, (int)(geometryFactory.CreatePolygon(null, null)).BoundaryDimension);
            Assert.AreEqual(1, (int)(geometryFactory.CreateMultiPolygon(null)).BoundaryDimension);
            Assert.AreEqual(0, (int)(geometryFactory.CreateMultiLineString(null)).BoundaryDimension);
            Assert.AreEqual(-1, (int)(geometryFactory.CreateMultiPoint((Point[])null)).BoundaryDimension);

            Assert.AreEqual(0, (geometryFactory.CreatePoint((Coordinate)null)).NumPoints);
            Assert.AreEqual(0, (geometryFactory.CreateLinearRing((CoordinateSequence)null)).NumPoints);
            Assert.AreEqual(0, (geometryFactory.CreateLineString((Coordinate[])null)).NumPoints);
            Assert.AreEqual(0, (geometryFactory.CreatePolygon(null, null)).NumPoints);
            Assert.AreEqual(0, (geometryFactory.CreateMultiPolygon(null)).NumPoints);
            Assert.AreEqual(0, (geometryFactory.CreateMultiLineString(null)).NumPoints);
            Assert.AreEqual(0, (geometryFactory.CreateMultiPoint((Point[])null)).NumPoints);

            Assert.AreEqual(0, (geometryFactory.CreatePoint((Coordinate)null)).Coordinates.Length);
            Assert.AreEqual(0, (geometryFactory.CreateLinearRing((CoordinateSequence)null)).Coordinates.Length);
            Assert.AreEqual(0, (geometryFactory.CreateLineString((Coordinate[])null)).Coordinates.Length);
            Assert.AreEqual(0, (geometryFactory.CreatePolygon(null, null)).Coordinates.Length);
            Assert.AreEqual(0, (geometryFactory.CreateMultiPolygon(null)).Coordinates.Length);
            Assert.AreEqual(0, (geometryFactory.CreateMultiLineString(null)).Coordinates.Length);
            Assert.AreEqual(0, (geometryFactory.CreateMultiPoint((Point[])null)).Coordinates.Length);
        }
        public void SetUp()
        {
            this.factory = new GeometryFactory();

            this.geometries = new IGeometry[]
            {
                this.factory.CreatePoint(1.5, 1.5),
                this.factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(-i / 2.0, i / 2.0))),
                this.factory.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)),
                                           new Coordinate[][]
                {
                    Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray(),
                    Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray()
                }),
                this.factory.CreateMultiPoint(Enumerable.Range(1, 4).Select(i => this.factory.CreatePoint(i / 2.0, i / 2.0))),
                this.factory.CreateMultiLineString(new ILineString[]
                {
                    this.factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i))),
                    this.factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(i / 2.0, i / 2.0)))
                }),
                this.factory.CreateMultiPolygon(new IPolygon[]
                {
                    this.factory.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)),
                                               new Coordinate[][]
                    {
                        Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray(),
                        Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray()
                    }),
                    this.factory.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i / 2.0, i / 2.0)))
                })
            };

            this.mockReferenceSystem = new Mock <IReferenceSystem>(MockBehavior.Strict);
            this.mockReferenceSystem.Setup(referenceSystem => referenceSystem.Code).Returns(1000);
            this.mockReferenceSystem.Setup(referenceSystem => referenceSystem.Dimension).Returns(2);

            this.mockReferenceSystemFactory = new Mock <IReferenceSystemFactory>(MockBehavior.Strict);
            this.mockReferenceSystemFactory.Setup(factory => factory.CreateReferenceSystemFromIdentifier("EPSG::1000")).Returns(this.mockReferenceSystem.Object);

            GeometryFactory factoryWithReference = new GeometryFactory(this.mockReferenceSystem.Object);

            this.geometriesWithReference = new IGeometry[]
            {
                factoryWithReference.CreatePoint(1.5, 1.5),
                factoryWithReference.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(-i / 2.0, i / 2.0))),
                factoryWithReference.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)),
                                                   new Coordinate[][]
                {
                    Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray(),
                    Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray()
                }),
                factoryWithReference.CreateMultiPoint(Enumerable.Range(1, 4).Select(i => this.factory.CreatePoint(i / 2.0, i / 2.0))),
                factoryWithReference.CreateMultiLineString(new ILineString[]
                {
                    this.factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i))),
                    this.factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(i / 2.0, i / 2.0)))
                }),
                factoryWithReference.CreateMultiPolygon(new IPolygon[]
                {
                    factoryWithReference.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)),
                                                       new Coordinate[][]
                    {
                        Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray(),
                        Enumerable.Range(1, 4).Select(i => new Coordinate(i, i)).ToArray()
                    }),
                    factoryWithReference.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i / 2.0, i / 2.0)))
                })
            };

            this.geometriesMarkup = new String[]
            {
                "<gml:Point xmlns:gml=\"http://www.opengis.net/gml/\"><gml:pos>1.5 1.5</gml:pos></gml:Point>",
                "<gml:LineString xmlns:gml=\"http://www.opengis.net/gml/\"><gml:posList>-0.5 0.5 -1 1 -1.5 1.5 -2 2</gml:posList></gml:LineString>",
                "<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml/\"><gml:outerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>",
                "<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml/\"><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2</gml:posList></gml:MultiPoint>",
                "<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml/\"><gml:LineStringMember><gml:LineString><gml:posList>1 1 2 2 3 3 4 4</gml:posList></gml:LineString></gml:LineStringMember><gml:LineStringMember><gml:LineString><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2</gml:posList></gml:LineString></gml:LineStringMember></gml:MultiLineString>",
                "<gml:MultiPolygon xmlns:gml=\"http://www.opengis.net/gml/\"><gml:PolygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></gml:PolygonMember><gml:PolygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2 0.5 0.5</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:PolygonMember></gml:MultiPolygon>"
            };

            this.identifier = "12345678";

            this.geometriesMarkupWithIdentifier = new String[]
            {
                "<gml:Point gml:id=\"12345678\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:pos>1.5 1.5</gml:pos></gml:Point>",
                "<gml:LineString gml:id=\"12345678\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:posList>-0.5 0.5 -1 1 -1.5 1.5 -2 2</gml:posList></gml:LineString>",
                "<gml:Polygon gml:id=\"12345678\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:outerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>",
                "<gml:MultiPoint gml:id=\"12345678\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2</gml:posList></gml:MultiPoint>",
                "<gml:MultiLineString gml:id=\"12345678\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:LineStringMember><gml:LineString><gml:posList>1 1 2 2 3 3 4 4</gml:posList></gml:LineString></gml:LineStringMember><gml:LineStringMember><gml:LineString><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2</gml:posList></gml:LineString></gml:LineStringMember></gml:MultiLineString>",
                "<gml:MultiPolygon gml:id=\"12345678\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:PolygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></gml:PolygonMember><gml:PolygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2 0.5 0.5</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:PolygonMember></gml:MultiPolygon>"
            };

            this.geometriesMarkupWithReference = new String[]
            {
                "<gml:Point srsName=\"http://www.opengis.net/def/crs/EPSG/0/1000\" srsDimension=\"2\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:pos>1.5 1.5</gml:pos></gml:Point>",
                "<gml:LineString srsName=\"http://www.opengis.net/def/crs/EPSG/0/1000\" srsDimension=\"2\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:posList>-0.5 0.5 -1 1 -1.5 1.5 -2 2</gml:posList></gml:LineString>",
                "<gml:Polygon srsName=\"http://www.opengis.net/def/crs/EPSG/0/1000\" srsDimension=\"2\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:outerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>",
                "<gml:MultiPoint srsName=\"http://www.opengis.net/def/crs/EPSG/0/1000\" srsDimension=\"2\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2</gml:posList></gml:MultiPoint>",
                "<gml:MultiLineString srsName=\"http://www.opengis.net/def/crs/EPSG/0/1000\" srsDimension=\"2\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:LineStringMember><gml:LineString><gml:posList>1 1 2 2 3 3 4 4</gml:posList></gml:LineString></gml:LineStringMember><gml:LineStringMember><gml:LineString><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2</gml:posList></gml:LineString></gml:LineStringMember></gml:MultiLineString>",
                "<gml:MultiPolygon srsName=\"http://www.opengis.net/def/crs/EPSG/0/1000\" srsDimension=\"2\" xmlns:gml=\"http://www.opengis.net/gml/\"><gml:PolygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:posList>1 1 2 2 3 3 4 4 1 1</gml:posList></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></gml:PolygonMember><gml:PolygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>0.5 0.5 1 1 1.5 1.5 2 2 0.5 0.5</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:PolygonMember></gml:MultiPolygon>"
            };

            this.geometryComparer = new GeometryComparer();
        }