/// <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); }
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)); } }
/// <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); }
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); }
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); }
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")); } }