Exemple #1
0
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="file">The stream to read.</param>
        /// <param name="geometryFactory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory)
        {
            int shapeTypeNum             = file.ReadInt32();
            ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString());

            if (!(shapeType == ShapeGeometryTypes.LineString || shapeType == ShapeGeometryTypes.LineStringM ||
                  shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM))
            {
                throw new ShapefileException("Attempting to load a non-arc as arc.");
            }

            //read and for now ignore bounds.
            double[] box = new double[4];
            for (int i = 0; i < 4; i++)
            {
                double d = file.ReadDouble();
                box[i] = d;
            }

            int numParts  = file.ReadInt32();
            int numPoints = file.ReadInt32();

            int[] partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = file.ReadInt32();
            }

            ILineString[] lines = new LineString[numParts];
            int           start, finish, length;

            for (int part = 0; part < numParts; part++)
            {
                start = partOffsets[part];
                if (part == numParts - 1)
                {
                    finish = numPoints;
                }
                else
                {
                    finish = partOffsets[part + 1];
                }
                length = finish - start;
                CoordinateList points = new CoordinateList();
                points.Capacity = length;
                Coordinate external;
                for (int i = 0; i < length; i++)
                {
                    external = new Coordinate(file.ReadDouble(), file.ReadDouble());
                    // points.Add(geometryFactory.PrecisionModel.ToInternal(external));
                    new PrecisionModel(geometryFactory.PrecisionModel).MakePrecise(external);
                    points.Add(external);
                }
                lines[part] = geometryFactory.CreateLineString((ICoordinate[])points.ToArray(typeof(ICoordinate)));
            }
            return(geometryFactory.CreateMultiLineString(lines));
        }
Exemple #2
0
        /// <summary>
        /// Initializes a new instance of the ShapefileHeader class with values read in from the stream.
        /// </summary>
        /// <remarks>Reads the header information from the stream.</remarks>
        /// <param name="shpBinaryReader">BigEndianBinaryReader stream to the shapefile.</param>
        public ShapefileHeader(BigEndianBinaryReader shpBinaryReader)
        {
            if (shpBinaryReader == null)
            {
                throw new ArgumentNullException("shpBinaryReader");
            }

            _fileCode = shpBinaryReader.ReadInt32BE();
            if (_fileCode != Shapefile.ShapefileId)
            {
                throw new ShapefileException("The first four bytes of this file indicate this is not a shape file.");
            }

            // skip 5 unsed bytes
            shpBinaryReader.ReadInt32BE();
            shpBinaryReader.ReadInt32BE();
            shpBinaryReader.ReadInt32BE();
            shpBinaryReader.ReadInt32BE();
            shpBinaryReader.ReadInt32BE();

            _fileLength = shpBinaryReader.ReadInt32BE();

            _version = shpBinaryReader.ReadInt32();
            Debug.Assert(_version == 1000, "Shapefile version", String.Format("Expecting only one version (1000), but got {0}", _version));
            int shapeType = shpBinaryReader.ReadInt32();

            _shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeType.ToString());

            //read in and store the bounding box
            double[] coords = new double[4];
            for (int i = 0; i < 4; i++)
            {
                coords[i] = shpBinaryReader.ReadDouble();
            }
            _bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]);

            // skip z and m bounding boxes.
            for (int i = 0; i < 4; i++)
            {
                shpBinaryReader.ReadDouble();
            }
        }
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="file">The stream to read.</param>
        /// <param name="geometryFactory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory)
        {
            int shapeTypeNum             = file.ReadInt32();
            ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString());

            if (!(shapeType == ShapeGeometryTypes.Point || shapeType == ShapeGeometryTypes.PointM ||
                  shapeType == ShapeGeometryTypes.PointZ || shapeType == ShapeGeometryTypes.PointZM))
            {
                throw new ShapefileException("Attempting to load a point as point.");
            }
            double     x        = file.ReadDouble();
            double     y        = file.ReadDouble();
            Coordinate external = new Coordinate(x, y);

            // return geometryFactory.CreatePoint(geometryFactory.PrecisionModel.ToInternal(external));
            new PrecisionModel(geometryFactory.PrecisionModel).MakePrecise(external);
            return(geometryFactory.CreatePoint(external));
        }
