コード例 #1
0
 /// <summary>
 /// Function to read a <see cref="IPoint"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
 /// </summary>
 /// <param name="reader">The reader to use</param>
 /// <param name="ordinates">The ordinates to read</param>
 /// <returns>The read point geometry</returns>
 protected IGeometry ReadPoint(BinaryReader reader, Ordinates ordinates)
 {
     var buffer = new CoordinateBuffer(1, ShapeFileConstants.NoDataBorder, true);
     ReadCoordinates(reader, 1, new[] { 0 }, ordinates, buffer);
     IGeometry point = _factory.CreatePoint(buffer.ToSequence());
     return point;
 }
コード例 #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="totalRecordLength">Total length of the record we are about 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 IGeometry Read(BigEndianBinaryReader file, int totalRecordLength, IGeometryFactory factory)
        {
            int totalRead = 0;
            ShapeGeometryType type = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);
            //type = (ShapeGeometryType) EnumUtility.Parse(typeof (ShapeGeometryType), shapeTypeNum.ToString());
            if (type == ShapeGeometryType.NullShape)
                return factory.CreatePoint((Coordinate)null);

            if (type != ShapeType)
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));

            CoordinateBuffer buffer = new CoordinateBuffer(1, NoDataBorderValue, true);
            IPrecisionModel precisionModel = factory.PrecisionModel;

            double x = precisionModel.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
            double y = precisionModel.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));

            double? z = null, m = null;
            
            // Trond Benum: Let's read optional Z and M values                                
            if (HasZValue() && totalRead < totalRecordLength)
                z = ReadDouble(file, totalRecordLength, ref totalRead);

            if ((HasMValue() || HasZValue()) &&
                (totalRead < totalRecordLength))
                m = ReadDouble(file, totalRecordLength, ref totalRead);

            buffer.AddCoordinate(x, y, z, m);
            return factory.CreatePoint(buffer.ToSequence(factory.CoordinateSequenceFactory));
        }
コード例 #3
0
        private static ICoordinateSequence ToDotSpatial(CoordinateBuffer buffer)
        {
            double[] z, m;
            var      xy = buffer.ToXYZM(out z, out m);

            return(new DotSpatialAffineCoordinateSequence(xy, z, m));
        }
コード例 #4
0
 /// <summary>
 /// Function to read a <see cref="IPoint"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
 /// </summary>
 /// <param name="reader">The reader to use</param>
 /// <param name="ordinates">The ordinates to read</param>
 /// <returns>The read point geometry</returns>
 protected IGeometry ReadPoint(BinaryReader reader, Ordinates ordinates)
 {
     var buffer = new CoordinateBuffer(1, ShapeFileConstants.NoDataBorder, true);
     ReadCoordinates(reader, 1, new[] { 0 }, ordinates, buffer);
     IGeometry point = _factory.CreatePoint(buffer.ToSequence());
     return point;
 }
コード例 #5
0
        private static ICoordinateSequence ToPackedFloatArray(CoordinateBuffer buffer)
        {
            float[] pa;
            var     dim = buffer.ToPackedArray(out pa);

            return(new PackedDoubleCoordinateSequence(pa, dim));
        }
コード例 #6
0
        private static void TestToSequenceMethod(ICoordinateSequenceFactory factory)
        {
            var rnd    = new Random(8894);
            var buffer = new CoordinateBuffer(NumCoordinates);

            for (var i = 0; i < NumCoordinates; i++)
            {
                buffer.AddCoordinate(rnd.NextDouble(), rnd.NextDouble());
            }

            System.Diagnostics.Trace.WriteLine(
                string.Format("\nConversion using {0} factory", (factory ?? GeoAPI.GeometryServiceProvider.Instance.DefaultCoordinateSequenceFactory).GetType().Name));

            var sw = new System.Diagnostics.Stopwatch();

            sw.Start();
            var seqCold = buffer.ToSequence(factory);

            sw.Stop();
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Cold converting sequence of {0} coordinates in {1}ms.", NumCoordinates, sw.ElapsedMilliseconds));
            long total = 0;

            foreach (var rndBuffer in (_randomCoordinateBuffers ?? (_randomCoordinateBuffers = RandomCoordinateBuffers(NumTests))))
            {
                sw.Stop();
                sw.Start();
                var seqWarm = rndBuffer.ToSequence(factory);
                sw.Stop();
                Assert.AreEqual(rndBuffer.Count, seqWarm.Count);
                total += sw.ElapsedTicks;
            }
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Warm converting {0} random coordinate buffers in {1}ticks.", NumTests, total));
        }
コード例 #7
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="totalRecordLength">Total length of the record we are about 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 IGeometry Read(BigEndianBinaryReader file, int totalRecordLength, IGeometryFactory factory)
        {
            int totalRead = 0;
            ShapeGeometryType type = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);
            //type = (ShapeGeometryType) EnumUtility.Parse(typeof (ShapeGeometryType), shapeTypeNum.ToString());
            if (type == ShapeGeometryType.NullShape)
                return factory.CreatePoint((Coordinate)null);

            if (type != ShapeType)
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));

            CoordinateBuffer buffer = new CoordinateBuffer(1, NoDataBorderValue, true);
            IPrecisionModel precisionModel = factory.PrecisionModel;

            double x = precisionModel.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
            double y = precisionModel.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));

            double? z = null, m = null;
            
            // Trond Benum: Let's read optional Z and M values                                
            if (HasZValue() && totalRead < totalRecordLength)
                z = ReadDouble(file, totalRecordLength, ref totalRead);

            if ((HasMValue() || HasZValue()) &&
                (totalRead < totalRecordLength))
                m = ReadDouble(file, totalRecordLength, ref totalRead);

            buffer.AddCoordinate(x, y, z, m);
            return factory.CreatePoint(buffer.ToSequence(factory.CoordinateSequenceFactory));
        }
コード例 #8
0
        public void TestAddCoordinatesDisallowRepeated()
        {
            var buf = new CoordinateBuffer();
            buf.AddCoordinate(0, 0);
            Assert.IsFalse(buf.AddCoordinate(0, 0, allowRepeated: false));

            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #9
0
        /// <summary>
        /// Function to read a <see cref="IMultiPoint"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read polygonal geometry</returns>
        public IGeometry ReadMultiPoint(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // jump boundingbox

            var numPoints = ReadNumPoints(reader);
            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, new[] { numPoints - 1 }, ordinates, buffer);
            return _factory.CreateMultiPoint(buffer.ToSequence());
        }
