예제 #1
0
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivant 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.NullShape)
            {
                return(null);
            }

            if (!(shapeType == ShapeGeometryTypes.MultiPoint || shapeType == ShapeGeometryTypes.MultiPointM ||
                  shapeType == ShapeGeometryTypes.MultiPointZ || shapeType == ShapeGeometryTypes.MultiPointZM))
            {
                throw new ShapefileException("Attempting to load a non-multipoint as multipoint.");
            }

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

            // Read points
            int numPoints = file.ReadInt32();

            IPoint[] points = new IPoint[numPoints];
            for (int i = 0; i < numPoints; i++)
            {
                points[i] = geometryFactory.CreatePoint(new Coordinate(file.ReadDouble(), file.ReadDouble()));
            }
            return(geometryFactory.CreateMultiPoint(points));
        }
예제 #2
0
        /// <summary>
        /// Returns the appropriate class to convert a shaperecord to an OGIS geometry given the type of shape.
        /// </summary>
        /// <param name="type">The shapefile type.</param>
        /// <returns>An instance of the appropriate handler to convert the shape record to a Geometry object.</returns>
        public static ShapeHandler GetShapeHandler(ShapeGeometryTypes type)
        {
            switch (type)
            {
            case ShapeGeometryTypes.Point:
            case ShapeGeometryTypes.PointM:
            case ShapeGeometryTypes.PointZ:
            case ShapeGeometryTypes.PointZM:
                return(new PointHandler());

            case ShapeGeometryTypes.Polygon:
            case ShapeGeometryTypes.PolygonM:
            case ShapeGeometryTypes.PolygonZ:
            case ShapeGeometryTypes.PolygonZM:
                return(new PolygonHandler());

            case ShapeGeometryTypes.LineString:
            case ShapeGeometryTypes.LineStringM:
            case ShapeGeometryTypes.LineStringZ:
            case ShapeGeometryTypes.LineStringZM:
                return(new MultiLineHandler());

            case ShapeGeometryTypes.MultiPoint:
            case ShapeGeometryTypes.MultiPointM:
            case ShapeGeometryTypes.MultiPointZ:
            case ShapeGeometryTypes.MultiPointZM:
                return(new MultiPointHandler());

            default:
                return(null);
            }
        }
예제 #3
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();	
		}
예제 #4
0
		/// <summary>
		/// Returns the appropriate class to convert a shaperecord to an OGIS geometry given the type of shape.
		/// </summary>
		/// <param name="type">The shapefile type.</param>
		/// <returns>An instance of the appropriate handler to convert the shape record to a Geometry object.</returns>
        public static ShapeHandler GetShapeHandler(ShapeGeometryTypes type) 
		{
			switch (type) 
			{
				case ShapeGeometryTypes.Point:
                case ShapeGeometryTypes.PointM:
                case ShapeGeometryTypes.PointZ:
                case ShapeGeometryTypes.PointZM:
					return new PointHandler();

                case ShapeGeometryTypes.Polygon:
                case ShapeGeometryTypes.PolygonM:
                case ShapeGeometryTypes.PolygonZ:
                case ShapeGeometryTypes.PolygonZM:
					return new PolygonHandler();

                case ShapeGeometryTypes.LineString:
                case ShapeGeometryTypes.LineStringM:
                case ShapeGeometryTypes.LineStringZ:
                case ShapeGeometryTypes.LineStringZM:
					return new MultiLineHandler();

                case ShapeGeometryTypes.MultiPoint:
                case ShapeGeometryTypes.MultiPointM:
                case ShapeGeometryTypes.MultiPointZ:
                case ShapeGeometryTypes.MultiPointZM:
                    return new MultiPointHandler();

                default:
                    return null;
			}			
		}
예제 #5
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));
        }
예제 #6
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.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();
            ICoordinate external = new Coordinate(x, y);

            geometryFactory.PrecisionModel.MakePrecise(external);
            return(geometryFactory.CreatePoint(external));
        }
