public static List<IFeature> Select(this IFeatureSet self, Shape shape, SpatialPredicate predicate = SpatialPredicate.Intersects)
        {
            var result = new List<IFeature>();
            var pg = new NetTopologySuite.Geometries.Prepared.PreparedGeometryFactory().Create(shape.ToGeoAPI());

            foreach (var feat in self.Features)
            {
                var valid = false;
                var tryShape = feat.ToShape().ToGeoAPI();
                switch (predicate)
                {
                    case SpatialPredicate.Intersects:
                        valid = pg.Intersects(tryShape);
                        break;
                    case SpatialPredicate.Overlaps:
                        valid = pg.Overlaps(tryShape);
                        break;
                    case SpatialPredicate.Touches:
                        valid = pg.Touches(tryShape);
                        break;
                    case SpatialPredicate.Within:
                        valid = pg.Within(tryShape);
                        break;
                    case SpatialPredicate.Contains:
                        valid = pg.Contains(tryShape);
                        break;
                    case SpatialPredicate.ContainsProperly:
                        valid = pg.ContainsProperly(tryShape);
                        break;
                    case SpatialPredicate.Covers:
                        valid = pg.Covers(tryShape);
                        break;
                    case SpatialPredicate.CoveredBy:
                        valid = pg.CoveredBy(tryShape);
                        break;
                    case SpatialPredicate.Disjoint:
                        valid = pg.Disjoint(tryShape);
                        break;
                }
                if (valid)
                    result.Add(feat);
            }
            return result;
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a new multi-part polygon shape.  Winding order should control holes.
        /// </summary>
        /// <param name="allParts">The list of all the lists of coordinates.</param>
        /// <returns>A new Multi-Polygon Shape.</returns>
        public Shape CreateMultiPolygonFromCoordinates(IEnumerable<IEnumerable<Coordinate>> allParts)
        {
            Shape shp = new Shape(FeatureType.Polygon);
            List<Coordinate> allCoords = new List<Coordinate>();
            List<int> offsets = new List<int>();
            List<int> counts = new List<int>();
            int count = 0;
            int numParts = 0;
            foreach (List<Coordinate> part in allParts)
            {
                int coordinatecount = 0;
                foreach (Coordinate c in part)
                {
                    allCoords.Add(c);
                    count++;
                    coordinatecount++;
                }
                offsets.Add(count);
                counts.Add(coordinatecount);
                numParts++;
            }

            shp.Vertices = new double[allCoords.Count * 2];
            for (int i = 0; i < allCoords.Count; i++)
            {
                shp.Vertices[i * 2] = allCoords[i].X;
                shp.Vertices[i * 2 + 1] = allCoords[i].Y;
            }
            ShapeRange result = new ShapeRange(FeatureType.Polygon);

            for (int i = 0; i < numParts; i++)
            {
                PartRange prt = new PartRange(shp.Vertices, 0, offsets[i], FeatureType.Polygon);
                prt.NumVertices = counts[i];
                result.Parts.Add(prt);
            }
            return shp;
        }
Esempio n. 3
0
        /// <summary>
        /// Finish the shape.
        /// </summary>
        /// <param name="sender">The object sender.</param>
        /// <param name="e">An empty EventArgs class.</param>
        public void FinishShape(object sender, EventArgs e)
        {
            if (_featureSet != null && !_featureSet.IsDisposed)
            {
                Feature f = null;
                if (_featureSet.FeatureType == FeatureType.MultiPoint)
                {
                    f = new Feature(new MultiPoint(_coordinates));
                }
                if (_featureSet.FeatureType == FeatureType.Line || _featureSet.FeatureType == FeatureType.Polygon)
                {
                    FinishPart(sender, e);
                    Shape shp = new Shape(_featureSet.FeatureType);
                    foreach (List<Coordinate> part in _parts)
                    {
                        if (part.Count >= 2)
                        {
                            shp.AddPart(part, _featureSet.CoordinateType);
                        }
                    }
                    f = new Feature(shp);
                }
                if (f != null)
                {
                    _featureSet.Features.Add(f);
                }
                _featureSet.InvalidateVertices();
                _featureSet.UpdateExtent();
            }

            _coordinates = new List<Coordinate>();
            _parts = new List<List<Coordinate>>();
        }
        /// <inheritdocs/>
        protected override Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp, IEnvelope envelope)
        {
            // Read from the index file because some deleted records
            // might still exist in the .shp file.
            long offset = (shx.Shapes[shp].ByteOffset);
            fs.Seek(offset, SeekOrigin.Begin);
            Shape myShape = new Shape();
            // Position     Value               Type        Number      Byte Order
            ShapeRange shape = new ShapeRange(FeatureType.Line);
            //--------------------------------------------------------------------
            shape.RecordNumber = fs.ReadInt32(Endian.BigEndian);
            // Byte 0       Record Number       Integer     1           Big
            shape.ContentLength = fs.ReadInt32(Endian.BigEndian);
            // Byte 4       Content Length      Integer     1           Big
            shape.ShapeType = (ShapeType)fs.ReadInt32();
            // Byte 8       Shape Type          Integer     1           Little
            shape.StartIndex = 0;
            if (shape.ShapeType == ShapeType.NullShape)
            {
                return null;
            }

            myShape.Range = shape;

            //bbReader.Read(allBounds, shp*32, 32);
            double xMin = fs.ReadDouble(); // Byte 12      Xmin                Double      1           Little
            double yMin = fs.ReadDouble(); // Byte 20      Ymin                Double      1           Little
            double xMax = fs.ReadDouble(); // Byte 28      Xmax                Double      1           Little
            double yMax = fs.ReadDouble(); // Byte 36      Ymax                Double      1           Little
            shape.Extent = new Extent(xMin, yMin, xMax, yMax);
            // Don't add this shape to the result
            if (envelope != null)
            {
                if (!myShape.Range.Extent.Intersects(envelope))
                {
                    return null;
                }
            }

            shape.NumParts = fs.ReadInt32(); // Byte 44      NumParts            Integer     1           Little
            //feature.NumPoints = bbReader.ReadInt32();             // Byte 48      NumPoints           Integer     1           Little
            shape.NumPoints = fs.ReadInt32();

            // Create an envelope from the extents box in the file.
            //feature.Envelope = new Envelope(xMin, xMax, yMin, yMax);
            int[] partIndices = fs.ReadInt32(shape.NumParts);
            myShape.Vertices = fs.ReadDouble(shape.NumPoints * 2);

            if (header.ShapeType == ShapeType.PolyLineM)
            {
                // These are listed as "optional" but there isn't a good indicator of how to determine if they were added.
                // To handle the "optional" M values, check the contentLength for the feature.
                // The content length does not include the 8-byte record header and is listed in 16-bit words.
                if (shape.ContentLength * 2 > 44 + 4 * shape.NumParts + 16 * shape.NumPoints)
                {
                    myShape.MinM = fs.ReadDouble();
                    myShape.MaxM = fs.ReadDouble();

                    myShape.M = fs.ReadDouble(shape.NumPoints);
                    shape.Extent = new ExtentM(shape.Extent, myShape.MinM, myShape.MaxM);
                }
            }
            else if (header.ShapeType == ShapeType.PolyLineZ)
            {
                bool hasM = shape.ContentLength * 2 > 60 + 4 * shape.NumParts + 24 * shape.NumPoints;
                myShape.MinZ = fs.ReadDouble();
                myShape.MaxZ = fs.ReadDouble();

                // For Z shapefiles, the Z part is not optional.
                myShape.Z = fs.ReadDouble(shape.NumPoints);

                // These are listed as "optional" but there isn't a good indicator of how to determine if they were added.
                // To handle the "optional" M values, check the contentLength for the feature.
                // The content length does not include the 8-byte record header and is listed in 16-bit words.)
                if (hasM)
                {
                    myShape.MinM = fs.ReadDouble();
                    myShape.MaxM = fs.ReadDouble();
                    myShape.M = fs.ReadDouble(shape.NumPoints);
                    shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, myShape.MinM, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, myShape.MaxM, myShape.MaxZ);
                }
                else
                    shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, double.MaxValue, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, double.MinValue, myShape.MaxZ);
            }

            myShape.Range = shape;

            for (int part = 0; part < shape.NumParts; part++)
            {
                int partOff = partIndices[part];
                int pointCount = shape.NumPoints - partOff;
                if (part < shape.NumParts - 1)
                {
                    pointCount = partIndices[part + 1] - partOff;
                }
                PartRange partR = new PartRange(myShape.Vertices, 0, partOff, FeatureType.Line) { NumVertices = pointCount };
                shape.Parts.Add(partR);
            }
            return myShape;
        }