コード例 #10
0
        public void TestAddCoordinates()
        {
            var buf = new CoordinateBuffer();
            buf.AddCoordinate(0, 0);
            Assert.IsTrue(buf.AddCoordinate(0, 0));

            Assert.AreEqual(2, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #11
0
        public void TestAddCoordinates()
        {
            var buf = new CoordinateBuffer();

            buf.AddCoordinate(0, 0);
            Assert.IsTrue(buf.AddCoordinate(0, 0));

            Assert.AreEqual(2, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #12
0
        public void TestAddCoordinatesDisallowRepeated()
        {
            var buf = new CoordinateBuffer();

            buf.AddCoordinate(0, 0);
            Assert.IsFalse(buf.AddCoordinate(0, 0, allowRepeated: false));

            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #13
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="totalRecordLength">Total length of the record we are about 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 IGeometry Read(BigEndianBinaryReader file, int totalRecordLength, IGeometryFactory factory)
        {
            int totalRead    = 0;
            int shapeTypeNum = ReadInt32(file, totalRecordLength, ref totalRead);

            var type = (ShapeGeometryType)EnumUtility.Parse(typeof(ShapeGeometryType), shapeTypeNum.ToString());

            if (type == ShapeGeometryType.NullShape)
            {
                return(factory.CreateMultiPoint(new IPoint[] { }));
            }

            if (type != ShapeType)
            {
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));
            }

            // Read and for now ignore bounds.
            int bblength = GetBoundingBoxLength();

            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
            {
                double d = ReadDouble(file, totalRecordLength, ref totalRead);
                boundingBox[boundingBoxIndex] = d;
            }

            // Read points
            var numPoints = ReadInt32(file, totalRecordLength, ref totalRead);
            var buffer    = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var points    = new IPoint[numPoints];
            var pm        = factory.PrecisionModel;

            for (var i = 0; i < numPoints; i++)
            {
                var x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                var y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                buffer.AddCoordinate(x, y);
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the points, let's read optional Z and M values
            GetZMValues(file, totalRecordLength, ref totalRead, buffer);

            var sequences = buffer.ToSequences(factory.CoordinateSequenceFactory);

            for (var i = 0; i < numPoints; i++)
            {
                points[i] = factory.CreatePoint(sequences[i]);
            }

            geom = factory.CreateMultiPoint(points);

            return(geom);
        }
コード例 #14
0
 public void BeginFigure(double x, double y, double?z, double?m)
 {
     if (_inFigure)
     {
         throw new ApplicationException();
     }
     _coordinateBuffer = new CoordinateBuffer();
     //_coordinates = new List<Coordinate>();
     AddCoordinate(x, y, z, m);
     _inFigure = true;
 }
コード例 #15
0
        /// <summary>
        /// Function to read a <see cref="ILineString"/> or <see cref="IMultiLineString"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read lineal geometry</returns>
        protected IGeometry ReadLineString(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // Jump boundingbox

            var numParts = ReadNumParts(reader);
            var numPoints = ReadNumPoints(reader);
            var indexParts = ReadIndexParts(reader, numParts, numPoints);

            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, indexParts, ordinates, buffer);

            if (numParts == 1)
                return _factory.CreateLineString(buffer.ToSequence());
            return CreateMultiLineString(buffer.ToSequences());
        }
コード例 #16
0
        /// <summary>
        /// Function to read a either a <see cref="IPolygon"/> or an <see cref="IMultiPolygon"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read polygonal geometry</returns>
        protected IGeometry ReadPolygon(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // jump boundingbox

            var numParts = ReadNumParts(reader);
            var numPoints = ReadNumPoints(reader);
            var indexParts = ReadIndexParts(reader, numParts, numPoints);

            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, indexParts, ordinates, buffer);

            return numParts == 1
                ? _factory.CreatePolygon(_factory.CreateLinearRing(buffer.ToSequence()), null)
                : CreateSingleOrMultiPolygon(buffer);
        }
コード例 #17
0
        /// <summary>
        /// Function to read a <see cref="ILineString"/> or <see cref="IMultiLineString"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read lineal geometry</returns>
        protected IGeometry ReadLineString(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // Jump boundingbox

            var numParts = ReadNumParts(reader);
            var numPoints = ReadNumPoints(reader);
            var indexParts = ReadIndexParts(reader, numParts, numPoints);

            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, indexParts, ordinates, buffer);

            if (numParts == 1)
                return _factory.CreateLineString(buffer.ToSequence());
            return CreateMultiLineString(buffer.ToSequences());
        }
コード例 #18
0
        public void TestInsertCoordinates()
        {
            var buf = new CoordinateBuffer();
            Assert.IsTrue(buf.AddCoordinate(0, 0));
            
            Assert.IsTrue(buf.AddCoordinate(10, 10));
            Assert.AreEqual(2, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsTrue(buf.InsertCoordinate(0, -10d, -10d));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
            
            Assert.IsTrue(buf.InsertCoordinate(0, -10d, -10d));
            Assert.AreEqual(4, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #19
0
        private static IEnumerable <CoordinateBuffer> RandomCoordinateBuffers(int numBuffers)
        {
            var rnd  = new Random(numBuffers);
            var list = new List <CoordinateBuffer>(numBuffers);

            for (var i = 0; i < numBuffers; i++)
            {
                var numCoordinates = rnd.Next(100, 500);
                var buffer         = new CoordinateBuffer(numCoordinates);
                for (var j = 0; j < numCoordinates; j++)
                {
                    buffer.AddCoordinate(rnd.NextDouble(), rnd.NextDouble());
                }
                list.Add(buffer);
            }
            return(list);
        }
コード例 #20
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="totalRecordLength">Total length of the record we are about 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, int totalRecordLength, IGeometryFactory geometryFactory)
        {
            int totalRead = 0;
            int shapeTypeNum = ReadInt32(file, totalRecordLength, ref totalRead);

            var type = (ShapeGeometryType) EnumUtility.Parse(typeof(ShapeGeometryType), shapeTypeNum.ToString());
            if (type == ShapeGeometryType.NullShape)
                return geometryFactory.CreateMultiPoint(new IPoint[] { });

            if (type != ShapeType)
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));

            // Read and for now ignore bounds.
            int bblength = GetBoundingBoxLength();
            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
            {
                double d = ReadDouble(file, totalRecordLength, ref totalRead);
                boundingBox[boundingBoxIndex] = d;
            }

            // Read points
            var numPoints = ReadInt32(file, totalRecordLength, ref totalRead);
            var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var points = new IPoint[numPoints];
            var pm = geometryFactory.PrecisionModel;

            for (var i = 0; i < numPoints; i++)
            {
                var x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                var y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                buffer.AddCoordinate(x, y);
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the points, let's read optional Z and M values            
            GetZMValues(file, totalRecordLength, ref totalRead, buffer);            

            var sequences = buffer.ToSequences(geometryFactory.CoordinateSequenceFactory);
            for (var i = 0; i < numPoints; i++)
                points[i] = geometryFactory.CreatePoint(sequences[i]);
         
            geom = geometryFactory.CreateMultiPoint(points);
          
            return geom;
        }        
コード例 #21
0
        public void TestInsertCoordinatesDisallowRepeated()
        {
            var buf = new CoordinateBuffer();
            Assert.IsTrue(buf.AddCoordinate(0, 0));
            
            Assert.IsTrue(buf.AddCoordinate(10, 10));
            Assert.IsTrue(buf.InsertCoordinate(0, -10d, -10d, allowRepeated: false));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsFalse(buf.InsertCoordinate(0, -10d, -10d, allowRepeated: false));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsFalse(buf.InsertCoordinate(1, -10d, -10d, allowRepeated: false));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #22
0
        public void TestInsertCoordinates()
        {
            var buf = new CoordinateBuffer();

            Assert.IsTrue(buf.AddCoordinate(0, 0));

            Assert.IsTrue(buf.AddCoordinate(10, 10));
            Assert.AreEqual(2, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsTrue(buf.InsertCoordinate(0, -10d, -10d));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsTrue(buf.InsertCoordinate(0, -10d, -10d));
            Assert.AreEqual(4, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #23
0
        public void TestInsertCoordinatesDisallowRepeated()
        {
            var buf = new CoordinateBuffer();

            Assert.IsTrue(buf.AddCoordinate(0, 0));

            Assert.IsTrue(buf.AddCoordinate(10, 10));
            Assert.IsTrue(buf.InsertCoordinate(0, -10d, -10d, allowRepeated: false));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsFalse(buf.InsertCoordinate(0, -10d, -10d, allowRepeated: false));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            Assert.IsFalse(buf.InsertCoordinate(1, -10d, -10d, allowRepeated: false));
            Assert.AreEqual(3, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);
        }
コード例 #24
0
        public void TestAddMarkers()
        {
            var cb = new CoordinateBuffer(10);

            for (var i = 0; i < 10; i++)
            {
                if (i > 0 && i % 5 == 0)
                {
                    cb.AddMarker();
                }
                cb.AddCoordinate(i, i);
            }
            //cb.AddMarker();

            var seqs = cb.ToSequences();

            Assert.AreEqual(2, seqs.Length);
            Assert.AreEqual(5, seqs[0].Count);
            Assert.AreEqual(5, seqs[1].Count);
        }
コード例 #25
0
ファイル: ShapeReader.cs プロジェクト: klosejay/Gisoft.Map
        /// <summary>
        /// Creates a single Polygon with holes.
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        private IGeometry CreateSingleOrMultiPolygon(CoordinateBuffer buffer)
        {
            // Support vars
            var cses         = buffer.ToSequences();
            var shellRings   = new List <ILinearRing>();
            var holeRings    = new List <ILinearRing>();
            var numHoleRings = new Queue <int>();

            //Sort for shells and holes
            foreach (var cs in cses)
            {
                var ring = _factory.CreateLinearRing(cs);
                if (!ring.IsCCW)
                {
                    shellRings.Add(ring);
                    numHoleRings.Enqueue(holeRings.Count);
                }
                else
                {
                    holeRings.Add(ring);
                }
            }
            numHoleRings.Enqueue(holeRings.Count);

            if (shellRings.Count == 1)
            {
                return(_factory.CreatePolygon(shellRings[0], holeRings.ToArray()));
            }

            var polygons = new IPolygon[shellRings.Count];
            var offset   = numHoleRings.Dequeue();

            for (int i = 0; i < shellRings.Count; i++)
            {
                var shellRing = shellRings[i];
                var numHoles  = numHoleRings.Dequeue();
                var holes     = holeRings.GetRange(offset, numHoles - offset).ToArray();
                polygons[i] = _factory.CreatePolygon(shellRing, holes);
            }
            return(_factory.CreateMultiPolygon(polygons));
        }
コード例 #26
0
        private static void TestToSequenceMethod(CoordinateBufferToSequenceConverterHandler converter)
        {
            var rnd    = new Random(8894);
            var buffer = new CoordinateBuffer();

            for (var i = 0; i < NumCoordinates; i++)
            {
                buffer.AddCoordinate(rnd.NextDouble(), rnd.NextDouble());
            }

            System.Diagnostics.Trace.WriteLine(
                string.Format("\nConversion using {0} method", converter.Method.Name));

            var sw = new System.Diagnostics.Stopwatch();

            sw.Start();
            var seqCold = buffer.ToSequence(converter);

            sw.Stop();
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Cold converting sequence of {0} coordinates in {1}ms.", NumCoordinates, sw.ElapsedMilliseconds));

            long total = 0;

            foreach (var rndBuffer in (_randomCoordinateBuffers ?? (_randomCoordinateBuffers = RandomCoordinateBuffers(NumTests))))
            {
                sw.Stop();
                sw.Start();
                var seqWarm = rndBuffer.ToSequence(converter);
                sw.Stop();
                Assert.AreEqual(rndBuffer.Count, seqWarm.Count);
                total += sw.ElapsedTicks;
            }
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Warm converting {0} random coordinate buffers in {1}ticks.", NumTests, total));
        }
コード例 #27
0
        private static void TestAddCoordinatesOptional(double noDataValue = double.NaN)
        {
            Assert.IsFalse(0d.Equals(noDataValue), "noDataValue must not be 0");
            Assert.IsFalse(1d.Equals(noDataValue), "noDataValue must not be 1");

            var buf = new CoordinateBuffer(noDataValue);

            buf.AddCoordinate(0, 0, m: noDataValue);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            buf.Clear();
            buf.AddCoordinate(0, 0, m: 1);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XYM);

            buf.Clear();
            buf.AddCoordinate(0, 0, noDataValue);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            buf.Clear();
            buf.AddCoordinate(0, 0, 1);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XYZ);

            buf.Clear();
            buf.AddCoordinate(0, 0, noDataValue, noDataValue);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            buf.Clear();
            buf.AddCoordinate(0, 0, 1, 1);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XYZM);
        }
コード例 #28
0
 private static ICoordinateSequence ToCoordinateArray(CoordinateBuffer buffer)
 {
     return new CoordinateArraySequence(buffer.ToCoordinateArray());
 }
コード例 #29
0
        private static void TestToSequenceMethod(ICoordinateSequenceFactory factory)
        {
            var rnd = new Random(8894);
            var buffer = new CoordinateBuffer(NumCoordinates);

            for (var i = 0; i < NumCoordinates; i++)
                buffer.AddCoordinate(rnd.NextDouble(), rnd.NextDouble());

            System.Diagnostics.Trace.WriteLine(
                string.Format("\nConversion using {0} factory", (factory ?? GeoAPI.GeometryServiceProvider.Instance.DefaultCoordinateSequenceFactory).GetType().Name));

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            var seqCold = buffer.ToSequence(factory);
            sw.Stop();
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Cold converting sequence of {0} coordinates in {1}ms.", NumCoordinates, sw.ElapsedMilliseconds));
            long total = 0;
            foreach (var rndBuffer in (_randomCoordinateBuffers ?? (_randomCoordinateBuffers = RandomCoordinateBuffers(NumTests))))
            {

                sw.Stop();
                sw.Start();
                var seqWarm = rndBuffer.ToSequence(factory);
                sw.Stop();
                Assert.AreEqual(rndBuffer.Count, seqWarm.Count);
                total += sw.ElapsedTicks;
            }
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Warm converting {0} random coordinate buffers in {1}ticks.", NumTests, total));

        }
コード例 #30
0
        /// <summary>
        /// Function to read a <see cref="IMultiPoint"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read polygonal geometry</returns>
        public IGeometry ReadMultiPoint(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // jump boundingbox

            var numPoints = ReadNumPoints(reader);
            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, new[] { numPoints - 1 }, ordinates, buffer);
            return _factory.CreateMultiPoint(buffer.ToSequence());
        }
コード例 #31
0
 private static IEnumerable<CoordinateBuffer> RandomCoordinateBuffers(int numBuffers)
 {
     var rnd = new Random(numBuffers);
     var list = new List<CoordinateBuffer>(numBuffers);
     for (var i = 0; i < numBuffers; i++)
     {
         var numCoordinates = rnd.Next(100, 500);
         var buffer = new CoordinateBuffer(numCoordinates);
         for (var j = 0; j < numCoordinates; j++)
             buffer.AddCoordinate(rnd.NextDouble(), rnd.NextDouble());
         list.Add(buffer);
     }
     return list;
 }
コード例 #32
0
 private static void CheckDefinedFlags(CoordinateBuffer buffer, Ordinates defined)
 {
     Assert.AreEqual(defined, buffer.DefinedOrdinates, "Defined flags are not set correctly\nExpected: {0}, Actual: {1}", defined, buffer.DefinedOrdinates);
 }
コード例 #33
0
		public void BeginFigure(double x, double y, double? z, double? m)
		{
			if (_inFigure)
			{
				throw new ApplicationException();
			}
            _coordinateBuffer = new CoordinateBuffer();
			//_coordinates = new List<Coordinate>();
			AddCoordinate(x, y, z, m);
			_inFigure = true;
		}
コード例 #34
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="totalRecordLength">Total length of the record we are about 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 IGeometry Read(BigEndianBinaryReader file, int totalRecordLength, IGeometryFactory factory)
        {
            int totalRead = 0;
            var type = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);
            if (type == ShapeGeometryType.NullShape)
                return factory.CreatePolygon(null, null);

            if (type != ShapeType)
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));

            // Read and for now ignore bounds.
            var bblength = GetBoundingBoxLength();
            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
                boundingBox[boundingBoxIndex] = ReadDouble(file, totalRecordLength, ref totalRead);

            var numParts = ReadInt32(file, totalRecordLength, ref totalRead);
            var numPoints = ReadInt32(file, totalRecordLength, ref totalRead);
            var partOffsets = new int[numParts];
            for (var i = 0; i < numParts; i++)
                partOffsets[i] = ReadInt32(file, totalRecordLength, ref totalRead);

            var skippedList = new HashSet<int>();

            //var allPoints = new List<Coordinate>();
            var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var pm = factory.PrecisionModel;
            for (var part = 0; part < numParts; part++)
            {
                var start = partOffsets[part];
                var finish = (part == numParts - 1) 
                    ? numPoints 
                    : partOffsets[part + 1];
                
                var length = finish - start;
                for (var i = 0; i < length; i++)
                {
                    var x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    var y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));

                    // Thanks to Abhay Menon!
                    if (!(Coordinate.NullOrdinate.Equals(x) || Coordinate.NullOrdinate.Equals(y)))
                        buffer.AddCoordinate(x, y);
                    else
                        skippedList.Add(start + i);
                }
                //Add a marker that we have finished one part of the geometry
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the parts, let's read optional Z and M values
            // and populate Z in the coordinate before we start manipulating the segments
            // We have to track corresponding optional M values and set them up in the 
            // Geometries via ICoordinateSequence further down.
            GetZMValues(file, totalRecordLength, ref totalRead, buffer, skippedList);

            // Get the resulting sequences
            var sequences = buffer.ToSequences(factory.CoordinateSequenceFactory);
            var shells = new List<ILinearRing>();
            var holes = new List<ILinearRing>();
            for (var i = 0; i < sequences.Length; i++)
            {
                //Skip garbage input data with 0 points
                if (sequences[i].Count < 1) continue;

                var tmp = EnsureClosedSequence(sequences[i], factory.CoordinateSequenceFactory);
                var ring = factory.CreateLinearRing(tmp);
                if (ring.IsCCW)
                    holes.Add(ring);
                else
                    shells.Add(ring);
            }

            // Ensure the ring is encoded right
            if (shells.Count == 0 && holes.Count == 1)
            {
                shells.Add(factory.CreateLinearRing(holes[0].CoordinateSequence.Reversed()));
                holes.Clear();
            }


            // Now we have lists of all shells and all holes
            var holesForShells = new List<List<ILinearRing>>(shells.Count);
            for (var i = 0; i < shells.Count; i++)
                holesForShells.Add(new List<ILinearRing>());

            //Thanks to Bruno.Labrecque
            //Sort shells by area, rings should only be added to the smallest shell, that contains the ring
            shells.Sort(ProbeLinearRing);

            // Find holes
            foreach (var testHole in holes)
            {
                var testEnv = testHole.EnvelopeInternal;
                var testPt = testHole.GetCoordinateN(0);
                
                //We have the shells sorted
                for (var j = 0; j < shells.Count; j++)
                {
                    var tryShell = shells[j];
                    var tryEnv = tryShell.EnvelopeInternal;
                    var isContained = tryEnv.Contains(testEnv) && CGAlgorithms.IsPointInRing(testPt, tryShell.Coordinates);

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (isContained)
                    {
                        // 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.
                        var holesForThisShell = holesForShells[j];
                        holesForThisShell.Add(testHole);
                        
                        //Suggested by Bruno.Labrecque
                        //A LinearRing should only be added to one outer shell
                        break;
                    }
                }
            }

            var polygons = new IPolygon[shells.Count];
            for (var i = 0; i < shells.Count; i++)
                polygons[i] = (factory.CreatePolygon(shells[i], holesForShells[i].ToArray()));

            if (polygons.Length == 1)
                geom = polygons[0];
            else 
                geom = factory.CreateMultiPolygon(polygons);
      
            return geom;
        }
