public void Setup() { wkbreader = new WKBReader(factory); geometry0 = wkbreader.Read(test00_Geom0_WkbByteArray); Debug.WriteLine(geometry0.ToString()); geometry1 = wkbreader.Read(test00_Geom1_WkbByteArray); Debug.WriteLine(geometry1.ToString()); }
public void OracleWKBBigIndianReadTest() { IGeometry result = null; using(Stream stream = new FileStream(blobFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { WKBReader wkbreader = new WKBReader(); result = wkbreader.Read(stream); } Debug.WriteLine(result.ToString()); Assert.IsNotNull(result); }
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> /// Given a table, returns a list of features to export. Assumes table geometries are in WGS84 /// </summary> /// <param name="tableName">Name of the sqlite table</param> /// <param name="spatialFilter">Should we load and use a spatial filter?</param> /// <returns></returns> public List<Feature> GetShapeFeaturesToExport(string tableName, bool spatialFilter) { using (var conn = DbClient.GetConnection()) { Dictionary<string, DataRow> shapeDict = GetShapeRowsByLOGRECNO(conn); var variablesDT = DataClient.GetMagicTable(conn, DbClient, string.Format("select * from \"{0}\" ", tableName)); if ((variablesDT == null) || (variablesDT.Rows.Count == 0)) { _log.Warn("Nothing to export, data table is empty"); _log.Error("Nothing to export, data table is empty"); return null; } bool shouldReproject = (!string.IsNullOrEmpty(this.OutputProjectionFilename)); ICoordinateTransformation reprojector = null; ICoordinateSystem destCRS = null; if (!string.IsNullOrEmpty(this.OutputProjectionFilename)) { destCRS = Utilities.GetCoordinateSystemByWKTFile(this.OutputProjectionFilename); reprojector = Utilities.BuildTransformationObject(GeographicCoordinateSystem.WGS84, destCRS); } //TODO: bool shouldAddMissingShapes = this.IncludeEmptyGridCells; HashSet<string> allShapeIDs = new HashSet<string>(shapeDict.Keys); //Build hashset, remove by shapeid as shapes are added, //go through and add missing shapes if 'shouldAddMissingShapes' is set... bool variablesHaveGeoID = variablesDT.Columns.Contains("GEOID"); List<IGeometry> filteringGeoms = null; if (!string.IsNullOrEmpty(this.ExportFilterFilename)) { filteringGeoms = (spatialFilter) ? GetFilteringGeometries(this.ExportFilterFilename, destCRS) : null; //Die if we're supposed to have a filter but don't if (spatialFilter && filteringGeoms == null) { return null; } } GisSharpBlog.NetTopologySuite.IO.WKBReader binReader = new WKBReader( ShapefileHelper.GetGeomFactory()); var features = new List<Feature>(variablesDT.Rows.Count); foreach (DataRow row in variablesDT.Rows) { var id = row["LOGRECNO"] as string; if (!shapeDict.ContainsKey(id)) continue; allShapeIDs.Remove(id); AttributesTable t = new AttributesTable(); foreach (DataColumn col in variablesDT.Columns) { //produces more sane results. t.AddAttribute( Utilities.EnsureMaxLength(col.ColumnName, 10), Utilities.GetAsType(col.DataType, row[col.Ordinal], null) ); } byte[] geomBytes = (byte[])shapeDict[id]["Geometry"]; IGeometry geom = binReader.Read(geomBytes); if (geom == null) { _log.WarnFormat("Geometry for LRN {0} was empty!", id); continue; } if (shouldReproject) { geom = Utilities.ReprojectGeometry(geom, reprojector); } if (spatialFilter) { if (!IsIncluded(geom, filteringGeoms)) { continue; } } if (!variablesHaveGeoID) { t.AddAttribute("GEOID", shapeDict[id]["GEOID"]); } if (this.AddStrippedGEOIDcolumn) { t.AddAttribute("GEOID_STRP", (t["GEOID"] as string).Replace(Settings.GeoidPrefix, "")); } if (this.AddGeometryAttributesToOutput) { t.AddAttribute("AREA", geom.Area); t.AddAttribute("PERIMETER", geom.Length); var centroid = geom.Centroid; t.AddAttribute("CENTROID_X", centroid.X); t.AddAttribute("CENTROID_Y", centroid.Y); } features.Add(new Feature(geom, t)); } if (shouldAddMissingShapes) { _log.DebugFormat("Adding {0} missing shapes", allShapeIDs.Count); foreach (string id in allShapeIDs) { byte[] geomBytes = (byte[])shapeDict[id]["Geometry"]; IGeometry geom = binReader.Read(geomBytes); if (geom == null) { _log.WarnFormat("Geometry for LRN {0} was empty!", id); continue; } if (shouldReproject) { geom = Utilities.ReprojectGeometry(geom, reprojector); } if (spatialFilter) { if (!IsIncluded(geom, filteringGeoms)) { continue; } } AttributesTable t = new AttributesTable(); foreach (DataColumn col in variablesDT.Columns) { //produces more sane results. t.AddAttribute(Utilities.EnsureMaxLength(col.ColumnName, 10), null); } if (!variablesHaveGeoID) { t.AddAttribute("GEOID", shapeDict[id]["GEOID"]); } if (this.AddStrippedGEOIDcolumn) { t.AddAttribute("GEOID_STRP", (t["GEOID"] as string).Replace(Settings.GeoidPrefix, "")); } if (this.AddGeometryAttributesToOutput) { t.AddAttribute("AREA", geom.Area); t.AddAttribute("PERIMETER", geom.Length); var centroid = geom.Centroid; t.AddAttribute("CENTROID_X", centroid.X); t.AddAttribute("CENTROID_Y", centroid.Y); } t["LOGRECNO"] = id; features.Add(new Feature(geom, t)); } } return features; } }
public List<IGeometry> GetFilteringGeometries(string filename, ICoordinateSystem outputCrs) { if ((string.IsNullOrEmpty(filename)) || (!File.Exists(filename))) { _log.ErrorFormat("GetFilteringGeometries failed, shapefile is empty or does not exist {0} ", filename); return null; } //inputCrs should be valid if LoadShapefile returns true ICoordinateSystem inputCrs; if (!ShapefileHelper.LoadShapefile(filename, Path.GetFileNameWithoutExtension(filename), DbClient, out inputCrs)) { _log.Error("Could not load filtering geometries!"); return null; } string tableName = Path.GetFileNameWithoutExtension(filename); string sqlcmd = string.Format("SELECT AsBinary(Geometry) AS Geometry FROM \"{0}\" ", tableName); var wholeShapeTable = DataClient.GetMagicTable(DbClient.GetConnection(), DbClient, sqlcmd); List<IGeometry> results = new List<IGeometry>(wholeShapeTable.Rows.Count); ICoordinateTransformation reprojector = null; if (outputCrs != null) { reprojector = Utilities.BuildTransformationObject(inputCrs, outputCrs); } GisSharpBlog.NetTopologySuite.IO.WKBReader binReader = new WKBReader( new GeometryFactory()); foreach (DataRow row in wholeShapeTable.Rows) { byte[] geomBytes = (byte[])row["Geometry"]; IGeometry geom = binReader.Read(geomBytes); if (geom == null || geom.Dimension != Dimensions.Surface) { continue; } if (reprojector != null) { geom = Utilities.ReprojectGeometry(geom, reprojector); } results.Add(geom); } //Cleanup so we don't store lots of crap in database sqlcmd = string.Format("DROP TABLE \"{0}\" ", tableName); var droptable = DbClient.GetCommand(sqlcmd); droptable.ExecuteNonQuery(); if (results.Count == 0) { _log.Error("Could not use shapefile to create filter because no two dimensional geometries were found"); return null; } return results; }
public void TestMaximimPrecisionDigitsFormatting() { IGeometryFactory factory = GeometryFactory.Default; WKBReader wkbreader = new WKBReader(factory); IGeometry wkb1 = wkbreader.Read(test00_Geom0_WkbByteArray); Assert.IsNotNull(wkb1); Assert.IsTrue(wkb1.IsValid); IGeometry wkb2 = wkbreader.Read(test00_Geom1_WkbByteArray); Assert.IsNotNull(wkb2); Assert.IsTrue(wkb2.IsValid); Exception ex = TryOverlay(wkb1, wkb2); Assert.IsNotNull(ex); Assert.IsTrue(ex.GetType() == typeof(TopologyException)); string tos1 = writer.Write(wkb1); Assert.IsNotNull(tos1); string tos2 = writer.Write(wkb2); Assert.IsNotNull(tos2); WKTReader reader = new WKTReader(factory); IGeometry wkt1 = reader.Read(tos1); Assert.IsNotNull(wkt1); Assert.IsTrue(wkt1.IsValid); IGeometry wkt2 = reader.Read(tos2); Assert.IsNotNull(wkt2); Assert.IsTrue(wkt2.IsValid); Assert.IsTrue(wkb1.EqualsExact(wkt1), "First geometry pair must be equal!"); Assert.IsTrue(wkb2.EqualsExact(wkt2), "Second geometry pair must be equal!"); ex = TryOverlay(wkt1, wkt2); Assert.IsNotNull(ex, "Operation must fail!"); Assert.IsTrue(ex.GetType() == typeof(TopologyException)); }
public void BuildShapefilesFromGraphBinary() { int index = 0; IGeometry edges; WKBReader reader = new WKBReader(factory); using (FileStream stream = new FileStream("graph", FileMode.Open, FileAccess.Read, FileShare.Read)) { edges = reader.Read(stream); index++; } Assert.AreEqual(1, index); Assert.IsNotNull(edges); Assert.IsInstanceOfType(typeof(MultiLineString), edges); Assert.AreEqual(1179, edges.NumGeometries); string field1 = "OBJECTID"; string field2 = "DESCRIPTION"; IList features = new List<Feature>(edges.NumGeometries); for (int i = 0; i < edges.NumGeometries; i++) { IGeometry ls = edges.GetGeometryN(i); Assert.IsInstanceOfType(typeof(LineString), ls); Feature f = new Feature(ls, new AttributesTable()); f.Attributes.AddAttribute(field1, i); f.Attributes.AddAttribute(field2, String.Format("length: {0}", Convert.ToInt64(ls.Length))); features.Add(f); } Assert.IsNotEmpty(features); Assert.AreEqual(edges.NumGeometries, features.Count); DbaseFileHeader header = new DbaseFileHeader(); header.NumRecords = edges.NumGeometries; header.NumFields = 1; header.AddColumn(field1, 'N', 5, 0); header.AddColumn(field2, 'C', 254, 0); string path = "graph"; if (File.Exists(path + shp)) File.Delete(path + shp); Assert.IsFalse(File.Exists(path + shp)); if (File.Exists(path + shx)) File.Delete(path + shx); Assert.IsFalse(File.Exists(path + shx)); if (File.Exists(path + dbf)) File.Delete(path + dbf); Assert.IsFalse(File.Exists(path + dbf)); ShapefileDataWriter writer = new ShapefileDataWriter(path, factory); writer.Header = header; writer.Write(features); Assert.IsTrue(File.Exists(path + shp)); Assert.IsTrue(File.Exists(path + shx)); Assert.IsTrue(File.Exists(path + dbf)); IList subset = new List<Feature>(15); for (int i = 0; i < 15; i++) subset.Add(features[i]); Assert.IsNotEmpty(subset); Assert.AreEqual(15, subset.Count); path = "minimalgraph"; if (File.Exists(path + shp)) File.Delete(path + shp); Assert.IsFalse(File.Exists(path + shp)); if (File.Exists(path + shx)) File.Delete(path + shx); Assert.IsFalse(File.Exists(path + shx)); if (File.Exists(path + dbf)) File.Delete(path + dbf); Assert.IsFalse(File.Exists(path + dbf)); writer = new ShapefileDataWriter(path, factory); writer.Header = header; writer.Write(subset); Assert.IsTrue(File.Exists(path + shp)); Assert.IsTrue(File.Exists(path + shx)); Assert.IsTrue(File.Exists(path + dbf)); }
private void dataAddedWorker_DoWork(object sender, DoWorkEventArgs args) { var worker = sender as BackgroundWorker; //going to modify the list so can't use a foreach. while (true) { if (layerDataToProcess.Count == 0) { break; } VectorLayerData vectorLayerData = layerDataToProcess[0]; if (worker != null && worker.CancellationPending) { args.Cancel = true; break; } StyleSpecification style = Styles[cDefaultStyleID]; string styleID = (!string.IsNullOrEmpty(vectorLayerData.Style)) ? vectorLayerData.Style : LayerDefinition.LayerStyleName; if (Styles.ContainsKey(styleID)) { style = Styles[styleID]; } var wkbReader = new WKBReader(new GeometryFactory(new PrecisionModel(), 4326)); try { IGeometry geo = wkbReader.Read(vectorLayerData.Geo); VectorLayerData data = vectorLayerData; Dispatcher.BeginInvoke(delegate { var infogeo = new InfoGeometry(geo, style, MapInstance, this) { Label = data.Label, LabelVisibility = (LayerDefinition.LabelOn) ? Visibility.Visible : Visibility.Collapsed, ItemID = data.ID, EnableBalloon = EnableBalloon, EnableSelection = EnableSelection, TimeStamp = data.TimeStamp, }; infogeo.Balloon += (o, e) => { if ( ((InfoGeometry)o).BalloonData.Count == 0) { Commands.LoadBalloonDataCommand.Execute(e, o); } }; infogeo.Selected += (o, e) => Commands.ItemSelectedCommand.Execute(o); if (LayerDefinition.PermissionToEdit) { infogeo.Selected += (o, e) => Commands.EditVectorCommand.Execute(o); } mapLayerGeometries.Add(infogeo); }); } catch (Exception e) { Debug.WriteLine(e.Message); } layerDataToProcess.Remove(vectorLayerData); } }