Example #1
0
        /// <summary>
        /// Find the nearest feature to worldPos out of a collection of candidates. If there is no geometry
        /// with a distance less than limit null is returned.
        /// </summary>
        /// <param name="candidates"></param>
        /// <param name="worldPos"></param>
        /// <param name="limit"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        private static IFeature FindNearestFeature(VectorLayer vectorLayer, IEnumerable candidates, ICoordinate worldPos,
                                                   float limit, out double distance)
        {
            IPoint point = GeometryFactory.CreatePoint(worldPos.X, worldPos.Y);

            IFeature current = null;

            distance = double.MaxValue;
            foreach (IFeature feature in candidates)
            {
                IGeometry geometry;
                if (vectorLayer.CustomRenderers.Count > 0)
                {
                    geometry = vectorLayer.CustomRenderers[0].GetRenderedFeatureGeometry(feature, vectorLayer);
                }
                else
                {
                    if (vectorLayer.CoordinateTransformation != null)
                    {
                        geometry = GeometryTransform.TransformGeometry(feature.Geometry, vectorLayer.CoordinateTransformation.MathTransform);
                    }
                    else
                    {
                        geometry = feature.Geometry;
                    }
                }
                double localDistance = geometry.Distance(point);
                if ((localDistance < distance) && (localDistance < limit))
                {
                    current  = feature;
                    distance = localDistance;
                }
            }
            return(current);
        }
Example #2
0
        protected IEnumerable <TrackerFeature> CreateTrackersForGeometry(IGeometry geometry)
        {
            var coordinates = geometry.Coordinates;

            if (coordinates.Length == 0)
            {
                yield break;
            }

            yield return(new TrackerFeature(this, GeometryFactory.CreatePoint(coordinates[0].X, coordinates[0].Y), 0,
                                            trackerSmallStart));

            for (var i = 1; i < coordinates.Length - 1; i++)
            {
                yield return
                    (new TrackerFeature(this, GeometryFactory.CreatePoint(coordinates[i].X, coordinates[i].Y), i,
                                        trackerSmall));
            }

            if (coordinates.Length > 1)
            {
                yield return
                    (new TrackerFeature(this, GeometryFactory.CreatePoint(coordinates.Last().X, coordinates.Last().Y),
                                        coordinates.Length - 1, trackerSmallEnd));
            }
        }
Example #3
0
        /// <summary>
        /// Returns the next feature at worldPos.
        /// </summary>
        /// <param name="worldPos"></param>
        /// <param name="limit"></param>
        /// <param name="outLayer"></param>
        /// the layer containing the next feature; null if no next feature is found.
        /// <param name="feature"></param>
        /// <param name="condition"></param>
        /// <returns>the next feature at worldPos, null if there is no next feature.</returns>
        public IFeature GetNextFeatureAtPosition(ICoordinate worldPos, float limit, out Layer outLayer, IFeature feature,
                                                 Func <ILayer, bool> condition)
        {
            IEnvelope envelope     = GetEnvelope(worldPos, limit);
            IFeature  nextFeature  = null;
            bool      featureFound = false;

            outLayer = null;

            foreach (ILayer mapLayer in Map.GetAllVisibleLayers(false))
            {
                var    vectorLayer = mapLayer as VectorLayer;
                IPoint point       = GeometryFactory.CreatePoint(worldPos);
                if (vectorLayer == null || !vectorLayer.IsSelectable)
                {
                    continue;
                }
                if ((null != condition) && (!condition(vectorLayer)))
                {
                    continue;
                }

                if (vectorLayer.DataSource != null)
                {
                    var objectsAt = vectorLayer.GetFeatures(envelope);
                    foreach (IFeature featureAt in objectsAt)
                    {
                        // GetFeatures(envelope) uses the geometry bounds; this results in more
                        // geometries than we actually are interested in (especially linestrings and polygons).
                        double distance = featureAt.Geometry.Distance(point);

                        if (distance >= limit)
                        {
                            continue;
                        }
                        if (featureFound)
                        {
                            nextFeature = featureAt;
                            outLayer    = vectorLayer;
                            return(nextFeature);
                        }
                        if (featureAt == feature)
                        {
                            featureFound = true;
                            continue;
                        }
                        if (null != nextFeature)
                        {
                            continue;
                        }
                        // If feature is last in collections objectsAt nextfeature is first
                        nextFeature = featureAt;
                        outLayer    = vectorLayer;
                    }
                }
            }
            return(nextFeature);
        }