コード例 #35
0
 private static void CheckDefinedFlags(CoordinateBuffer buffer, Ordinates defined)
 {
     Assert.AreEqual(defined, buffer.DefinedOrdinates, "Defined flags are not set correctly\nExpected: {0}, Actual: {1}", defined, buffer.DefinedOrdinates);
 }
コード例 #36
0
 private static ICoordinateSequence ToPackedFloatArray(CoordinateBuffer buffer)
 {
     float[] pa;
     var dim = buffer.ToPackedArray(out pa);
     return new PackedDoubleCoordinateSequence(pa, dim);
 }
コード例 #37
0
        /// <summary>
        /// Function to read a either a <see cref="IPolygon"/> or an <see cref="IMultiPolygon"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read polygonal geometry</returns>
        protected IGeometry ReadPolygon(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // jump boundingbox

            var numParts = ReadNumParts(reader);
            var numPoints = ReadNumPoints(reader);
            var indexParts = ReadIndexParts(reader, numParts, numPoints);

            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, indexParts, ordinates, buffer);

            return numParts == 1
                ? _factory.CreatePolygon(_factory.CreateLinearRing(buffer.ToSequence()), null)
                : CreateSingleOrMultiPolygon(buffer);
        }
コード例 #38
0
        /*
         * protected static double[] ReadDoubles(BigEndianBinaryReader reader, int count)
         * {
         *  var result = new double[count];
         *  for (var i = 0; i < count; i++)
         *      result[i] = reader.ReadDouble();
         *  return result;
         * }
         */

        /// <summary>
        /// Get the z values and populate each one of them in Coordinate.Z
        /// If there are M values, return an array with those.
        /// </summary>
        /// <param name="file">The reader</param>
        /// <param name="totalRecordLength">Total number of bytes in this record</param>
        /// <param name="currentlyReadBytes">How many bytes are read from this record</param>
        /// <param name="buffer">The coordinate buffer</param>
        /// <param name="skippedList">A list of indices which have not been added to the buffer</param>
        protected void GetZMValues(BigEndianBinaryReader file, int totalRecordLength, ref int currentlyReadBytes, CoordinateBuffer buffer, HashSet <int> skippedList = null)
        {
            int numPoints = buffer.Capacity;

            if (HasZValue())
            {
                boundingBox[boundingBoxIndex++] = ReadDouble(file, totalRecordLength, ref currentlyReadBytes);
                boundingBox[boundingBoxIndex++] = ReadDouble(file, totalRecordLength, ref currentlyReadBytes);

                int numSkipped = 0;
                for (int i = 0; i < numPoints; i++)
                {
                    double z = ReadDouble(file, totalRecordLength, ref currentlyReadBytes);
                    if (skippedList?.Contains(i) != true)
                    {
                        buffer.SetZ(i - numSkipped, z);
                    }
                    else
                    {
                        numSkipped++;
                    }
                }
            }

            // Trond: Note that M value is always optional per the shapefile spec. So we need to test total read record bytes
            // v.s. read bytes to see if we have them or not
            // Also: If we have Z we might have M. Per shapefile defn.
            if ((HasMValue() || HasZValue()) && currentlyReadBytes < totalRecordLength)
            {
                boundingBox[boundingBoxIndex++] = ReadDouble(file, totalRecordLength, ref currentlyReadBytes);
                boundingBox[boundingBoxIndex++] = ReadDouble(file, totalRecordLength, ref currentlyReadBytes);

                int numSkipped = 0;
                for (int i = 0; i < numPoints; i++)
                {
                    double m = ReadDouble(file, totalRecordLength, ref currentlyReadBytes);
                    if (skippedList?.Contains(i) != true)
                    {
                        buffer.SetM(i - numSkipped, m);
                    }
                    else
                    {
                        numSkipped++;
                    }
                }
            }

            if (currentlyReadBytes < totalRecordLength)
            {
                int remaining = totalRecordLength - currentlyReadBytes;
                file.ReadBytes(remaining * 2);
            }
        }
