Example #1
0
        /// <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;
            }
        }
Example #2
0
        /// <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);
                    }
                }
            }
        }
Example #3
0
        /// <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));
            }
        }