/// <summary>
        /// Deserializes all edges.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="size"></param>
        /// <param name="graph"></param>
        protected override void DeserializeEdges(LimitedStream stream, long size, DynamicGraphRouterDataSource <LiveEdge> graph)
        {
            var typeModel = RuntimeTypeModel.Create();

            typeModel.Add(typeof(SerializableEdge), true);
            typeModel.Add(typeof(GeoCoordinateSimple), true);

            long position = stream.Position;

            while (stream.Position < position + size)
            { // keep looping until the appropriate number of bytes have been read.
                var serializableEdges = typeModel.DeserializeWithSize(stream, null, typeof(SerializableEdge[])) as SerializableEdge[];
                for (int idx = 0; idx < serializableEdges.Length; idx++)
                {
                    ICoordinateCollection coordinateCollection = null;
                    if (serializableEdges[idx].Coordinates != null)
                    {
                        coordinateCollection = new CoordinateArrayCollection <GeoCoordinateSimple>(serializableEdges[idx].Coordinates);
                    }
                    graph.AddEdge(serializableEdges[idx].FromId, serializableEdges[idx].ToId,
                                  new LiveEdge()
                    {
                        Distance = serializableEdges[idx].Distance,
                        Value    = serializableEdges[idx].Value
                    }, coordinateCollection);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Returns true if the given vertex has the given neighbour.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="shape"></param>
        /// <returns></returns>
        public bool GetEdgeShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
        {
            Tile tile;

            if (_tilesPerVertex.TryGetValue(vertex1, out tile))
            {
                // load missing tile if needed.
                this.LoadMissingTile(tile);
                _tilesPerVertex.Remove(vertex1);
            }

            // get the arcs and return.
            if (_vertices.Length > vertex1)
            {
                var vertex = _vertices[(int)vertex1];
                if (vertex != null &&
                    vertex.Arcs != null)
                {
                    for (int idx = 0; idx < vertex.Arcs.Length; idx++)
                    {
                        if (vertex.Arcs[idx].Item1 == vertex2)
                        {
                            shape = null;
                            if (vertex.Arcs[idx].Item3 != null)
                            {
                                shape = new CoordinateArrayCollection <GeoCoordinateSimple>(vertex.Arcs[idx].Item3);
                            }
                            return(true);
                        }
                    }
                }
            }
            shape = null;
            return(false);
        }
Пример #3
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            try
            {
                JObject jsonObj = JObject.Load(reader);

                ITypedCoordinateContainer typedCoorContainerResult = (ITypedCoordinateContainer)Activator.CreateInstance(objectType);


                if (jsonObj.HasValues)
                {
                    JProperty typeProp        = jsonObj.Property("type");
                    JProperty coordinatesProp = jsonObj.Property("coordinates");
                    if (typeProp != null && coordinatesProp != null)
                    {
                        string type      = typeProp.Value.ToString();
                        JArray coorArray = string.IsNullOrWhiteSpace(coordinatesProp.Value.ToString()) ? null : JArray.FromObject(coordinatesProp.Value);
                        if (coorArray != null)
                        {
                            ICoordinateCollection coorResult      = null;
                            ITypedCoordinate      typedCoorResult = null;

                            if (type == "Point")
                            {
                                //TJM: Assume simple array of coordinate pairs...
                                coorResult = GetPointFromJArray(coorArray, _isLegacyFormat);
                                //TJM: It's ok if the coorResult is null.
                                typedCoorResult = new PointCoordinate(coorResult);
                            }
                            else if (type == "LineString")
                            {
                                //TJM: Assume array of "Point".
                                coorResult      = GetLineStringFromJArray(coorArray, _isLegacyFormat);
                                typedCoorResult = new LineStringCoordinate(coorResult);
                            }
                            else if (type == "Polygon")
                            {
                                //TJM: Assume array of "LineString".
                                coorResult      = GetPolygonFromJArray(coorArray, _isLegacyFormat);
                                typedCoorResult = new PolygonCoordinate(coorResult);
                            }

                            typedCoorContainerResult.Coordinates = typedCoorResult;

                            return(typedCoorContainerResult);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //TJM: Should we do anything here??
            }

            return(null);
        }
Пример #4
0
        /// <summary>
        /// Gets the shape for the arc in from the given vertex and at the given index.
        /// </summary>
        /// <param name="vertexId">The vertex id.</param>
        /// <param name="arcIdx">The index of the arc.</param>
        /// <param name="shape">The shape.</param>
        /// <returns>True if there was a shape.</returns>
        private bool GetShapeForArc(uint vertexId, uint arcIdx, out ICoordinateCollection shape)
        {
            var vertex         = _vertices[(int)vertexId];
            var arcCoordinates = vertex.Arcs[arcIdx];

            shape = null;
            if (arcCoordinates.Item3 != null)
            {
                shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Item3);
            }
            return(true);
        }
Пример #5
0
        /// <summary>
        /// Returns the coordinate collection at the given id.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="coordinates"></param>
        /// <returns></returns>
        public bool Get(long id, out ICoordinateCollection coordinates)
        {
            long index, size;

            if (this.TryGetIndexAndSize(id, out index, out size))
            {
                coordinates = new HugeCoordinateCollection(_coordinates, index, size);
                return(true);
            }
            coordinates = null;
            return(false);
        }
        private void AssertCoordinateFormatForTypedCoordinateContainer(TypedCoordinateContainer coordContainer)
        {
            //TJM: The result should be dealing with a Point type for simplicity to check the coordinates.
            ICoordinateCollection coordColl = coordContainer.Coordinates.Coordinates;

            while (coordColl.Children != null)
            {
                coordColl = coordColl.Children.FirstOrDefault();
            }

            CoordinatePair coordPair = coordColl as CoordinatePair;

            string expectedResult = DummyTimeLineJson.GetCoordinateTestValueFromType("Point", coordPair.IsLegacyFormat);

            //TJM: Kind of a hack, but whatever...I want to get the exact result from our sample data.
            expectedResult = expectedResult.Replace("[", "").Replace("]", "");
            string[] coordinateSplit = expectedResult.Split(',');
            // Set values based on whether we're using legacy format for the coordinate.
            decimal latitude  = 0;
            decimal longitude = 0;

            for (int i = 0; i < coordinateSplit.Length; i++)
            {
                decimal coordNum;
                if (decimal.TryParse(coordinateSplit[i], out coordNum))
                {
                    if (i == 0)
                    {
                        if (coordPair.IsLegacyFormat)
                        {
                            latitude = coordNum;
                        }
                        else
                        {
                            longitude = coordNum;
                        }
                    }
                    else if (i == 1)
                    {
                        if (coordPair.IsLegacyFormat)
                        {
                            longitude = coordNum;
                        }
                        else
                        {
                            latitude = coordNum;
                        }
                    }
                }
            }

            AssertLatitudeandLongitude(latitude, longitude, coordPair);
        }
Пример #7
0
        /// <summary>
        /// Sets the coordinates starting at the given index.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="coordinates"></param>
        private void DoSet(long index, ICoordinateCollection coordinates)
        {
            long idx = index;

            coordinates.Reset();
            while (coordinates.MoveNext())
            {
                _coordinates[idx]     = coordinates.Latitude;
                _coordinates[idx + 1] = coordinates.Longitude;
                idx = idx + 2;
            }
        }
Пример #8
0
            /// <summary>
            /// Returns a simple array.
            /// </summary>
            /// <param name="simples"></param>
            /// <returns></returns>
            public static SerializableCoordinate[] FromSimpleArray(ICoordinateCollection shape)
            {
                if (shape == null)
                {
                    return(null);
                }
                var simples     = shape.ToArray();
                var coordinates = new SerializableCoordinate[simples.Length];

                for (int idx = 0; idx < simples.Length; idx++)
                {
                    coordinates[idx]           = new SerializableCoordinate();
                    coordinates[idx].Latitude  = simples[idx].Latitude;
                    coordinates[idx].Longitude = simples[idx].Longitude;
                }
                return(coordinates);
            }
Пример #9
0
        /// <summary>
        /// Adds the new coordinates at the end of the current coordinates.
        /// </summary>
        /// <param name="coordinates"></param>
        /// <returns></returns>
        private ulong DoAdd(ICoordinateCollection coordinates)
        {
            var newId = (ulong)(_nextIdx * MAX_COLLECTION_SIZE) + (ulong)coordinates.Count;

            coordinates.Reset();
            while (coordinates.MoveNext())
            {
                if (_coordinates.Length <= (_nextIdx * 2) + 1)
                { // make sure they fit!
                    this.IncreaseCoordinates();
                }
                _coordinates[(_nextIdx * 2)]     = coordinates.Latitude;
                _coordinates[(_nextIdx * 2) + 1] = coordinates.Longitude;
                _nextIdx = _nextIdx + 1;
            }
            return(newId);
        }
Пример #10
0
        /// <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 ICoordinateCollection shape)
        {
            long edgeDataIdx;
            bool edgeDataForward;

            if (this.GetEdgeIdx(vertex1, vertex2, out edgeDataIdx, out edgeDataForward))
            { // the edge exists.
                shape = _edgeShapes[edgeDataIdx];
                if (shape != null && !edgeDataForward)
                { // invert shape.
                    shape = shape.Reverse();
                }
                return(true);
            }
            shape = null;
            return(false);
        }
Пример #11
0
        /// <summary>
        /// Returns the edge shape between the two given vertices.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="shape"></param>
        public bool GetEdgeShape(long vertex1, long vertex2, out ICoordinateCollection shape)
        {
            if (vertex1 > 0 && vertex2 > 0)
            {
                if (_datasource.ContainsEdges((uint)vertex1, (uint)vertex2))
                { // has the arc.
                    if (!_removedArcs.Contains(new Arc()
                    {
                        Vertex1 = vertex1,
                        Vertex2 = vertex2
                    }))
                    { // edge was not removed, only now return it's shape from the source.
                        if (_datasource.GetEdgeShape((uint)vertex1, (uint)vertex2, out shape))
                        {
                            if (shape != null)
                            {
                                shape.Reset();
                            }
                            return(true);
                        }
                        return(false);
                    }
                }
            }

            // also check new arcs.
            foreach (var newArc in _newEdges)
            {
                if (newArc.Key == vertex1 &&
                    newArc.Value.Key == vertex2)
                {
                    shape = newArc.Value.Value.Item2;
                    if (shape != null)
                    {
                        shape.Reset();
                    }
                    return(true);
                }
            }
            shape = null;
            return(false);
        }
Пример #12
0
        /// <summary>
        /// Adds/updates the coordinate collection at the given id.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="coordinates"></param>
        public void Add(long id, ICoordinateCollection coordinates)
        {
            long index, size;

            if (this.TryGetIndexAndSize(id, out index, out size))
            {
                if (size == coordinates.Count * 2)
                { // just update in-place.
                    this.DoSet(index, coordinates);
                }
                else
                { // remove and add new.
                    _index[id] = this.DoAdd(coordinates);
                }
            }
            else
            { // add new coordinates.
                _index[id] = this.DoAdd(coordinates);
            }
        }
        /// <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);
        }
Пример #14
0
        /// <summary>
        /// Gets an edge-shape based on the from vertex and the index of the edge.
        /// </summary>
        /// <param name="vertex">The vertex where the edge is incident.</param>
        /// <param name="index">The index of the edge.</param>
        /// <param name="shape">The shape, if any, to return.</param>
        /// <returns></returns>
        internal bool GetShapeForArc(uint vertex, uint index, out ICoordinateCollection shape)
        {
            var  localArcs = this.GetEdges(vertex);
            uint edgeIdx   = 0;

            while (localArcs.MoveNext() &&
                   edgeIdx < index)
            {
                edgeIdx++;
            }
            //if(localArcs.isInverted)
            //{ // make sure to return the inverse edge.
            //    shape = null;
            //    if(localArcs.Intermediates != null)
            //    {
            //        shape = localArcs.Intermediates.Reverse();
            //    }
            //    return true;
            //}
            shape = localArcs.Intermediates;
            return(true);
        }
Пример #15
0
        /// <summary>
        /// Gets the shape for the arc in the given block and at the given index.
        /// </summary>
        /// <param name="blockId">The index of the block to search.</param>
        /// <param name="arcIdx">The index of the arc in the block.</param>
        /// <param name="shape">The shape.</param>
        /// <returns>True if there was a shape.</returns>
        private bool GetShapeForArc(uint blockId, uint arcIdx, out ICoordinateCollection shape)
        {
            CHBlockCoordinates blockCoordinates;

            if (!_blockShapes.TryGet(blockId, out blockCoordinates))
            { // damn block not cached!
                blockCoordinates = this.DeserializeShape(blockId);
                if (blockCoordinates == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blockShapes.Add(blockId, blockCoordinates);
            }
            var arcCoordinates = blockCoordinates.Arcs[arcIdx];

            shape = null;
            if (arcCoordinates.Coordinates != null)
            {
                shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Coordinates);
            }
            return(true);
        }
Пример #16
0
 /// <summary>
 /// Gets an edge from the given graph taking into account 'can have duplicates'.
 /// </summary>
 /// <param name="graph"></param>
 /// <param name="from"></param>
 /// <param name="to"></param>
 /// <param name="existingData"></param>
 /// <param name="shape"></param>
 /// <returns></returns>
 private bool GetEdge(GraphBase <TEdgeData> graph, uint from, uint to, out TEdgeData existingData, out ICoordinateCollection shape)
 {
     if (!graph.CanHaveDuplicates)
     {
         graph.GetEdgeShape(from, to, out shape);
         return(graph.GetEdge(from, to, out existingData));
     }
     else
     {
         var edges = graph.GetEdges(from, to);
         while (edges.MoveNext())
         {
             if (edges.Neighbour == to)
             {
                 existingData = edges.EdgeData;
                 shape        = edges.Intermediates;
                 return(true);
             }
         }
         existingData = default(TEdgeData);
         shape        = null;
         return(false);
     }
 }
Пример #17
0
        /// <summary>
        /// Adds an edge.
        /// </summary>
        /// <param name="forward"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="tags"></param>
        /// <param name="intermediates"></param>
        protected virtual void AddRoadEdge(TagsCollectionBase tags, uint from, uint to, List <GeoCoordinateSimple> intermediates)
        {
            float         latitude;
            float         longitude;
            GeoCoordinate fromCoordinate = null;

            if (_graph.GetVertex(from, out latitude, out longitude))
            { //
                fromCoordinate = new GeoCoordinate(latitude, longitude);
            }
            GeoCoordinate toCoordinate = null;

            if (_graph.GetVertex(to, out latitude, out longitude))
            { //
                toCoordinate = new GeoCoordinate(latitude, longitude);
            }

            if (fromCoordinate != null && toCoordinate != null)
            { // calculate the edge data.
                TEdgeData             existingData;
                ICoordinateCollection forwardShape;
                if (this.GetEdge(_graph, from, to, out existingData, out forwardShape))
                {     // oeps, an edge already exists!
                    if (intermediates != null && intermediates.Count > 0)
                    { // add one of the intermediates as new vertex.
                        uint newVertex;
                        if (forwardShape != null && forwardShape.Count > 0)
                        { // the other edge also has a shape, make sure to also split it.
                            var existingIntermediates = new List <GeoCoordinateSimple>(forwardShape.ToSimpleArray());
                            newVertex = _graph.AddVertex(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude);

                            // add edge before.
                            var beforeEdgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                        fromCoordinate, new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), null);
                            _graph.AddEdge(from, newVertex, beforeEdgeData, null);
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                beforeEdgeData = (TEdgeData)beforeEdgeData.Reverse();
                                _graph.AddEdge(newVertex, from, beforeEdgeData, null);
                            }

                            // add edge after.
                            var afterIntermediates = existingIntermediates.GetRange(1, existingIntermediates.Count - 1);
                            var afterEdgeData      = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                            new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), toCoordinate, afterIntermediates);
                            _graph.AddEdge(newVertex, to, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                afterIntermediates.Reverse();
                                afterEdgeData = (TEdgeData)afterEdgeData.Reverse();
                                _graph.AddEdge(to, newVertex, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            }

                            // remove original edge.
                            _graph.RemoveEdge(from, to, existingData);
                            if (_graph.IsDirected && _graph.CanHaveDuplicates)
                            { // also remove opposite edges.
                                _graph.RemoveEdge(to, from, (TEdgeData)existingData.Reverse());
                            }
                        }

                        newVertex = _graph.AddVertex(intermediates[0].Latitude, intermediates[0].Longitude);
                        var newEdgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                 fromCoordinate, new GeoCoordinate(intermediates[0].Latitude, intermediates[0].Longitude), null);
                        _graph.AddEdge(from, newVertex, newEdgeData, null);
                        if (_graph.IsDirected)
                        { // also the need to add the reverse edge.
                            newEdgeData = (TEdgeData)newEdgeData.Reverse();
                            _graph.AddEdge(newVertex, from, newEdgeData, null);
                        }

                        from           = newVertex;
                        fromCoordinate = new GeoCoordinate(intermediates[0].Latitude, intermediates[0].Longitude);
                        intermediates  = intermediates.GetRange(1, intermediates.Count - 1);
                    }
                    else
                    {     // hmm, no intermediates, the other edge should have them.
                        if (forwardShape != null && forwardShape.Count > 0)
                        { // there is a shape, add one of the intermediates as a new vertex.
                            var existingIntermediates = new List <GeoCoordinateSimple>(forwardShape.ToSimpleArray());
                            var newVertex             = _graph.AddVertex(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude);

                            // add edge before.
                            var beforeEdgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                        fromCoordinate, new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), null);
                            _graph.AddEdge(from, newVertex, beforeEdgeData, null);
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                beforeEdgeData = (TEdgeData)beforeEdgeData.Reverse();
                                _graph.AddEdge(newVertex, from, beforeEdgeData, null);
                            }

                            // add edge after.
                            var afterIntermediates = existingIntermediates.GetRange(1, existingIntermediates.Count - 1);
                            var afterEdgeData      = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                            new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), toCoordinate, afterIntermediates);
                            _graph.AddEdge(newVertex, to, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                afterIntermediates.Reverse();
                                afterEdgeData = (TEdgeData)afterEdgeData.Reverse();
                                _graph.AddEdge(to, newVertex, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            }

                            if (_graph.CanHaveDuplicates)
                            { // make sure to remove the existing edge if graph allows duplicates.
                                _graph.RemoveEdge(from, to);
                                if (_graph.IsDirected)
                                { // also remove the reverse.
                                    _graph.RemoveEdge(to, from);
                                }
                            }
                        }
                        else
                        {
                            // do nothing just overwrite what is there, probably a bug in OSM, two overlapping ways, sharing nodes.
                        }
                    }

                    // edge was there already but was removed,split or needs to be replaced.
                    var edgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                          fromCoordinate, toCoordinate, intermediates);
                    _graph.AddEdge(from, to, edgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray()));
                    if (_graph.IsDirected)
                    { // also the need to add the reverse edge.
                        intermediates.Reverse();
                        edgeData = (TEdgeData)edgeData.Reverse();
                        _graph.AddEdge(to, from, edgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray()));
                    }
                }
                else
                { // edge is not there yet, just add it.
                    ICoordinateCollection intermediatesCollection = null;
                    if (intermediates != null)
                    {
                        intermediatesCollection = new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray());
                    }

                    // add new edge.
                    var edgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                          fromCoordinate, toCoordinate, intermediates);
                    _graph.AddEdge(from, to, edgeData, intermediatesCollection);
                    if (_graph.IsDirected)
                    { // also the need to add the reverse edge.
                        if (intermediates != null)
                        {
                            intermediates.Reverse();
                            intermediatesCollection = new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray());
                        }
                        edgeData = (TEdgeData)edgeData.Reverse();
                        _graph.AddEdge(to, from, edgeData, intermediatesCollection);
                    }
                }
            }
        }
