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


            if (shapeType != ShapeType.Arc)
            {
                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 = reader.ReadDouble();
                box[i] = d;
            }



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

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

            LineString[] 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;
                Coordinate[] coords = new Coordinate[length];

                for (int i = 0; i < length; i++)
                {
                    Coordinate coord = new Coordinate(reader.ReadDouble(), reader.ReadDouble());
                    factory.getPrecisionModel().makePrecise(coord);

                    coords[i] = coord;
                }

                lines[part] = factory.createLineString(new PackedCoordinateSequence.Float(coords, 2));
            }
            return(factory.createMultiLineString(lines));
        }
コード例 #2
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 Geometry Read(BigEndianBinaryReader file, GeometryFactory geometryFactory)
        {
            int       shapeTypeNum = file.ReadInt32();
            ShapeType shapeType    = (ShapeType)Enum.Parse(typeof(ShapeType), shapeTypeNum.ToString());

            if (shapeType != ShapeType.Arc)
            {
                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();
            }

            LineString[] 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;
                Coordinates points = new Coordinates();
                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));
                }
                lines[part] = geometryFactory.CreateLineString(points);
            }
            return(geometryFactory.CreateMultiLineString(lines));
        }
コード例 #3
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 Geometry Read(BigEndianBinaryReader file, GeometryFactory geometryFactory)
		{
			int shapeTypeNum = file.ReadInt32();
			ShapeType shapeType = (ShapeType)Enum.Parse(typeof(ShapeType),shapeTypeNum.ToString());
			if (shapeType != ShapeType.Arc)
			{
				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();
			}
			
			LineString[] 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;
				Coordinates points = new Coordinates();
				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));
				}
				lines[part] = geometryFactory.CreateLineString(points);

			}
			return geometryFactory.CreateMultiLineString(lines);
		}
コード例 #4
0
ファイル: ShapefileHeader.cs プロジェクト: vmoll/geotools
        /// <summary>
        /// Initializes a new instance of the <see cref="ShapefileHeader">ShapefileHeader</see> class with values read in from the stream.
        /// </summary>
        /// <remarks>Reads the header information from the stream.</remarks>
        /// <param name="reader">BigEndianBinaryReader stream to the shapefile.</param>
        public ShapefileHeader(BigEndianBinaryReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            _fileCode = reader.ReadIntBE();

            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
            for (int i = 0; i < 5; i++)
            {
                reader.ReadIntBE();
            }

            _fileLength = reader.ReadIntBE();
            _version = reader.ReadInt32();

            Debug.Assert(_version == 1000, "Shapefile version", String.Format(System.Globalization.CultureInfo.InvariantCulture, "Expecting only one version (1000), but got {0}", _version));

            int shapeType = reader.ReadInt32();

            if (Enum.IsDefined(typeof(ShapeType), shapeType))
            {
                _shapeType = (ShapeType)shapeType;
            }
            else
            {
                throw new ShapefileException("Invalid shape type");
            }

            // Read in and store the bounding box
            double[] coords = new double[4];

            for (int i = 0; i < coords.Length; i++)
            {
                coords[i] = reader.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++)
            {
                reader.ReadDouble();
            }
        }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShapefileHeader">ShapefileHeader</see> class with values read in from the stream.
        /// </summary>
        /// <remarks>Reads the header information from the stream.</remarks>
        /// <param name="reader">BigEndianBinaryReader stream to the shapefile.</param>
        public ShapefileHeader(BigEndianBinaryReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            _fileCode = reader.ReadIntBE();

            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
            for (int i = 0; i < 5; i++)
            {
                reader.ReadIntBE();
            }

            _fileLength = reader.ReadIntBE();
            _version    = reader.ReadInt32();

            Debug.Assert(_version == 1000, "Shapefile version", String.Format(System.Globalization.CultureInfo.InvariantCulture, "Expecting only one version (1000), but got {0}", _version));

            int shapeType = reader.ReadInt32();

            if (Enum.IsDefined(typeof(ShapeType), shapeType))
            {
                _shapeType = (ShapeType)shapeType;
            }
            else
            {
                throw new ShapefileException("Invalid shape type");
            }

            // Read in and store the bounding box
            double[] coords = new double[4];

            for (int i = 0; i < coords.Length; i++)
            {
                coords[i] = reader.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++)
            {
                reader.ReadDouble();
            }
        }