コード例 #39
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="totalRecordLength">Total length of the record we are about 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, int totalRecordLength, IGeometryFactory geometryFactory)
        {
            int totalRead = 0;
            var type = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);
            if (type == ShapeGeometryType.NullShape)
                return geometryFactory.CreateMultiLineString(null);

            if (type != ShapeType)
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));

            // Read and for now ignore bounds.
            int bblength = GetBoundingBoxLength();
            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
            {
                double d = ReadDouble(file, totalRecordLength, ref totalRead);
                boundingBox[boundingBoxIndex] = d;
            }

            int numParts = ReadInt32(file, totalRecordLength, ref totalRead);
            int numPoints = ReadInt32(file, totalRecordLength, ref totalRead);
            int[] partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
                partOffsets[i] = ReadInt32(file, totalRecordLength, ref totalRead);

            var lines = new List<ILineString>(numParts);
            var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var pm = geometryFactory.PrecisionModel;

            for (var part = 0; part < numParts; part++)
            {
                var start = partOffsets[part];
                var finish = part == numParts - 1
                                 ? numPoints
                                 : partOffsets[part + 1];
                var length = finish - start;
                
                for (var i = 0; i < length; i++)
                {
                    var x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    var y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    buffer.AddCoordinate(x, y);
                }
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the parts, let's read optional Z and M values
            // and populate Z in the coordinate before we start manipulating the segments
            // We have to track corresponding optional M values and set them up in the 
            // Geometries via ICoordinateSequence further down.
            GetZMValues(file, totalRecordLength, ref totalRead, buffer);

            var sequences = new List<ICoordinateSequence>(buffer.ToSequences(geometryFactory.CoordinateSequenceFactory));

            for (var s = 0; s < sequences.Count; s++)
            {
                var points = sequences[s];

                //Skip garbage input data with 0 points
                if (points.Count < 1) continue;

                var createLineString = true;
                if (points.Count == 1)
                {
                    switch (GeometryInstantiationErrorHandling)
                    {
                        case GeometryInstantiationErrorHandlingOption.ThrowException:
                            break;
                        case GeometryInstantiationErrorHandlingOption.Empty:
                            sequences[s] = geometryFactory.CoordinateSequenceFactory.Create(0, points.Ordinates);
                            break;
                        case GeometryInstantiationErrorHandlingOption.TryFix:
                            sequences[s] = AddCoordinateToSequence(points, geometryFactory.CoordinateSequenceFactory,
                                points.GetOrdinate(0, Ordinate.X), points.GetOrdinate(0, Ordinate.Y),
                                points.GetOrdinate(0, Ordinate.Z), points.GetOrdinate(0, Ordinate.M));
                            break;
                        case GeometryInstantiationErrorHandlingOption.Null:
                            createLineString = false;
                            break;
                    }
                }

                if (createLineString)
                {
                    // Grabs m values if we have them
                    var line = geometryFactory.CreateLineString(points);
                    lines.Add(line);
                }
            }

            geom = (lines.Count != 1)
                ? (IGeometry)geometryFactory.CreateMultiLineString(lines.ToArray())
                : lines[0];          
            return geom;
        }
