/// <summary> /// Adds a new edge. /// </summary> public void AddCoreEdge(uint vertex1, uint vertex2, Data.Network.Edges.EdgeData data, List <Coordinate> shape, long wayId, ushort nodeIdx) { if (data.Distance >= _db.Network.MaxEdgeDistance) { // distance is too big to fit into the graph's data field. // just add the edge with the max distance, length can be recalculated on the fly for these edges // or (and this is what's probably done) we split up the edge later and add a proper length. data = new Data.Network.Edges.EdgeData() { Distance = _db.Network.MaxEdgeDistance, Profile = data.Profile, MetaId = data.MetaId }; } // add the edge. var edgeId = _db.Network.AddEdge(vertex1, vertex2, data, shape.Simplify(_simplifyEpsilonInMeter)); // save the original way-id and node index for this edge. if (_wayIds != null) { _wayIds[edgeId] = wayId; _wayNodeIndices[edgeId] = nodeIdx; } }
/// <summary> /// Adds a new edge. /// </summary> private void AddEdge(uint vertex1, uint vertex2, Data.Network.Edges.EdgeData edgeData, List <Coordinate> intermediates) { var edge = _routerDb.Network.GetEdgeEnumerator(vertex1).FirstOrDefault(x => x.To == vertex2); if (edge == null) { // everything is fine, no edge exists yet. _routerDb.Network.AddEdge(vertex1, vertex2, edgeData, new Graphs.Geometric.Shapes.ShapeEnumerable(intermediates)); } else { // an edge exists already, split the current one or the one that exists already. var meta = edgeData.MetaId; var profile = edgeData.Profile; var distance = edgeData.Distance; if (edge.Data.Distance == edgeData.Distance && edge.Data.Profile == edgeData.Profile && edge.Data.MetaId == edgeData.MetaId) { // do nothing, identical duplicate data. } else { // try and use intermediate points if any. // try and use intermediate points. var splitMeta = edgeData.MetaId; var splitProfile = edgeData.Profile; var splitDistance = edgeData.Distance; if (intermediates.Count == 0 && edge != null && edge.Shape != null) { // no intermediates in current edge. // save old edge data. intermediates = new List <Coordinate>(edge.Shape); vertex1 = edge.From; vertex2 = edge.To; splitMeta = edge.Data.MetaId; splitProfile = edge.Data.Profile; splitDistance = edge.Data.Distance; // just add edge, and split the other one. _routerDb.Network.RemoveEdges(vertex1, vertex2); // make sure to overwrite and not add an extra edge. _routerDb.Network.AddEdge(vertex1, vertex2, new Data.Network.Edges.EdgeData() { MetaId = meta, Distance = System.Math.Max(distance, 0.0f), Profile = (ushort)profile }, null); } if (intermediates.Count > 0) { // intermediates found, use the first intermediate as the core-node. var newCoreVertex = _routerDb.Network.VertexCount; _routerDb.Network.AddVertex(newCoreVertex, intermediates[0].Latitude, intermediates[0].Longitude); // calculate new distance and update old distance. var newDistance = Coordinate.DistanceEstimateInMeter( _routerDb.Network.GetVertex(vertex1), intermediates[0]); splitDistance -= newDistance; // add first part. _routerDb.Network.AddEdge(vertex1, newCoreVertex, new Data.Network.Edges.EdgeData() { MetaId = splitMeta, Distance = System.Math.Max(newDistance, 0.0f), Profile = (ushort)splitProfile }, null); // add second part. intermediates.RemoveAt(0); _routerDb.Network.AddEdge(newCoreVertex, vertex2, new Data.Network.Edges.EdgeData() { MetaId = splitMeta, Distance = System.Math.Max(splitDistance, 0.0f), Profile = (ushort)splitProfile }, intermediates); } else { // no intermediate or shapepoint found in either one. two identical edge overlayed with different profiles. // add two other vertices with identical positions as the ones given. // connect them with an edge of length '0'. var fromLocation = _routerDb.Network.GetVertex(vertex1); var newFromVertex = _routerDb.Network.VertexCount; _routerDb.Network.AddVertex(newFromVertex, fromLocation.Latitude, fromLocation.Longitude); _routerDb.Network.AddEdge(vertex1, newFromVertex, new Data.Network.Edges.EdgeData() { Distance = 0, MetaId = splitMeta, Profile = (ushort)splitProfile }, null); var toLocation = _routerDb.Network.GetVertex(vertex2); var newToVertex = _routerDb.Network.VertexCount; _routerDb.Network.AddVertex(newToVertex, toLocation.Latitude, toLocation.Longitude); _routerDb.Network.AddEdge(newToVertex, vertex1, new Data.Network.Edges.EdgeData() { Distance = 0, MetaId = splitMeta, Profile = (ushort)splitProfile }, null); _routerDb.Network.AddEdge(newFromVertex, newToVertex, new Data.Network.Edges.EdgeData() { Distance = splitDistance, MetaId = splitMeta, Profile = (ushort)splitProfile }, null); } } } }
/// <summary> /// Adds a new edge. /// </summary> public void AddCoreEdge(uint vertex1, uint vertex2, Data.Network.Edges.EdgeData data, List <Coordinate> shape) { if (data.Distance < _db.Network.MaxEdgeDistance) { // edge is ok, smaller than max distance. _db.Network.AddEdge(vertex1, vertex2, data, shape.Simplify(_simplifyEpsilonInMeter)); } else { // edge is too big. if (shape == null) { // make sure there is a shape. shape = new List <Coordinate>(); } shape = new List <Coordinate>(shape); shape.Insert(0, _db.Network.GetVertex(vertex1)); shape.Add(_db.Network.GetVertex(vertex2)); for (var s = 1; s < shape.Count; s++) { var distance = Coordinate.DistanceEstimateInMeter(shape[s - 1], shape[s]); if (distance >= _db.Network.MaxEdgeDistance) { // insert a new intermediate. shape.Insert(s, new Coordinate() { Latitude = (float)(((double)shape[s - 1].Latitude + (double)shape[s].Latitude) / 2.0), Longitude = (float)(((double)shape[s - 1].Longitude + (double)shape[s].Longitude) / 2.0), }); s--; } } var i = 0; var shortShape = new List <Coordinate>(); var shortDistance = 0.0f; uint shortVertex = Constants.NO_VERTEX; Coordinate?shortPoint; i++; while (i < shape.Count) { var distance = Coordinate.DistanceEstimateInMeter(shape[i - 1], shape[i]); if (distance + shortDistance > _db.Network.MaxEdgeDistance) { // ok, previous shapepoint was the maximum one. shortPoint = shortShape[shortShape.Count - 1]; shortShape.RemoveAt(shortShape.Count - 1); // add vertex. shortVertex = _db.Network.VertexCount; _db.Network.AddVertex(shortVertex, shortPoint.Value.Latitude, shortPoint.Value.Longitude); // add edge. _db.Network.AddEdge(vertex1, shortVertex, new Data.Network.Edges.EdgeData() { Distance = (float)shortDistance, MetaId = data.MetaId, Profile = data.Profile }, shortShape.Simplify(_simplifyEpsilonInMeter)); vertex1 = shortVertex; // set new short distance, empty shape. shortShape.Clear(); shortShape.Add(shape[i]); shortDistance = distance; i++; } else { // just add short distance and move to the next shape point. shortShape.Add(shape[i]); shortDistance += distance; i++; } } // add final segment. if (shortShape.Count > 0) { shortShape.RemoveAt(shortShape.Count - 1); } // add edge. _db.Network.AddEdge(vertex1, vertex2, new Data.Network.Edges.EdgeData() { Distance = (float)shortDistance, MetaId = data.MetaId, Profile = data.Profile }, shortShape.Simplify(_simplifyEpsilonInMeter)); } }