Exemple #4
0
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="file">The stream to read.</param>
        /// <param name="geometryFactory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory)
        {
            int shapeTypeNum             = file.ReadInt32();
            ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString());

            if (!(shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM ||
                  shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM))
            {
                throw new ShapefileException("Attempting to load a non-polygon as polygon.");
            }

            // Read and for now ignore bounds.
            double[] box = new double[4];
            for (int i = 0; i < 4; i++)
            {
                box[i] = file.ReadDouble();
            }

            int[] partOffsets;
            int   numParts  = file.ReadInt32();
            int   numPoints = file.ReadInt32();

            partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = file.ReadInt32();
            }

            ArrayList shells = new ArrayList();
            ArrayList holes  = new ArrayList();

            int start, finish, length;

            for (int part = 0; part < numParts; part++)
            {
                start = partOffsets[part];
                if (part == numParts - 1)
                {
                    finish = numPoints;
                }
                else
                {
                    finish = partOffsets[part + 1];
                }
                length = finish - start;
                CoordinateList points = new CoordinateList();
                points.Capacity = length;
                for (int i = 0; i < length; i++)
                {
                    Coordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble());
                    new PrecisionModel(geometryFactory.PrecisionModel).MakePrecise(external);
                    Coordinate internalCoord = external;
                    points.Add(internalCoord);
                }

                ILinearRing ring = geometryFactory.CreateLinearRing((Coordinate[])points.ToArray(typeof(Coordinate)));

                // If shape have only a part, jump orientation check and add to shells
                if (numParts == 1)
                {
                    shells.Add(ring);
                }
                else
                {
                    // Orientation check
                    if (CGAlgorithms.IsCCW((Coordinate[])points.ToArray(typeof(Coordinate))))
                    {
                        holes.Add(ring);
                    }
                    else
                    {
                        shells.Add(ring);
                    }
                }
            }

            // Now we have a list of all shells and all holes
            ArrayList holesForShells = new ArrayList(shells.Count);

            for (int i = 0; i < shells.Count; i++)
            {
                holesForShells.Add(new ArrayList());
            }
            // Find holes
            for (int i = 0; i < holes.Count; i++)
            {
                LinearRing  testRing = (LinearRing)holes[i];
                LinearRing  minShell = null;
                IEnvelope   minEnv   = null;
                IEnvelope   testEnv  = testRing.EnvelopeInternal;
                ICoordinate testPt   = testRing.GetCoordinateN(0);
                LinearRing  tryRing;
                for (int j = 0; j < shells.Count; j++)
                {
                    tryRing = (LinearRing)shells[j];
                    IEnvelope tryEnv = tryRing.EnvelopeInternal;
                    if (minShell != null)
                    {
                        minEnv = minShell.EnvelopeInternal;
                    }
                    bool           isContained = false;
                    CoordinateList coordList   = new CoordinateList(tryRing.Coordinates);
                    if (tryEnv.Contains(testEnv) &&
                        (CGAlgorithms.IsPointInRing(testPt, (Coordinate[])coordList.ToArray(typeof(Coordinate))) ||
                         (PointInList(testPt, coordList))))
                    {
                        isContained = true;
                    }

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (isContained)
                    {
                        if (minShell == null || minEnv.Contains(tryEnv))
                        {
                            minShell = tryRing;
                        }

                        // Suggested by Brian Macomber and added 3/28/2006:
                        // holes were being found but never added to the holesForShells array
                        // so when converted to geometry by the factory, the inner rings were never created.
                        ArrayList holesForThisShell = (ArrayList)holesForShells[j];
                        holesForThisShell.Add(holes[i]);
                    }
                }
            }

            IPolygon[] polygons = new Polygon[shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = geometryFactory.CreatePolygon((LinearRing)shells[i],
                                                            (LinearRing[])((ArrayList)holesForShells[i]).ToArray(typeof(LinearRing)));
            }

            if (polygons.Length == 1)
            {
                return(polygons[0]);
            }
            // It's a multi part
            return(geometryFactory.CreateMultiPolygon(polygons));
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="beReader"></param>
 private void ReadFeatureHeader(BigEndianBinaryReader beReader)
 {
     int recordNumber  = beReader.ReadInt32BE();
     int contentLength = beReader.ReadInt32BE();
     int shapeType     = beReader.ReadInt32();
 }