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))); }
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"); } }
/// <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}"); } }
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()); }
/// <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)); }
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)); }
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())); }
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)); }
/// <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); } }
/// <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); } } }
/// <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); }
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); } }
/// <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)); }
/// <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); } } }
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)); }
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)); }
/// <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)); }
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(); }