Esempio n. 5
0
        /// <inheritdoc/>
        public void AddShape(Shape shape)
        {
            IFeature addedFeature;

            // This first section controls the indices which need to happen regardless
            // because drawing uses indices even if editors like working with features.
            int count = (_vertices != null) ? _vertices.Length / 2 : 0; // Original number of points
            int totalCount = shape.Range.NumPoints + count;
            int start = shape.Range.StartIndex;
            int num = shape.Range.NumPoints;

            double[] vertices = new double[totalCount * 2];
            if (_vertices != null)
            {
                Array.Copy(_vertices, 0, vertices, 0, _vertices.Length);
            }

            if (shape.Vertices != null)
            {
                Array.Copy(shape.Vertices, start * 2, vertices, count * 2, num * 2);
                if (_m != null || shape.M != null)
                {
                    double[] m = new double[totalCount];
                    if (_m != null)
                    {
                        Array.Copy(_m, 0, m, 0, _m.Length);
                    }

                    if (shape.M != null)
                    {
                        Array.Copy(shape.Vertices, start, m, count, num);
                    }

                    _m = m;
                }

                if (_z != null || shape.Z != null)
                {
                    double[] z = new double[totalCount];
                    if (_z != null)
                    {
                        Array.Copy(_z, 0, z, 0, _z.Length);
                    }

                    if (shape.Z != null)
                    {
                        Array.Copy(shape.Vertices, start, z, count, num);
                    }

                    _z = z;
                }
            }

            shape.Range.StartIndex = count;
            ShapeIndices.Add(shape.Range);
            Vertex = vertices;
            if (Extent == null)
            {
                Extent = new Extent();
            }

            Extent.ExpandToInclude(shape.Range.Extent);

            if (!IndexMode)
            {
                // Just add a new feature
                addedFeature = new Feature(shape);

                Features.Add(addedFeature);
                addedFeature.DataRow = AddAttributes(shape);
                if (!shape.Range.Extent.IsEmpty())
                {
                    Extent.ExpandToInclude(new Extent(addedFeature.Envelope));
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// handles the attributes while adding a shape
        /// </summary>
        /// <param name="shape">
        /// </param>
        /// <returns>
        /// A data row, but only if attributes are populated
        /// </returns>
        private DataRow AddAttributes(Shape shape)
        {
            // Handle attributes if the array is not null.  Assumes compatible schema.
            if (shape.Attributes != null)
            {
                DataColumn[] columns = GetColumns();
                Dictionary<string, object> rowContent = new Dictionary<string, object>();
                object[] fixedContent = new object[columns.Length];
                DataRow addedRow;
                if (shape.Attributes.Length != columns.Length)
                {
                    throw new ArgumentException("Attribute column count mismatch.");
                }

                for (int iField = 0; iField < columns.Length; iField++)
                {
                    object value = shape.Attributes[iField];
                    if (value != null)
                    {
                        if (columns[iField].DataType != value.GetType())
                        {
                            // this may throw an exception if the type casting fails
                            value = Convert.ChangeType(value, columns[iField].DataType);
                        }

                        fixedContent[iField] = value;
                        rowContent.Add(columns[iField].ColumnName, value);
                    }
                }

                if (AttributesPopulated)
                {
                    // just add a new DataRow
                    addedRow = _dataTable.NewRow();
                    addedRow.ItemArray = fixedContent;
                    return addedRow;
                }

                // Insert a new row in the source
                AddRow(rowContent);
            }

            return null;
        }
Esempio n. 7
0
        /// <inheritdoc/>
        public virtual Shape GetShape(int index, bool getAttributes)
        {
            if (IndexMode == false)
            {
                return new Shape(Features[index]);
            }

            Shape result = new Shape(FeatureType);

            // This will also deep copy the parts, attributes and vertices
            ShapeRange range = ShapeIndices[index];
            result.Range = range.Copy();
            int start = range.StartIndex;
            int numPoints = range.NumPoints;

            if (_z != null && (_z.Length - start) >= numPoints)
            {
                result.Z = new double[numPoints];
                Array.Copy(_z, start, result.Z, 0, numPoints);
            }

            if (_m != null && (_m.Length - start) >= numPoints)
            {
                result.M = new double[numPoints];
                Array.Copy(_m, start, result.M, 0, numPoints);
            }

            double[] vertices = new double[numPoints * 2];
            Array.Copy(_vertices, start * 2, vertices, 0, numPoints * 2);
            result.Vertices = vertices;

            // There is presumed to be only a single shape in the output array.
            result.Range.StartIndex = 0;
            if (AttributesPopulated)
            {
                if (getAttributes)
                {
                    result.Attributes = DataTable.Rows[index].ItemArray;
                }
            }
            else
            {
                DataTable dt = GetAttributes(index, 1);
                if (dt != null && dt.Rows.Count > 0)
                {
                    result.Attributes = dt.Rows[0].ItemArray;
                }
            }

            return result;
        }
        /// <inheritdocs/>
        public Shape[] GetShapes(int[] indices)
        {
            Shape[] result = new Shape[indices.Length];

            ShapefileIndexFile shx = CacheShapeIndexFile();

            // Check to ensure the fileName is not null
            if (Filename == null)
            {
                throw new NullReferenceException(Filename);
            }

            if (File.Exists(Filename) == false)
            {
                throw new FileNotFoundException(Filename);
            }

            // Get the basic header information.
            ShapefileHeader header = new ShapefileHeader(Filename);

            // Check to ensure that the fileName is the correct shape type
            if (header.ShapeType != ShapeType &&
                 header.ShapeType != ShapeTypeM &&
                 header.ShapeType != ShapeTypeZ)
            {
                throw new ArgumentException("Wrong feature type.");
            }

            FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            try
            {
                if (fs.Length == 100)
                {
                    // The shapefile is empty so we can simply return here
                    return result;
                }
                int numShapes = shx.Shapes.Count;
                for (int j = 0; j < indices.Length; j++)
                {
                    int index = indices[j];
                    if (index < numShapes)
                        result[j] = GetShapeAtIndex(fs, shx, header, index, null);
                }
                return result;
            }
            finally
            {
                fs.Close();
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Tests the intersection with a shape
 /// </summary>
 /// <param name="shape"></param>
 /// <returns></returns>
 public bool Intersects(Shape shape)
 {
     return Intersects(shape.Range);
 }
Esempio n. 10
0
        private static Shape ReadMultiPolygon(Stream data)
        {
            Shape result = new Shape(FeatureType.Polygon);
            int numPolygons = ReadInt32(data);
            List<double[]> rings = new List<double[]>();
            int partOffset = 0;
            for (int iPoly = 0; iPoly < numPolygons; iPoly++)
            {
                data.Seek(5, SeekOrigin.Current); // endian and geometry type
                int numRings = ReadInt32(data);
                for (int iRing = 0; iRing < numRings; iRing++)
                {
                    int numPoints = ReadInt32(data); // ring structures are like a linestring without the final point.
                    double[] coords = ReadDouble(data, 2 * numPoints);
                    if (iRing == 0)
                    {
                        // By shapefile standard, the shell should be clockwise
                        if (IsCounterClockwise(coords))
                            coords = ReverseCoords(coords);
                    }
                    else
                    {
                        // By shapefile standard, the holes should be counter clockwise.
                        if (!IsCounterClockwise(coords))
                            coords = ReverseCoords(coords);
                    }
                    PartRange lPrt = new PartRange(FeatureType.Polygon);
                    lPrt.PartOffset = partOffset;
                    lPrt.NumVertices = numPoints;
                    result.Range.Parts.Add(lPrt);
                    partOffset += coords.Length / 2;
                    rings.Add(coords);
                }
            }

            double[] allVertices = new double[partOffset * 2];
            int offset = 0;
            foreach (double[] ring in rings)
            {
                Array.Copy(ring, 0, allVertices, offset, ring.Length);
                offset += ring.Length;
            }
            result.Vertices = allVertices;
            return result;
        }
Esempio n. 11
0
 private static Shape ReadMultiLineString(Stream data)
 {
     Shape result = new Shape(FeatureType.Line);
     int numLineStrings = ReadInt32(data);
     List<double[]> strings = new List<double[]>();
     int partOffset = 0;
     for (int iString = 0; iString < numLineStrings; iString++)
     {
         // Each of these needs to read a full WKBLineString
         data.Seek(5, SeekOrigin.Current); //ignore header
         int numPoints = ReadInt32(data);
         double[] coords = ReadDouble(data, 2 * numPoints);
         PartRange lPrt = new PartRange(FeatureType.Line);
         lPrt.PartOffset = partOffset;
         lPrt.NumVertices = numPoints;
         result.Range.Parts.Add(lPrt);
         partOffset += coords.Length / 2;
         strings.Add(coords);
     }
     double[] allVertices = new double[partOffset * 2];
     int offset = 0;
     foreach (double[] ring in strings)
     {
         Array.Copy(ring, 0, allVertices, offset, ring.Length);
         offset += ring.Length;
     }
     result.Vertices = allVertices;
     return result;
 }
Esempio n. 12
0
 private static Shape ReadLineString(Stream data)
 {
     Shape result = new Shape(FeatureType.Line);
     int count = ReadInt32(data);
     double[] coords = ReadDouble(data, 2 * count);
     PartRange lPrt = new PartRange(FeatureType.Line);
     lPrt.NumVertices = count;
     result.Range.Parts.Add(lPrt);
     result.Vertices = coords;
     return result;
 }
Esempio n. 13
0
 /// <summary>
 /// Reads one multipoint shape from a data stream.
 /// (this assumes that the two bytes (endian and type) have already been read.
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 private static Shape ReadMultiPoint(Stream data)
 {
     Shape result = new Shape(FeatureType.MultiPoint);
     int count = ReadInt32(data);
     PartRange prt = new PartRange(FeatureType.MultiPoint);
     prt.NumVertices = count;
     result.Range.Parts.Add(prt);
     double[] vertices = new double[count * 2];
     for (int iPoint = 0; iPoint < count; iPoint++)
     {
         data.ReadByte(); // ignore endian
         ReadInt32(data); // ignore geometry type
         double[] coord = ReadDouble(data, 2);
         Array.Copy(coord, 0, vertices, iPoint * 2, 2);
     }
     result.Vertices = vertices;
     return result;
 }
Esempio n. 14
0
 /// <summary>
 /// This assumes that the byte order and shapetype have already been read.
 /// </summary>
 /// <param name="data"></param>
 public static Shape ReadPoint(Stream data)
 {
     Shape result = new Shape();
     result.Range = new ShapeRange(FeatureType.Point);
     PartRange prt = new PartRange(FeatureType.Point);
     prt.NumVertices = 1;
     result.Range.Parts.Add(prt);
     result.Vertices = ReadDouble(data, 2);
     return result;
 }
        /// <inheritdocs/>
        protected override Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp, IEnvelope envelope)
        {
            // Read from the index file because some deleted records
            // might still exist in the .shp file.
            long offset = (shx.Shapes[shp].ByteOffset);
            fs.Seek(offset, SeekOrigin.Begin);
            Shape myShape = new Shape();
            // Position     Value               Type        Number      Byte Order
            ShapeRange shape = new ShapeRange(FeatureType.Point); //--------------------------------------------------------------------
            shape.RecordNumber = fs.ReadInt32(Endian.BigEndian);     // Byte 0       Record Number       Integer     1           Big
            shape.ContentLength = fs.ReadInt32(Endian.BigEndian);    // Byte 4       Content Length      Integer     1           Big
            ShapeType shapeType = (ShapeType)fs.ReadInt32(); // Byte 8       Shape Type          Integer     1           Little
            if (shapeType == ShapeType.NullShape)
            {
                return null;
            }
            double[] vertices = fs.ReadDouble(2);
            double x = vertices[0], y = vertices[1];
            // Don't add this shape to the result
            if (envelope != null)
            {
                if (!envelope.Contains(new Coordinate(x, y)))
                {
                    return null;
                }
            }

            shape.StartIndex = 0;
            shape.NumParts = 1;
            shape.NumPoints = 1;
            shape.ShapeType = shapeType;
            shape.Extent = new Extent(x, y, x, y);
            myShape.Range = shape;
            myShape.Vertices = vertices;

            if (header.ShapeType == ShapeType.PointM)
            {
                myShape.M = fs.ReadDouble(1);
                myShape.MinM = myShape.MaxM = myShape.M[0];
                shape.Extent = new ExtentM(shape.Extent, myShape.MinM, myShape.MaxM);
            }
            else if (header.ShapeType == ShapeType.PointZ)
            {
                // For Z shapefiles, the Z part is not optional.
                myShape.Z = fs.ReadDouble(1);
                myShape.MinZ = myShape.MaxZ = myShape.Z[0];
                myShape.M = fs.ReadDouble(1);
                myShape.MinM = myShape.MaxM = myShape.M[0];
                shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, myShape.MinM, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, myShape.MaxM, myShape.MaxZ);
            }

            PartRange partR = new PartRange(myShape.Vertices, 0, 0, FeatureType.Point) { NumVertices = 1 };
            shape.Parts.Add(partR);
            myShape.Range = shape;

            return myShape;
        }