コード例 #40
0
        private static void TestToSequenceMethod(CoordinateBufferToSequenceConverterHandler converter)
        {
            var rnd = new Random(8894);
            var buffer = new CoordinateBuffer();

            for (var i = 0; i < NumCoordinates; i++)
                buffer.AddCoordinate(rnd.NextDouble(), rnd.NextDouble());

            System.Diagnostics.Trace.WriteLine(
                string.Format("\nConversion using {0} method", converter.Method.Name));

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            var seqCold = buffer.ToSequence(converter);
            sw.Stop();
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Cold converting sequence of {0} coordinates in {1}ms.", NumCoordinates, sw.ElapsedMilliseconds));
            
            long total = 0;
            foreach (var rndBuffer in (_randomCoordinateBuffers ?? (_randomCoordinateBuffers = RandomCoordinateBuffers(NumTests))))
            {
                sw.Stop();
                sw.Start();
                var seqWarm = rndBuffer.ToSequence(converter);
                sw.Stop();
                Assert.AreEqual(rndBuffer.Count, seqWarm.Count);
                total += sw.ElapsedTicks;
            }
            System.Diagnostics.Trace.WriteLine(
                string.Format("  Warm converting {0} random coordinate buffers in {1}ticks.", NumTests, total));

        }
コード例 #41
0
ファイル: ShapeReader.cs プロジェクト: klosejay/Gisoft.Map
        /// <summary>
        /// Method to read the coordinates block
        /// </summary>
        /// <param name="reader">The reader</param>
        /// <param name="numPoints">The total number of points to read</param>
        /// <param name="markers">The markers</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <param name="buffer">The buffer to add the coordinates to.</param>
        private static void ReadCoordinates(BinaryReader reader, int numPoints, int[] markers, Ordinates ordinates, CoordinateBuffer buffer)
        {
            var offset = buffer.Count;
            var j      = 0;

            // Add x- and y-ordinates
            for (var i = 0; i < numPoints; i++)
            {
                //Read x- and y- ordinates
                buffer.AddCoordinate(reader.ReadDouble(), reader.ReadDouble());

                //Check if we have reached a marker
                if (i != markers[j])
                {
                    continue;
                }

                //Add a marker
                buffer.AddMarker();
                j++;
            }

            // are there any z-ordinates
            if ((ordinates & Ordinates.Z) == Ordinates.Z)
            {
                //Read zInterval
                /*var zInterval = */ ReadInterval(reader);
                //Set the z-values
                for (var i = 0; i < numPoints; i++)
                {
                    buffer.SetZ(offset + i, reader.ReadDouble());
                }
            }
            if ((ordinates & Ordinates.M) == Ordinates.M)
            {
                //Read m-interval
                /*var mInterval = */ ReadInterval(reader);
                //Set the m-values
                for (var i = 0; i < numPoints; i++)
                {
                    buffer.SetZ(offset + i, reader.ReadDouble());
                }
            }
        }