예제 #7
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>
            /// Initializes a new instance of the ShapefileEnumerator class.
            /// </summary>
            /// <param name="shapefile"></param>
            public ShapefileEnumerator(ShapefileReader shapefile)
            {
                _parent = shapefile;

                // create a file stream for each enumerator that is given out. This allows the same file
                // to have one or more enumerator. If we used the parents stream - than only one IEnumerator
                // could be given out.
                FileStream stream = new FileStream(_parent._filename, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read);

                _shpBinaryReader = new BigEndianBinaryReader(stream);

                // skip header - since parent has already read this.
                _shpBinaryReader.ReadBytes(100);
                ShapeGeometryTypes type = _parent._mainHeader.ShapeType;

                _handler = Shapefile.GetShapeHandler(type);
                if (_handler == null)
                {
                    throw new NotSupportedException("Unsuported shape type:" + type);
                }
            }
        /// <summary>
        /// Reads the shapefile and returns a GeometryCollection representing all the records in the shapefile.
        /// </summary>
        /// <returns>GeometryCollection representing every record in the shapefile.</returns>
        public IGeometryCollection ReadAll()
        {
            ArrayList          list    = new ArrayList();
            ShapeGeometryTypes type    = _mainHeader.ShapeType;
            ShapeHandler       handler = Shapefile.GetShapeHandler(type);

            if (handler == null)
            {
                throw new NotSupportedException("Unsupported shape type:" + type);
            }

            int i = 0;

            foreach (Geometry geometry in this)
            {
                list.Add(geometry);
                i++;
            }

            IGeometry[] geomArray = GeometryFactory.ToGeometryArray(list);
            return(_geometryFactory.CreateGeometryCollection(geomArray));
        }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public virtual IGeometry Read(BinaryReader reader)
        {
            ShapeGeometryTypes shapeType = (ShapeGeometryTypes)reader.ReadInt32();

            switch (shapeType)
            {
            case ShapeGeometryTypes.Point:
            case ShapeGeometryTypes.PointM:
            case ShapeGeometryTypes.PointZ:
            case ShapeGeometryTypes.PointZM:
                return(ReadPoint(reader));

            case ShapeGeometryTypes.LineString:
            case ShapeGeometryTypes.LineStringM:
            case ShapeGeometryTypes.LineStringZ:
            case ShapeGeometryTypes.LineStringZM:
                return(ReadLineString(reader));

            case ShapeGeometryTypes.Polygon:
            case ShapeGeometryTypes.PolygonM:
            case ShapeGeometryTypes.PolygonZ:
            case ShapeGeometryTypes.PolygonZM:
                return(ReadPolygon(reader));

            case ShapeGeometryTypes.MultiPoint:
            case ShapeGeometryTypes.MultiPointM:
            case ShapeGeometryTypes.MultiPointZ:
            case ShapeGeometryTypes.MultiPointZM:
                return(ReadMultiPoint(reader));

            case ShapeGeometryTypes.MultiPatch:
                throw new NotImplementedException("FeatureType " + shapeType + " not supported.");

            default:
                throw new ArgumentOutOfRangeException("FeatureType " + shapeType + " not recognized by the system");
            }
        }
예제 #11
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));
        }
예제 #12
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.NullShape)
            {
                return(null);
            }

            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 ILineString[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;
                ICoordinate external;
                for (int i = 0; i < length; i++)
                {
                    external = new Coordinate(file.ReadDouble(), file.ReadDouble());
                    geometryFactory.PrecisionModel.MakePrecise(external);
                    points.Add(external);
                }
                if (numPoints < 2)
                {
                    lines[part] = geometryFactory.CreateLineString(null as Topology.Geometries.ICoordinate[]);
                }
                else
                {
                    lines[part] = geometryFactory.CreateLineString(points.ToArray());
                }
            }

            //If we have Z-coordinates, read them..
            if (shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM)
            {
                //z-Bounds
                double zMin = file.ReadDouble();
                double zMax = file.ReadDouble();
                for (int part = 0; part < numParts; part++)
                {
                    start = partOffsets[part];
                    if (part == numParts - 1)
                    {
                        finish = numPoints;
                    }
                    else
                    {
                        finish = partOffsets[part + 1];
                    }
                    length = finish - start;
                    for (int i = 0; i < length; i++)
                    {
                        double val = file.ReadDouble();
                        if (numPoints > 1)
                        {
                            lines[part].Coordinates[i].Z = val;
                        }
                    }
                }
            }

            //If we have M-coordinates, read them..
            if (shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZM)
            {
                //m-Bounds
                double mMin = file.ReadDouble();
                double mMax = file.ReadDouble();
                for (int part = 0; part < numParts; part++)
                {
                    start = partOffsets[part];
                    if (part == numParts - 1)
                    {
                        finish = numPoints;
                    }
                    else
                    {
                        finish = partOffsets[part + 1];
                    }
                    length = finish - start;
                    for (int i = 0; i < length; i++)
                    {
                        double val = file.ReadDouble();
                        //dont store..
                    }
                }
            }

            return(geometryFactory.CreateMultiLineString(lines));
        }