Пример #18
0
 /// <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 override bool GetEdgeShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
 {
     throw new InvalidOperationException("Cannot use GetEdgeShape on a graph that can have duplicate edges.");
 }
Пример #19
0
        /// <summary>
        /// Adds an edge with the associated data.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="data"></param>
        /// <param name="coordinates"></param>
        /// <remarks>This only adds edge vertex1->vertex2 NOT vertex2->vertex1</remarks>
        public override void AddEdge(uint vertex1, uint vertex2, TEdgeData data, ICoordinateCollection coordinates)
        {
            if (_readonly)
            {
                throw new Exception("Graph is readonly.");
            }
            if (vertex1 == vertex2)
            {
                throw new ArgumentException("Given vertices must be different.");
            }
            if (_nextVertexId <= vertex1)
            {
                throw new ArgumentOutOfRangeException("vertex1", "vertex1 is not part of this graph.");
            }
            if (_nextVertexId <= vertex2)
            {
                throw new ArgumentOutOfRangeException("vertex2", "vertex2 is not part of this graph.");
            }

            var vertex1Idx = vertex1 * VERTEX_SIZE;
            var edgeCount  = _vertices[vertex1Idx + EDGE_COUNT];
            var edgeId     = _vertices[vertex1Idx + FIRST_EDGE];

            if ((edgeCount & (edgeCount - 1)) == 0)
            { // edgeCount is a power of two, increase space.
                // update vertex.
                uint newEdgeId = _nextEdgeId;
                _vertices[vertex1Idx + FIRST_EDGE] = newEdgeId;

                // move edges.
                if (edgeCount > 0)
                {
                    if (newEdgeId + (2 * edgeCount) >= _edges.Length)
                    { // edges need to be increased.
                        this.IncreaseEdgeSize();
                    }

                    for (uint toMoveIdx = edgeId; toMoveIdx < edgeId + edgeCount; toMoveIdx = toMoveIdx + EDGE_SIZE)
                    {
                        _edges[newEdgeId]      = _edges[toMoveIdx];
                        _edgeData[newEdgeId]   = _edgeData[toMoveIdx];
                        _edgeShapes[newEdgeId] = _edgeShapes[toMoveIdx];

                        newEdgeId++;
                    }

                    // the edge id is the last new edge id.
                    edgeId = newEdgeId;

                    // increase the nextEdgeId, these edges have been added at the end of the edge-array.
                    _nextEdgeId = _nextEdgeId + (2 * edgeCount);
                }
                else
                {     // just add next edge id.
                    if (_nextEdgeId + 1 >= _edges.Length)
                    { // edges need to be increased.
                        this.IncreaseEdgeSize();
                    }

                    edgeId = _nextEdgeId;
                    _nextEdgeId++;
                }
            }
            else
            {     // calculate edgeId of new edge.
                if (_nextEdgeId + 1 >= _edges.Length)
                { // edges need to be increased.
                    this.IncreaseEdgeSize();
                }

                edgeId = edgeId + edgeCount;
                _nextEdgeId++;
            }

            // update edge count in vertex.
            edgeCount++;
            _vertices[vertex1Idx + EDGE_COUNT] = edgeCount;

            // update edge.
            _edges[edgeId]      = vertex2;
            _edgeData[edgeId]   = data;
            _edgeShapes[edgeId] = coordinates;
            return;
        }