コード例 #6
0
ファイル: ShapeHandler.cs プロジェクト: tinuvieltr/geotools
        /// <summary>
        /// Returns the <see cref="ShapeType">ShapeType</see> for the current record.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>The <see cref="ShapeType">ShapeType</see> for the current record.</returns>
        /// <exception cref="ShapefileException">The shape type is invalid.</exception>
        protected ShapeType GetShapeType(BigEndianBinaryReader reader)
        {
            int type = reader.ReadInt32();

            if (!Enum.IsDefined(typeof(ShapeType), type))
            {
                throw new ShapefileException("Invalid shape type.");
            }

            return((ShapeType)type);
        }
コード例 #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.ReadIntBE();
            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.ReadIntBE();
            shpBinaryReader.ReadIntBE();
            shpBinaryReader.ReadIntBE();
            shpBinaryReader.ReadIntBE();
            shpBinaryReader.ReadIntBE();

            _fileLength = shpBinaryReader.ReadIntBE();

            _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 = (ShapeType)Enum.Parse(typeof(ShapeType), 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();
            }
        }
コード例 #8
0
ファイル: MultiLineHandler.cs プロジェクト: vmoll/geotools
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="reader">The stream to read.</param>
        /// <param name="factory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override Geometry Read(BigEndianBinaryReader reader, GeometryFactory factory)
        {
            int shapeTypeNum = reader.ReadInt32();
            ShapeType shapeType = (ShapeType)Enum.Parse(typeof(ShapeType),shapeTypeNum.ToString());

            if (shapeType != ShapeType.Arc)
            {
                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= reader.ReadDouble();
                box[i] =d;
            }

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

            LineString[] 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;
                Coordinate[] coords = new Coordinate[length];

                for (int i = 0; i < length; i++)
                {
                    Coordinate coord = new Coordinate(reader.ReadDouble(), reader.ReadDouble());
                    factory.getPrecisionModel().makePrecise(coord);

                    coords[i] = coord;
                }

                lines[part] = factory.createLineString(new PackedCoordinateSequence.Float(coords, 2));
            }
            return factory.createMultiLineString(lines);
        }
コード例 #9
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.ReadIntBE();	
			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.ReadIntBE();
			shpBinaryReader.ReadIntBE();
			shpBinaryReader.ReadIntBE();
			shpBinaryReader.ReadIntBE();
			shpBinaryReader.ReadIntBE();

			_fileLength = shpBinaryReader.ReadIntBE();

			_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 = (ShapeType)Enum.Parse(typeof(ShapeType),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();	
			}
		}
コード例 #10
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 Geometry Read(BigEndianBinaryReader file, GeometryFactory geometryFactory)
        {
            int       shapeTypeNum = file.ReadInt32();
            ShapeType shapeType    = (ShapeType)Enum.Parse(typeof(ShapeType), shapeTypeNum.ToString());

            if (shapeType != ShapeType.Point)
            {
                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)));
        }
コード例 #11
0
ファイル: ShapeHandler.cs プロジェクト: vmoll/geotools
        /// <summary>
        /// Returns the <see cref="ShapeType">ShapeType</see> for the current record.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>The <see cref="ShapeType">ShapeType</see> for the current record.</returns>
        /// <exception cref="ShapefileException">The shape type is invalid.</exception>
        protected ShapeType GetShapeType(BigEndianBinaryReader reader)
        {
            int type = reader.ReadInt32();

            if (!Enum.IsDefined(typeof(ShapeType), type))
            {
                throw new ShapefileException("Invalid shape type.");
            }

            return (ShapeType)type;
        }