コード例 #42
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="totalRecordLength">Total length of the record we are about 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, int totalRecordLength, IGeometryFactory geometryFactory)
        {
            int totalRead = 0;
            var type      = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);

            if (type == ShapeGeometryType.NullShape)
            {
                return(geometryFactory.CreatePolygon(null, null));
            }

            if (type != ShapeType)
            {
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));
            }

            // Read and for now ignore bounds.
            var bblength = GetBoundingBoxLength();

            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
            {
                boundingBox[boundingBoxIndex] = ReadDouble(file, totalRecordLength, ref totalRead);
            }

            var numParts    = ReadInt32(file, totalRecordLength, ref totalRead);
            var numPoints   = ReadInt32(file, totalRecordLength, ref totalRead);
            var partOffsets = new int[numParts];

            for (var i = 0; i < numParts; i++)
            {
                partOffsets[i] = ReadInt32(file, totalRecordLength, ref totalRead);
            }

            var skippedList = new HS();

            //var allPoints = new List<Coordinate>();
            var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var pm     = geometryFactory.PrecisionModel;

            for (var part = 0; part < numParts; part++)
            {
                var start  = partOffsets[part];
                var finish = (part == numParts - 1)
                    ? numPoints
                    : partOffsets[part + 1];

                var length = finish - start;
                for (var i = 0; i < length; i++)
                {
                    var x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    var y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));

                    // Thanks to Abhay Menon!
                    if (!(Coordinate.NullOrdinate.Equals(x) || Coordinate.NullOrdinate.Equals(y)))
                    {
                        buffer.AddCoordinate(x, y);
                    }
                    else
                    {
                        skippedList.Add(start + i);
                    }
                }
                //Add a marker that we have finished one part of the geometry
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the parts, let's read optional Z and M values
            // and populate Z in the coordinate before we start manipulating the segments
            // We have to track corresponding optional M values and set them up in the
            // Geometries via ICoordinateSequence further down.
            GetZMValues(file, totalRecordLength, ref totalRead, buffer, skippedList);

            // Get the resulting sequences
            var sequences = buffer.ToSequences(geometryFactory.CoordinateSequenceFactory);
            var shells    = new List <ILinearRing>();
            var holes     = new List <ILinearRing>();

            for (var i = 0; i < sequences.Length; i++)
            {
                var tmp  = EnsureClosedSequence(sequences[i], geometryFactory.CoordinateSequenceFactory);
                var ring = geometryFactory.CreateLinearRing(tmp);
                if (ring.IsCCW)
                {
                    holes.Add(ring);
                }
                else
                {
                    shells.Add(ring);
                }
            }

            // Ensure the ring is encoded right
            if (shells.Count == 0 && holes.Count == 1)
            {
                shells.Add(geometryFactory.CreateLinearRing(holes[0].CoordinateSequence.Reversed()));
                holes.Clear();
            }


            // Now we have lists of all shells and all holes
            var holesForShells = new List <List <ILinearRing> >(shells.Count);

            for (var i = 0; i < shells.Count; i++)
            {
                holesForShells.Add(new List <ILinearRing>());
            }

            //Thanks to Bruno.Labrecque
            //Sort shells by area, rings should only be added to the smallest shell, that contains the ring
            shells.Sort(ProbeLinearRing);

            // Find holes
            foreach (var testHole in holes)
            {
                var testEnv = testHole.EnvelopeInternal;
                var testPt  = testHole.GetCoordinateN(0);

                //We have the shells sorted
                for (var j = 0; j < shells.Count; j++)
                {
                    var tryShell    = shells[j];
                    var tryEnv      = tryShell.EnvelopeInternal;
                    var isContained = tryEnv.Contains(testEnv) && CGAlgorithms.IsPointInRing(testPt, tryShell.Coordinates);

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (isContained)
                    {
                        // 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.
                        var holesForThisShell = holesForShells[j];
                        holesForThisShell.Add(testHole);

                        //Suggested by Bruno.Labrecque
                        //A LinearRing should only be added to one outer shell
                        break;
                    }
                }
            }

            var polygons = new IPolygon[shells.Count];

            for (var i = 0; i < shells.Count; i++)
            {
                polygons[i] = (geometryFactory.CreatePolygon(shells[i], holesForShells[i].ToArray()));
            }

            if (polygons.Length == 1)
            {
                geom = polygons[0];
            }
            else
            {
                geom = geometryFactory.CreateMultiPolygon(polygons);
            }

            return(geom);
        }