Пример #20
0
 /// <summary>
 /// Adds a new edge.
 /// </summary>
 /// <param name="vertex1"></param>
 /// <param name="vertex2"></param>
 /// <param name="data"></param>
 /// <param name="coordinates"></param>
 public override void AddEdge(uint vertex1, uint vertex2, TEdgeData data, ICoordinateCollection coordinates)
 {
     _graph.AddEdge(vertex1, vertex2, data, coordinates);
 }
Пример #21
0
        /// <summary>
        /// Adds the coordinate collection at the given id.
        /// </summary>
        public void Add(long id, ICoordinateCollection coordinates)
        {
            long index, size;
            if (this.TryGetIndexAndSize(id, out index, out size))
            {
                throw new InvalidOperationException("Item with same key already exists.");
            }
            _index[id] = this.DoAdd(coordinates);

            if (_nextId <= id)
            { // update max id.
                _nextId = id + 1;
            }
        }
Пример #22
0
 /// <summary>
 /// Returns true if the given vertex has the given neighbour.
 /// </summary>
 /// <param name="vertex1"></param>
 /// <param name="vertex2"></param>
 /// <param name="shape"></param>
 /// <returns></returns>
 public bool GetEdgeShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
 {
     return(this.LoadArcShape(vertex1, vertex2, out shape));
 }
 public PolygonCoordinate(ICoordinateCollection coordinates)
 {
     Coordinates = coordinates;
 }