コード例 #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 Geometry Read(BigEndianBinaryReader file, GeometryFactory geometryFactory)
		{
			int shapeTypeNum = file.ReadInt32();
			ShapeType shapeType = (ShapeType)Enum.Parse(typeof(ShapeType),shapeTypeNum.ToString());
			if (shapeType != ShapeType.Polygon)
			{
				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;
				Coordinates points = new Coordinates();
				points.Capacity=length;
				for (int i = 0; i < length; i++)
				{
					Coordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble() );
					Coordinate internalCoord = geometryFactory.PrecisionModel.ToInternal(external);
					points.Add(internalCoord);
				}
				LinearRing ring = geometryFactory.CreateLinearRing(points);
				//Debug.Assert(ring.IsValid()==false,"Ring is not valid.");
				if (_cga.IsCCW(points))
				{
					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 homes
			for (int i = 0; i < holes.Count; i++)
			{
				LinearRing testRing = (LinearRing) holes[i];
				LinearRing minShell = null;
				Envelope minEnv = null;
				Envelope testEnv = testRing.GetEnvelopeInternal();
				Coordinate testPt = testRing.GetCoordinateN(0);
				LinearRing tryRing;
				for (int j = 0; j < shells.Count; j++)
				{
					tryRing = (LinearRing) shells[j];
					Envelope tryEnv = tryRing.GetEnvelopeInternal();
					if (minShell != null) 
					{
						minEnv = minShell.GetEnvelopeInternal();
					}
					bool isContained = false;
					Coordinates coordList = tryRing.GetCoordinates() ;
					if (tryEnv.Contains(testEnv)
						&& (_cga.IsPointInRing(testPt,coordList ) ||
						(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;
						}
					}
				}
				//if (minShell==null)
				//{
				//	throw new InvalidOperationException("Could not find shell for a hole. Try a different precision model.");
				//}
			}
			Polygon[] 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);

		}
コード例 #13
0
        private void Initialize()
        {
            // Cache the .dbf header
            _dbfHeader = new DbaseFileHeader();

            using (BinaryReader dbfReader = new BinaryReader(File.OpenRead(Path.Combine(Path.GetDirectoryName(_path), Path.GetFileNameWithoutExtension(_path) + ".dbf"))))
            {
                _dbfHeader.ReadHeader(dbfReader);
                _dbfHeaderOffset = dbfReader.BaseStream.Position;
            }

            // Need to make one pass over the geometries and pull out the bounding boxes
            _spatialIndex = new com.vividsolutions.jts.index.strtree.STRtree();
            _extents      = new Envelope();

            using (BigEndianBinaryReader shpReader = new BigEndianBinaryReader(File.OpenRead(_path)))
                using (ShapefileIndexReader shxReader = new ShapefileIndexReader(Path.Combine(Path.GetDirectoryName(_path), Path.GetFileNameWithoutExtension(_path) + ".shx")))
                {
                    // Get the shape type
                    _type = new ShapefileHeader(shpReader).ShapeType;

                    while (shxReader.Read())
                    {
                        int offset = shxReader.GetOffest();
                        int length = shxReader.GetLength();

                        // Move to the start of geometry
                        shpReader.BaseStream.Position = offset * 2;

                        double xMin;
                        double yMin;
                        double xMax;
                        double yMax;

                        int recordNumber  = shpReader.ReadIntBE();
                        int contentLength = shpReader.ReadIntBE();

                        // Read shape type
                        int type = shpReader.ReadInt32();

                        if (type != 1)
                        {
                            xMin = shpReader.ReadDouble();
                            yMin = shpReader.ReadDouble();
                            xMax = shpReader.ReadDouble();
                            yMax = shpReader.ReadDouble();
                        }
                        else
                        {
                            // Point - read x and y
                            xMin = shpReader.ReadDouble();
                            yMin = shpReader.ReadDouble();
                            xMax = yMin;
                            yMax = yMin;
                        }

                        // Build the envelope
                        Envelope extents = new Envelope(xMin, xMax, yMin, yMax);

                        // Add to total extents
                        _extents.expandToInclude(extents);

                        // Insert the index of the record into the spatial index
                        _spatialIndex.insert(extents, new ShapefileRecordPointer(recordNumber, offset * 2, contentLength, (int)_dbfHeaderOffset + (_dbfHeader.RecordLength * (recordNumber - 1))));
                    }

                    // Build the index once
                    _spatialIndex.build();
                }
        }
コード例 #14
0
ファイル: PolygonHandler.cs プロジェクト: vmoll/geotools
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="reader">The stream to read.</param>
        /// <param name="factory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override Geometry Read(BigEndianBinaryReader reader, GeometryFactory factory)
        {
            if (this.GetShapeType(reader) != ShapeType.Polygon)
            {
                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 < box.Length; i++)
            {
                box[i] = reader.ReadDouble();
            }

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

            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = reader.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;
                Coordinate[] coords = new Coordinate[length];

                for (int i = 0; i < length; i++)
                {
                    Coordinate coord = new Coordinate(reader.ReadDouble(), reader.ReadDouble());
                    factory.getPrecisionModel().makePrecise(coord);

                    coords[i] = coord;
                }

                LinearRing ring = factory.createLinearRing(new PackedCoordinateSequence.Float(coords, 2));

                if (com.vividsolutions.jts.algorithm.RobustCGAlgorithms.isCCW(coords))
                {
                    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 homes
            for (int i = 0; i < holes.Count; i++)
            {
                LinearRing testRing = (LinearRing) holes[i];
                LinearRing minShell = null;
                Envelope minEnv = null;
                Envelope testEnv = testRing.getEnvelopeInternal();
                Coordinate testPt = testRing.getCoordinateN(0);
                LinearRing tryRing;
                for (int j = 0; j < shells.Count; j++)
                {
                    tryRing = (LinearRing) shells[j];
                    Envelope tryEnv = tryRing.getEnvelopeInternal();
                    if (minShell != null)
                    {
                        minEnv = minShell.getEnvelopeInternal();
                    }
                    bool isContained = false;

                    Coordinate[] coordList = tryRing.getCoordinates();

                    if (tryEnv.contains(testEnv)
                        && (com.vividsolutions.jts.algorithm.RobustCGAlgorithms.isPointInRing(testPt, coordList ) ||
                        (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;
                        }
                        ArrayList list = (ArrayList)holesForShells[j];
                        list.Add(testRing);
                    }
                }
                if (minShell==null)
                {
            //					throw new InvalidOperationException("Could not find shell for a hole. Try a different precision model.");
                }
            }
            Polygon[] polygons = new Polygon[shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = factory.createPolygon((LinearRing) shells[i], (LinearRing[])((ArrayList) holesForShells[i]).ToArray(typeof(LinearRing)));
            }

            if (polygons.Length == 1)
            {
                return polygons[0];
            }
            //it's a multi part
            return factory.createMultiPolygon(polygons);
        }
コード例 #15
0
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="reader">The stream to read.</param>
        /// <param name="factory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>

        public override Geometry Read(BigEndianBinaryReader reader, GeometryFactory factory)
        {
            if (this.GetShapeType(reader) != ShapeType.Polygon)
            {
                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 < box.Length; i++)
            {
                box[i] = reader.ReadDouble();
            }

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

            int[] partOffsets = new int[numParts];

            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = reader.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;
                Coordinate[] coords = new Coordinate[length];

                for (int i = 0; i < length; i++)
                {
                    Coordinate coord = new Coordinate(reader.ReadDouble(), reader.ReadDouble());
                    factory.getPrecisionModel().makePrecise(coord);

                    coords[i] = coord;
                }

                LinearRing ring = factory.createLinearRing(new PackedCoordinateSequence.Float(coords, 2));

                if (com.vividsolutions.jts.algorithm.RobustCGAlgorithms.isCCW(coords))
                {
                    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 homes
            for (int i = 0; i < holes.Count; i++)
            {
                LinearRing testRing = (LinearRing)holes[i];
                LinearRing minShell = null;
                Envelope   minEnv   = null;
                Envelope   testEnv  = testRing.getEnvelopeInternal();
                Coordinate testPt   = testRing.getCoordinateN(0);
                LinearRing tryRing;
                for (int j = 0; j < shells.Count; j++)
                {
                    tryRing = (LinearRing)shells[j];
                    Envelope tryEnv = tryRing.getEnvelopeInternal();
                    if (minShell != null)
                    {
                        minEnv = minShell.getEnvelopeInternal();
                    }
                    bool isContained = false;

                    Coordinate[] coordList = tryRing.getCoordinates();

                    if (tryEnv.contains(testEnv) &&
                        (com.vividsolutions.jts.algorithm.RobustCGAlgorithms.isPointInRing(testPt, coordList) ||
                         (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;
                        }
                        ArrayList list = (ArrayList)holesForShells[j];
                        list.Add(testRing);
                    }
                }
                if (minShell == null)
                {
//					throw new InvalidOperationException("Could not find shell for a hole. Try a different precision model.");
                }
            }
            Polygon[] polygons = new Polygon[shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = factory.createPolygon((LinearRing)shells[i], (LinearRing[])((ArrayList)holesForShells[i]).ToArray(typeof(LinearRing)));
            }

            if (polygons.Length == 1)
            {
                return(polygons[0]);
            }
            //it's a multi part
            return(factory.createMultiPolygon(polygons));
        }
コード例 #16
0
        private void Initialize()
        {
            // Cache the .dbf header
            _dbfHeader = new DbaseFileHeader();

            using (BinaryReader dbfReader = new BinaryReader(File.OpenRead(Path.Combine(Path.GetDirectoryName(_path), Path.GetFileNameWithoutExtension(_path) + ".dbf"))))
            {
                _dbfHeader.ReadHeader(dbfReader);
                _dbfHeaderOffset = dbfReader.BaseStream.Position;
            }

            // Need to make one pass over the geometries and pull out the bounding boxes
            _spatialIndex = new com.vividsolutions.jts.index.strtree.STRtree();
            _extents = new Envelope();

            using (BigEndianBinaryReader shpReader = new BigEndianBinaryReader(File.OpenRead(_path)))
            using (ShapefileIndexReader shxReader = new ShapefileIndexReader(Path.Combine(Path.GetDirectoryName(_path), Path.GetFileNameWithoutExtension(_path) + ".shx")))
            {
                // Get the shape type
                _type = new ShapefileHeader(shpReader).ShapeType;

                while (shxReader.Read())
                {
                    int offset = shxReader.GetOffest();
                    int length = shxReader.GetLength();

                    // Move to the start of geometry
                    shpReader.BaseStream.Position = offset * 2;

                    double xMin;
                    double yMin;
                    double xMax;
                    double yMax;

                    int recordNumber = shpReader.ReadIntBE();
                    int contentLength = shpReader.ReadIntBE();

                    // Read shape type
                    int type = shpReader.ReadInt32();

                    if (type != 1)
                    {
                        xMin = shpReader.ReadDouble();
                        yMin = shpReader.ReadDouble();
                        xMax = shpReader.ReadDouble();
                        yMax = shpReader.ReadDouble();
                    }
                    else
                    {
                        // Point - read x and y
                        xMin = shpReader.ReadDouble();
                        yMin = shpReader.ReadDouble();
                        xMax = yMin;
                        yMax = yMin;
                    }

                    // Build the envelope
                    Envelope extents = new Envelope(xMin, xMax, yMin, yMax);

                    // Add to total extents
                    _extents.expandToInclude(extents);

                    // Insert the index of the record into the spatial index
                    _spatialIndex.insert(extents, new ShapefileRecordPointer(recordNumber, offset * 2, contentLength, (int)_dbfHeaderOffset + (_dbfHeader.RecordLength * (recordNumber - 1))));
                }

                // Build the index once
                _spatialIndex.build();
            }
        }
コード例 #17
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 Geometry Read(BigEndianBinaryReader file, GeometryFactory geometryFactory)
        {
            int       shapeTypeNum = file.ReadInt32();
            ShapeType shapeType    = (ShapeType)Enum.Parse(typeof(ShapeType), shapeTypeNum.ToString());

            if (shapeType != ShapeType.Polygon)
            {
                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;
                Coordinates points = new Coordinates();
                points.Capacity = length;
                for (int i = 0; i < length; i++)
                {
                    Coordinate external      = new Coordinate(file.ReadDouble(), file.ReadDouble());
                    Coordinate internalCoord = geometryFactory.PrecisionModel.ToInternal(external);
                    points.Add(internalCoord);
                }
                LinearRing ring = geometryFactory.CreateLinearRing(points);
                //Debug.Assert(ring.IsValid()==false,"Ring is not valid.");
                if (_cga.IsCCW(points))
                {
                    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 homes
            for (int i = 0; i < holes.Count; i++)
            {
                LinearRing testRing = (LinearRing)holes[i];
                LinearRing minShell = null;
                Envelope   minEnv   = null;
                Envelope   testEnv  = testRing.GetEnvelopeInternal();
                Coordinate testPt   = testRing.GetCoordinateN(0);
                LinearRing tryRing;
                for (int j = 0; j < shells.Count; j++)
                {
                    tryRing = (LinearRing)shells[j];
                    Envelope tryEnv = tryRing.GetEnvelopeInternal();
                    if (minShell != null)
                    {
                        minEnv = minShell.GetEnvelopeInternal();
                    }
                    bool        isContained = false;
                    Coordinates coordList   = tryRing.GetCoordinates();
                    if (tryEnv.Contains(testEnv) &&
                        (_cga.IsPointInRing(testPt, coordList) ||
                         (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;
                        }
                    }
                }
                //if (minShell==null)
                //{
                //	throw new InvalidOperationException("Could not find shell for a hole. Try a different precision model.");
                //}
            }
            Polygon[] 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));
        }