コード例 #43
0
 private static ICoordinateSequence ToCoordinateArray(CoordinateBuffer buffer)
 {
     return(new CoordinateArraySequence(buffer.ToCoordinateArray()));
 }
コード例 #44
0
        public void TestAddMarkers()
        {
            var cb = new CoordinateBuffer(10);
            for (var i = 0; i < 10; i++)
            {
                if (i > 0 && i % 5 == 0)
                    cb.AddMarker();
                cb.AddCoordinate(i, i);
            }
            //cb.AddMarker();

            var seqs = cb.ToSequences();
            Assert.AreEqual(2, seqs.Length);
            Assert.AreEqual(5, seqs[0].Count);
            Assert.AreEqual(5, seqs[1].Count);
        }
コード例 #45
0
        /// <summary>
        /// Method to read the coordinates block
        /// </summary>
        /// <param name="reader">The reader</param>
        /// <param name="numPoints">The total number of points to read</param>
        /// <param name="markers">The markers</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <param name="buffer">The buffer to add the coordinates to.</param>
        private static void ReadCoordinates(BinaryReader reader, int numPoints, int[] markers, Ordinates ordinates, CoordinateBuffer buffer)
        {
            var offset = buffer.Count;
            var j = 0;

            // Add x- and y-ordinates
            for (var i = 0; i < numPoints; i++)
            {
                //Read x- and y- ordinates
                buffer.AddCoordinate(reader.ReadDouble(), reader.ReadDouble());

                //Check if we have reached a marker
                if (i != markers[j]) continue;

                //Add a marker
                buffer.AddMarker();
                j++;
            }

            // are there any z-ordinates
            if ((ordinates & Ordinates.Z) == Ordinates.Z)
            {
                //Read zInterval
                /*var zInterval = */ ReadInterval(reader);
                //Set the z-values
                for (var i = 0; i < numPoints; i++)
                    buffer.SetZ(offset + i, reader.ReadDouble());
            }
            if ((ordinates & Ordinates.M) == Ordinates.M)
            {
                //Read m-interval
                /*var mInterval = */ ReadInterval(reader);
                //Set the m-values
                for (var i = 0; i < numPoints; i++)
                    buffer.SetZ(offset + i, reader.ReadDouble());
            }
        }