Пример #24
0
        /// <summary>
        /// Sets the coordinates starting at the given index.
        /// </summary>
        private ulong DoSet(long index, ICoordinateCollection coordinates)
        {
            if (coordinates == null)
            { // just return the null-pointer if null.
                return NULL;
            }

            var id = (ulong)(index * MAX_COLLECTION_SIZE) + (ulong)coordinates.Count;
            coordinates.Reset();
            while(coordinates.MoveNext())
            {
                _coordinates[index * 2] = coordinates.Latitude;
                _coordinates[index * 2 + 1] = coordinates.Longitude;
                index++;
            }
            return id;
        }
Пример #25
0
        /// <summary>
        /// Loads the edge between the given vertices.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="shape"></param>
        /// <returns></returns>
        private bool LoadArcShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
        {
            uint blockId = CHBlock.CalculateId(vertex1, _blockSize);
            CHBlockCoordinates blockCoordinates;

            if (!_blockShapes.TryGet(blockId, out blockCoordinates))
            { // damn block not cached!
                blockCoordinates = this.DeserializeShape(blockId);
                if (blockCoordinates == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blockShapes.Add(blockId, blockCoordinates);
            }
            CHBlock block;

            if (!_blocks.TryGet(blockId, out block))
            { // damn block not cached!
                block = this.DeserializeBlock(blockId);
                if (block == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blocks.Add(blockId, block);
            }
            uint blockIdx = vertex1 - blockId;

            if (block.Vertices != null &&
                blockIdx < block.Vertices.Length)
            { // block is found and the vertex is there!
                for (int arcIdx = block.Vertices[blockIdx].ArcIndex;
                     arcIdx < block.Vertices[blockIdx].ArcIndex + block.Vertices[blockIdx].ArcCount; arcIdx++)
                { // loop over all arcs.
                    var chArc = block.Arcs[arcIdx];
                    if (chArc.TargetId == vertex2)
                    {
                        var arcCoordinates = blockCoordinates.Arcs[arcIdx];
                        shape = null;
                        if (arcCoordinates.Coordinates != null)
                        {
                            shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Coordinates);
                        }
                        return(true);
                    }
                }
            }
            blockId = CHBlock.CalculateId(vertex2, _blockSize);
            if (!_blocks.TryGet(blockId, out block))
            { // damn block not cached!
                block = this.DeserializeBlock(blockId);
                if (block == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blocks.Add(blockId, block);
            }
            if (!_blockShapes.TryGet(blockId, out blockCoordinates))
            { // damn block not cached!
                blockCoordinates = this.DeserializeShape(blockId);
                if (blockCoordinates == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blockShapes.Add(blockId, blockCoordinates);
            }
            blockIdx = vertex2 - blockId;
            if (block.Vertices != null &&
                blockIdx < block.Vertices.Length)
            { // block is found and the vertex is there!
                for (int arcIdx = block.Vertices[blockIdx].ArcIndex;
                     arcIdx < block.Vertices[blockIdx].ArcIndex + block.Vertices[blockIdx].ArcCount; arcIdx++)
                { // loop over all arcs.
                    var chArc = block.Arcs[arcIdx];
                    if (chArc.TargetId == vertex1)
                    {
                        var arcCoordinates = blockCoordinates.Arcs[arcIdx];
                        shape = null;
                        if (arcCoordinates.Coordinates != null)
                        {
                            shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Coordinates);
                        }
                        return(true);
                    }
                }
            }
            shape = null;
            return(false);
        }
 /// <summary>
 /// Adds/updates the coordinate collection at the given id.
 /// </summary>
 /// <param name="id"></param>
 /// <param name="coordinates"></param>
 public void Add(long id, ICoordinateCollection coordinates)
 {
     long index, size;
     if (this.TryGetIndexAndSize(id, out index, out size))
     {
         if(size == coordinates.Count * 2)
         { // just update in-place.
             this.DoSet(index, coordinates);
         }
         else
         { // remove and add new.
             _index[id] = this.DoAdd(coordinates);
         }
     }
     else
     { // add new coordinates.
         _index[id] = this.DoAdd(coordinates);
     }
 }
 /// <summary>
 /// Adds the new coordinates at the end of the current coordinates.
 /// </summary>
 /// <param name="coordinates"></param>
 /// <returns></returns>
 private ulong DoAdd(ICoordinateCollection coordinates)
 {
     var newId = (ulong)(_nextIdx * MAX_COLLECTION_SIZE) + (ulong)coordinates.Count;
     coordinates.Reset();
     while(coordinates.MoveNext())
     {
         _coordinates[(_nextIdx * 2)] = coordinates.Latitude;
         _coordinates[(_nextIdx * 2) + 1] = coordinates.Longitude;
         _nextIdx = _nextIdx + 1;
     }
     return newId;
 }
Пример #28
0
 public LineStringCoordinate(ICoordinateCollection coordinates)
 {
     Coordinates = coordinates;
 }
Пример #29
0
        /// <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).ToList();
                if (edges.Count == 2)
                { // find one of the neighbours that is usefull.
                    vertexToProcess = edges[0].Neighbour;
                    edges           = _graph.GetEdges(vertexToProcess).ToList();
                    verticesList.Clear();
                    verticesList.Add(vertexToProcess);
                    while (edges.Count == 2)
                    { // keep looping until there is a vertex that is usefull.
                        vertexToProcess = edges[0].Neighbour;
                        if (verticesList.Contains(vertexToProcess))
                        { // take the other vertex.
                            vertexToProcess = edges[1].Neighbour;
                            if (verticesList.Contains(vertexToProcess))
                            { // an island was detected with only vertices having two neighbours.
                                // TODO: find a way to handle this!
                                edges = new List <Edge <LiveEdge> >(0);
                                break;
                            }
                        }
                        verticesList.Add(vertexToProcess);
                        edges = _graph.GetEdges(vertexToProcess).ToList();
                    }
                }
                if (edges.Count > 0)
                { // ok, the vertex was not already processed.
                    nextPosition++;
                    var oldEdges   = new List <Edge <LiveEdge> >(edges);
                    var ignoreList = new HashSet <uint>();
                    foreach (var oldEdge in oldEdges)
                    {
                        if (ignoreList.Contains(oldEdge.Neighbour))
                        { // ignore this edge: already removed in a previous iteration.
                            break;
                        }

                        // don't re-process edges that already have coordinates.
                        ICoordinateCollection oldEdgeValueCoordinates;
                        _graph.GetEdgeShape(vertexToProcess, oldEdge.Neighbour, 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.EdgeData.Distance;
                        var current  = oldEdge.Neighbour;
                        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).ToList();
                        while (nextEdges.Count == 2)
                        { // ok the current vertex can be removed.
                            var nextEdge = nextEdges[0];
                            if (nextEdge.Neighbour == previous)
                            { // it's the other edge!
                                nextEdge = nextEdges[1];
                            }

                            // compare edges.
                            if (nextEdge.EdgeData.Forward != oldEdge.EdgeData.Forward ||
                                nextEdge.EdgeData.Tags != oldEdge.EdgeData.Tags)
                            { // oeps, edges are different!
                                break;
                            }

                            // check for intermediates.
                            ICoordinateCollection nextEdgeValueCoordinates;
                            _graph.GetEdgeShape(current, nextEdge.Neighbour, 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.EdgeData.Distance;

                            // set current/previous.
                            previous = current;
                            current  = nextEdge.Neighbour;
                            vertices.Add(current);

                            // get next edges.
                            nextEdges = _graph.GetEdges(current).ToList();
                        }

                        // check if the edge contains intermediate points.
                        if (vertices.Count == 2)
                        { // no intermediate points: add the empty coordinate list.
                            var oldEdgeValue = oldEdge.EdgeData;

                            // keep edges that already have intermediates.
                            ICoordinateCollection edgeToKeepValueCoordinates = null;
                            var edgesToKeep = new List <Tuple <uint, LiveEdge, ICoordinateCollection> >();
                            foreach (var edgeToKeep in _graph.GetEdges(vertexToProcess).ToList())
                            {
                                edgeToKeepValueCoordinates = null;
                                if (edgeToKeep.Neighbour == oldEdge.Neighbour &&
                                    _graph.GetEdgeShape(vertexToProcess, edgeToKeep.Neighbour, out edgeToKeepValueCoordinates))
                                {
                                    edgesToKeep.Add(new Tuple <uint, LiveEdge, ICoordinateCollection>(
                                                        edgeToKeep.Neighbour, edgeToKeep.EdgeData, edgeToKeepValueCoordinates));
                                }
                            }

                            // delete olds arcs.
                            _graph.RemoveEdge(vertexToProcess, oldEdge.Neighbour);

                            // add new arc.
                            if (oldEdgeValue.Forward)
                            {
                                _graph.AddEdge(vertexToProcess, oldEdge.Neighbour, oldEdgeValue, null);
                            }
                            else
                            {
                                _graph.AddEdge(vertexToProcess, oldEdge.Neighbour, (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.EdgeData.Forward)
                            {
                                _graph.AddEdge(vertices[0], vertices[vertices.Count - 1], new LiveEdge()
                                {
                                    Forward  = oldEdge.EdgeData.Forward,
                                    Tags     = oldEdge.EdgeData.Tags,
                                    Distance = distance
                                }, new CoordinateArrayCollection <GeoCoordinateSimple>(coordinates));
                            }
                            else
                            {
                                var reverse = new GeoCoordinateSimple[coordinates.Length];
                                coordinates.CopyToReverse(reverse, 0);
                                _graph.AddEdge(vertices[vertices.Count - 1], vertices[0], new LiveEdge()
                                {
                                    Forward  = !oldEdge.EdgeData.Forward,
                                    Tags     = oldEdge.EdgeData.Tags,
                                    Distance = distance
                                }, new CoordinateArrayCollection <GeoCoordinateSimple>(reverse));
                            }
                        }
                    }
                }
                // 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();
        }
Пример #30
0
 /// <summary>
 /// Creates a new edge by copying the given edge.
 /// </summary>
 /// <param name="neighbour"></param>
 /// <param name="edgeData"></param>
 /// <param name="intermediates"></param>
 public Edge(uint neighbour, TEdgeData edgeData, ICoordinateCollection intermediates)
 {
     this.Neighbour     = neighbour;
     this.EdgeData      = edgeData;
     this.Intermediates = intermediates;
 }
Пример #31
0
 /// <summary>
 /// Returns true if the given vertex has the given neighbour.
 /// </summary>
 /// <param name="vertex1"></param>
 /// <param name="vertex2"></param>
 /// <param name="shape"></param>
 /// <returns></returns>
 public override bool GetEdgeShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
 {
     return(_graph.GetEdgeShape(vertex1, vertex2, out shape));
 }
 public PointCoordinate(ICoordinateCollection coordinates)
 {
     Coordinates = coordinates;
 }
Пример #33
0
        /// <summary>
        /// Adds an edge with the associated data.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="data"></param>
        /// <param name="coordinates"></param>
        public void AddEdge(uint vertex1, uint vertex2, TEdgeData data, ICoordinateCollection coordinates)
        {
            if (vertex1 == vertex2)
            {
                throw new ArgumentException("Given vertices must be different.");
            }
            if (_nextVertexId <= vertex1)
            {
                throw new ArgumentOutOfRangeException("vertex1", "vertex1 is not part of this graph.");
            }
            if (_nextVertexId <= vertex2)
            {
                throw new ArgumentOutOfRangeException("vertex2", "vertex2 is not part of this graph.");
            }

            var edgeId = _vertices[vertex1];

            if (_vertices[vertex1] != NO_EDGE)
            { // check for an existing edge first.
                // check if the arc exists already.
                edgeId = _vertices[vertex1];
                uint nextEdgeSlot = 0;
                while (edgeId != NO_EDGE)
                { // keep looping.
                    uint otherVertexId  = 0;
                    uint previousEdgeId = edgeId;
                    bool forward        = true;
                    if (_edges[edgeId + NODEA] == vertex1)
                    {
                        otherVertexId = _edges[edgeId + NODEB];
                        nextEdgeSlot  = edgeId + NEXTNODEA;
                        edgeId        = _edges[edgeId + NEXTNODEA];
                    }
                    else
                    {
                        otherVertexId = _edges[edgeId + NODEA];
                        nextEdgeSlot  = edgeId + NEXTNODEB;
                        edgeId        = _edges[edgeId + NEXTNODEB];
                        forward       = false;
                    }
                    if (otherVertexId == vertex2)
                    { // this is the edge we need.
                        if (!forward)
                        {
                            data = (TEdgeData)data.Reverse();
                            if (coordinates != null)
                            { // also reverse coordinates!
                                coordinates = coordinates.Reverse();
                            }
                        }
                        _edgeData[previousEdgeId / 4]   = data;
                        _edgeShapes[previousEdgeId / 4] = coordinates;
                        return;
                    }
                }

                // create a new edge.
                edgeId = _nextEdgeId;
                if (_nextEdgeId + NEXTNODEB >= _edges.Length)
                { // there is a need to increase edges array.
                    this.IncreaseEdgeSize();
                }
                _edges[_nextEdgeId + NODEA]     = vertex1;
                _edges[_nextEdgeId + NODEB]     = vertex2;
                _edges[_nextEdgeId + NEXTNODEA] = NO_EDGE;
                _edges[_nextEdgeId + NEXTNODEB] = NO_EDGE;
                _nextEdgeId = _nextEdgeId + EDGE_SIZE;

                // append the new edge to the from list.
                _edges[nextEdgeSlot] = edgeId;

                // set data.
                _edgeData[edgeId / 4]   = data;
                _edgeShapes[edgeId / 4] = coordinates;
            }
            else
            { // create a new edge and set.
                edgeId             = _nextEdgeId;
                _vertices[vertex1] = _nextEdgeId;

                if (_nextEdgeId + NEXTNODEB >= _edges.Length)
                { // there is a need to increase edges array.
                    this.IncreaseEdgeSize();
                }
                _edges[_nextEdgeId + NODEA]     = vertex1;
                _edges[_nextEdgeId + NODEB]     = vertex2;
                _edges[_nextEdgeId + NEXTNODEA] = NO_EDGE;
                _edges[_nextEdgeId + NEXTNODEB] = NO_EDGE;
                _nextEdgeId = _nextEdgeId + EDGE_SIZE;

                // set data.
                _edgeData[edgeId / 4]   = data;
                _edgeShapes[edgeId / 4] = coordinates;
            }

            var toEdgeId = _vertices[vertex2];

            if (toEdgeId != NO_EDGE)
            { // there are existing edges.
                uint nextEdgeSlot = 0;
                while (toEdgeId != NO_EDGE)
                { // keep looping.
                    uint otherVertexId = 0;
                    if (_edges[toEdgeId + NODEA] == vertex2)
                    {
                        otherVertexId = _edges[toEdgeId + NODEB];
                        nextEdgeSlot  = toEdgeId + NEXTNODEA;
                        toEdgeId      = _edges[toEdgeId + NEXTNODEA];
                    }
                    else
                    {
                        otherVertexId = _edges[toEdgeId + NODEA];
                        nextEdgeSlot  = toEdgeId + NEXTNODEB;
                        toEdgeId      = _edges[toEdgeId + NEXTNODEB];
                    }
                }
                _edges[nextEdgeSlot] = edgeId;
            }
            else
            { // there are no existing edges point the vertex straight to it's first edge.
                _vertices[vertex2] = edgeId;
            }

            return;
        }
 /// <summary>
 /// Adds the new coordinates at the end of the current coordinates.
 /// </summary>
 /// <param name="coordinates"></param>
 /// <returns></returns>
 private ulong DoAdd(ICoordinateCollection coordinates)
 {
     var newId = (ulong)(_nextIdx * MAX_COLLECTION_SIZE) + (ulong)coordinates.Count;
     coordinates.Reset();
     while(coordinates.MoveNext())
     {
         if (_coordinates.Length <= (_nextIdx * 2) + 1)
         { // make sure they fit!
             this.IncreaseCoordinates();
         }
         _coordinates[(_nextIdx * 2)] = coordinates.Latitude;
         _coordinates[(_nextIdx * 2) + 1] = coordinates.Longitude;
         _nextIdx = _nextIdx + 1;
     }
     return newId;
 }
 /// <summary>
 /// Sets the coordinates starting at the given index.
 /// </summary>
 /// <param name="index"></param>
 /// <param name="coordinates"></param>
 private void DoSet(long index, ICoordinateCollection coordinates)
 {
     long idx = index;
     coordinates.Reset();
     while(coordinates.MoveNext())
     {
         _coordinates[idx] = coordinates.Latitude;
         _coordinates[idx + 1] = coordinates.Longitude;
         idx = idx + 2;
     }
 }
 /// <summary>
 /// Returns the coordinate collection at the given id.
 /// </summary>
 /// <param name="id"></param>
 /// <param name="coordinates"></param>
 /// <returns></returns>
 public bool Get(long id, out ICoordinateCollection coordinates)
 {
     long index, size;
     if (this.TryGetIndexAndSize(id, out index, out size))
     {
         coordinates = new HugeCoordinateCollection(_coordinates, index, size);
         return true;
     }
     coordinates = null;
     return false;
 }
Пример #37
0
        /// <summary>
        /// Adds the new coordinates at the end of the current coordinates.
        /// </summary>
        /// <returns></returns>
        private ulong DoAdd(ICoordinateCollection coordinates)
        {
            if(coordinates == null)
            { // just return the null-pointer if null.
                return NULL;
            }

            var id = (ulong)(_nextIdx * MAX_COLLECTION_SIZE) + (ulong)coordinates.Count;
            coordinates.Reset();
            while(coordinates.MoveNext())
            {
                if (_coordinates.Length <= (_nextIdx * 2) + 1)
                { // make sure they fit!
                    this.IncreaseCoordinates();
                }
                _coordinates[(_nextIdx * 2)] = coordinates.Latitude;
                _coordinates[(_nextIdx * 2) + 1] = coordinates.Longitude;
                _nextIdx = _nextIdx + 1;
            }
            return id;
        }