Example #4
0
        public static IEnvelope GetEnvelope(ICoordinate worldPos, float radius)
        {
            // maak een rectangle in wereldcoordinaten ter grootte van 20 pixels rondom de click
            IPoint    p        = GeometryFactory.CreatePoint(worldPos);
            IEnvelope Envelope = (IEnvelope)p.EnvelopeInternal.Clone();

            Envelope.SetCentre(p, radius, radius);
            return(Envelope);
        }
Example #5
0
        public static IEnvelope GetEnvelope(ICoordinate worldPos, double width, double height)
        {
            // maak een rectangle in wereldcoordinaten ter grootte van 20 pixels rondom de click
            IPoint    p        = GeometryFactory.CreatePoint(worldPos.X, worldPos.Y);
            IEnvelope Envelope = (IEnvelope)p.EnvelopeInternal.Clone();

            Envelope.SetCentre(p, width, height);
            return(Envelope);
        }
Example #6
0
        public override TrackerFeature GetTrackerAtCoordinate(Coordinate worldPos)
        {
            var trackerFeature = base.GetTrackerAtCoordinate(worldPos);

            if (trackerFeature == null)
            {
                var org   = Layer.Map.ImageToWorld(new PointF(0, 0));
                var range = Layer.Map.ImageToWorld(new PointF(6, 6)); // todo make attribute
                if (SourceFeature.Geometry.Distance(GeometryFactory.CreatePoint(worldPos)) < Math.Abs(range.X - org.X))
                {
                    return(AllTracker);
                }
            }
            return(trackerFeature);
        }
        /// <summary>
        /// Reads and parses the geometry with ID 'oid' from the ShapeFile
        /// </summary>
        /// <remarks><see cref="FilterDelegate">Filtering</see> is not applied to this method</remarks>
        /// <param name="oid">Object ID</param>
        /// <returns>geometry</returns>
        private unsafe IGeometry ReadGeometry(int oid)
        {
            if (_ShapeType == ShapeType.Polygon || _ShapeType == ShapeType.PolygonM || _ShapeType == ShapeType.PolygonZ)
            {
                return(ReadPolygon(oid));
            }

            var dataPtr = zeroPtr + recordHeaders[oid].Offset + 8;
            var type    = *((ShapeType *)dataPtr);

            if (type == ShapeType.Null)
            {
                return(null);
            }

            dataPtr += 4;

            if (IsPoint)
            {
                var x = *((double *)dataPtr); dataPtr += 8;
                var y = *((double *)dataPtr);

                return(GeometryFactory.CreatePoint(x, y));
            }

            if (_ShapeType == ShapeType.Multipoint || _ShapeType == ShapeType.MultiPointM || _ShapeType == ShapeType.MultiPointZ)
            {
                dataPtr += 32; // min/max box

                var points  = new List <IPoint>();
                var nPoints = *(int *)dataPtr; // get the number of points
                dataPtr += 4;

                if (nPoints == 0)
                {
                    return(null);
                }

                for (var i = 0; i < nPoints; i++)
                {
                    var x = *((double *)dataPtr); dataPtr += 8;
                    var y = *((double *)dataPtr); dataPtr += 8;

                    points.Add(GeometryFactory.CreatePoint(x, y));
                }


                return(GeometryFactory.CreateMultiPoint(points.ToArray()));
            }

            if (_ShapeType == ShapeType.PolyLine || _ShapeType == ShapeType.Polygon ||
                _ShapeType == ShapeType.PolyLineM || _ShapeType == ShapeType.PolygonM ||
                _ShapeType == ShapeType.PolyLineZ || _ShapeType == ShapeType.PolygonZ)
            {
                dataPtr += 32;                // min/max

                int nParts = *(int *)dataPtr; // get number of parts (segments)
                dataPtr += 4;

                if (nParts == 0)
                {
                    return(null);
                }

                int nPoints = *((int *)dataPtr); // get number of points
                dataPtr += 4;

                var segments = new int[nParts + 1];

                //Read in the segment indexes
                for (int b = 0; b < nParts; b++)
                {
                    segments[b] = *((int *)dataPtr);
                    dataPtr    += 4;
                }

                //add end point
                segments[nParts] = nPoints;

                if ((int)_ShapeType % 10 == 3)
                {
                    var mline = new List <ILineString>();
                    for (var lineId = 0; lineId < nParts; lineId++)
                    {
                        var line = new List <Coordinate>();
                        for (var i = segments[lineId]; i < segments[lineId + 1]; i++)
                        {
                            var x = *((double *)dataPtr); dataPtr += 8;
                            var y = *((double *)dataPtr); dataPtr += 8;
                            line.Add(GeometryFactoryEx.CreateCoordinate(x, y));
                        }

                        //line.Vertices.Add(new SharpMap.Geometries.Point(
                        mline.Add(GeometryFactory.CreateLineString(line.ToArray()));
                    }

                    if (mline.Count == 1)
                    {
                        return(mline[0]);
                    }

                    return(GeometryFactory.CreateMultiLineString(mline.ToArray()));
                }

                // TODO: check it!
                //(_ShapeType == ShapeType.Polygon etc...)
                {
                    //First read all the rings
                    //List<SharpMap.Geometries.LinearRing> rings = new List<SharpMap.Geometries.LinearRing>();
                    var rings = new List <ILinearRing>();
                    for (int RingID = 0; RingID < nParts; RingID++)
                    {
                        //SharpMap.Geometries.LinearRing ring = new SharpMap.Geometries.LinearRing();
                        var ring = new List <Coordinate>();
                        for (int i = segments[RingID]; i < segments[RingID + 1]; i++)
                        {
                            ring.Add(GeometryFactoryEx.CreateCoordinate(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
                        }

                        // polygon should be closed, try to fix
                        if (!ring[ring.Count - 1].Equals2D(ring[0]))
                        {
                            ring.Add(GeometryFactoryEx.CreateCoordinate(ring[0].X, ring[0].Y));
                        }

                        //ring.Vertices.Add(new SharpMap.Geometries.Point
                        rings.Add(GeometryFactory.CreateLinearRing(ring.ToArray()));
                    }
                    var IsCounterClockWise = new bool[rings.Count];
                    int PolygonCount       = 0;
                    for (int i = 0; i < rings.Count; i++)
                    {
                        IsCounterClockWise[i] = GeometryFactory.IsCCW(rings[i].Coordinates);
                        if (!IsCounterClockWise[i])
                        {
                            PolygonCount++;
                        }
                    }
                    if (PolygonCount == 1) //We only have one polygon
                    {
                        ILinearRing shell = rings[0];
                        var         holes = new List <ILinearRing>();
                        if (rings.Count > 1)
                        {
                            for (int i = 1; i < rings.Count; i++)
                            {
                                holes.Add(rings[i]);
                            }
                        }
                        return(GeometryFactory.CreatePolygon(shell, holes.ToArray()));
                    }
                    else
                    {
                        var         polys = new List <IPolygon>();
                        ILinearRing shell = rings[0];
                        var         holes = new List <ILinearRing>();
                        for (int i = 1; i < rings.Count; i++)
                        {
                            if (!IsCounterClockWise[i])
                            {
                                polys.Add(GeometryFactory.CreatePolygon(shell, null));
                                shell = rings[i];
                            }
                            else
                            {
                                holes.Add(rings[i]);
                            }
                        }
                        polys.Add(GeometryFactory.CreatePolygon(shell, holes.ToArray()));
                        return(GeometryFactory.CreateMultiPolygon(polys.ToArray()));
                    }
                }
            }
            else
            {
                throw (new ApplicationException("Shapefile type " + _ShapeType.ToString() + " not supported"));
            }
        }