コード例 #46
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="totalRecordLength">Total length of the record we are about 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 file, int totalRecordLength, GeometryFactory factory)
        {
            int totalRead = 0;
            var type      = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead);

            if (type == ShapeGeometryType.NullShape)
            {
                return(factory.CreateMultiLineString(null));
            }

            if (type != ShapeType)
            {
                throw new ShapefileException(string.Format("Encountered a '{0}' instead of a  '{1}'", type, ShapeType));
            }

            // Read and for now ignore bounds.
            int bblength = GetBoundingBoxLength();

            boundingBox = new double[bblength];
            for (; boundingBoxIndex < 4; boundingBoxIndex++)
            {
                double d = ReadDouble(file, totalRecordLength, ref totalRead);
                boundingBox[boundingBoxIndex] = d;
            }

            int numParts  = ReadInt32(file, totalRecordLength, ref totalRead);
            int numPoints = ReadInt32(file, totalRecordLength, ref totalRead);

            int[] partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = ReadInt32(file, totalRecordLength, ref totalRead);
            }

            var lines  = new List <LineString>(numParts);
            var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true);
            var pm     = factory.PrecisionModel;

            for (int part = 0; part < numParts; part++)
            {
                int start  = partOffsets[part];
                int finish = part == numParts - 1
                                 ? numPoints
                                 : partOffsets[part + 1];
                int length = finish - start;

                for (int i = 0; i < length; i++)
                {
                    double x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    double y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead));
                    buffer.AddCoordinate(x, y);
                }
                buffer.AddMarker();
            }

            // Trond Benum: We have now read all the parts, let's read optional Z and M values
            // and populate Z in the coordinate before we start manipulating the segments
            // We have to track corresponding optional M values and set them up in the
            // Geometries via CoordinateSequence further down.
            GetZMValues(file, totalRecordLength, ref totalRead, buffer);

            var sequences = new List <CoordinateSequence>(buffer.ToSequences(factory.CoordinateSequenceFactory));

            for (int s = 0; s < sequences.Count; s++)
            {
                var points = sequences[s];

                //Skip garbage input data with 0 points
                if (points.Count < 1)
                {
                    continue;
                }

                bool createLineString = true;
                if (points.Count == 1)
                {
                    switch (GeometryInstantiationErrorHandling)
                    {
                    case GeometryInstantiationErrorHandlingOption.ThrowException:
                        break;

                    case GeometryInstantiationErrorHandlingOption.Empty:
                        sequences[s] = factory.CoordinateSequenceFactory.Create(0, points.Ordinates);
                        break;

                    case GeometryInstantiationErrorHandlingOption.TryFix:
                        sequences[s] = AddCoordinateToSequence(points, factory.CoordinateSequenceFactory,
                                                               points.GetX(0), points.GetY(0),
                                                               points.GetZ(0), points.GetM(0));
                        break;

                    case GeometryInstantiationErrorHandlingOption.Null:
                        createLineString = false;
                        break;
                    }
                }

                if (createLineString)
                {
                    // Grabs m values if we have them
                    var line = factory.CreateLineString(points);
                    lines.Add(line);
                }
            }

            geom = (lines.Count != 1)
                ? (Geometry)factory.CreateMultiLineString(lines.ToArray())
                : lines[0];
            return(geom);
        }
コード例 #47
0
        /// <summary>
        /// Creates a single Polygon with holes.
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        private IGeometry CreateSingleOrMultiPolygon(CoordinateBuffer buffer)
        {
            // Support vars
            var cses = buffer.ToSequences();
            var shellRings = new List<ILinearRing>();
            var holeRings = new List<ILinearRing>();
            var numHoleRings = new Queue<int>();

            //Sort for shells and holes
            foreach (var cs in cses)
            {
                var ring = _factory.CreateLinearRing(cs);
                if (!ring.IsCCW)
                {
                    shellRings.Add(ring);
                    numHoleRings.Enqueue(holeRings.Count);
                }
                else
                    holeRings.Add(ring);
            }
            numHoleRings.Enqueue(holeRings.Count);

            if (shellRings.Count == 1)
                return _factory.CreatePolygon(shellRings[0], holeRings.ToArray());

            var polygons = new IPolygon[shellRings.Count];
            var offset = numHoleRings.Dequeue();
            for (int i = 0; i < shellRings.Count; i++)
            {
                var shellRing = shellRings[i];
                var numHoles = numHoleRings.Dequeue();
                var holes = holeRings.GetRange(offset, numHoles - offset).ToArray();
                polygons[i] = _factory.CreatePolygon(shellRing, holes);
            }
            return _factory.CreateMultiPolygon(polygons);            
        }
コード例 #48
0
 private static ICoordinateSequence ToDotSpatial(CoordinateBuffer buffer)
 {
     double[] z, m;
     var xy = buffer.ToXYZM(out z, out m);
     return new DotSpatialAffineCoordinateSequence(xy, z, m);
 }
コード例 #49
0
        private static void TestAddCoordinatesOptional(double noDataValue = double.NaN)
        {
            Assert.IsFalse(0d.Equals(noDataValue), "noDataValue must not be 0");
            Assert.IsFalse(1d.Equals(noDataValue), "noDataValue must not be 1");

            var buf = new CoordinateBuffer(noDataValue);

            buf.AddCoordinate(0, 0, m: noDataValue);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            buf.Clear();
            buf.AddCoordinate(0, 0, m: 1);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XYM);

            buf.Clear();
            buf.AddCoordinate(0, 0, noDataValue);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            buf.Clear();
            buf.AddCoordinate(0, 0, 1);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XYZ);

            buf.Clear();
            buf.AddCoordinate(0, 0, noDataValue, noDataValue);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XY);

            buf.Clear();
            buf.AddCoordinate(0, 0, 1, 1);
            Assert.AreEqual(1, buf.Count);
            CheckDefinedFlags(buf, Ordinates.XYZM);
        }