/// <summary> /// Update the header to include the feature extent /// </summary> /// <param name="header"></param> /// <param name="feature"></param> /// <param name="writeHeaderFiles"> </param> protected void UpdateHeader(ShapefileHeader header, IBasicGeometry feature, bool writeHeaderFiles) { // Update the envelope IEnvelope newExt; // First, check to see if there are no features (ShxLength == 50) if (header.ShxLength <= 50) { // This is the lone feature, so just set the extent to the feature extent newExt = feature.Envelope; } else { // Other features, so include new feature newExt = new Envelope(header.Xmin, header.Xmax, header.Ymin, header.Ymax, header.Zmin, header.Zmax); newExt.ExpandToInclude(feature.Envelope); } header.Xmin = newExt.Minimum.X; header.Ymin = newExt.Minimum.Y; header.Zmin = newExt.Minimum.Z; header.Xmax = newExt.Maximum.X; header.Ymax = newExt.Maximum.Y; header.Zmax = newExt.Maximum.Z; header.ShxLength = header.ShxLength + 4; if (writeHeaderFiles) { WriteHeader(header, Filename); WriteHeader(header, header.ShxFilename); } }
/// <summary> /// Creates a new instance of a feature, by specifying the feature type enumeration and a /// set of coordinates that can be either a list or an array as long as it is enumerable. /// </summary> /// <param name="featureType">The feature type</param> /// <param name="coordinates">The coordinates to pass</param> public Feature(FeatureType featureType, IEnumerable <Coordinate> coordinates) { switch (featureType) { case FeatureType.Line: _dataRow = null; _basicGeometry = new LineString(coordinates); _envelopSource = CacheTypes.Dynamic; break; case FeatureType.MultiPoint: _dataRow = null; _basicGeometry = new MultiPoint(coordinates); _envelopSource = CacheTypes.Dynamic; break; case FeatureType.Point: _dataRow = null; _basicGeometry = new Point(coordinates.First()); _envelopSource = CacheTypes.Dynamic; break; case FeatureType.Polygon: _dataRow = null; _basicGeometry = new Polygon(coordinates); _envelopSource = CacheTypes.Dynamic; break; } }
/// <summary> /// /// </summary> /// <param name="line"></param> private void AddLineString(IBasicGeometry line) { IList <Coordinate> coord = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates); if (coord.Count < 2) { _hasTooFewPoints = true; _invalidPoint = coord[0]; return; } // add the edge for the LineString // line edges do not have locations for their left and right sides Edge e = new Edge(coord, new Label(_argIndex, LocationType.Interior)); _lineEdgeMap.Add(line, e); InsertEdge(e); /* * Add the boundary points of the LineString, if any. * Even if the LineString is closed, add both points as if they were endpoints. * This allows for the case that the node already exists and is a boundary point. */ Assert.IsTrue(coord.Count >= 2, "found LineString with single point"); InsertBoundaryPoint(_argIndex, coord[0]); InsertBoundaryPoint(_argIndex, coord[coord.Count - 1]); }
private static RectangleF PlaceLineLabel(IBasicGeometry lineString, Func <SizeF> labelSize, MapArgs e, ILabelSymbolizer symb) { ILineString ls = Geometry.FromBasicGeometry(lineString) as ILineString; if (ls == null) { return(RectangleF.Empty); } Coordinate c; if (symb.LabelPlacementMethod == LabelPlacementMethod.Centroid) { c = ls.Centroid.Coordinate; } else if (symb.LabelPlacementMethod == LabelPlacementMethod.InteriorPoint) { c = ls.InteriorPoint.Coordinate; } else { c = ls.Envelope.Center(); } var lz = labelSize(); PointF adjustment = Position(symb, lz); float x = Convert.ToSingle((c.X - e.MinX) * e.Dx) + adjustment.X; float y = Convert.ToSingle((e.MaxY - c.Y) * e.Dy) + adjustment.Y; return(new RectangleF(x, y, lz.Width, lz.Height)); }
/// <summary> /// Adds a geometry by creating a new leaf node. /// </summary> /// <param name="geometry">The geometry to be added.</param> protected override void AddGeometry(IBasicGeometry geometry) { HilbertNode leaf = new HilbertNode(geometry, this.GetHilbertValue(geometry)); HilbertNode leafContainer = this.ChooseLeafContainer(leaf); if (leafContainer == this.Root && leafContainer.ChildrenCount == 0) { this.Height = 1; } HilbertNode newNode = null; if (!this.IsFull(leafContainer)) { leafContainer.AddChild(leaf); } else { newNode = this.HandleOverflow(leafContainer, leaf); } HilbertNode rightRoot = this.AdjustTree(leafContainer, newNode); this.IncreaseHeight(rightRoot); }
/// <summary> /// Adds a geometry to this subtree. /// </summary> /// <param name="geometry">The geometry to be added.</param> public void Add(IBasicGeometry geometry) { // If this is a leaf node without contents, add geometry to this node and return if (this.IsEmpty) { this.contents.Add(geometry); return; } // If this is a leaf node with contents, create children and subdivide current contents between the children if (this.children.Count == 0) { this.CreateChildren(); this.SubdivideContents(); } // Find child which has an envelope that contains current geometry, and recursively call Add on that child, then return foreach (QuadTreeNode child in this.children) { if (child.envelope.Contains(geometry.Envelope)) { child.Add(geometry); return; } } // If we got here it means that no this node's envelope contains geometry, but no child's envelope does. Add geometry to this node. this.contents.Add(geometry); }
/// <summary> /// /// </summary> /// <param name="ring"></param> /// <param name="graph"></param> private static void VisitInteriorRing(IBasicGeometry ring, PlanarGraph graph) { IList <Coordinate> pts = ring.Coordinates; Coordinate pt0 = pts[0]; /* * Find first point in coord list different to initial point. * Need special check since the first point may be repeated. */ Coordinate pt1 = FindDifferentPoint(pts, pt0); Edge e = graph.FindEdgeInSameDirection(pt0, pt1); DirectedEdge de = (DirectedEdge)graph.FindEdgeEnd(e); DirectedEdge intDe = null; if (de.Label.GetLocation(0, PositionType.Right) == LocationType.Interior) { intDe = de; } else if (de.Sym.Label.GetLocation(0, PositionType.Right) == LocationType.Interior) { intDe = de.Sym; } Assert.IsTrue(intDe != null, "unable to find dirEdge with Interior on RHS"); VisitLinkedDirectedEdges(intDe); }
/// <summary> /// Calculates the position of the polygon label. /// </summary> /// <param name="geom"></param> /// <param name="e"></param> /// <param name="labelSize"></param> /// <param name="symb"></param> /// <returns></returns> private static RectangleF PlacePolygonLabel(IBasicGeometry geom, MapArgs e, Func <SizeF> labelSize, ILabelSymbolizer symb, float angle) { IPolygon pg = Geometry.FromBasicGeometry(geom) as IPolygon; if (pg == null) { return(RectangleF.Empty); } Coordinate c; switch (symb.LabelPlacementMethod) { case LabelPlacementMethod.Centroid: c = pg.Centroid.Coordinates[0]; break; case LabelPlacementMethod.InteriorPoint: c = pg.InteriorPoint.Coordinate; break; default: c = geom.Envelope.Center(); break; } return(PlaceLabel(c, e, labelSize, symb, angle)); }
/// <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(IBasicGeometry geometry, System.IO.BinaryWriter file, IGeometryFactory geometryFactory) { if(!(geometry is MultiPoint)) throw new ArgumentException("Geometry Type error: MultiPoint expected, but the type retrieved is " + geometry.GetType().Name); //if (!geometry.IsValid) // Trace.WriteLine("Invalid multipoint being written."); MultiPoint mpoint = geometry as MultiPoint; file.Write(int.Parse(Enum.Format(typeof(ShapeGeometryTypes), this.ShapeType, "d"))); IEnvelope box = geometry.Envelope; IEnvelope bounds = ShapeHandler.GetEnvelopeExternal(new PrecisionModel(geometryFactory.PrecisionModel), box); file.Write(bounds.Minimum.X); file.Write(bounds.Minimum.Y); file.Write(bounds.Maximum.X); file.Write(bounds.Maximum.Y); int numPoints = mpoint.NumPoints; file.Write(numPoints); // write the points for (int i = 0; i < numPoints; i++) { Point point = (Point)mpoint.Geometries[i]; file.Write(point.X); file.Write(point.Y); } }
/// <summary> /// Removes the specified geometry from the tree. /// </summary> /// <param name="geometry">The geometry.</param> /// <returns><c>true</c>, if the tree contains the geometry, otherwise, <c>false</c>.</returns> protected virtual Boolean RemoveGeometry(IBasicGeometry geometry) { Node leafContainer = null; this.FindLeafContainer(geometry, this.Root, ref leafContainer); if (leafContainer == null) { return(false); } Node nodeToRemove = leafContainer.Children.First(x => x.Geometry == geometry); leafContainer.RemoveChild(nodeToRemove); this.CondenseTree(leafContainer); while (this.Root.ChildrenCount == 1 && !this.Root.IsLeafContainer) { this.Root = this.Root.Children[0]; this.Root.Parent = null; this.Height--; } if (this.Root.ChildrenCount == 0) // occurs when the last element is removed { this.Clear(); } this.NumberOfGeometries--; return(true); }
/// <summary> /// The left and right topological location arguments assume that the ring is oriented CW. /// If the ring is in the opposite orientation, /// the left and right locations must be interchanged. /// </summary> /// <param name="lr"></param> /// <param name="cwLeft"></param> /// <param name="cwRight"></param> private void AddPolygonRing(IBasicGeometry lr, LocationType cwLeft, LocationType cwRight) { IList <Coordinate> coord = CoordinateArrays.RemoveRepeatedPoints(lr.Coordinates); if (coord.Count < 4) { _hasTooFewPoints = true; _invalidPoint = coord[0]; return; } LocationType left = cwLeft; LocationType right = cwRight; if (CgAlgorithms.IsCounterClockwise(coord)) { left = cwRight; right = cwLeft; } Edge e = new Edge(coord, new Label(_argIndex, LocationType.Boundary, left, right)); _lineEdgeMap.Add(lr, e); InsertEdge(e); // insert the endpoint as a node, to mark that it is on the boundary InsertPoint(_argIndex, coord[0], LocationType.Boundary); }
/// <summary> /// This constructor allows the creation of a feature but will automatically /// add the feature to the parent featureset. /// </summary> /// <param name="geometry">The IBasicGeometry to use for this feature</param> /// <param name="parent">The IFeatureSet to add this feature to.</param> public Feature(IBasicGeometry geometry, IFeatureSet parent) { _basicGeometry = geometry; _dataRow = parent.DataTable.NewRow(); _envelopSource = CacheTypes.Dynamic; parent.Features.Add(this); }
/// <summary> /// 线 /// </summary> /// <param name="geometry"></param> /// <returns></returns> public static IEnumerable <byte> GetPolyLineBytes(IBasicGeometry geometry) { if (geometry.GetType().Name == "MultiPolyLine") { //var polyLine = ((MultiPolyLine)geometry).PolyLines[0]; return(GetMultiPolyLineBytes(geometry)); } else { var bytes = new List <byte>(); var line = (PolyLine)geometry; MultiGeometryPreHandle(bytes, line.Envelope, 1, line.PointsNum ); //Index to the First Point in Part bytes.AddRange(BitConverter.GetBytes(0)); foreach (var point in line.Points) { bytes.AddRange(BitConverter.GetBytes(point.X)); bytes.AddRange(BitConverter.GetBytes(point.Y)); } return(bytes); } }
private static RectangleF PlacePolygonLabel(IBasicGeometry geom, MapArgs e, Func <SizeF> labelSize, ILabelSymbolizer symb) { IPolygon pg = Geometry.FromBasicGeometry(geom) as IPolygon; if (pg == null) { return(RectangleF.Empty); } Coordinate c; switch (symb.LabelPlacementMethod) { case LabelPlacementMethod.Centroid: c = pg.Centroid.Coordinates[0]; break; case LabelPlacementMethod.InteriorPoint: c = pg.InteriorPoint.Coordinate; break; default: c = geom.Envelope.Center(); break; } if (e.GeographicExtents.Intersects(c) == false) { return(RectangleF.Empty); } var lz = labelSize(); PointF adjustment = Position(symb, lz); float x = Convert.ToSingle((c.X - e.MinX) * e.Dx) + adjustment.X; float y = Convert.ToSingle((e.MaxY - c.Y) * e.Dy) + adjustment.Y; return(new RectangleF(x, y, lz.Width, lz.Height)); }
private static Geometry Intersect(IFeature f, IGeometry envelope) { Geometry clip; if (f.GeometryType == "GeometryCollection") { // This hack because DotSpatial 1.9 throws NullReferenceException when trying to Intersect GeometryCollection List <IBasicGeometry> arr = new List <IBasicGeometry>(); for (int i = 0; i < f.NumGeometries; i++) { IBasicGeometry g = f.GetBasicGeometryN(i); IFeature intersection = new Feature(g).Intersection(envelope); if (intersection == null) { continue; } clip = (Geometry)intersection.BasicGeometry; arr.Add(clip); } clip = new GeometryCollection(arr, new GeometryFactory()); } else { IFeature intersection = f.Intersection(envelope); if (intersection == null) { return(null); } clip = (Geometry)intersection.BasicGeometry; } return(clip); }
/// <summary> /// Creates a new tree based on an unindexed geometry. /// </summary> /// <param name="geometry">The geometry.</param> private void CreateNew(IBasicGeometry geometry) { IEnumerable <IBasicGeometry> allGeometries = this.Search(this.root.Envelope); this.root = new QuadTreeNode(Envelope.FromEnvelopes(this.root.Envelope, geometry.Envelope)); this.Add(geometry); this.Add(allGeometries); }
/// <summary> /// Writes to the given stream the equilivent shape file record given a Geometry object. /// </summary> /// <param name="geometry">The geometry object to write.</param> /// <param name="file">The stream to write to.</param> /// <param name="geometryFactory">The geometry factory to use.</param> public override void Write(IBasicGeometry geometry, System.IO.BinaryWriter file, IGeometryFactory geometryFactory) { file.Write(int.Parse(Enum.Format(typeof(ShapeGeometryTypes), this.ShapeType, "d"))); // Coordinate external = geometryFactory.PrecisionModel.ToExternal( geometry.Coordinates[0] ); Coordinate external = geometry.Coordinates[0]; file.Write(external.X); file.Write(external.Y); }
/// <inheritdocs/> protected override void AppendBasicGeometry(ShapefileHeader header, IBasicGeometry feature, int numFeatures) { FileInfo fi = new FileInfo(Filename); int offset = Convert.ToInt32(fi.Length / 2); FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000); FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100); Coordinate point = feature.Coordinates[0]; int contentLength = 6; if (header.ShapeType == ShapeType.PointM) { contentLength += 4; // one additional value (m) } if (header.ShapeType == ShapeType.PointZ) { contentLength += 8; // 2 additional values (m, z) } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shxStream.Flush(); shxStream.Close(); // X Y Points // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(numFeatures); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (header.ShapeType == ShapeType.NullShape) { return; } shpStream.WriteLe(point.X); // Byte 12 X Double 1 Little shpStream.WriteLe(point.Y); // Byte 20 Y Double 1 Little if (header.ShapeType == ShapeType.PointM) { shpStream.WriteLe(point.M); // Byte 28 M Double 1 Little } else if (header.ShapeType == ShapeType.PointZ) { shpStream.WriteLe(point.Z); // Byte 28 Z Double 1 Little shpStream.WriteLe(point.M); // Byte 36 M Double 1 Little } shpStream.Flush(); shpStream.Close(); offset += contentLength; Shapefile.WriteFileLength(Filename, offset); Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4); }
/// <summary> /// 点 /// </summary> /// <param name="geometry"></param> /// <returns></returns> public static IEnumerable <byte> GetPointBytes(IBasicGeometry geometry) { var point = (GeoPoint)geometry; var bytes = new List <byte>(); bytes.AddRange(BitConverter.GetBytes(point.X)); bytes.AddRange(BitConverter.GetBytes(point.Y)); return(bytes); }
/// <summary> /// Removes the specified geometry from the index. /// </summary> /// <param name="geometry">The geometry.</param> /// <returns><c>true</c> if the geometry is indexed; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The geometry is null.</exception> public virtual Boolean Remove(IBasicGeometry geometry) { if (geometry == null) { throw new ArgumentNullException(nameof(geometry)); } return(this.RemoveGeometry(geometry)); }
/// <summary> /// Removes the specified geometry from the index. /// </summary> /// <param name="geometry">The geometry.</param> /// <returns><c>true</c> if the geometry is indexed; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The geometry is null.</exception> public bool Remove(IBasicGeometry geometry) { if (geometry == null) { throw new ArgumentNullException("geometry", "Geometry to remove must not be null."); } return(this.root.Remove(geometry)); }
/// <summary> /// Determines whether the specified geometry is indexed. /// </summary> /// <param name="geometry">The geometry.</param> /// <returns><c>true</c> if the specified geometry is indexed; otherwise <c>false</c>.</returns> public virtual Boolean Contains(IBasicGeometry geometry) { if (geometry == null) { return(false); } return(this.ContainsGeometry(geometry, this.Root)); }
private IFeature ExtractGeographicData(XmlNode c) { string geoData = ""; IBasicGeometry geo = null; string[] pointValue = null; if (typeGeometry == DotSpatial.Topology.FeatureType.Point) { foreach (XmlNode e in c) { if (e.LocalName == Geometry) { geoData = e.InnerText; } } string point = Convert.ToString(geoData); pointValue = point.Split(' '); geo = new Point(Convert.ToDouble(pointValue[0]), Convert.ToDouble(pointValue[1])); } if (typeGeometry == DotSpatial.Topology.FeatureType.Polygon) { foreach (XmlNode e in c) { if (e.LocalName == Geometry) { var t = e.FirstChild.OuterXml; var s = new XmlSerializer(typeof(MultiSurfaceType)); MultiSurfaceType multi = s.Deserialize(new StringReader(t)) as MultiSurfaceType; geo = GetPolygon(multi); // geoData = e.InnerText; } } } if (typeGeometry == DotSpatial.Topology.FeatureType.Line) { foreach (XmlNode e in c) { if (e.LocalName == Geometry) { var t = e.FirstChild.OuterXml; var s = new XmlSerializer(typeof(MultiLineStringType)); MultiLineStringType multi = s.Deserialize(new StringReader(t)) as MultiLineStringType; geo = GetPolyline(multi); // geoData = e.InnerText; } } } IFeature feat = fea.AddFeature(geo); return(feat); }
/// <summary> /// Adds a geometry to the index. /// </summary> /// <param name="geometry">The geometry.</param> /// <exception cref="System.ArgumentNullException">The geometry is null.</exception> public void Add(IBasicGeometry geometry) { if (geometry == null) { throw new ArgumentNullException(nameof(geometry)); } this.AddGeometry(geometry); this.NumberOfGeometries++; }
/// <summary> /// This method will attempt to add the specified geometry to the list. /// If the feature type is currently unspecified, this will specify the feature type. /// </summary> /// <param name="self">This feature list</param> /// <param name="geometry">The geometry to create a new feature from.</param> /// <exception cref="FeatureTypeMismatchException">Thrown if the new geometry does not match the currently specified feature type. </exception> public static void Add(this IFeatureList self, IBasicGeometry geometry) { Feature f = new Feature(geometry); if (f.FeatureType != self.Parent.FeatureType && self.Parent.FeatureType != FeatureType.Unspecified) { throw new FeatureTypeMismatchException(); } self.Add(f); }
private static CoreSpatial.IFeature ToCsFeature(this NetTopologySuite.Features.IFeature feature) { var originalGeom = feature.Geometry; IBasicGeometry basicGeometry = null; switch (originalGeom.OgcGeometryType) { case OgcGeometryType.Point: { basicGeometry = ((Point)originalGeom).TcsGeometry(); break; } case OgcGeometryType.MultiPoint: { basicGeometry = ((MultiPoint)originalGeom).TcsGeometry(); break; } case OgcGeometryType.LineString: { if (originalGeom.GeometryType == "LinearRing") { basicGeometry = ((LinearRing)originalGeom).TcsGeometry(); } else { basicGeometry = ((LineString)originalGeom).TcsGeometry(); } break; } case OgcGeometryType.MultiLineString: { basicGeometry = ((MultiLineString)originalGeom).TcsGeometry(); break; } case OgcGeometryType.Polygon: { basicGeometry = ((Polygon)originalGeom).TcsGeometry(); break; } default: throw new Exception("not support GeometryType: " + originalGeom.GeometryType); } IGeometry geometry = new Geometry(basicGeometry); var result = new Feature(geometry); return(result); }
private static IEnumerable <byte> GeOneLineBytes(IBasicGeometry geometry) { var line = (PolyLine)geometry; var bytes = new List <byte>(); foreach (var point in line.Points) { bytes.AddRange(BitConverter.GetBytes(point.X)); bytes.AddRange(BitConverter.GetBytes(point.Y)); } return(bytes); }
private static LineString ToCoords(IBasicGeometry ls) { List <GeographicPosition> p = new List <GeographicPosition>(); foreach (Coordinate point in ls.Coordinates) { p.Add(new GeographicPosition(point.Y, point.X)); } var points = new LineString(p); return(points); }
/// <summary> /// 面 /// </summary> /// <param name="geometry"></param> /// <returns></returns> public static IEnumerable <byte> GetPolygonBytes(IBasicGeometry geometry) { var polygon = (Polygon)geometry; foreach (var polygonPolyLine in polygon.PolyLines) { if (!polygonPolyLine.IsLineRing) { polygonPolyLine.Points.Add(polygonPolyLine.Points[0]); } } return(GetMultiPolyLineBytes(polygon)); }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="ring"></param> /// <returns></returns> private static LocationType LocateInPolygonRing(Coordinate p, IBasicGeometry ring) { // can this test be folded into IsPointInRing? if (CgAlgorithms.IsOnLine(p, ring.Coordinates)) { return(LocationType.Boundary); } if (CgAlgorithms.IsPointInRing(p, ring.Coordinates)) { return(LocationType.Interior); } return(LocationType.Exterior); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <returns></returns> private bool IsLineStringContainedInBoundary(IBasicGeometry line) { IList <Coordinate> seq = line.Coordinates; for (int i = 0; i < seq.Count - 1; i++) { if (!IsLineSegmentContainedInBoundary(seq[i], seq[i + 1])) { return(false); } } return(true); }
private static RectangleF PlacePointLabel(IBasicGeometry f, MapArgs e, SizeF labelSize, ILabelSymbolizer symb) { Coordinate c = f.GetBasicGeometryN(1).Coordinates[0]; if (e.GeographicExtents.Intersects(c) == false) { return(RectangleF.Empty); } PointF adjustment = Position(symb, labelSize); float x = Convert.ToSingle((c.X - e.MinX) * e.Dx) + adjustment.X; float y = Convert.ToSingle((e.MaxY - c.Y) * e.Dy) + adjustment.Y; return(new RectangleF(x, y, labelSize.Width, labelSize.Height)); }
/// <summary> /// Creates a shape based on the specified geometry. This shape will be standing alone, /// all by itself. The attributes will be null. /// </summary> /// <param name="geometry">The geometry to create a shape from.</param> public Shape(IBasicGeometry geometry) { if (geometry == null) throw new ArgumentNullException("geometry"); var coords = geometry.Coordinates; _vertices = new double[geometry.NumPoints * 2]; _z = new double[geometry.NumPoints]; _m = new double[geometry.NumPoints]; for (var i = 0; i < coords.Count; i++) { var c = coords[i]; _vertices[i * 2] = c.X; _vertices[i * 2 + 1] = c.Y; _z[i] = c.Z; _m[i] = c.M; } _shapeRange = ShapeRangeFromGeometry(geometry, _vertices, 0); }
/// <summary> /// Writes to the given stream the equilivent shape file record given a Geometry object. /// </summary> /// <param name="geometry">The geometry object to write.</param> /// <param name="file">The stream to write to.</param> /// <param name="geometryFactory">The geometry factory to use.</param> public override void Write(IBasicGeometry geometry, System.IO.BinaryWriter file, IGeometryFactory geometryFactory) { MultiLineString multi = (MultiLineString) geometry; file.Write(int.Parse(Enum.Format(typeof(ShapeGeometryTypes), this.ShapeType, "d"))); IEnvelope box = multi.EnvelopeInternal; file.Write(box.Minimum.X); file.Write(box.Minimum.Y); file.Write(box.Maximum.X); file.Write(box.Maximum.Y); int numParts = multi.NumGeometries; int numPoints = multi.NumPoints; file.Write(numParts); file.Write(numPoints); // write the offsets int offset=0; for (int i = 0; i < numParts; i++) { IGeometry g = multi.GetGeometryN(i); file.Write( offset ); offset = offset + g.NumPoints; } Coordinate external; for (int part = 0; part < numParts; part++) { CoordinateList points = new CoordinateList(multi.GetGeometryN(part).Coordinates); for (int i = 0; i < points.Count; i++) { // external = geometryFactory.PrecisionModel.ToExternal((Coordinate)points[i]); external = (Coordinate)points[i]; file.Write(external.X); file.Write(external.Y); } } }
/// <summary> /// Presuming that the specified basic geometry describes a MultiPolygon, this will perform the necessary /// casting in order to create a MultiPolygon. If, in fact, it is only a BasicMultiPolygon, this will /// create a new, fully functional MultiPolygon based on the same coordinates. /// </summary> /// <param name="inGeometry">The IBasicGeometry to turn into a MultiPolygon. </param> public static new IMultiPolygon FromBasicGeometry(IBasicGeometry inGeometry) { // Multipolygons cast directly IMultiPolygon result = inGeometry as IMultiPolygon; if (result != null) return result; // Polygons are just wrapped in a Multipolygon with the one polygon as an element IPolygon p = (IPolygon)inGeometry; if (p != null) { return new MultiPolygon(new[] { p }); } IBasicPolygon bp = (IBasicPolygon)inGeometry; if (bp != null) { return new MultiPolygon(new[] { bp }); } IPolygon[] polygonArray = new IPolygon[inGeometry.NumGeometries]; // assume that we have some kind of MultiGeometry of IBasicPolygon objects for (int i = 0; i < inGeometry.NumGeometries; i++) { IBasicPolygon ibp = (IBasicPolygon)inGeometry.GetBasicGeometryN(i); polygonArray[i] = new Polygon(ibp); } return new MultiPolygon(polygonArray); }
/// <summary> /// Checks validity of a Point. /// </summary> /// <param name="g"></param> private void CheckValidCoordinates(IBasicGeometry g) { CheckInvalidCoordinates(g.Coordinates); }
/// <summary> /// This will attempt to create a new MultiLineString from the specified basic geometry. /// </summary> /// <param name="inBasicGeometry">A Basic geometry that shoule be a LineString or MultiLineString</param> /// <param name="inFactory">Any valid Geometry Factory</param> public MultiLineString(IBasicGeometry inBasicGeometry, IGeometryFactory inFactory) : base(inBasicGeometry, inFactory) { }
private static RectangleF PlaceLineLabel(IBasicGeometry lineString, SizeF labelSize, MapArgs e, ILabelSymbolizer symb) { ILineString ls = Geometry.FromBasicGeometry(lineString) as ILineString; if (ls == null) return RectangleF.Empty; Coordinate c; if (symb.LabelPlacementMethod == LabelPlacementMethod.Centroid) c = ls.Centroid.Coordinate; else if (symb.LabelPlacementMethod == LabelPlacementMethod.InteriorPoint) c = ls.InteriorPoint.Coordinate; else c = ls.Envelope.Center(); PointF adjustment = Position(symb, labelSize); float x = Convert.ToSingle((c.X - e.MinX) * e.Dx) + adjustment.X; float y = Convert.ToSingle((e.MaxY - c.Y) * e.Dy) + adjustment.Y; return new RectangleF(x, y, labelSize.Width, labelSize.Height); }
/// <summary> /// Generates a new feature, adds it to the features and returns the value. /// </summary> /// <param name="geometry"> /// The geometry. /// </param> /// <returns> /// The feature that was added to this featureset /// </returns> public IFeature AddFeature(IBasicGeometry geometry) { IFeature f = new Feature(geometry, this); return f; }
/// <summary> /// /// </summary> /// <param name="ring"></param> /// <param name="graph"></param> private static void VisitInteriorRing(IBasicGeometry ring, PlanarGraph graph) { IList<Coordinate> pts = ring.Coordinates; Coordinate pt0 = pts[0]; /* * Find first point in coord list different to initial point. * Need special check since the first point may be repeated. */ Coordinate pt1 = FindDifferentPoint(pts, pt0); Edge e = graph.FindEdgeInSameDirection(pt0, pt1); DirectedEdge de = (DirectedEdge)graph.FindEdgeEnd(e); DirectedEdge intDe = null; if (de.Label.GetLocation(0, PositionType.Right) == LocationType.Interior) intDe = de; else if (de.Sym.Label.GetLocation(0, PositionType.Right) == LocationType.Interior) intDe = de.Sym; Assert.IsTrue(intDe != null, "unable to find dirEdge with Interior on RHS"); VisitLinkedDirectedEdges(intDe); }
/// <summary> /// Create a ShapeRange from a Geometry to use in constructing a Shape /// </summary> /// <param name="geometry"></param> /// <param name="vertices"></param> /// <param name="offset">offset into vertices array where this feature starts</param> /// <returns></returns> public static ShapeRange ShapeRangeFromGeometry(IBasicGeometry geometry, double[] vertices, int offset) { var featureType = geometry.FeatureType; ShapeRange shx = new ShapeRange(featureType) { Extent = new Extent(geometry.Envelope) }; int vIndex = offset / 2; shx.Parts = new List<PartRange>(); int shapeStart = vIndex; for (int part = 0; part < geometry.NumGeometries; part++) { PartRange prtx = new PartRange(vertices, shapeStart, vIndex - shapeStart, featureType); IBasicPolygon bp = geometry.GetBasicGeometryN(part) as IBasicPolygon; if (bp != null) { // Account for the Shell prtx.NumVertices = bp.Shell.NumPoints; vIndex += bp.Shell.NumPoints; // The part range should be adjusted to no longer include the holes foreach (var hole in bp.Holes) { PartRange holex = new PartRange(vertices, shapeStart, vIndex - shapeStart, featureType) { NumVertices = hole.NumPoints }; shx.Parts.Add(holex); vIndex += hole.NumPoints; } } else { int numPoints = geometry.GetBasicGeometryN(part).NumPoints; // This is not a polygon, so just add the number of points. vIndex += numPoints; prtx.NumVertices = numPoints; } shx.Parts.Add(prtx); } return shx; }
/// <summary> /// Gets the length in bytes the Geometry will need when written as a shape file record. /// </summary> /// <param name="geometry">The Geometry object to use.</param> /// <returns>The length in 16bit words the Geometry will use when represented as a shape file record.</returns> public abstract int GetLength(IBasicGeometry geometry);
/// <summary> /// If the input geometry is a singular basic geometry, this will become a collection of 1 geometry. /// If the input geometry is a multi- basic geometry, this will simply ensure that each member /// is upgraded to a full geometry. /// </summary> /// <param name="inGeometry"></param> /// <param name="inFactory"></param> public GeometryCollection(IBasicGeometry inGeometry, IGeometryFactory inFactory) : base(inFactory) { if (inGeometry == null) { _geometries = new IGeometry[] { }; return; } IBasicPolygon pg = inGeometry.GetBasicGeometryN(0) as IBasicPolygon; if (pg != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { pg = inGeometry.GetBasicGeometryN(iGeom) as IBasicPolygon; _geometries[iGeom] = new Polygon(pg); } return; } IBasicPoint pt = inGeometry.GetBasicGeometryN(0) as IBasicPoint; if (pt != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { pt = inGeometry.GetBasicGeometryN(iGeom) as IBasicPoint; _geometries[iGeom] = new Point(pt); } return; } IBasicLineString ls = inGeometry.GetBasicGeometryN(0) as IBasicLineString; if (ls != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { ls = inGeometry.GetBasicGeometryN(iGeom) as IBasicLineString; _geometries[iGeom] = new LineString(ls); } return; } }
/// <summary> /// This will attempt to create a new MultiPolygon from the specified basic geometry. /// </summary> /// <param name="inBasicGeometry">A Polygon or MultiPolygon</param> /// <param name="inFactory">An implementation of the IGeometryFactory interface</param> public MultiPolygon(IBasicGeometry inBasicGeometry, IGeometryFactory inFactory) : base(inBasicGeometry, inFactory) { }
/// <summary> /// This is convenient for casting troublesome basic geometries into fully fledged geometries /// without having to parse them each time. It uses the constructors, and effectively the default factory. /// </summary> /// <param name="geom"></param> /// <returns></returns> public static IGeometry FromBasicGeometry(IBasicGeometry geom) { // first try to use the geometry as a sub-class itself IBasicPolygon pg = geom as IBasicPolygon; if (pg != null) return new Polygon(pg); IBasicLineString ls = geom as IBasicLineString; if (ls != null) return new LineString(ls); IBasicPoint p = geom as IBasicPoint; if (p != null)return new Point(p); // if that fails, test for multi-geometry IBasicGeometry test = geom.GetBasicGeometryN(0); pg = test as IBasicPolygon; if (pg != null) return new MultiPolygon(geom); ls = test as IBasicLineString; if (ls != null) return new MultiLineString(geom); p = test as IBasicPoint; if (p != null) return new MultiPoint(geom); return null; }
private static RectangleF PlacePolygonLabel(IBasicGeometry geom, MapArgs e, SizeF labelSize, ILabelSymbolizer symb) { IPolygon pg = Geometry.FromBasicGeometry(geom) as IPolygon; if (pg == null) return RectangleF.Empty; Coordinate c; switch (symb.LabelPlacementMethod) { case LabelPlacementMethod.Centroid: c = pg.Centroid.Coordinates[0]; break; case LabelPlacementMethod.InteriorPoint: c = pg.InteriorPoint.Coordinate; break; default: c = geom.Envelope.Center(); break; } if (e.GeographicExtents.Intersects(c) == false) return RectangleF.Empty; PointF adjustment = Position(symb, labelSize); float x = Convert.ToSingle((c.X - e.MinX) * e.Dx) + adjustment.X; float y = Convert.ToSingle((e.MaxY - c.Y) * e.Dy) + adjustment.Y; RectangleF result = new RectangleF(x, y, labelSize.Width, labelSize.Height); return result; }
/// <summary> /// Writes the specified feature collection. /// </summary> /// <param name="featurelayer">The feature collection.</param> public virtual void Write(IFeatureSet featurelayer) { // Test if the Header is initialized if (Header == null) throw new ApplicationException("Header must be set first!"); try { // Write shp and shx IBasicGeometry[] geometries = new IBasicGeometry[featurelayer.Features.Count]; int index = 0; // putting these into an array effectively re-indexes the members, so by putting // them into an array, we ensure the order will match the order of the dbf. foreach (IFeature feature in featurelayer.Features) { geometries[index++] = feature.BasicGeometry; //dbaseWriter.Write(feature.Value.DataRow, ); } shapeWriter.Write(shpFile, new GeometryCollection(geometries, geometryFactory)); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { // Close dbf writer dbaseWriter.Close(); } }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="ring"></param> /// <returns></returns> private static LocationType LocateInPolygonRing(Coordinate p, IBasicGeometry ring) { // can this test be folded into IsPointInRing? if (CgAlgorithms.IsOnLine(p, ring.Coordinates)) return LocationType.Boundary; if (CgAlgorithms.IsPointInRing(p, ring.Coordinates)) return LocationType.Interior; return LocationType.Exterior; }
/// <summary> /// Writes to the given stream the equilivent shape file record given a Geometry object. /// </summary> /// <param name="geometry">The geometry object to write.</param> /// <param name="file">The stream to write to.</param> /// <param name="geometryFactory">The geometry factory to use.</param> public abstract void Write(IBasicGeometry geometry, System.IO.BinaryWriter file, IGeometryFactory geometryFactory);
/// <summary> /// Given a geomtery object, returns the equilivent shape file type. /// </summary> /// <param name="geom">A Geometry object.</param> /// <returns>The equilivent for the geometry object.</returns> public static ShapeGeometryTypes GetShapeType(IBasicGeometry geom) { if (geom is IBasicPoint) return ShapeGeometryTypes.Point; if (geom is IBasicPolygon) return ShapeGeometryTypes.Polygon; if (geom is IBasicLineString) return ShapeGeometryTypes.LineString; return ShapeGeometryTypes.NullShape; }
/// <summary> /// Using an envelope intersection has some optimizations by checking against the envelope /// of the geometry. In the worst case scenario, the envelope crops the geometry, and a new geometry is created. /// This will be much faster if the envelope contains the geometries envelope, however, simply returning /// the original geometry. /// </summary> /// <param name="self">The <c>IEnvelope</c> that is being extended by this method</param> /// <param name="geom">A geometric intersection against the area of this envelope</param> /// <returns>A geometry, cropped to the space of this envelope if necessary.</returns> public static IBasicGeometry Intersection(this IEnvelope self, IBasicGeometry geom) { if (self == null || geom == null) return null; if (self.IsNull) return null; IEnvelope env = geom.Envelope; if (env.Intersects(self) == false) return null; if (self.Contains(env)) return geom; IGeometry g = Geometry.FromBasicGeometry(geom); return g.Intersection(self.ToPolygon()); }
/// <summary> /// This is convenient for casting troublesome basic geometries into fully fledged geometries /// without having to parse them each time. It uses the constructors, and effectively the default factory. /// </summary> /// <param name="geom"></param> /// <returns></returns> public static IGeometry FromBasicGeometry(IBasicGeometry geom) { // first try to use the geometry as a sub-class itself IBasicPolygon pg = geom as IBasicPolygon; if (pg != null) return new Polygon(pg); IBasicLineString ls = geom as IBasicLineString; if (ls != null) return new LineString(ls); IBasicPoint p = geom as IBasicPoint; if (p != null) return new Point(p); // if that fails, test for multi-geometry if (geom.NumGeometries > 0) { IBasicGeometry test = geom.GetBasicGeometryN(0); pg = test as IBasicPolygon; if (pg != null) return new MultiPolygon(geom); ls = test as IBasicLineString; if (ls != null) return new MultiLineString(geom); p = test as IBasicPoint; if (p != null) return new MultiPoint(geom); } else { // test for empty geometries var iGeometry = geom as IGeometry; if (iGeometry != null && iGeometry.IsEmpty) return iGeometry; } return null; }
/// <inheritdocs/> protected override void AppendBasicGeometry(ShapefileHeader header, IBasicGeometry feature, int numFeatures) { FileInfo fi = new FileInfo(Filename); int offset = Convert.ToInt32(fi.Length / 2); FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000); FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100); List<int> parts = new List<int>(); List<Coordinate> points = new List<Coordinate>(); int contentLength = 22; for (int iPart = 0; iPart < feature.NumGeometries; iPart++) { parts.Add(points.Count); IBasicLineString pg = feature.GetBasicGeometryN(iPart) as IBasicLineString; if (pg == null) continue; points.AddRange(pg.Coordinates); } contentLength += 2 * parts.Count; if (header.ShapeType == ShapeType.PolyLine) { contentLength += points.Count * 8; } if (header.ShapeType == ShapeType.PolyLineM) { contentLength += 8; // mmin mmax contentLength += points.Count * 12; // x, y, m } if (header.ShapeType == ShapeType.PolyLineZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += points.Count * 16; // x, y, m, z } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shxStream.Flush(); shxStream.Close(); // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(numFeatures); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (header.ShapeType == ShapeType.NullShape) { return; } shpStream.WriteLe(feature.Envelope.Minimum.X); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(feature.Envelope.Minimum.Y); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(feature.Envelope.Maximum.X); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(feature.Envelope.Maximum.Y); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(parts.Count); // Byte 44 NumParts Integer 1 Little shpStream.WriteLe(points.Count); // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little foreach (int iPart in parts) { shpStream.WriteLe(iPart); } double[] xyVals = new double[points.Count * 2]; int i = 0; foreach (Coordinate coord in points) { xyVals[i * 2] = coord.X; xyVals[i * 2 + 1] = coord.Y; i++; } shpStream.WriteLe(xyVals, 0, 2 * points.Count); if (header.ShapeType == ShapeType.PolyLineZ) { shpStream.WriteLe(feature.Envelope.Minimum.Z); shpStream.WriteLe(feature.Envelope.Maximum.Z); double[] zVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; ipoint++) { zVals[ipoint] = points[ipoint].Z; } shpStream.WriteLe(zVals, 0, points.Count); } if (header.ShapeType == ShapeType.PolyLineM || header.ShapeType == ShapeType.PolyLineZ) { if (feature.Envelope == null) { shpStream.WriteLe(0.0); shpStream.WriteLe(0.0); } else { shpStream.WriteLe(feature.Envelope.Minimum.M); shpStream.WriteLe(feature.Envelope.Maximum.M); } double[] mVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; i++) { mVals[ipoint] = points[ipoint].M; ipoint++; } shpStream.WriteLe(mVals, 0, points.Count); } shpStream.Flush(); shpStream.Close(); offset += contentLength; Shapefile.WriteFileLength(Filename, offset + 4); // Add 4 for the record header Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4); }
/// <summary> /// This will attempt to create a new MultiPolygon from the specified basic geometry. /// </summary> /// <param name="inBasicGeometry">A Polygon or MultiPolygon</param> public MultiPolygon(IBasicGeometry inBasicGeometry) : base(inBasicGeometry, DefaultFactory) { }
/// <summary> /// This will attempt to create a new MultiLineString from the specified basic geometry. /// </summary> /// <param name="inBasicGeometry">A Basic geometry that shoule be a LineString or MultiLineString</param> public MultiLineString(IBasicGeometry inBasicGeometry) : base(inBasicGeometry, DefaultFactory) { }
/// <summary> /// /// </summary> /// <param name="ring"></param> public SimplePointInRing(IBasicGeometry ring) { _pts = ring.Coordinates; }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <returns></returns> private bool IsLineStringContainedInBoundary(IBasicGeometry line) { IList<Coordinate> seq = line.Coordinates; for (int i = 0; i < seq.Count - 1; i++) { if (!IsLineSegmentContainedInBoundary(seq[i], seq[i+1])) return false; } return true; }
private static RectangleF PlacePointLabel(IBasicGeometry f, MapArgs e, SizeF labelSize, ILabelSymbolizer symb) { Coordinate c = f.GetBasicGeometryN(1).Coordinates[0]; if (e.GeographicExtents.Intersects(c) == false) return RectangleF.Empty; PointF adjustment = Position(symb, labelSize); float x = Convert.ToSingle((c.X - e.MinX) * e.Dx) + adjustment.X; float y = Convert.ToSingle((e.MaxY - c.Y) * e.Dy) + adjustment.Y; return new RectangleF(x, y, labelSize.Width, labelSize.Height); }