/// <summary> /// Writes shapes. /// </summary> /// <param name="filename">The string value defining shape file name without .shp extension</param> /// <param name="geometryCollection"> MapAround.Geometry.GeometryCollection instance containing /// the geometries to write to shape file</param> public void WriteShapes(string filename, GeometryCollection geometryCollection) { if (geometryCollection.HasDifferentTypeInstances) { throw new ArgumentException("Geometries in the shape file should be the instances of the same type.", "geometryCollection"); } using (FileStream shpStream = new FileStream(filename + ".shp", FileMode.Create)) { using (FileStream shxStream = new FileStream(filename + ".shx", FileMode.Create)) { BigEndianBinaryWriter shpBinaryWriter = new BigEndianBinaryWriter(shpStream); //, Encoding.ASCII); BigEndianBinaryWriter shxBinaryWriter = new BigEndianBinaryWriter(shxStream); //, Encoding.ASCII); // body type and a handler Handlers.ShapeHandler handler = ShapeFile.GetShapeHandler(ShapeFile.GetShapeType(geometryCollection[0]));//.Geometries[0])); int numShapes = geometryCollection.Count; // calc the length of the shp file, so it can put in the header. int shpLength = 50; for (int i = 0; i < numShapes; i++) { IGeometry body = (IGeometry)geometryCollection[i]; //.Geometries[i]; shpLength += 4; // length of header in WORDS shpLength += handler.GetLength(body); // length of shape in WORDS } int shxLength = 50 + (4 * numShapes); // write the .shp header ShapeFileHeader shpHeader = new ShapeFileHeader(); shpHeader.FileLength = shpLength; // get envelope in external coordinates BoundingRectangle bounds = geometryCollection.GetBoundingRectangle(); shpHeader.SetBounds(bounds); shpHeader.FileCode = 9994; shpHeader.ShapeType = (int)ShapeFile.GetShapeType(geometryCollection[0]);//.Geometries[0]); shpHeader.Write(shpBinaryWriter, ShapeFile.GetShapeType(geometryCollection[0])); // write the .shx header ShapeFileHeader shxHeader = new ShapeFileHeader(); shxHeader.FileLength = shxLength; shxHeader.SetBounds(shpHeader);//.Bounds = shpHeader.Bounds; // assumes Geometry type of the first item will the same for all other items in the collection. shxHeader.FileCode = 9994; shxHeader.ShapeType = (int)ShapeFile.GetShapeType(geometryCollection[0]); shxHeader.Write(shxBinaryWriter, ShapeFile.GetShapeType(geometryCollection[0])); // write the individual records. int _pos = 50; // header length in WORDS for (int i = 0; i < numShapes; i++) { IGeometry body = geometryCollection[i];//.Geometries[i]; int recordLength = handler.GetLength(body); shpBinaryWriter.WriteIntBE(i + 1); shpBinaryWriter.WriteIntBE(recordLength); shxBinaryWriter.WriteIntBE(_pos); shxBinaryWriter.WriteIntBE(recordLength); _pos += 4; // length of header in WORDS handler.Write(body, shpBinaryWriter); //, geometryFactory); _pos += recordLength; // length of shape in WORDS } shxBinaryWriter.Flush(); shxBinaryWriter.Close(); shpBinaryWriter.Flush(); shpBinaryWriter.Close(); } } }
/// <summary> /// Reads a record from the specified stream. /// </summary> /// <param name="stream">A System.IO.Stream instance to read</param> /// <param name="recordOffset">An offset of record</param> /// <param name="bounds">An object representing a bounds of the reading area</param> public ShapeFileRecord ReadRecord(Stream stream, int?recordOffset, BoundingRectangle bounds) { #region old //if (recordOffset != null) // stream.Seek(recordOffset.Value, 0); //ShapeFileRecord record = new ShapeFileRecord(); //record.Offset = stream.Position; //// заголовок записи //record.RecordNumber = ShapeFile.ReadInt32_BE(stream); //record.ContentLength = ShapeFile.ReadInt32_BE(stream); //// тип геометрической фигуры //record.ShapeType = ShapeFile.ReadInt32_LE(stream); //bool wasRead = false; //switch (record.ShapeType) //{ // case (int)ShapeType.NullShape: // break; // case (int)ShapeType.Point: // wasRead = ShapeFile.ReadPoint(stream, bounds, record); // break; // case (int)ShapeType.PolyLine: // wasRead = ShapeFile.ReadPolygon(stream, bounds, record); // break; // case (int)ShapeType.Polygon: // wasRead = ShapeFile.ReadPolygon(stream, bounds, record); // break; // case (int)ShapeType.Multipoint: // wasRead = ShapeFile.ReadMultipoint(stream, bounds, record); // break; // default: // { // string msg = String.Format(System.Globalization.CultureInfo.InvariantCulture, "ShapeType {0} is not supported.", (int)record.ShapeType); // throw new InvalidDataException(msg); // } //} //if (wasRead) //{ // this._records.Add(record); // return record; //} //else return null; #endregion #region New if (recordOffset != null) { stream.Seek(recordOffset.Value, 0); } ShapeFileRecord record = new ShapeFileRecord(); record.Offset = stream.Position; // заголовок записи //BigEndianBinaryReader reader = new BigEndianBinaryReader(stream); //record.RecordNumber = reader.ReadInt32BE();// ShapeFile.ReadInt32_BE(stream); //record.ContentLength = reader.ReadInt32BE();// ShapeFile.ReadInt32_BE(stream); record.RecordNumber = stream.ReadInt32BE(); // ShapeFile.ReadInt32_BE(stream); record.ContentLength = stream.ReadInt32BE(); // ShapeFile.ReadInt32_BE(stream); // тип геометрической фигуры record.ShapeType = stream.ReadInt32(); //.ReadInt32BE();// ShapeFile.ReadInt32_LE(stream); ShapeHandler handler = ShapeFile.GetShapeHandler((ShapeType)record.ShapeType); if (handler.Read(stream, bounds, record)) { this._records.Add(record); return(record); } else { return(null); } #endregion }
private int internalQueryFeatures(IFeatureReceiver fr, BoundingRectangle bounds, bool checkBounds) { if (_cacheAccessor != null && !string.IsNullOrEmpty(fr.Alias)) { _cacheAccessor.Key = fr.Alias; if (_cacheAccessor.ExistsInCache) return FillFromCache(_cacheAccessor, fr, bounds, _processAttributes); else // If the object is not found in the cache, you must remove all objects from a file, to put them in the cache checkBounds = false; } ShapeFile shapeFile = new ShapeFile(); shapeFile.AttributesEncoding = _attributesEncoding; shapeFile.Read(_fileName, checkBounds ? bounds : null); if (ProcessAttributes) { fr.FeatureAttributeNames.Clear(); foreach (string s in shapeFile.AttributeNames) fr.FeatureAttributeNames.Add(s); } int result = 0; string layerHashStr = fr.GetHashCode().ToString(); List<Feature> points = new List<Feature>(); List<Feature> multiPoints = new List<Feature>(); List<Feature> polylines = new List<Feature>(); List<Feature> polygons = new List<Feature>(); foreach (ShapeFileRecord record in shapeFile.Records) { if (!checkBounds || (record.MaxX >= bounds.MinX && record.MaxY >= bounds.MinY && record.MinX <= bounds.MaxX && record.MinY <= bounds.MaxY)) { Feature newFeature = null; IGeometry geometry = geometryFromShapeRecord(record); if (geometry != null) { newFeature = new Feature(geometry); newFeature.UniqKey = layerHashStr + record.RecordNumber.ToString(); if (ProcessAttributes && record.Attributes != null) newFeature.Attributes = record.Attributes.ItemArray; if (processFeature(newFeature, fr, points, multiPoints, polylines, polygons)) result++; } } } // If the objects are not extracted from the cache may be added to the cache. // This should be done only if the retrieval of all objects (checkBounds == false) if (_cacheAccessor != null && !string.IsNullOrEmpty(fr.Alias) && checkBounds == false) { addFeaturesToCache(fr, points, multiPoints, polylines, polygons); } return result; }