/// <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); }
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> /// 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> /// 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)); }
/// <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); }
/// <inheritdoc/> 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); IBasicPolygon pg = feature.GetBasicGeometryN(iPart) as IBasicPolygon; if (pg == null) { continue; } var bl = pg.Shell; var coords = bl.Coordinates; if (CgAlgorithms.IsCounterClockwise(coords)) { // Exterior rings need to be clockwise coords.Reverse(); } points.AddRange(coords); foreach (IBasicLineString hole in pg.Holes) { parts.Add(points.Count); var holeCoords = hole.Coordinates; if (CgAlgorithms.IsCounterClockwise(holeCoords) == false) { // Interior rings need to be counter-clockwise holeCoords.Reverse(); } points.AddRange(holeCoords); } } contentLength += 2 * parts.Count; if (header.ShapeType == ShapeType.Polygon) { contentLength += points.Count * 8; } if (header.ShapeType == ShapeType.PolygonM) { contentLength += 8; // mmin mmax contentLength += points.Count * 12; // x, y, m } if (header.ShapeType == ShapeType.PolygonZ) { 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.PolygonZ) { 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.PolygonM || header.ShapeType == ShapeType.PolygonZ) { 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); Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4); }
/// <summary> /// This returns itself as the first geometry /// </summary> /// <returns>An IBasicGeometry interface</returns> /// <exception cref="IndexOutOfRangeException">Index cannot be less than 0 or greater than 1</exception> public IBasicGeometry GetBasicGeometryN(int index) { return(_basicGeometry.GetBasicGeometryN(index)); }
/// <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; }
/// <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> /// 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; } }
private static RectangleF PlacePointLabel(IBasicGeometry f, MapArgs e, Func <SizeF> labelSize, ILabelSymbolizer symb, float angle) { Coordinate c = f.GetBasicGeometryN(1).Coordinates[0]; return(PlaceLabel(c, e, labelSize, symb, angle)); }
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> /// 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; }
/// <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); }