public static Coordinate ImageToWorld(IMap map, double width, double height) { Coordinate c1 = map.ImageToWorld(new PointF(0, 0)); Coordinate c2 = map.ImageToWorld(new PointF((float)width, (float)height)); return(GeometryFactoryEx.CreateCoordinate(Math.Abs(c1.X - c2.X), Math.Abs(c1.Y - c2.Y))); }
public void CustomGeometryFactoryShouldBeAllowedWithSRID() { var pm = new PrecisionModel(10); const int initialSRID = 0; var csf = PackedCoordinateSequenceFactory.FloatFactory; const LinearRingOrientation orientation = LinearRingOrientation.Clockwise; var gf = new GeometryFactoryEx(pm, initialSRID, csf) { OrientationOfExteriorRing = orientation, }; const int expectedSRID = 4326; string xml = $@" <gml:Point srsName='urn:ogc:def:crs:EPSG::{expectedSRID}' xmlns:gml='http://www.opengis.net/gml'> <gml:coordinates>45.67, 65.43</gml:coordinates> </gml:Point>"; var gr = new GMLReader(gf); foreach (var readMethod in GetReadMethods()) { var pt = (Point)readMethod(gr, xml); Assert.That(pt.Factory, Is.InstanceOf <GeometryFactoryEx>() .With.Property(nameof(GeometryFactoryEx.SRID)).EqualTo(expectedSRID) .With.Property(nameof(GeometryFactoryEx.OrientationOfExteriorRing)).EqualTo(orientation) .With.Property(nameof(GeometryFactoryEx.PrecisionModel)).EqualTo(pm) .With.Property(nameof(GeometryFactoryEx.CoordinateSequenceFactory)).EqualTo(csf)); } }
private static GeometryFactoryEx GetGeometryFactoryEx() { var geo = new GeometryFactoryEx(new PrecisionModel(PrecisionModels.FloatingSingle), GeoManager.StandardSRID); geo.OrientationOfExteriorRing = LinearRingOrientation.CCW; return(geo); }
private static void TestShellRingOrientationSetter(GeometryFactoryEx gf, LinearRingOrientation ringOrientation, int failKind) { try { gf.OrientationOfExteriorRing = ringOrientation; if (failKind != 0) { Assert.Fail("Setting exterior ring orientation should have failed!"); } Assert.AreEqual(ringOrientation, gf.OrientationOfExteriorRing); } catch (ArgumentOutOfRangeException iae) { if (failKind != 1) { Assert.Fail("Wrong argument"); } } catch (InvalidOperationException isa) { if (failKind != 2) { Assert.Fail("Setting exterior ring orientation twice!"); } } catch (Exception e) { Assert.Fail(e.Message); } }
public void TestShellRingOrientationSetting() { // check default var gf = new GeometryFactoryEx(); Assert.AreEqual(LinearRingOrientation.CounterClockwise, gf.OrientationOfExteriorRing); // Check for valid ring orientation values gf = new GeometryFactoryEx(); TestShellRingOrientationSetter(gf, LinearRingOrientation.DontCare, 0); gf = new GeometryFactoryEx(); TestShellRingOrientationSetter(gf, LinearRingOrientation.Clockwise, 0); gf = new GeometryFactoryEx(); TestShellRingOrientationSetter(gf, LinearRingOrientation.RightHandRule, 0); gf = new GeometryFactoryEx(); TestShellRingOrientationSetter(gf, LinearRingOrientation.CounterClockwise, 0); gf = new GeometryFactoryEx(); TestShellRingOrientationSetter(gf, LinearRingOrientation.LeftHandRule, 0); // check for invalid arguments gf = new GeometryFactoryEx(); TestShellRingOrientationSetter(gf, (LinearRingOrientation)(-2), 1); TestShellRingOrientationSetter(gf, (LinearRingOrientation)2, 1); // check prevention of setting after first usage var ro = gf.OrientationOfExteriorRing; // don't fail if value does not change TestShellRingOrientationSetter(gf, ro, 0); TestShellRingOrientationSetter(gf, LinearRingOrientation.RightHandRule, 2); TestShellRingOrientationSetter(gf, LinearRingOrientation.DontCare, 2); }
public void ZoomToBox_WithAspectCorrection() { var map = new Map(new Size(400, 200)); map.ZoomToFit(GeometryFactory.CreateEnvelope(10, 20, 100, 180)); Assert.AreEqual(GeometryFactoryEx.CreateCoordinate(15, 140), map.Center); Assert.AreEqual(160d, map.Zoom); }
public void ZoomToBox_NoAspectCorrection() { var map = new Map(new Size(400, 200)); map.ZoomToFit(GeometryFactory.CreateEnvelope(20, 50, 100, 80)); Assert.AreEqual(GeometryFactoryEx.CreateCoordinate(35, 90), map.Center); Assert.AreEqual(40d, map.Zoom); }
public void ImageToWorld_DefaultMap_ReturnValue() { var map = new Map(new Size(500, 200)) { Center = GeometryFactoryEx.CreateCoordinate(23, 34), Zoom = 1000 }; Coordinate p = map.ImageToWorld(new PointF(242.5f, 92)); Assert.AreEqual(GeometryFactoryEx.CreateCoordinate(8, 50), p); }
public void WorldToMap_DefaultMap_ReturnValue() { var map = new Map(new Size(500, 200)); map.Center = GeometryFactoryEx.CreateCoordinate(23, 34); map.Zoom = 1000; PointF p = map.WorldToImage(GeometryFactoryEx.CreateCoordinate(8, 50)); Assert.AreEqual(new PointF(242f, 92), p); }
public void WorldToImage() { var map = new Map(new Size(1000, 500)) { Zoom = 360, Center = GeometryFactoryEx.CreateCoordinate(0, 0) }; Assert.AreEqual(new PointF(500, 250), map.WorldToImage(GeometryFactoryEx.CreateCoordinate(0, 0))); Assert.AreEqual(new PointF(0, 0), map.WorldToImage(GeometryFactoryEx.CreateCoordinate(-180, 90))); Assert.AreEqual(new PointF(0, 500), map.WorldToImage(GeometryFactoryEx.CreateCoordinate(-180, -90))); Assert.AreEqual(new PointF(1000, 0), map.WorldToImage(GeometryFactoryEx.CreateCoordinate(180, 90))); Assert.AreEqual(new PointF(1000, 500), map.WorldToImage(GeometryFactoryEx.CreateCoordinate(180, -90))); }
private static IGeometry CreateCell(double offsetX, double offsetY, double extentX, double extentY) { var vertices = new List <Coordinate> { GeometryFactoryEx.CreateCoordinate(offsetX, offsetY), GeometryFactoryEx.CreateCoordinate(offsetX + extentX, offsetY), GeometryFactoryEx.CreateCoordinate(offsetX + extentX, offsetY + extentY), GeometryFactoryEx.CreateCoordinate(offsetX, offsetY + extentY) }; vertices.Add((Coordinate)vertices[0].Clone()); ILinearRing newLinearRing = new LinearRing(vertices.ToArray()); return(new Polygon(newLinearRing)); }
private IPolygon CreatePolygon(double left, double top, double right, double bottom) { var vertices = new List <Coordinate> { GeometryFactoryEx.CreateCoordinate(left, bottom), GeometryFactoryEx.CreateCoordinate(right, bottom), GeometryFactoryEx.CreateCoordinate(right, top), GeometryFactoryEx.CreateCoordinate(left, top) }; vertices.Add((Coordinate)vertices[0].Clone()); ILinearRing newLinearRing = GeometryFactory.CreateLinearRing(vertices.ToArray()); return(GeometryFactory.CreatePolygon(newLinearRing, null)); }
public override void OnDraw(Graphics graphics) { if (MultiSelectionMode == MultiSelectionMode.Lasso) { GraphicsHelper.DrawSelectionLasso(graphics, KeyExtendSelection ? Color.Magenta : Color.DeepSkyBlue, selectPoints.ToArray()); } else { Coordinate coordinate1 = GeometryFactoryEx.CreateCoordinate(mouseDownLocation.X, mouseDownLocation.Y); Coordinate coordinate2 = GeometryFactoryEx.CreateCoordinate(WORLDPOSITION.X, WORLDPOSITION.Y); PointF point1 = Map.WorldToImage(coordinate1); PointF point2 = Map.WorldToImage(coordinate2); GraphicsHelper.DrawSelectionRectangle(graphics, KeyExtendSelection ? Color.Magenta : Color.DeepSkyBlue, point1, point2); } }
private void StartNewLine(Coordinate worldPos) { List <Coordinate> verticies = new List <Coordinate> { GeometryFactoryEx.CreateCoordinate(worldPos.X, worldPos.Y), GeometryFactoryEx.CreateCoordinate(worldPos.X, worldPos.Y) }; ILineString lineString = GeometryFactory.CreateLineString(verticies.ToArray()); ((DataTableFeatureProvider)newLineLayer.DataSource).Clear(); newLineLayer.DataSource.Add(lineString); adding = true; ActualAutoCurve = AutoCurve; ActualMinDistance = MinDistance; }
public static IGeometry Scale(IGeometry geom, double scale) { var center = geom.Centroid; var coordinates = new List <Coordinate>(); foreach (var coordinate in geom.Coordinates) { var x = (scale * (coordinate.X - center.X)) + center.X; var y = (scale * (coordinate.Y - center.Y)) + center.Y; coordinates.Add(GeometryFactoryEx.CreateCoordinate(x, y)); } return(GeometryFactory.CreateLineString(coordinates.ToArray())); }
public void Initalize_MapInstance() { var map = new Map(new Size(2, 1)); Assert.IsNotNull(map); Assert.IsNotNull(map.Layers); Assert.AreEqual(2f, map.Size.Width); Assert.AreEqual(1f, map.Size.Height); Assert.AreEqual(Color.Transparent, map.BackColor); Assert.AreEqual(1e9, map.MaximumZoom); Assert.AreEqual(1e-4, map.MinimumZoom); Assert.AreEqual(GeometryFactoryEx.CreateCoordinate(0, 0), map.Center, "map.Center should be initialized to (0,0)"); Assert.AreEqual(1000, map.Zoom, "Map zoom should be initialized to 1000.0"); }
private void ShowSnapResult(SnapResult snapResult) { var sld = ((DataTableFeatureProvider)snapLayer.DataSource); sld.Clear(); if (null == snapResult) { return; } IList <IGeometry> visibleSnaps = snapResult.VisibleSnaps; //if (null == visisbleSnaps) if (0 == visibleSnaps.Count) { List <Coordinate> vertices = new List <Coordinate>(); if (-1 != snapResult.SnapIndexPrevious) { vertices.Add(GeometryFactoryEx.CreateCoordinate(snapResult.NearestTarget.Coordinates[snapResult.SnapIndexPrevious].X, snapResult.NearestTarget.Coordinates[snapResult.SnapIndexPrevious].Y)); } vertices.Add(GeometryFactoryEx.CreateCoordinate(snapResult.Location.X, snapResult.Location.Y)); IGeometry active = GeometryFactory.CreatePoint(snapResult.Location.X, snapResult.Location.Y); if (-1 != snapResult.SnapIndexNext) { vertices.Add(GeometryFactoryEx.CreateCoordinate(snapResult.NearestTarget.Coordinates[snapResult.SnapIndexNext].X, snapResult.NearestTarget.Coordinates[snapResult.SnapIndexNext].Y)); } if (vertices.Count > 1) { ILineString snapLineString = GeometryFactory.CreateLineString(vertices.ToArray()); sld.Add(snapLineString); } sld.Add(active); } else { foreach (var snap in visibleSnaps) { sld.Add(snap); } } }
/// <summary> /// /// </summary> /// <param name="ls"></param> /// <param name="transform"></param> /// <returns></returns> private static List <Coordinate> ExtractCoordinates(ILineString ls, IMathTransform transform) { IList <double[]> points = new List <double[]>(ls.NumPoints); foreach (Coordinate c in ls.Coordinates) { points.Add(ToArray(c.X, c.Y)); } points = transform.TransformList(points); List <Coordinate> coords = new List <Coordinate>(points.Count); foreach (double[] p in points) { coords.Add(GeometryFactoryEx.CreateCoordinate(p[0], p[1])); } return(coords); }
/// <summary> /// Transforms from image coordinates to world coordinate system (WCS). /// NOTE: This method DOES NOT take the MapTransform property into account (use SharpMap.Map.MapToWorld instead) /// </summary> /// <param name="p">Point in image coordinate system</param> /// <param name="map">Map reference</param> /// <returns>Point in WCS</returns> public static Coordinate MapToWorld(System.Drawing.PointF p, SharpMap.Map map) { if (map.PixelHeight == double.PositiveInfinity) { throw new ArgumentException("Can not convert map coordinates to world coordinates, pixelwidth (mapsize) not set.", "map"); } //if (this.MapTransform != null && !this.MapTransform.IsIdentity) //{ // System.Drawing.PointF[] p2 = new System.Drawing.PointF[] { p }; // this.MapTransform.TransformPoints(new System.Drawing.PointF[] { p }); // this.MapTransformInverted.TransformPoints(p2); // return Utilities.Transform.MapToWorld(p2[0], this); //} //else Envelope env = map.Envelope; return(GeometryFactoryEx.CreateCoordinate(env.MinX + p.X * map.PixelWidth, env.MaxY - p.Y * map.PixelHeight)); }
public void PolygonSnapFree(ref double minDistance, ref SnapResult snapResult, IPolygon polygon, Coordinate worldPos) { for (int i = 1; i < polygon.Coordinates.Length; i++) { Coordinate c1 = polygon.Coordinates[i - 1]; Coordinate c2 = polygon.Coordinates[i]; double distance = GeometryHelper.LinePointDistance(c1.X, c1.Y, c2.X, c2.Y, worldPos.X, worldPos.Y); if (distance >= minDistance) { continue; } minDistance = distance; snapResult = new SnapResult(GeometryFactoryEx.CreateCoordinate(worldPos.X, worldPos.Y), null, null, polygon, i - 1, i) { Rule = this }; } }
/// <summary> /// Initializes a new map /// </summary> /// <param name="size">Size of map in pixels</param> public Map(Size size) { name = "map"; maximumZoom = 1e9; minimumZoom = 1e-4; center = GeometryFactoryEx.CreateCoordinate(0, 0); zoom = 1000; pixelAspectRatio = 1.0; Size = size; Layers = new EventedList <ILayer>(); BackColor = Color.Transparent; mapTransform = new Matrix(); mapTransformInverted = new Matrix(); UpdateDimensions(); }
public void AddingALayerShouldCauseZoomToExtendsIfNoValidExtendsBefore() { var map = new Map(new Size(10, 100)) { Center = GeometryFactoryEx.CreateCoordinate(90, 900) }; //now add a layer with defined extends var geometry = GeometryFromWKT.Parse("LINESTRING (20 20, 20 30, 30 30, 30 20, 40 20)"); var dataSource = new DataTableFeatureProvider(geometry); var vectorLayerWithExtends = new VectorLayer("Layer with extends") { DataSource = dataSource }; map.Layers.Add(vectorLayerWithExtends); Assert.AreEqual(new Envelope(19, 41, -85, 135), map.Envelope); }
public void Clone() { var map = new Map(new Size(10, 100)) { Center = GeometryFactoryEx.CreateCoordinate(90, 900) }; map.Layers.Add(new VectorLayer("Layer 1")); map.Layers.Add(new VectorLayer("Layer 3")); map.Layers.Add(new VectorLayer("Layer 2")); var clonedMap = (Map)map.Clone(); Assert.AreEqual(map.Name, clonedMap.Name); Assert.AreEqual(map.Layers.Count, clonedMap.Layers.Count); Assert.AreEqual(map.Size.Width, clonedMap.Size.Width); Assert.AreEqual(map.Size.Height, clonedMap.Size.Height); Assert.AreEqual(map.Center.X, clonedMap.Center.X); Assert.AreEqual(map.Center.Y, clonedMap.Center.Y); Assert.AreEqual(map.Zoom, clonedMap.Zoom, 1e-10); }
private void CalculateLabelOnLinestring(ILineString line, ref SharpMap.Rendering.Label label, IMap map) { double dx, dy; double tmpx, tmpy; double angle = 0.0; // first find the middle segment of the line int midPoint = (line.Coordinates.Length - 1) / 2; if (line.Coordinates.Length > 2) { dx = line.Coordinates[midPoint + 1].X - line.Coordinates[midPoint].X; dy = line.Coordinates[midPoint + 1].Y - line.Coordinates[midPoint].Y; } else { midPoint = 0; dx = line.Coordinates[1].X - line.Coordinates[0].X; dy = line.Coordinates[1].Y - line.Coordinates[0].Y; } if (dy == 0) { label.Rotation = 0; } else if (dx == 0) { label.Rotation = 90; } else { // calculate angle of line angle = -Math.Atan(dy / dx) + Math.PI * 0.5; angle *= (180d / Math.PI); // convert radians to degrees label.Rotation = (float)angle - 90; // -90 text orientation } tmpx = line.Coordinates[midPoint].X + (dx * 0.5); tmpy = line.Coordinates[midPoint].Y + (dy * 0.5); label.LabelPoint = map.WorldToImage(GeometryFactoryEx.CreateCoordinate(tmpx, tmpy)); }
public void TestEnvelopeToGeometry() { var env = new Envelope(-10, 10, -8, 8); var gf = new GeometryFactoryEx(); Assert.IsTrue(((Polygon)gf.ToGeometry(env)).Shell.IsCCW); gf = new GeometryFactoryEx { OrientationOfExteriorRing = LinearRingOrientation.DontCare }; Assert.IsFalse(((Polygon)gf.ToGeometry(env)).Shell.IsCCW); gf = new GeometryFactoryEx { OrientationOfExteriorRing = LinearRingOrientation.Clockwise }; Assert.IsFalse(((Polygon)gf.ToGeometry(env)).Shell.IsCCW); gf = new GeometryFactoryEx { OrientationOfExteriorRing = LinearRingOrientation.CounterClockwise }; Assert.IsTrue(((Polygon)gf.ToGeometry(env)).Shell.IsCCW); }
public override void OnMouseMove(Coordinate worldPosition, MouseEventArgs e) { if (VectorLayer == null) { return; } if (!(MouseButtons.None == e.Button || MouseButtons.Left == e.Button)) { return; } if (startCoordinate != null) { EndCoordinate = GeometryFactoryEx.CreateCoordinate(worldPosition.X, worldPosition.Y); } Snap(worldPosition); StartDrawing(); DoDrawing(true); StopDrawing(); }
/// <summary> /// Intersection scalar (used for weighting in building the tree) /// #Todo /// </summary> private string LongestAxis(Envelope box) { Coordinate boxdim = GeometryFactoryEx.CreateCoordinate(box.MaxX - box.MinX, box.MaxY - box.MinY); string la = String.Empty; // longest axis double lav = 0; // longest axis length // for each dimension //for (uint ii = 0; ii < 2; ii++) //{ // check if its longer if (boxdim.X > lav) { la = "X"; lav = boxdim.X; } if (boxdim.Y > lav) { la = "Y"; lav = boxdim.Y; } return(la); }
public void SettingSRIDShouldCopyFactoryFaithfully() { var pm = new PrecisionModel(10); const int initialSRID = 0; var csf = PackedCoordinateSequenceFactory.FloatFactory; const LinearRingOrientation orientation = LinearRingOrientation.Clockwise; var gf = new GeometryFactoryEx(pm, initialSRID, csf) { OrientationOfExteriorRing = orientation, }; var env = new Envelope(-10, 10, -8, 8); var g = gf.ToGeometry(env); const int expectedSRID = 4326; g.SRID = expectedSRID; Assert.That(g.Factory, Is.InstanceOf <GeometryFactoryEx>() .With.Property(nameof(GeometryFactoryEx.SRID)).EqualTo(expectedSRID) .With.Property(nameof(GeometryFactoryEx.OrientationOfExteriorRing)).EqualTo(orientation) .With.Property(nameof(GeometryFactoryEx.PrecisionModel)).EqualTo(pm) .With.Property(nameof(GeometryFactoryEx.CoordinateSequenceFactory)).EqualTo(csf)); }
/// <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 unsafe IGeometry ReadGeometry(int oid) { if (_ShapeType == ShapeType.Polygon || _ShapeType == ShapeType.PolygonM || _ShapeType == ShapeType.PolygonZ) { return(ReadPolygon(oid)); } var dataPtr = zeroPtr + recordHeaders[oid].Offset + 8; var type = *((ShapeType *)dataPtr); if (type == ShapeType.Null) { return(null); } dataPtr += 4; if (IsPoint) { var x = *((double *)dataPtr); dataPtr += 8; var y = *((double *)dataPtr); return(GeometryFactory.CreatePoint(x, y)); } if (_ShapeType == ShapeType.Multipoint || _ShapeType == ShapeType.MultiPointM || _ShapeType == ShapeType.MultiPointZ) { dataPtr += 32; // min/max box var points = new List <IPoint>(); var nPoints = *(int *)dataPtr; // get the number of points dataPtr += 4; if (nPoints == 0) { return(null); } for (var i = 0; i < nPoints; i++) { var x = *((double *)dataPtr); dataPtr += 8; var y = *((double *)dataPtr); dataPtr += 8; points.Add(GeometryFactory.CreatePoint(x, y)); } return(GeometryFactory.CreateMultiPoint(points.ToArray())); } if (_ShapeType == ShapeType.PolyLine || _ShapeType == ShapeType.Polygon || _ShapeType == ShapeType.PolyLineM || _ShapeType == ShapeType.PolygonM || _ShapeType == ShapeType.PolyLineZ || _ShapeType == ShapeType.PolygonZ) { dataPtr += 32; // min/max int nParts = *(int *)dataPtr; // get number of parts (segments) dataPtr += 4; if (nParts == 0) { return(null); } int nPoints = *((int *)dataPtr); // get number of points dataPtr += 4; var segments = new int[nParts + 1]; //Read in the segment indexes for (int b = 0; b < nParts; b++) { segments[b] = *((int *)dataPtr); dataPtr += 4; } //add end point segments[nParts] = nPoints; if ((int)_ShapeType % 10 == 3) { var mline = new List <ILineString>(); for (var lineId = 0; lineId < nParts; lineId++) { var line = new List <Coordinate>(); for (var i = segments[lineId]; i < segments[lineId + 1]; i++) { var x = *((double *)dataPtr); dataPtr += 8; var y = *((double *)dataPtr); dataPtr += 8; line.Add(GeometryFactoryEx.CreateCoordinate(x, y)); } //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())); } // TODO: check it! //(_ShapeType == ShapeType.Polygon etc...) { //First read all the rings //List<SharpMap.Geometries.LinearRing> rings = new List<SharpMap.Geometries.LinearRing>(); var rings = new List <ILinearRing>(); for (int RingID = 0; RingID < nParts; RingID++) { //SharpMap.Geometries.LinearRing ring = new SharpMap.Geometries.LinearRing(); var ring = new List <Coordinate>(); for (int i = segments[RingID]; i < segments[RingID + 1]; i++) { ring.Add(GeometryFactoryEx.CreateCoordinate(brShapeFile.ReadDouble(), brShapeFile.ReadDouble())); } // polygon should be closed, try to fix if (!ring[ring.Count - 1].Equals2D(ring[0])) { ring.Add(GeometryFactoryEx.CreateCoordinate(ring[0].X, ring[0].Y)); } //ring.Vertices.Add(new SharpMap.Geometries.Point rings.Add(GeometryFactory.CreateLinearRing(ring.ToArray())); } var 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]; var 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 { var polys = new List <IPolygon>(); ILinearRing shell = rings[0]; var 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")); } }
private unsafe IGeometry ReadPolygon(int oid) { var dataPtr = zeroPtr + recordHeaders[oid].Offset; var polygonRecord = (PolygonRecordP *)(dataPtr + 8); //First read all the rings int offset = polygonRecord->DataOffset; int parts = polygonRecord->NumParts; var rings = new ILinearRing[parts]; for (int part = 0; part < parts; ++part) { int points; if ((parts - part) > 1) { points = polygonRecord->PartOffsets[part + 1] - polygonRecord->PartOffsets[part]; } else { points = polygonRecord->NumPoints - polygonRecord->PartOffsets[part]; } if (points <= 1) { continue; } var ring = new Coordinate[points]; int index = 0; PointD *pointPtr = (PointD *)(dataPtr + 8 + offset + (polygonRecord->PartOffsets[part] << 4)); PointD point = *(pointPtr++); ring[index] = GeometryFactoryEx.CreateCoordinate(point.X, point.Y); ++index; while (index < points) { point = *(pointPtr++); ring[index] = GeometryFactoryEx.CreateCoordinate(point.X, point.Y); ++index; } // polygon should be closed, try to fix if (!ring[ring.Length - 1].Equals2D(ring[0])) { ring[ring.Length - 1] = GeometryFactoryEx.CreateCoordinate(ring[0].X, ring[0].Y); } rings[part] = GeometryFactory.CreateLinearRing(ring); } if (rings.Length == 1) //We only have one polygon { ILinearRing shell = rings[0]; if (rings.Length > 1) { var holes = new ILinearRing[rings.Length]; for (int i = 1; i < rings.Length; i++) { holes[i] = rings[i]; } return(GeometryFactory.CreatePolygon(shell, holes)); } return(GeometryFactory.CreatePolygon(shell, null)); } else { var polys = new List <IPolygon>(); ILinearRing shell = rings[0]; var holes = new List <ILinearRing>(); for (int i = 1; i < rings.Length; i++) { if (!GeometryFactory.IsCCW(rings[i].Coordinates)) { 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())); } }