示例#1
0
        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);             
        }
示例#2
0
        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;
        }
示例#3
0
        /// <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;
            }
        }