/// <summary> /// Adds a new vertex. /// </summary> /// <param name="latitude"></param> /// <param name="longitude"></param> /// <returns></returns> public override uint AddVertex(float latitude, float longitude) { if (_readonly) { throw new Exception("Graph is readonly."); } // create vertex. var newId = _nextVertexId; var vertexIdx = newId * VERTEX_SIZE; if (vertexIdx + 1 >= _vertices.Length) { this.IncreaseVertexSize(); } _coordinates[newId] = new GeoCoordinateSimple() { Latitude = latitude, Longitude = longitude }; _vertices[vertexIdx + EDGE_COUNT] = 0; _nextVertexId++; // increase for next vertex. return(newId); }
/// <summary> /// Adds another line location to this one. /// </summary> /// <param name="location"></param> public void Add(ReferencedLine location) { if (this.Vertices[this.Vertices.Length - 1] == location.Vertices[0]) { // there is a match. // merge vertices. var vertices = new long[this.Vertices.Length + location.Vertices.Length - 1]; this.Vertices.CopyTo(vertices, 0); for (int idx = 1; idx < location.Vertices.Length; idx++) { vertices[this.Vertices.Length + idx - 1] = location.Vertices[idx]; } this.Vertices = vertices; // merge edges. var edges = new LiveEdge[this.Edges.Length + location.Edges.Length]; this.Edges.CopyTo(edges, 0); location.Edges.CopyTo(edges, this.Edges.Length); this.Edges = edges; // merge edge shapes. var edgeShapes = new GeoCoordinateSimple[this.Edges.Length + location.Edges.Length][]; this.EdgeShapes.CopyTo(edgeShapes, 0); location.EdgeShapes.CopyTo(edgeShapes, this.EdgeShapes.Length); this.EdgeShapes = edgeShapes; return; } throw new Exception("Cannot add a location without them having one vertex incommon."); }
public static FeatureCollection GetFeaturesIn(this RouterDb db, float minLatitude, float minLongitude, float maxLatitude, float maxLongitude) { RoutingNetwork network = db.Network; FeatureCollection featureCollection = new FeatureCollection(); HashSet <uint> uintSet1 = network.GeometricGraph.Search(minLatitude, minLongitude, maxLatitude, maxLongitude); HashSet <long> longSet = new HashSet <long>(); RoutingNetwork.EdgeEnumerator edgeEnumerator = network.GetEdgeEnumerator(); HashSet <uint> uintSet2 = new HashSet <uint>(); foreach (uint vertex1 in uintSet1) { GeoCoordinateSimple vertex2 = network.GeometricGraph.GetVertex(vertex1); featureCollection.Add(new Feature((Geometry) new Point(new GeoCoordinate((double)vertex2.Latitude, (double)vertex2.Longitude)), (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>) new Tag[1] { Tag.Create("id", vertex1.ToInvariantString()) }))); edgeEnumerator.MoveTo(vertex1); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { if (!longSet.Contains((long)edgeEnumerator.Id)) { longSet.Add((long)edgeEnumerator.Id); List <ICoordinate> shape = network.GetShape(edgeEnumerator.Current); List <GeoCoordinate> geoCoordinateList = new List <GeoCoordinate>(); foreach (ICoordinate coordinate in shape) { geoCoordinateList.Add(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude)); } LineString lineString = new LineString((IEnumerable <GeoCoordinate>)geoCoordinateList); RouterDb db1 = db; EdgeData data = edgeEnumerator.Data; int profile = (int)data.Profile; data = edgeEnumerator.Data; int metaId = (int)data.MetaId; TagsCollectionBase profileAndMeta = db1.GetProfileAndMeta((uint)profile, (uint)metaId); profileAndMeta.AddOrReplace(Tag.Create("id", edgeEnumerator.Id.ToInvariantString())); featureCollection.Add(new Feature((Geometry)lineString, (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>)profileAndMeta))); if (!uintSet1.Contains(edgeEnumerator.To)) { uintSet2.Add(edgeEnumerator.To); } } } } foreach (uint vertex1 in uintSet2) { GeoCoordinateSimple vertex2 = network.GeometricGraph.GetVertex(vertex1); featureCollection.Add(new Feature((Geometry) new Point(new GeoCoordinate((double)vertex2.Latitude, (double)vertex2.Longitude)), (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>) new Tag[1] { Tag.Create("id", vertex1.ToInvariantString()) }))); } return(featureCollection); }
/// <summary> /// Returns a simple array. /// </summary> /// <param name="coordinates"></param> /// <returns></returns> public static GeoCoordinateSimple[] ToSimpleArray(SerializableCoordinate[] coordinates) { if (coordinates == null) { return(null); } var simples = new GeoCoordinateSimple[coordinates.Length]; for (int idx = 0; idx < coordinates.Length; idx++) { simples[idx].Latitude = coordinates[idx].Latitude; simples[idx].Longitude = coordinates[idx].Longitude; } return(simples); }
/// <summary> /// Tries to the the coordinate at the given index. /// </summary> /// <param name="idx"></param> /// <param name="coordinate"></param> /// <returns></returns> public bool TryGet(long idx, out ICoordinate coordinate) { bool value = this.Contains(idx); if (value) { coordinate = new GeoCoordinateSimple() { Latitude = _coordinates[idx * 2], Longitude = _coordinates[(idx * 2) + 1] }; return(true); } coordinate = null; return(false); }
/// <summary> /// Adds a new vertex. /// </summary> /// <param name="latitude"></param> /// <param name="longitude"></param> /// <returns></returns> public uint AddVertex(float latitude, float longitude) { // make sure vertices array is large enough. if (_nextVertexId >= _vertices.Length) { this.IncreaseVertexSize(); } // create vertex. uint newId = _nextVertexId; _coordinates[newId] = new GeoCoordinateSimple() { Latitude = latitude, Longitude = longitude }; _nextVertexId++; // increase for next vertex. return(newId); }
/// <summary> /// Adds a new arc. /// </summary> public void AddEdge(long vertex1, long vertex2, TEdge edge, GeoCoordinateSimple[] shape) { if (shape == null) { this.AddEdge(vertex1, vertex2, edge); return; } _newEdges.Add(new KeyValuePair <long, KeyValuePair <long, Tuple <TEdge, ICoordinateCollection> > >( vertex1, new KeyValuePair <long, Tuple <TEdge, ICoordinateCollection> >(vertex2, new Tuple <TEdge, ICoordinateCollection>(edge, new CoordinateArrayCollection <GeoCoordinateSimple>(shape))))); var reverseShape = new GeoCoordinateSimple[shape.Length]; for (var i = 0; i < shape.Length; i++) { reverseShape[shape.Length - 1 - i] = shape[i]; } _newEdges.Add(new KeyValuePair <long, KeyValuePair <long, Tuple <TEdge, ICoordinateCollection> > >( vertex2, new KeyValuePair <long, Tuple <TEdge, ICoordinateCollection> >(vertex1, new Tuple <TEdge, ICoordinateCollection>( (TEdge)edge.Reverse(), new CoordinateArrayCollection <GeoCoordinateSimple>(reverseShape))))); }
/// <summary> /// Returns the simple array. /// </summary> /// <returns></returns> public static GeoCoordinateSimple[] ToSimpleArray(this ICoordinateCollection collection) { if (collection == null) { return(null); } var array = new GeoCoordinateSimple[collection.Count]; int idx = 0; collection.Reset(); while (collection.MoveNext()) { array[idx] = new GeoCoordinateSimple() { Latitude = collection.Latitude, Longitude = collection.Longitude }; idx++; } return(array); }
/// <summary> /// Creates a new object that is a copy of the current instance. /// </summary> /// <returns></returns> public override object Clone() { GeoCoordinateSimple[][] edgeShapes = null; if (this.EdgeShapes != null) { edgeShapes = new GeoCoordinateSimple[this.EdgeShapes.Length][]; for (var i = 0; i < edgeShapes.Length; i++) { edgeShapes[i] = edgeShapes[i] == null ? null : edgeShapes[i].Clone() as GeoCoordinateSimple[]; } } return(new ReferencedLine(_graph) { Edges = this.Edges == null ? null : this.Edges.Clone() as LiveEdge[], Vertices = this.Vertices == null ? null : this.Vertices.Clone() as long[], EdgeShapes = edgeShapes, NegativeOffsetPercentage = this.NegativeOffsetPercentage, PositiveOffsetPercentage = this.PositiveOffsetPercentage }); }
/// <summary> /// Adds a new vertex. /// </summary> /// <param name="latitude"></param> /// <param name="longitude"></param> /// <returns></returns> public uint AddVertex(float latitude, float longitude) { // create vertex. var newId = _nextVertexId; var vertexIdx = newId * VERTEX_SIZE; if (vertexIdx + 1 >= _vertices.Length) { this.IncreaseVertexSize(); } _coordinates[newId] = new GeoCoordinateSimple() { Latitude = latitude, Longitude = longitude }; // _vertices[vertexIdx + FIRST_EDGE] = NO_EDGE; _vertices[vertexIdx + EDGE_COUNT] = 0; _nextVertexId++; // increase for next vertex. return(newId); }
/// <summary> /// Gets the shape associated with the given edge and returns true if it exists. /// </summary> /// <param name="vertex1"></param> /// <param name="vertex2"></param> /// <param name="shape"></param> /// <returns></returns> public bool GetEdgeShape(uint vertex1, uint vertex2, out GeoCoordinateSimple[] shape) { long edgeDataIdx; bool edgeDataForward; if (this.GetEdgeIdx(vertex1, vertex2, out edgeDataIdx, out edgeDataForward)) { // the edge exists. shape = _edgeShapes[edgeDataIdx]; if (!edgeDataForward && shape != null) { // edge is backward. var reverse = new GeoCoordinateSimple[shape.Length]; for (int idx = 0; idx < shape.Length; idx++) { reverse[idx] = shape[shape.Length - idx - 1]; } shape = reverse; } return(true); } shape = null; return(false); }
public static FeatureCollection GetFeaturesIn(this GeometricGraph graph, float minLatitude, float minLongitude, float maxLatitude, float maxLongitude) { FeatureCollection featureCollection = new FeatureCollection(); HashSet <uint> uintSet = graph.Search(minLatitude, minLongitude, maxLatitude, maxLongitude); HashSet <long> longSet = new HashSet <long>(); GeometricGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(); foreach (uint vertex1 in uintSet) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); featureCollection.Add(new Feature((Geometry) new Point(new GeoCoordinate((double)vertex2.Latitude, (double)vertex2.Longitude)), (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>) new Tag[1] { Tag.Create("id", vertex1.ToInvariantString()) }))); edgeEnumerator.MoveTo(vertex1); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { if (!longSet.Contains((long)edgeEnumerator.Id)) { longSet.Add((long)edgeEnumerator.Id); List <ICoordinate> shape = graph.GetShape(edgeEnumerator.Current); List <GeoCoordinate> geoCoordinateList = new List <GeoCoordinate>(); foreach (ICoordinate coordinate in shape) { geoCoordinateList.Add(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude)); } LineString lineString = new LineString((IEnumerable <GeoCoordinate>)geoCoordinateList); featureCollection.Add(new Feature((Geometry)lineString, (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>) new Tag[1] { Tag.Create("id", edgeEnumerator.Id.ToInvariantString()) }))); } } } return(featureCollection); }
public static FeatureCollection GetFeatures(this RouterDb db) { RoutingNetwork network = db.Network; FeatureCollection featureCollection = new FeatureCollection(); HashSet <long> longSet = new HashSet <long>(); RoutingNetwork.EdgeEnumerator edgeEnumerator = network.GetEdgeEnumerator(); for (uint vertex1 = 0; vertex1 < network.VertexCount; ++vertex1) { GeoCoordinateSimple vertex2 = network.GeometricGraph.GetVertex(vertex1); featureCollection.Add(new Feature((Geometry) new Point(new GeoCoordinate((double)vertex2.Latitude, (double)vertex2.Longitude)), (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>) new Tag[1] { Tag.Create("id", vertex1.ToInvariantString()) }))); edgeEnumerator.MoveTo(vertex1); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { if (!longSet.Contains((long)edgeEnumerator.Id)) { longSet.Add((long)edgeEnumerator.Id); List <ICoordinate> shape = network.GetShape(edgeEnumerator.Current); List <GeoCoordinate> geoCoordinateList = new List <GeoCoordinate>(); foreach (ICoordinate coordinate in shape) { geoCoordinateList.Add(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude)); } LineString lineString = new LineString((IEnumerable <GeoCoordinate>)geoCoordinateList); TagsCollectionBase profileAndMeta = db.GetProfileAndMeta((uint)edgeEnumerator.Data.Profile, edgeEnumerator.Data.MetaId); profileAndMeta.AddOrReplace(Tag.Create("id", edgeEnumerator.Id.ToInvariantString())); featureCollection.Add(new Feature((Geometry)lineString, (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>)profileAndMeta))); } } } return(featureCollection); }
public override void AddNode(Node node) { if (this._firstPass) { this._nodeCount = this._nodeCount + 1L; double num1 = node.Latitude.Value; if (num1 < this._minLatitude) { this._minLatitude = num1; } if (num1 > this._maxLatitude) { this._maxLatitude = num1; } double num2 = node.Longitude.Value; if (num2 < this._minLongitude) { this._minLongitude = num2; } if (num2 > this._maxLongitude) { this._maxLongitude = num2; } if (this.Processors == null) { return; } foreach (ITwoPassProcessor processor in this.Processors) { processor.FirstPass(node); } } else { if (this.Processors != null) { foreach (ITwoPassProcessor processor in this.Processors) { processor.SecondPass(node); } } long?id1; if (!this._stages[this._stage].Contains(node.Longitude.Value, node.Latitude.Value)) { ILongIndex anyStageNodes = this._anyStageNodes; id1 = ((OsmGeo)node).Id; long number = id1.Value; if (!anyStageNodes.Contains(number)) { return; } } ILongIndex allRoutingNodes = this._allRoutingNodes; id1 = ((OsmGeo)node).Id; long number1 = id1.Value; if (!allRoutingNodes.Contains(number1)) { return; } NodeCoordinatesDictionary stageCoordinates = this._stageCoordinates; id1 = ((OsmGeo)node).Id; long id2 = id1.Value; // ISSUE: variable of a boxed type GeoCoordinateSimple local = new GeoCoordinateSimple() { Latitude = (float)node.Latitude.Value, Longitude = (float)node.Longitude.Value }; stageCoordinates.Add(id2, (ICoordinate)local); } }
public static uint[] SearchClosestEdges(this GeometricGraph graph, float latitude, float longitude, float latitudeOffset, float longitudeOffset, float maxDistanceMeter, Func <GeometricEdge, bool>[] isOks) { GeoCoordinate geoCoordinate = new GeoCoordinate((double)latitude, (double)longitude); HashSet <uint> uintSet1 = graph.Search(latitude - latitudeOffset, longitude - longitudeOffset, latitude + latitudeOffset, longitude + longitudeOffset); uint[] numArray1 = new uint[isOks.Length]; double[] numArray2 = new double[isOks.Length]; for (int index = 0; index < numArray1.Length; ++index) { numArray1[index] = uint.MaxValue; numArray2[index] = (double)maxDistanceMeter; } GeometricGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(); foreach (uint vertex1 in uintSet1) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); double num = GeoCoordinate.DistanceEstimateInMeter((double)latitude, (double)longitude, (double)vertex2.Latitude, (double)vertex2.Longitude); for (int index = 0; index < isOks.Length; ++index) { if (num < numArray2[index]) { edgeEnumerator.MoveTo(vertex1); while (edgeEnumerator.MoveNext()) { if (isOks[index](edgeEnumerator.Current)) { numArray2[index] = num; numArray1[index] = edgeEnumerator.Id; break; } } } } } GeoCoordinateBox[] boxes = new GeoCoordinateBox[isOks.Length]; for (int index = 0; index < boxes.Length; ++index) { boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.SouthEast)); } HashSet <uint> uintSet2 = new HashSet <uint>(); foreach (uint vertex1 in uintSet1) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); if (edgeEnumerator.MoveTo(vertex1) && edgeEnumerator.HasData) { while (edgeEnumerator.MoveNext()) { if (!uintSet2.Contains(edgeEnumerator.Id)) { uintSet2.Add(edgeEnumerator.Id); bool[] flagArray = new bool[isOks.Length]; for (int index = 0; index < isOks.Length; ++index) { flagArray[index] = isOks[index] == null; } ICoordinate coordinate = (ICoordinate)vertex2; ShapeBase shapeBase = edgeEnumerator.Shape; if (shapeBase != null) { if (edgeEnumerator.DataInverted) { shapeBase = shapeBase.Reverse(); } IEnumerator <ICoordinate> enumerator = shapeBase.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext()) { ICoordinate current = enumerator.Current; double num1 = GeoCoordinate.DistanceEstimateInMeter((double)current.Latitude, (double)current.Longitude, (double)latitude, (double)longitude); for (int index = 0; index < numArray1.Length; ++index) { if (num1 < numArray2[index]) { if (!flagArray[index] && isOks[index](edgeEnumerator.Current)) { flagArray[index] = true; } if (flagArray[index]) { numArray2[index] = num1; numArray1[index] = edgeEnumerator.Id; boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.SouthEast)); } } } if (boxes.AnyIntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)current.Longitude, (double)current.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)current.Latitude, (double)current.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null) { double num2 = GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude); for (int index = 0; index < numArray1.Length; ++index) { if (num2 < numArray2[index]) { if (!flagArray[index] && isOks[index](edgeEnumerator.Current)) { flagArray[index] = true; } if (flagArray[index]) { numArray2[index] = num2; numArray1[index] = edgeEnumerator.Id; boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.SouthEast)); } } } } } coordinate = current; } } ICoordinate vertex3 = (ICoordinate)graph.GetVertex(edgeEnumerator.To); if (boxes.AnyIntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)vertex3.Longitude, (double)vertex3.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)vertex3.Latitude, (double)vertex3.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null) { double num = GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude); for (int index = 0; index < isOks.Length; ++index) { if (num < numArray2[index]) { if (!flagArray[index] && isOks[index](edgeEnumerator.Current)) { flagArray[index] = true; } if (flagArray[index]) { numArray2[index] = num; numArray1[index] = edgeEnumerator.Id; boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.SouthEast)); } } } } } } } } } return(numArray1); }
public static bool ProjectOn(this GeometricGraph graph, GeometricEdge edge, float latitude, float longitude, out float projectedLatitude, out float projectedLongitude, out float projectedDistanceFromFirst, out int projectedShapeIndex, out float distanceToProjected, out float totalLength) { distanceToProjected = float.MaxValue; projectedDistanceFromFirst = 0.0f; projectedLatitude = float.MaxValue; projectedLongitude = float.MaxValue; projectedShapeIndex = -1; ICoordinate coordinate1 = (ICoordinate)graph.GetVertex(edge.From); ShapeBase shape = edge.Shape; IEnumerator <ICoordinate> enumerator = (IEnumerator <ICoordinate>)null; if (shape != null) { enumerator = shape.GetEnumerator(); enumerator.Reset(); } float num1 = 0.0f; int num2 = -1; while (true) { bool flag = true; ICoordinate coordinate2; if (enumerator != null && enumerator.MoveNext()) { coordinate2 = enumerator.Current; } else { flag = false; coordinate2 = (ICoordinate)graph.GetVertex(edge.To); } PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate1.Latitude, (double)coordinate1.Longitude), new GeoCoordinate((double)coordinate2.Latitude, (double)coordinate2.Longitude), true, true).ProjectOn((PointF2D) new GeoCoordinate((double)latitude, (double)longitude)); if (pointF2D != (PointF2D)null) { double num3 = GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude); if (num3 < (double)distanceToProjected) { distanceToProjected = (float)num3; projectedLatitude = (float)pointF2D[1]; projectedLongitude = (float)pointF2D[0]; projectedDistanceFromFirst = num1 + (float)GeoCoordinate.DistanceEstimateInMeter((double)projectedLatitude, (double)projectedLongitude, (double)coordinate1.Latitude, (double)coordinate1.Longitude); projectedShapeIndex = num2 + 1; } } if (flag) { num1 += (float)GeoCoordinate.DistanceEstimateInMeter((double)coordinate1.Latitude, (double)coordinate1.Longitude, (double)coordinate2.Latitude, (double)coordinate2.Longitude); ++num2; coordinate1 = coordinate2; } else { break; } } GeoCoordinateSimple vertex = graph.GetVertex(edge.To); totalLength = num1 + (float)GeoCoordinate.DistanceEstimateInMeter((double)coordinate1.Latitude, (double)coordinate1.Longitude, (double)vertex.Latitude, (double)vertex.Longitude); return((double)distanceToProjected != 3.40282346638529E+38); }
public static List <uint> SearchCloserThan(this GeometricGraph graph, float latitude, float longitude, float offset, float maxDistanceMeter, Func <GeometricEdge, bool> isOk) { HashSet <uint> uintSet1 = new HashSet <uint>(); GeoCoordinate geoCoordinate = new GeoCoordinate((double)latitude, (double)longitude); HashSet <uint> uintSet2 = graph.Search(latitude, longitude, offset); GeometricGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(); foreach (uint vertex1 in uintSet2) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); if (GeoCoordinate.DistanceEstimateInMeter((double)latitude, (double)longitude, (double)vertex2.Latitude, (double)vertex2.Longitude) < (double)maxDistanceMeter) { edgeEnumerator.MoveTo(vertex1); while (edgeEnumerator.MoveNext()) { if (isOk(edgeEnumerator.Current)) { uintSet1.Add(edgeEnumerator.Id); break; } } } } GeoCoordinateBox geoCoordinateBox = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.SouthEast)); HashSet <uint> uintSet3 = new HashSet <uint>(); foreach (uint vertex1 in uintSet2) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); if (edgeEnumerator.MoveTo(vertex1) && edgeEnumerator.HasData) { while (edgeEnumerator.MoveNext()) { if (!uintSet3.Contains(edgeEnumerator.Id)) { uintSet3.Add(edgeEnumerator.Id); bool flag = isOk == null; ICoordinate coordinate = (ICoordinate)vertex2; ShapeBase shapeBase = edgeEnumerator.Shape; if (shapeBase != null) { if (edgeEnumerator.DataInverted) { shapeBase = shapeBase.Reverse(); } IEnumerator <ICoordinate> enumerator = shapeBase.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext()) { ICoordinate current = enumerator.Current; if (GeoCoordinate.DistanceEstimateInMeter((double)current.Latitude, (double)current.Longitude, (double)latitude, (double)longitude) < (double)maxDistanceMeter) { if (!flag && isOk(edgeEnumerator.Current)) { flag = true; } if (flag) { uintSet1.Add(edgeEnumerator.Id); } } if (geoCoordinateBox.IntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)current.Longitude, (double)current.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)current.Latitude, (double)current.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null && GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude) < (double)maxDistanceMeter) { if (!flag && isOk(edgeEnumerator.Current)) { flag = true; } if (flag) { uintSet1.Add(edgeEnumerator.Id); } } } coordinate = current; } } ICoordinate vertex3 = (ICoordinate)graph.GetVertex(edgeEnumerator.To); if (geoCoordinateBox.IntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)vertex3.Longitude, (double)vertex3.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)vertex3.Latitude, (double)vertex3.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null && GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude) < (double)maxDistanceMeter) { if (!flag && isOk(edgeEnumerator.Current)) { flag = true; } if (flag) { uintSet1.Add(edgeEnumerator.Id); } } } } } } } return(new List <uint>((IEnumerable <uint>)uintSet1)); }
/// <summary> /// Starts pre-processing all nodes. /// </summary> public void Start() { // build the empty coordinate list. var emptyCoordinateList = new GeoCoordinateSimple[0]; var verticesList = new HashSet <uint>(); // initialize status variables. uint nextToProcess = 0; uint nextPosition = 0; // search edge until a real node. double latestProgress = 0; while (nextToProcess < _graph.VertexCount) { // keep looping until all vertices have been processed. // select a new vertext to select. var vertexToProcess = nextToProcess; var edges = _graph.GetEdges(vertexToProcess); if (edges.Length == 2) { // find one of the neighbours that is usefull. vertexToProcess = edges[0].Key; edges = _graph.GetEdges(vertexToProcess); verticesList.Clear(); verticesList.Add(vertexToProcess); while (edges.Length == 2) { // keep looping until there is a vertex that is usefull. vertexToProcess = edges[0].Key; if (verticesList.Contains(vertexToProcess)) { // take the other vertex. vertexToProcess = edges[1].Key; if (verticesList.Contains(vertexToProcess)) { // an island was detected with only vertices having two neighbours. // TODO: find a way to handle this! edges = new KeyValuePair <uint, LiveEdge> [0]; break; } } verticesList.Add(vertexToProcess); edges = _graph.GetEdges(vertexToProcess); } } if (edges.Length > 0) { // ok, the vertex was not already processed. nextPosition++; var oldEdges = edges.Clone() as KeyValuePair <uint, LiveEdge>[]; var ignoreList = new HashSet <uint>(); foreach (var oldEdge in oldEdges) { if (ignoreList.Contains(oldEdge.Key)) { // ignore this edge: already removed in a previous iteration. break; } // don't re-process edges that already have coordinates. GeoCoordinateSimple[] oldEdgeValueCoordinates; _graph.GetEdgeShape(vertexToProcess, oldEdge.Key, out oldEdgeValueCoordinates); if (oldEdgeValueCoordinates != null) { // this edge has already been processed. break; } // STEP1: Build list of vertices that are only for form. // set current/previous. var distance = oldEdge.Value.Distance; var current = oldEdge.Key; var previous = vertexToProcess; // build list of vertices. var vertices = new List <uint>(); vertices.Add(previous); vertices.Add(current); // get next edges list. var nextEdges = _graph.GetEdges(current); while (nextEdges.Length == 2) { // ok the current vertex can be removed. var nextEdge = nextEdges[0]; if (nextEdge.Key == previous) { // it's the other edge! nextEdge = nextEdges[1]; } // compare edges. if (nextEdge.Value.Forward != oldEdge.Value.Forward || nextEdge.Value.Tags != oldEdge.Value.Tags) { // oeps, edges are different! break; } // check for intermediates. GeoCoordinateSimple[] nextEdgeValueCoordinates; _graph.GetEdgeShape(current, nextEdge.Key, out nextEdgeValueCoordinates); if (nextEdgeValueCoordinates != null) { // oeps, there are intermediates already, this can occur when two osm-ways are drawn on top of eachother. break; } // add distance. distance = distance + nextEdge.Value.Distance; // set current/previous. previous = current; current = nextEdge.Key; vertices.Add(current); // get next edges. nextEdges = _graph.GetEdges(current); } // check if the edge contains intermediate points. if (vertices.Count == 2) { // no intermediate points: add the empty coordinate list. var oldEdgeValue = oldEdge.Value; // keep edges that already have intermediates. GeoCoordinateSimple[] edgeToKeepValueCoordinates = null; var edgesToKeep = new List <Tuple <uint, LiveEdge, GeoCoordinateSimple[]> >(); foreach (var edgeToKeep in _graph.GetEdges(vertexToProcess)) { edgeToKeepValueCoordinates = null; if (edgeToKeep.Key == oldEdge.Key && _graph.GetEdgeShape(vertexToProcess, edgeToKeep.Key, out edgeToKeepValueCoordinates)) { edgesToKeep.Add(new Tuple <uint, LiveEdge, GeoCoordinateSimple[]>( edgeToKeep.Key, edgeToKeep.Value, edgeToKeepValueCoordinates)); } } // delete olds arcs. _graph.RemoveEdge(vertexToProcess, oldEdge.Key); // add new arc. if (oldEdgeValue.Forward) { _graph.AddEdge(vertexToProcess, oldEdge.Key, oldEdgeValue, null); } else { _graph.AddEdge(vertexToProcess, oldEdge.Key, (LiveEdge)oldEdgeValue.Reverse(), null); } // add edges to keep. foreach (var edgeToKeep in edgesToKeep) { _graph.AddEdge(vertexToProcess, edgeToKeep.Item1, edgeToKeep.Item2, edgeToKeep.Item3); } } else { // intermediate points: build array. // STEP2: Build array of coordinates. var coordinates = new GeoCoordinateSimple[vertices.Count - 2]; float latitude, longitude; for (int idx = 1; idx < vertices.Count - 1; idx++) { _graph.GetVertex(vertices[idx], out latitude, out longitude); coordinates[idx - 1] = new GeoCoordinateSimple() { Latitude = latitude, Longitude = longitude }; } // STEP3: Remove all unneeded edges. _graph.RemoveEdge(vertices[0], vertices[1]); // remove first edge. for (int idx = 1; idx < vertices.Count - 1; idx++) { // delete all intermidiate arcs. _graph.RemoveEdges(vertices[idx]); } _graph.RemoveEdge(vertices[vertices.Count - 1], vertices[vertices.Count - 2]); // remove last edge. if (vertices[0] == vertices[vertices.Count - 1]) { // also remove outgoing edge. ignoreList.Add(vertices[vertices.Count - 2]); // make sure this arc is ignored in next iteration. } // STEP4: Add new edge. if (oldEdge.Value.Forward) { _graph.AddEdge(vertices[0], vertices[vertices.Count - 1], new LiveEdge() { Forward = oldEdge.Value.Forward, Tags = oldEdge.Value.Tags, Distance = distance }, coordinates, this); } else { var reverse = new GeoCoordinateSimple[coordinates.Length]; coordinates.CopyToReverse(reverse, 0); _graph.AddEdge(vertices[vertices.Count - 1], vertices[0], new LiveEdge() { Forward = !oldEdge.Value.Forward, Tags = oldEdge.Value.Tags, Distance = distance }, reverse, this); } } } } // move to the next position. nextToProcess++; // report progress. float progress = (float)System.Math.Round((((double)nextToProcess / (double)_graph.VertexCount) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("LiveEdgePreprocessor", TraceEventType.Information, "Removing edges... {0}%", progress); latestProgress = progress; } } // compress the graph. this.CompressGraph(); }
/// <summary> /// Calculates a route between the two given vertices. /// </summary> /// <returns></returns> public override CandidateRoute FindCandidateRoute(CandidateVertexEdge from, CandidateVertexEdge to, FunctionalRoadClass minimum, bool ignoreFromEdge = false, bool ignoreToEdge = false) { var edgeInterpreter = new ShapefileEdgeInterpreter(); var interpreter = new ShapefileRoutingInterpreter(); var path = this.GetRouter().Calculate(this.Graph, interpreter, this.Vehicle, from, to, minimum, ignoreFromEdge, ignoreToEdge); // if no route is found, score is 0. if (path == null) { return(new CandidateRoute() { Route = null, Score = Score.New(Score.CANDIDATE_ROUTE, "Candidate route quality.", 0, 1) }); } var edges = new List <LiveEdge>(); var vertices = new List <long>(); vertices.Add(path.VertexId); while (path.From != null) { // add to vertices list. vertices.Add(path.From.VertexId); // get edge between current and from. var fromVertex = path.From.VertexId; var toVertex = path.VertexId; var edgeDistance = double.MaxValue; var arcs = this.Graph.GetEdges(fromVertex); LiveEdge?edge = null; foreach (var arc in arcs) { if (arc.Key == toVertex && arc.Value.Distance < edgeDistance) { // there is a candidate arc. edgeDistance = arc.Value.Distance; edge = arc.Value; } } if (!edge.HasValue) { // this should be impossible. throw new Exception("No edge found between two consequtive vertices on a route."); } edges.Add(edge.Value); // move to next segment. path = path.From; } // reverse lists. edges.Reverse(); vertices.Reverse(); // fill shapes. var edgeShapes = new GeoCoordinateSimple[edges.Count][]; for (int i = 0; i < edges.Count; i++) { edgeShapes[i] = this.Graph.GetEdgeShape(vertices[i], vertices[i + 1]); } return(new CandidateRoute() { Route = new ReferencedLine(this.Graph) { Edges = edges.ToArray(), EdgeShapes = edgeShapes, Vertices = vertices.ToArray() }, Score = Score.New(Score.CANDIDATE_ROUTE, "Candidate route quality.", 1, 1) }); }
public override void AddWay(Way way) { ICoordinate coordinate; EdgeData data; if (way == null) { return; } if (way.Nodes == null) { return; } if (way.Nodes.Count == 0) { return; } if (!this._firstPass) { if (this.Processors != null) { foreach (ITwoPassProcessor processor in this.Processors) { processor.SecondPass(way); } } if (this._vehicles.AnyCanTraverse(way.Tags)) { if (this._processedWays.Contains(way.Id.Value)) { return; } TagsCollection tagsCollection = new TagsCollection(way.Tags.Count); TagsCollection tagsCollection1 = new TagsCollection(way.Tags.Count); foreach (Tag tag in way.Tags) { if (!this._vehicles.IsRelevantForProfile(tag.Key)) { tagsCollection1.Add(tag); } else { tagsCollection.Add(tag); } } if (this._normalizeTags) { TagsCollection tagsCollection2 = new TagsCollection(tagsCollection.Count); if (!tagsCollection.Normalize(tagsCollection2, tagsCollection1, this._vehicles)) { return; } if (this.Processors != null) { foreach (ITwoPassProcessor twoPassProcessor in this.Processors) { Action <TagsCollectionBase, TagsCollectionBase> onAfterWayTagsNormalize = twoPassProcessor.OnAfterWayTagsNormalize; if (onAfterWayTagsNormalize == null) { continue; } onAfterWayTagsNormalize.Invoke(tagsCollection2, tagsCollection); } } tagsCollection = tagsCollection2; } uint num = this._db.EdgeProfiles.Add(tagsCollection); if (num > 16384) { throw new Exception("Maximum supported profiles exeeded, make sure only routing tags are included in the profiles."); } uint num1 = this._db.EdgeMeta.Add(tagsCollection1); int num2 = 0; Label0: while (num2 < way.Nodes.Count - 1) { List <ICoordinate> list = new List <ICoordinate>(); float single = 0f; if (!this._stageCoordinates.TryGetValue(way.Nodes[num2], out coordinate)) { for (int i = 0; i < way.Nodes.Count; i++) { this._anyStageNodes.Add(way.Nodes[i]); } return; } uint from = this.AddCoreNode(way.Nodes[num2], coordinate.Latitude, coordinate.Longitude); long item = way.Nodes[num2]; ICoordinate coordinate1 = coordinate; num2++; long to = -1; long item1 = 9223372036854775807L; while (this._stageCoordinates.TryGetValue(way.Nodes[num2], out coordinate)) { single = single + (float)GeoCoordinate.DistanceEstimateInMeter(coordinate1, coordinate); if (!this._coreNodes.Contains(way.Nodes[num2])) { list.Add(coordinate); coordinate1 = coordinate; num2++; } else { to = this.AddCoreNode(way.Nodes[num2], coordinate.Latitude, coordinate.Longitude); item1 = way.Nodes[num2]; if (from != to) { RoutingEdge routingEdge = Enumerable.FirstOrDefault <RoutingEdge>(this._db.Network.GetEdgeEnumerator(from), (RoutingEdge x) => x.To == to); if (routingEdge != null || from == to) { data = routingEdge.Data; if (data.Distance == single) { data = routingEdge.Data; if (data.Profile == num) { data = routingEdge.Data; if (data.MetaId == num1) { goto Label0; } } } uint metaId = num1; uint profile = num; float distance = single; if (list.Count == 0 && routingEdge != null && routingEdge.Shape != null) { list = new List <ICoordinate>(routingEdge.Shape); from = routingEdge.From; to = routingEdge.To; data = routingEdge.Data; metaId = data.MetaId; data = routingEdge.Data; profile = data.Profile; data = routingEdge.Data; distance = data.Distance; long num3 = to; data = new EdgeData() { MetaId = num1, Distance = System.Math.Max(single, 0f), Profile = (ushort)num }; this.AddCoreEdge(from, (uint)num3, data, null); } if (list.Count <= 0) { GeoCoordinateSimple vertex = this._db.Network.GetVertex(from); uint num4 = this.AddNewCoreNode(item, vertex.Latitude, vertex.Longitude); data = new EdgeData() { Distance = 0f, MetaId = metaId, Profile = (ushort)profile }; this.AddCoreEdge(from, num4, data, null); GeoCoordinateSimple geoCoordinateSimple = this._db.Network.GetVertex((uint)to); uint num5 = this.AddNewCoreNode(item1, geoCoordinateSimple.Latitude, geoCoordinateSimple.Longitude); long num6 = to; data = new EdgeData() { Distance = 0f, MetaId = metaId, Profile = (ushort)profile }; this.AddCoreEdge(num5, (uint)num6, data, null); data = new EdgeData() { Distance = distance, MetaId = metaId, Profile = (ushort)profile }; this.AddCoreEdge(num4, num5, data, null); goto Label0; } else { uint vertexCount = this._db.Network.VertexCount; this._db.Network.AddVertex(vertexCount, list[0].Latitude, list[0].Longitude); float single1 = (float)GeoCoordinate.DistanceEstimateInMeter(this._db.Network.GetVertex(from), list[0]); distance = distance - single1; data = new EdgeData() { MetaId = metaId, Distance = System.Math.Max(single1, 0f), Profile = (ushort)profile }; this.AddCoreEdge(from, vertexCount, data, null); list.RemoveAt(0); long num7 = to; data = new EdgeData() { MetaId = metaId, Distance = System.Math.Max(distance, 0f), Profile = (ushort)profile }; this.AddCoreEdge(vertexCount, (uint)num7, data, list); goto Label0; } } else { long num8 = to; data = new EdgeData() { MetaId = num1, Distance = single, Profile = (ushort)num }; this.AddCoreEdge(from, (uint)num8, data, list); goto Label0; } } else if (list.Count != 1) { if (list.Count < 2) { goto Label0; } uint vertexCount1 = this._db.Network.VertexCount; this._db.Network.AddVertex(vertexCount1, list[0].Latitude, list[0].Longitude); uint vertexCount2 = this._db.Network.VertexCount; this._db.Network.AddVertex(vertexCount2, list[list.Count() - 1].Latitude, list[list.Count - 1].Longitude); float single2 = (float)GeoCoordinate.DistanceEstimateInMeter(this._db.Network.GetVertex(from), list[0]); float single3 = (float)GeoCoordinate.DistanceEstimateInMeter(this._db.Network.GetVertex((uint)to), list[list.Count - 1]); list.RemoveAt(0); list.RemoveAt(list.Count - 1); data = new EdgeData() { MetaId = num1, Distance = single2, Profile = (ushort)num }; this.AddCoreEdge(from, vertexCount1, data, null); data = new EdgeData() { MetaId = num1, Distance = single - single3 - single2, Profile = (ushort)num }; this.AddCoreEdge(vertexCount1, vertexCount2, data, list); uint num9 = (uint)to; data = new EdgeData() { MetaId = num1, Distance = single3, Profile = (ushort)num }; this.AddCoreEdge(vertexCount2, num9, data, null); goto Label0; } else { uint vertexCount3 = this._db.Network.VertexCount; this._db.Network.AddVertex(vertexCount3, list[0].Latitude, list[0].Longitude); data = new EdgeData() { MetaId = num1, Distance = (float)GeoCoordinate.DistanceEstimateInMeter(this._db.Network.GetVertex(from), list[0]), Profile = (ushort)num }; this.AddCoreEdge(from, vertexCount3, data, null); goto Label0; } } } for (int j = 0; j < way.Nodes.Count; j++) { this._anyStageNodes.Add(way.Nodes[j]); } return; } this._processedWays.Add(way.Id.Value); } } else { if (this.Processors != null) { foreach (ITwoPassProcessor processor1 in this.Processors) { processor1.FirstPass(way); } } GeoCoordinateBox geoCoordinateBox = new GeoCoordinateBox(new GeoCoordinate(this._minLatitude, this._minLongitude), new GeoCoordinate(this._maxLatitude, this._maxLongitude)); double num10 = 1E-05; if (this._stages.Count == 0) { if (this._nodeCount > (long)500000000 || this._minimumStages > 1) { double num11 = System.Math.Max(System.Math.Ceiling((double)(this._nodeCount / (long)500000000)), (double)this._minimumStages); if (num11 >= 4) { num11 = 4; this._stages.Add(new GeoCoordinateBox(new GeoCoordinate(this._minLatitude, this._minLongitude), new GeoCoordinate(geoCoordinateBox.Center.Latitude, geoCoordinateBox.Center.Longitude))); this._stages[0] = this._stages[0].Resize(num10); this._stages.Add(new GeoCoordinateBox(new GeoCoordinate(this._minLatitude, geoCoordinateBox.Center.Longitude), new GeoCoordinate(geoCoordinateBox.Center.Latitude, this._maxLongitude))); this._stages[1] = this._stages[1].Resize(num10); this._stages.Add(new GeoCoordinateBox(new GeoCoordinate(geoCoordinateBox.Center.Latitude, this._minLongitude), new GeoCoordinate(this._maxLatitude, geoCoordinateBox.Center.Longitude))); this._stages[2] = this._stages[2].Resize(num10); this._stages.Add(new GeoCoordinateBox(new GeoCoordinate(geoCoordinateBox.Center.Latitude, geoCoordinateBox.Center.Longitude), new GeoCoordinate(this._maxLatitude, this._maxLongitude))); this._stages[3] = this._stages[3].Resize(num10); } else if (num11 < 2) { num11 = 1; this._stages.Add(geoCoordinateBox); this._stages[0] = this._stages[0].Resize(num10); } else { num11 = 2; this._stages.Add(new GeoCoordinateBox(new GeoCoordinate(this._minLatitude, this._minLongitude), new GeoCoordinate(this._maxLatitude, geoCoordinateBox.Center.Longitude))); this._stages[0] = this._stages[0].Resize(num10); this._stages.Add(new GeoCoordinateBox(new GeoCoordinate(this._minLatitude, geoCoordinateBox.Center.Longitude), new GeoCoordinate(this._maxLatitude, this._maxLongitude))); this._stages[1] = this._stages[1].Resize(num10); } } else { this._stages.Add(geoCoordinateBox); this._stages[0] = this._stages[0].Resize(num10); } } if (this._vehicles.AnyCanTraverse(way.Tags)) { for (int k = 0; k < way.Nodes.Count; k++) { long item2 = way.Nodes[k]; if (this._allRoutingNodes.Contains(item2) || this._allNodesAreCore) { this._coreNodes.Add(item2); } this._allRoutingNodes.Add(item2); } this._coreNodes.Add(way.Nodes[0]); this._coreNodes.Add(way.Nodes[way.Nodes.Count - 1]); return; } } }