/// <summary> /// Writes a geometry to a byte array using the specified encoding. /// </summary> /// <param name="g">The geometry to write</param> /// <param name="wkbByteOrder">Byte order</param> /// <returns>WKB representation of the geometry</returns> public static byte[] Write(IGeometry geometry, WkbByteOrder wkbByteOrder) { byte[] result = null; switch (wkbByteOrder) { case WkbByteOrder.Ndr: result = new WKBWriter(ByteOrder.LittleEndian).Write(geometry); break; case WkbByteOrder.Xdr: result = new WKBWriter(ByteOrder.BigEndian).Write(geometry); break; } return result; // MemoryStream ms = new MemoryStream(); // BinaryWriter bw = new BinaryWriter(ms); // // //Write the byteorder format. // bw.Write((byte)wkbByteOrder); // // //Write the type of this geometry // WriteType(g, bw, wkbByteOrder); // // //Write the geometry // WriteGeometry(g, bw, wkbByteOrder); // // return ms.ToArray(); }
public void TestWritingEmptyLineString() { var wkbWriter = new WKBWriter(); var memoryStream = new MemoryStream(); var linestring = new LineString(new ICoordinate[0]); Assert.IsNull(linestring.Coordinate); try { wkbWriter.Write(linestring, memoryStream); } finally { memoryStream.Close(); memoryStream.Dispose(); } }
public void OracleWKBBigIndianWriteTest() { ILinearRing shell = Factory.CreateLinearRing(new ICoordinate[] { new Coordinate(100,100), new Coordinate(200,100), new Coordinate(200,200), new Coordinate(100,200), new Coordinate(100,100), }); ILinearRing hole = Factory.CreateLinearRing(new ICoordinate[] { new Coordinate(120,120), new Coordinate(180,120), new Coordinate(180,180), new Coordinate(120,180), new Coordinate(120,120), }); IPolygon polygon = Factory.CreatePolygon(shell, new ILinearRing[] { hole, }); WKBWriter writer = new WKBWriter(ByteOrder.BigEndian); byte[] bytes = writer.Write(polygon); Assert.IsNotNull(bytes); Assert.IsNotEmpty(bytes); Debug.WriteLine(bytes.Length); }
protected Dictionary<string, DataRow> GetShapeRowsByLOGRECNO(DbConnection conn) { string geomSQL; string geographiesTablename = this.GetGeographyTablename(); string shapeSQL = string.Empty; switch (this.SummaryLevel) { //census_regions //census_divisions //states //case "050": // //counties // // Note: original sql for files fount at: // // "ShapeFileCountiesURL": "http://www.census.gov/geo/cob/bdy/co/co00shp/" // // "ShapeFileCountiesFilename": "co{FIPS-code}_d00_shp.zip" // // was: // // "select trim(COUNTY) as county, AsBinary(Geometry) as Geometry, '' as GEOID from counties "; // // // // // // Current source: // // "ShapeFileCountiesURL": "http://www2.census.gov/geo/tiger/TIGER2010/COUNTY/2010/", // // "ShapeFileCountiesFilename": "tl_2010_{FIPS-code}_county10.zip", // // Docs for current source: http://www.census.gov/geo/maps-data/data/pdfs/tiger/tgrshp2010/TGRSHP10SF1AA.pdf // // // shapeSQL = "select trim(COUNTYFP10) as county, AsBinary(Geometry) as Geometry, '' as GEOID from counties "; // geomSQL = "select LOGRECNO, trim(COUNTY) as county, GEOID from geographies_all where SUMLEVEL = '050' order by county "; // break; ////subdivisions //case "060": // shapeSQL = "select trim(COUNTY) as county, trim(COUSUB) as cousub, AsBinary(Geometry) as Geometry, '' as GEOID from county_subdivisions "; // geomSQL = "select LOGRECNO, trim(COUNTY) as county, trim(COUSUB) as cousub, GEOID from geographies_all where SUMLEVEL = '060' order by county, cousub"; // break; case "140": //tracts shapeSQL = "select trim(COUNTY) as county, trim(TRACT) as tract, '' as blkgroup, AsBinary(Geometry) as Geometry, '' as GEOID from census_tracts order by county, tract, blkgroup"; geomSQL = "select LOGRECNO, trim(COUNTY) as county, trim(TRACT) as tract, trim(BLKGRP) as blkgroup, GEOID from geographies where SUMLEVEL = '140' order by county, tract, blkgrp "; break; case "150": default: if (this.SummaryLevel != "150") { _log.Error("No Summary Level Selected -- defaulting to Block groups \"150\" -- "); this.SummaryLevel = "150"; } /* * NOTE! In the 2000 census shapefiles the block-group column name was "BLKGROUP", * in 2010, it was "BLKGRP"... so, lets magically recover and adjust based on what we find. */ bool hasAbbrevColumn = DataClient.HasColumn("BLKGRP", "census_blockgroups", conn, DbClient); string blkGroupColumn = (hasAbbrevColumn) ? "BLKGRP" : "BLKGROUP"; //block groups shapeSQL = string.Format("select trim(COUNTY) as county, trim(TRACT) as tract, trim({0}) as blkgroup, AsBinary(Geometry) as Geometry, '' as GEOID from census_blockgroups order by county, tract, blkgroup", blkGroupColumn); geomSQL = "select LOGRECNO, trim(COUNTY) as county, trim(TRACT) as tract, trim(BLKGRP) as blkgroup, GEOID from geographies where SUMLEVEL = '150' order by county, tract, blkgrp "; break; } var wholeGeomTable = DataClient.GetMagicTable(conn, DbClient, geomSQL); var wholeShapeTable = DataClient.GetMagicTable(conn, DbClient, shapeSQL); if (wholeShapeTable == null) { _log.Error("This shapefile had different columns than I was expecting, bailing"); return null; } // // Construct the appropriate key for whatever summary level we're using // GetGeometryRowKey keyDelegate = GetGeometryRowKeyGenerator(); // // organize our freshly pulled geometries table by composite_id // var geomKeys = new Dictionary<string, DataRow>(); foreach (DataRow row in wholeGeomTable.Rows) { string key = keyDelegate(row); geomKeys[key] = row; } var dict = new Dictionary<string, DataRow>(); GisSharpBlog.NetTopologySuite.IO.WKBReader binReader = new WKBReader(ShapefileHelper.GetGeomFactory()); GisSharpBlog.NetTopologySuite.IO.WKBWriter binWriter = new WKBWriter(); foreach (DataRow row in wholeShapeTable.Rows) { string key = keyDelegate(row); if (geomKeys.ContainsKey(key)) { string logrecno = geomKeys[key]["LOGRECNO"] as string; row["GEOID"] = geomKeys[key]["GEOID"]; if (dict.ContainsKey(logrecno)) { /* In theory, there should be a one-to-one relationship between logrecno and Geometry. * In practice, there are a small number of geometries that are discontiguous or self- * intersecting. Because the geometry shapefile only uses single polygons and not * multipolygons, they solve this problem by having duplicate rows in the geometry * shapefile with the same county, tract, and blkgroup numbers, one for each part of * the multipolygon. This is undocumented AFAIK, but can be seen in several places (see * logrecno 0014948 for PA for example). To account for this, we union geometries * together whenever we encounter duplicates and inform the user, so we don't end up * with missing geometries in the output. * * As this link indicates, tracts 9400 - 9499 are especially prone to this phenomenon: * http://www.census.gov/geo/www/cob/tr_metadata.html */ _log.DebugFormat("Duplicate records encountered for logical record number {0} (key {1}).", logrecno, key); if (row["GEOID"] != dict[logrecno]["GEOID"]) { _log.DebugFormat("GEOID {0} collided with GEOID {1}", row["GEOID"], dict[logrecno]["GEOID"]); } _log.DebugFormat("Attempting to merge geometries for duplicates together."); try { byte[] geomBytes = (byte[])row["Geometry"]; IGeometry geomToAdd = binReader.Read(geomBytes); geomBytes = (byte[])dict[logrecno]["Geometry"]; IGeometry currentGeom = binReader.Read(geomBytes); if (!geomToAdd.Equals(currentGeom)) { geomBytes = binWriter.Write(currentGeom.Union(geomToAdd)); row["Geometry"] = geomBytes; //saved to dict at end of current if clause _log.Debug("Geometry merge succeeded! Please double check all features in the output that match the above logrecno for consistency."); } } catch (Exception) { _log.Error("Geometry merge failed; only one geometry will be used! Output may be missing geometries!"); } } dict[logrecno] = row; } else { _log.DebugFormat("Couldn't find a geometry matching KEY (county/tract/blkgrp) {0}", key); } } return dict; }
/// <summary> /// Returns the Well-known Binary representation of this <c>Geometry</c>. /// For a definition of the Well-known Binary format, see the OpenGIS Simple /// Features Specification. /// </summary> /// <returns>The Well-known Binary representation of this <c>Geometry</c>.</returns> public byte[] ToBinary() { WKBWriter writer = new WKBWriter(); return writer.Write(this); }
public void BuildGraphBinary() { string path = "strade" + shp; Assert.IsTrue(File.Exists(path)); ShapefileReader reader = new ShapefileReader(path, factory); IGeometryCollection coll = reader.ReadAll(); Assert.IsNotNull(coll); Assert.IsNotEmpty(coll.Geometries); IGeometry result = coll.Geometries[0]; for (int i = 1; i < coll.NumGeometries; i++ ) { Debug.WriteLine(String.Format("Union of {0}'th geometry", i)); result = result.Union(coll.Geometries[i]); } Assert.IsNotNull(result); Assert.IsInstanceOfType(typeof(MultiLineString), result); WKBWriter wkbwriter = new WKBWriter(); byte[] rawdata = wkbwriter.Write(result); Assert.IsNotEmpty(rawdata); path = "graph"; if (File.Exists(path)) File.Delete(path); Assert.IsFalse(File.Exists(path)); using (FileStream stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None)) stream.Write(rawdata, 0, rawdata.Length); Assert.IsTrue(File.Exists(path)); }