private void TestShapeCreation() { ICoordinate[] points = new ICoordinate[3]; points[0] = new Coordinate(0, 0); points[1] = new Coordinate(1, 0); points[2] = new Coordinate(1, 1); LineString line_string = new LineString(points); AttributesTable attributes = new AttributesTable(); attributes.AddAttribute("FOO", "FOO"); Feature feature = new Feature(Factory.CreateMultiLineString(new ILineString[] { line_string }), attributes); Feature[] features = new Feature[1]; features[0] = feature; ShapefileDataWriter shp_writer = new ShapefileDataWriter("C:\\line_string"); shp_writer.Header = ShapefileDataWriter.GetHeader(features[0], features.Length); shp_writer.Write(features); }
public static IAttributesTable ReadAttributesTable(JsonTextReader jreader) { if (jreader == null) throw new ArgumentNullException("jreader", "A valid JSON reader object is required."); IAttributesTable attributes = null; if (jreader.MoveToContent() && jreader.TokenClass == JsonTokenClass.Object) { attributes = new AttributesTable(); jreader.ReadToken(JsonTokenClass.Object); while (jreader.TokenClass == JsonTokenClass.Member) { string key = jreader.ReadMember(); string value = jreader.ReadString(); if (!attributes.Exists(key)) attributes.AddAttribute(key, null); attributes[key] = value; } jreader.ReadToken(JsonTokenClass.EndObject); } return attributes; }
/// <summary> /// Builds from the given provider. /// </summary> /// <param name="provider"> /// The base <see cref="SharpMap.Data.Providers.IProvider"/> /// from witch initialize the <see cref="NtsProvider"/> instance. /// </param> private void BuildFromProvider(IProvider provider) { // Features list initialization features = new List<Feature>(provider.GetFeatureCount()); try { // Load all features from the given provider provider.Open(); Collection<uint> ids = provider.GetObjectIDsInView(provider.GetExtents()); foreach (uint id in ids) { FeatureDataRow dataRow = provider.GetFeature(id); GisSharpBlog.NetTopologySuite.Geometries.Geometry geometry = GeometryConverter.ToNTSGeometry(dataRow.Geometry, geometryFactory); AttributesTable attributes = new AttributesTable(); foreach (DataColumn column in dataRow.Table.Columns) { if (dataRow[column] == null || dataRow[column].GetType() == typeof (DBNull)) throw new ApplicationException("Null values not supported"); attributes.AddAttribute(column.ColumnName, dataRow[column]); } features.Add(new Feature(geometry, attributes)); } } finally { if (provider.IsOpen) provider.Close(); } }
/// <summary> /// Retrieves the contents of the specified table, and writes them to a shapefile /// </summary> /// <param name="tableName"></param> /// <returns></returns> public bool ExportGriddedShapefile(string tableName) { try { _log.DebugFormat("Retrieving contents of job {0}", tableName); //don't filter out geometries, we'll do that at the cell level var exportFeatures = GetShapeFeaturesToExport(tableName, false); if ((exportFeatures == null) || (exportFeatures.Count == 0)) { _log.ErrorFormat("Export of Job \"{0}\" failed, no features to export!", tableName); return false; } ICoordinateSystem outputCrs = GeographicCoordinateSystem.WGS84; if (!string.IsNullOrEmpty(this.OutputProjectionFilename)) { outputCrs = Utilities.GetCoordinateSystemByWKTFile(this.OutputProjectionFilename); } //if we need to reproject: List<IGeometry> filteringGeoms = GetFilteringGeometries(this.ExportFilterFilename, outputCrs); //put everything into a basic spatial index Envelope env = new Envelope(); var index = new GisSharpBlog.NetTopologySuite.Index.Strtree.STRtree(); for (int i = 0; i < exportFeatures.Count; i++) { Feature f = exportFeatures[i]; index.Insert(f.Geometry.EnvelopeInternal, f); env.ExpandToInclude(f.Geometry.EnvelopeInternal); } if (IsCancelled()) { _log.Debug("Job Cancelled..."); return false; } index.Build(); //adjust envelope to only scan area inside filtering geometries if (!string.IsNullOrEmpty(this.GridEnvelopeFilename)) { //a specified envelope file overrides the envelope of the filtering geometries env = GetGridEnvelope(); } else if ((filteringGeoms != null) && (filteringGeoms.Count > 0)) { //in the absence ... //TODO: finish-- env = new Envelope(); for (int i = 0; i < filteringGeoms.Count; i++) { env.ExpandToInclude(filteringGeoms[i].EnvelopeInternal); } } //progress tracking DateTime start = DateTime.Now, lastCheck = DateTime.Now; int lastProgress = 0; var features = new List<Feature>(exportFeatures.Count); double cellWidth = GridCellWidth; double cellHeight = GridCellHeight; bool discardEmptyGridCells = !IncludeEmptyGridCells; int numRows = (int)Math.Ceiling(env.Height / cellHeight); int numCols = (int)Math.Ceiling(env.Width / cellWidth); int expectedCells = numRows * numCols; if (expectedCells > 1000000) { _log.Warn("**********************"); _log.Warn("Your selected area will produce a shapefile with over a million cells, is that a good idea?"); _log.WarnFormat("Area of {0}, Expected Cell Count of {1}", env.Area, expectedCells); _log.Warn("**********************"); } DbaseFileHeader header = null; using (var conn = DbClient.GetConnection()) { //Dictionary<string, DataRow> shapeDict = GetShapeRowsByLOGRECNO(conn); var variablesDT = DataClient.GetMagicTable(conn, DbClient, string.Format("SELECT * FROM \"{0}\" where 0 = 1 ", tableName)); header = ShapefileHelper.SetupHeader(variablesDT); } ShapefileHelper.AddColumn(header, "CELLID", typeof(string)); ShapefileHelper.AddColumn(header, "GEOID", typeof(string)); if (this.AddStrippedGEOIDcolumn) { ShapefileHelper.AddColumn(header, "GEOID_STRP", typeof(string)); } //lets not add these to the fishnet exports just yet //if (this.AddGeometryAttributesToOutput) //{ // ShapefileHelper.AddColumn(header, "AREA", typeof(double)); // ShapefileHelper.AddColumn(header, "PERIMETER", typeof(double)); // ShapefileHelper.AddColumn(header, "CENTROID", typeof(double)); //} int cellCount = 0; int xidx = 0; for (double x = env.MinX; x < env.MaxX; x += cellWidth) { xidx++; int yidx = 0; for (double y = env.MinY; y < env.MaxY; y += cellHeight) { yidx++; cellCount++; string cellID = string.Format("{0}_{1}", xidx, yidx); Envelope cellEnv = new Envelope(x, x + cellWidth, y, y + cellHeight); IGeometry cellCenter = new Point(cellEnv.Centre); IGeometry cellGeom = Utilities.IEnvToIGeometry(cellEnv); Feature found = null; IList mightMatch = index.Query(cellGeom.EnvelopeInternal); foreach (Feature f in mightMatch) { if (f.Geometry.Contains(cellCenter)) { found = f; break; } } if ((found == null) && (discardEmptyGridCells)) { //_log.DebugFormat("No feature found for cell {0}", cellID); continue; } //if we have filtering geometries, skip a cell if it isn't included if (!IsIncluded(cellGeom, filteringGeoms)) { continue; } if ((cellCount % 1000) == 0) { int step = (int)((((double)cellCount) / ((double)expectedCells)) * 100.0); TimeSpan elapsed = (DateTime.Now - lastCheck); if ((step != lastProgress) && (elapsed.TotalSeconds > 1)) { _log.DebugFormat("{0:###.##}% complete, {1:#0.0#} seconds, {2} built, {3} checked, {4} left", step, (DateTime.Now - start).TotalSeconds, features.Count, cellCount, expectedCells - cellCount ); lastCheck = DateTime.Now; lastProgress = step; if (IsCancelled()) { _log.Debug("Job Cancelled..."); return false; } } } //this is a lot of work just to add an id... AttributesTable attribs = new AttributesTable(); if (found != null) { //if (!found.Attributes.GetNames().Contains("GEOID")) // throw new Exception("GEOID NOT FOUND!!!!"); foreach (string name in found.Attributes.GetNames()) { attribs.AddAttribute(name, found.Attributes[name]); } attribs.AddAttribute("CELLID", cellID); } else { foreach (var field in header.Fields) { attribs.AddAttribute(field.Name, null); } attribs["CELLID"] = cellID; } features.Add(new Feature(cellGeom, attribs)); } } _log.Debug("Done building cells, Saving Shapefile..."); header.NumRecords = features.Count; if (features.Count == 0) { _log.Error("No features found, exiting!"); return false; } string newShapefilename = Path.Combine(Environment.CurrentDirectory, tableName); if (!string.IsNullOrEmpty(OutputFolder)) { newShapefilename = Path.Combine(OutputFolder, tableName); } if (IsCancelled()) { _log.Debug("Job Cancelled..."); return false; } var writer = new ShapefileDataWriter(newShapefilename, ShapefileHelper.GetGeomFactory()); writer.Header = header; writer.Write(features); if (!string.IsNullOrEmpty(this.OutputProjectionFilename)) { //Reproject everything in this file to the requested projection... ShapefileHelper.MakeOutputProjFile(this.OutputProjectionFilename, newShapefilename); } else { ShapefileHelper.MakeCensusProjFile(newShapefilename); } _log.Debug("Done! Shapefile exported successfully"); return true; } catch (FileNotFoundException notFound) { string msg = "A needed file couldn't be found: " + notFound.FileName; _log.Error(msg); _log.Fatal("The export cannot continue. Exiting..."); throw new ApplicationException(msg); } catch (Exception ex) { _log.Error("Error while exporting shapefile", ex); } return false; }
/// <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; } }