/// <summary> /// Creates a new instance of a MultiPointShapefile for in-ram handling only. /// </summary> public MultiPointShapefile():base(FeatureTypes.MultiPoint) { _geometryFactory = new GeometryFactory(); Attributes = new AttributeTable(); Header = new ShapefileHeader(); Header.FileLength = 100; Header.ShapeType = ShapeTypes.MultiPoint; }
/// <summary> /// Initialize reader with the given <c>GeometryFactory</c>. /// </summary> /// <param name="factory"></param> public WKBReader(GeometryFactory factory) { this.factory = factory; }
/// <summary> /// Imports a shapefile into a dababase Table. /// </summary> /// <remarks> /// This method assumes a Table has already been created in the database. /// Calling this method does not close the connection that is passed in. /// </remarks> /// <param name="filename"></param> /// <param name="connectionstring"></param> /// <param name="tableName"></param> /// <returns></returns> public static int ImportShapefile(string filename, string connectionstring, string tableName) { using (SqlConnection connection = new SqlConnection(connectionstring)) { int rowsAdded = -1; PrecisionModel pm = new PrecisionModel(); GeometryFactory geometryFactory = new GeometryFactory(pm, -1); DataTable shpDataTable = Shapefile.CreateDataTable(filename, tableName, geometryFactory); string createTableSql = CreateDbTable(shpDataTable, true); SqlCommand createTableCommand = new SqlCommand(createTableSql, connection); connection.Open(); createTableCommand.ExecuteNonQuery(); string sqlSelect = String.Format("select * from {0}", tableName); SqlDataAdapter selectCommand = new SqlDataAdapter(sqlSelect, connection); // use a data adaptor - saves donig the inserts ourselves SqlDataAdapter dataAdapter = new SqlDataAdapter(); dataAdapter.SelectCommand = new SqlCommand(sqlSelect, connection); SqlCommandBuilder custCB = new SqlCommandBuilder(dataAdapter); DataSet ds = new DataSet(); // fill dataset dataAdapter.Fill(ds, shpDataTable.TableName); // copy rows from our datatable to the empty Table in the DataSet int i = 0; foreach (DataRow row in shpDataTable.Rows) { DataRow newRow = ds.Tables[0].NewRow(); newRow.ItemArray = row.ItemArray; //gotcha! - new row still needs to be added to the Table. //NewRow() just creates a new row with the same schema as the Table. It does //not add it to the Table. ds.Tables[0].Rows.Add(newRow); i++; } // update all the rows in batch rowsAdded = dataAdapter.Update(ds, shpDataTable.TableName); int iRows = shpDataTable.Rows.Count; Debug.Assert(rowsAdded != iRows, String.Format("{0} of {1} rows were added to the database.", rowsAdded, shpDataTable.Rows.Count)); return rowsAdded; } }
/// <summary> /// Creates a DataTable representing the information in a shape file. /// </summary> /// <param name="filename">The filename (minus the . and extension) to read.</param> /// <param name="tableName">The name to give to the Table.</param> /// <param name="geometryFactory">The geometry factory to use when creating the objects.</param> /// <returns>DataTable representing the data </returns> public static DataTable CreateDataTable(string filename, string tableName, GeometryFactory geometryFactory) { if (filename == null) throw new ArgumentNullException("filename"); if (tableName == null) throw new ArgumentNullException("tableName"); if (geometryFactory == null) throw new ArgumentNullException("geometryFactory"); ShapefileReader shpfileDataReader= new ShapefileReader(filename, geometryFactory); DataTable table = new DataTable(tableName); // use ICustomTypeDescriptor to get the properies/ fields. This way we can get the // length of the dbase char fields. Because the dbase char field is translated into a string // property, we lost the length of the field. We need to know the length of the // field when creating the Table in the database. IEnumerator enumerator = shpfileDataReader.GetEnumerator(); bool moreRecords = enumerator.MoveNext(); ICustomTypeDescriptor typeDescriptor = (ICustomTypeDescriptor)enumerator.Current; foreach(PropertyDescriptor property in typeDescriptor.GetProperties()) { ColumnStructure column = (ColumnStructure)property; Type fieldType = column.PropertyType; DataColumn datacolumn = new DataColumn(column.Name, fieldType); if (fieldType== typeof(string)) // use MaxLength to pass the length of the field in the dbase file datacolumn.MaxLength=column.Length; table.Columns.Add( datacolumn ); } // add the rows - need a do-while loop because we read one row in order to determine the fields int iRecordCount=0; object[] values = new object[shpfileDataReader.FieldCount]; do { iRecordCount++; shpfileDataReader.GetValues(values); table.Rows.Add(values); moreRecords = enumerator.MoveNext(); } while (moreRecords); return table; }
/// <summary> /// Returns an ShapefileDataReader representing the data in a shapefile. /// </summary> /// <param name="filename">The filename (minus the . and extension) to read.</param> /// <param name="geometryFactory">The geometry factory to use when creating the objects.</param> /// <returns>An ShapefileDataReader representing the data in the shape file.</returns> public static ShapefileReader CreateDataReader(string filename, GeometryFactory geometryFactory) { if (filename == null) throw new ArgumentNullException("filename"); if (geometryFactory == null) throw new ArgumentNullException("geometryFactory"); ShapefileReader shpDataReader= new ShapefileReader(filename,geometryFactory); return shpDataReader; }
/// <summary> /// Creates a sort of default geometry object from the default geometry factory, or creates /// a new one if one doesn't exist yet. /// </summary> protected Geometry() { if (DefaultFactory == null) { DefaultFactory = new GeometryFactory(new PrecisionModel(PrecisionModels.Floating)); } _factory = DefaultFactory; _srid = _factory.SRID; }
/// <summary> /// /// </summary> /// <param name="geom"></param> /// <returns></returns> public virtual IGeometry Reduce(IGeometry geom) { GeometryEditor geomEdit; if (_changePrecisionModel) { // GeometryFactory newFactory = new GeometryFactory(_newPrecisionModel, geom.SRID); GeometryFactory newFactory = new GeometryFactory(_newPrecisionModel); geomEdit = new GeometryEditor(newFactory); } else // don't change point factory geomEdit = new GeometryEditor(); return geomEdit.Edit(geom, new PrecisionReducerCoordinateOperation(this)); }
/// <summary> /// Initializes a new instance of the <see cref="T:ShapefileDataWriter"/> class. /// </summary> /// <param name="fileName">File path without any extension</param> /// <param name="geometryFactory"></param> public ShapefileWriter(string fileName, GeometryFactory geometryFactory) { this.geometryFactory = geometryFactory; // Files shpFile = fileName; dbfFile = fileName + ".dbf"; // Writers shapeWriter = new ShapeWriter(geometryFactory); dbaseWriter = new dBaseWriter(dbfFile); }
/// <summary> /// Writes a Geometry to the given binary wirter. /// </summary> /// <param name="geometry">The geometry to write.</param> /// <param name="file">The file stream to write to.</param> /// <param name="geometryFactory">The geometry factory to use.</param> public override void Write(IBasicGeometry geometry, System.IO.BinaryWriter file, IGeometryFactory geometryFactory) { // Diego Guidi say's: his check seems to be not useful and slow the operations... // if (!geometry.IsValid) // Trace.WriteLine("Invalid polygon being written."); IGeometryCollection multi; if (geometry is IGeometryCollection || geometry is IMultiLineString || geometry is IMultiPoint || geometry is IMultiPolygon) multi = (IGeometryCollection)geometry; else { IGeometryFactory gf; if (geometry is IGeometry) { gf = new GeometryFactory(new PrecisionModel(((IGeometry)geometry).PrecisionModel)); } else { gf = new GeometryFactory(); } multi = gf.CreateMultiPolygon( new[]{(Polygon) geometry} ); } file.Write(int.Parse(Enum.Format(typeof(ShapeGeometryTypes), ShapeType, "d"))); IEnvelope box = multi.EnvelopeInternal; IEnvelope bounds = GetEnvelopeExternal(new PrecisionModel(geometryFactory.PrecisionModel), box); file.Write(bounds.Minimum.X); file.Write(bounds.Minimum.Y); file.Write(bounds.Maximum.X); file.Write(bounds.Maximum.Y); int numParts = GetNumParts(multi); int numPoints = multi.NumPoints; file.Write(numParts); file.Write(numPoints); // write the offsets to the points int offset=0; for (int part = 0; part < multi.NumGeometries; part++) { // offset to the shell points Polygon polygon = (Polygon)multi.Geometries[part]; file.Write(offset); offset = offset + polygon.ExteriorRing.NumPoints; // offstes to the holes foreach (LinearRing ring in polygon.Holes) { file.Write(offset); offset = offset + ring.NumPoints; } } // write the points for (int part = 0; part < multi.NumGeometries; part++) { Polygon poly = (Polygon)multi.Geometries[part]; WriteCoords(poly.Shell.Coordinates, file); foreach(ILinearRing ring in poly.Holes) { WriteCoords(ring.Coordinates, file); } } }
/// <summary> /// Initializes a new instance of the ShapefileDataReader class. /// </summary> /// <param name="filename">The shapefile to read (minus the .shp extension)</param> ///<param name="geometryFactory">The GeometryFactory to use.</param> public ShapefileReader(string filename, GeometryFactory geometryFactory) { if (filename == null) throw new ArgumentNullException("filename"); if (geometryFactory == null) throw new ArgumentNullException("geometryFactory"); _geometryFactory = geometryFactory; _open = true; if (filename.ToLower().EndsWith(".shp")) filename = filename.ToLower().Replace(".shp",String.Empty); _dbfReader = new dBaseReader(filename + ".dbf"); _shpReader = new ShapeReader(filename + ".shp", geometryFactory); _dbfHeader = _dbfReader.GetHeader(); _recordCount = _dbfHeader.NumRecords; // copy dbase fields to our own array. Insert into the first position, the shape column _dbaseFields = new FieldDescriptor[_dbfHeader.Fields.Length + 1]; _dbaseFields[0] = FieldDescriptor.ShapeField(); for(int i=0; i < _dbfHeader.Fields.Length; i++) _dbaseFields[i+1] = _dbfHeader.Fields[i]; _ShapeHeader = _shpReader.Header; _dbfEnumerator = _dbfReader.GetEnumerator(); _shpEnumerator = _shpReader.GetEnumerator(); _moreRecords = true; }
/// <summary> /// Initializes a new instance of the Shapefile class with the given parameters. /// </summary> /// <param name="filename">The filename of the shape file to read (with .shp).</param> /// <param name="geometryFactory">The GeometryFactory to use when creating Geometry objects.</param> public ShapeReader(string filename, GeometryFactory geometryFactory) { if (filename == null) throw new ArgumentNullException("filename"); if (geometryFactory == null) throw new ArgumentNullException("geometryFactory"); _filename = filename; _geometryFactory = geometryFactory; // read header information. note, we open the file, read the header information and then // close the file. This means the file is not opened again until GetEnumerator() is requested. // For each call to GetEnumerator() a new BinaryReader is created. FileStream stream = new FileStream(filename, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read); BigEndianBinaryReader shpBinaryReader = new BigEndianBinaryReader(stream); _mainHeader = new ShapefileHeader(shpBinaryReader); shpBinaryReader.Close(); }