/// <summary> /// Serializes all the tags in the given index. This serialization preserves the id's of each tag collection. /// </summary> /// <param name="stream">The target stream.</param> /// <param name="tagsIndex">The tags index to serialize.</param> public static void Serialize(Stream stream, ITagsIndex tagsIndex) { int begin = (int)stream.Position; // build a string index. ObjectTable <string> stringTable = new ObjectTable <string>(false); // convert tag collections to simpler objects. List <KeyValuePair <uint, List <KeyValuePair <uint, uint> > > > tagsIndexList = new List <KeyValuePair <uint, List <KeyValuePair <uint, uint> > > >(); for (uint tagId = 0; tagId < tagsIndex.Max; tagId++) { TagsCollection tagsCollection = tagsIndex.Get(tagId); if (tagsCollection != null) { // convert the tags collection to a list and add to the tag index. List <KeyValuePair <uint, uint> > tagsList = new List <KeyValuePair <uint, uint> >(); foreach (Tag tag in tagsCollection) { uint keyId = stringTable.Add(tag.Key); uint valueId = stringTable.Add(tag.Value); tagsList.Add(new KeyValuePair <uint, uint>( keyId, valueId)); } tagsIndexList.Add(new KeyValuePair <uint, List <KeyValuePair <uint, uint> > >(tagId, tagsList)); } } // do the serialization. TagIndexSerializer.Serialize(begin, stream, tagsIndexList, stringTable); // clear everything. tagsIndexList.Clear(); }
/// <summary> /// Verifies the content of the given tags index agains the expected content list. /// </summary> /// <param name="tagsCollectionIndex"></param> /// <param name="expectedContent"></param> private void TestTagIndexContent(ITagsIndex tagsCollectionIndex, List <KeyValuePair <uint, TagsCollectionBase> > expectedContent) { // check the index. foreach (var pair in expectedContent) { var indexTags = tagsCollectionIndex.Get(pair.Key); Assert.AreEqual(pair.Value.Count, indexTags.Count); foreach (var tag in pair.Value) { Assert.IsTrue(indexTags.ContainsKeyValue(tag.Key, tag.Value)); } foreach (var tag in indexTags) { Assert.IsTrue(pair.Value.ContainsKeyValue(tag.Key, tag.Value)); } } }
/// <summary> /// Tests the given tags collection index. /// </summary> /// <param name="tagsCollectionIndex"></param> protected void TestTagIndex(ITagsIndex tagsCollectionIndex) { // set the seed manually. OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346); var addedTags = new List <KeyValuePair <uint, TagsCollectionBase> >(); for (int i = 0; i < 100; i++) { var tagsCollection = new TagsCollection(); var tagCollectionSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(3) + 1; for (int idx = 0; idx < tagCollectionSize; idx++) { var tagValue = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(3); tagsCollection.Add( string.Format("key_{0}", tagValue), string.Format("value_{0}", tagValue)); } var addCount = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(2) + 1; for (int idx = 0; idx < addCount; idx++) { var tagsId = tagsCollectionIndex.Add(tagsCollection); addedTags.Add(new KeyValuePair <uint, TagsCollectionBase>(tagsId, tagsCollection)); var indexTags = tagsCollectionIndex.Get(tagsId); Assert.AreEqual(tagsCollection.Count, indexTags.Count); foreach (var tag in tagsCollection) { Assert.IsTrue(indexTags.ContainsKeyValue(tag.Key, tag.Value)); } } } // test complete content. this.TestTagIndexContent(tagsCollectionIndex, addedTags); }
/// <summary> /// Searches the data for a point on an edge closest to the given coordinate. /// </summary> /// <param name="graph"></param> /// <param name="vehicle"></param> /// <param name="coordinate"></param> /// <param name="delta"></param> /// <param name="matcher"></param> /// <param name="pointTags"></param> /// <param name="interpreter"></param> public SearchClosestResult SearchClosest(IBasicRouterDataSource <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle, GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollection pointTags) { double searchBoxSize = delta; // create the search box. var searchBox = new GeoCoordinateBox(new GeoCoordinate( coordinate.Latitude - searchBoxSize, coordinate.Longitude - searchBoxSize), new GeoCoordinate( coordinate.Latitude + searchBoxSize, coordinate.Longitude + searchBoxSize)); // get the arcs from the data source. KeyValuePair <uint, KeyValuePair <uint, TEdgeData> >[] arcs = graph.GetArcs(searchBox); // loop over all. var closestWithMatch = new SearchClosestResult(double.MaxValue, 0); var closestWithoutMatch = new SearchClosestResult(double.MaxValue, 0); foreach (KeyValuePair <uint, KeyValuePair <uint, TEdgeData> > arc in arcs) { TagsCollection arcTags = _tagsIndex.Get(arc.Value.Value.Tags); bool canBeTraversed = vehicle.CanTraverse(arcTags); if (canBeTraversed) { // the edge can be traversed. // test the two points. float fromLatitude, fromLongitude; float toLatitude, toLongitude; double distance; if (graph.GetVertex(arc.Key, out fromLatitude, out fromLongitude) && graph.GetVertex(arc.Value.Key, out toLatitude, out toLongitude)) { // return the vertex. var fromCoordinates = new GeoCoordinate(fromLatitude, fromLongitude); distance = coordinate.Distance(fromCoordinates); if (distance < 0.00001) { // the distance is smaller than the tolerance value. closestWithoutMatch = new SearchClosestResult( distance, arc.Key); if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { closestWithMatch = new SearchClosestResult( distance, arc.Key); break; } } if (distance < closestWithoutMatch.Distance) { // the distance is smaller for the without match. closestWithoutMatch = new SearchClosestResult( distance, arc.Key); } if (distance < closestWithMatch.Distance) { // the distance is smaller for the with match. if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, _tagsIndex.Get(arc.Value.Value.Tags))) { closestWithMatch = new SearchClosestResult( distance, arc.Key); } } var toCoordinates = new GeoCoordinate(toLatitude, toLongitude); distance = coordinate.Distance(toCoordinates); if (distance < closestWithoutMatch.Distance) { // the distance is smaller for the without match. closestWithoutMatch = new SearchClosestResult( distance, arc.Value.Key); } if (distance < closestWithMatch.Distance) { // the distance is smaller for the with match. if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { closestWithMatch = new SearchClosestResult( distance, arc.Value.Key); } } // create a line. double distanceTotal = fromCoordinates.Distance(toCoordinates); if (distanceTotal > 0) { // the from/to are not the same location. var line = new GeoCoordinateLine(fromCoordinates, toCoordinates, true, true); distance = line.Distance(coordinate); if (distance < closestWithoutMatch.Distance) { // the distance is smaller. PointF2D projectedPoint = line.ProjectOn(coordinate); // calculate the position. if (projectedPoint != null) { // calculate the distance double distancePoint = fromCoordinates.Distance(projectedPoint); double position = distancePoint / distanceTotal; closestWithoutMatch = new SearchClosestResult( distance, arc.Key, arc.Value.Key, position); } } if (distance < closestWithMatch.Distance) { PointF2D projectedPoint = line.ProjectOn(coordinate); // calculate the position. if (projectedPoint != null) { // calculate the distance double distancePoint = fromCoordinates.Distance(projectedPoint); double position = distancePoint / distanceTotal; if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { closestWithMatch = new SearchClosestResult( distance, arc.Key, arc.Value.Key, position); } } } } } } } // return the best result. if (closestWithMatch.Distance < double.MaxValue) { return(closestWithMatch); } return(closestWithoutMatch); }
/// <summary> /// Verifies the content of the given tags index agains the expected content list. /// </summary> /// <param name="tagsCollectionIndex"></param> /// <param name="expectedContent"></param> private void TestTagIndexContent(ITagsIndex tagsCollectionIndex, List<KeyValuePair<uint, TagsCollectionBase>> expectedContent) { // check the index. foreach (var pair in expectedContent) { var indexTags = tagsCollectionIndex.Get(pair.Key); Assert.AreEqual(pair.Value.Count, indexTags.Count); foreach (var tag in pair.Value) { Assert.IsTrue(indexTags.ContainsKeyValue(tag.Key, tag.Value)); } foreach (var tag in indexTags) { Assert.IsTrue(pair.Value.ContainsKeyValue(tag.Key, tag.Value)); } } }
/// <summary> /// Tests the given tags collection index. /// </summary> /// <param name="tagsCollectionIndex"></param> protected void TestTagIndex(ITagsIndex tagsCollectionIndex) { // set the seed manually. OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346); var addedTags = new List<KeyValuePair<uint, TagsCollectionBase>>(); for (int i = 0; i < 100; i++) { var tagsCollection = new TagsCollection(); var tagCollectionSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(3) + 1; for (int idx = 0; idx < tagCollectionSize; idx++) { var tagValue = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(3); tagsCollection.Add( string.Format("key_{0}", tagValue), string.Format("value_{0}", tagValue)); } var addCount = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(2) + 1; for (int idx = 0; idx < addCount; idx++) { var tagsId = tagsCollectionIndex.Add(tagsCollection); addedTags.Add(new KeyValuePair<uint, TagsCollectionBase>(tagsId, tagsCollection)); var indexTags = tagsCollectionIndex.Get(tagsId); Assert.AreEqual(tagsCollection.Count, indexTags.Count); foreach (var tag in tagsCollection) { Assert.IsTrue(indexTags.ContainsKeyValue(tag.Key, tag.Value)); } } } // test complete content. this.TestTagIndexContent(tagsCollectionIndex, addedTags); }
/// <summary> /// Serializes all the tags in the given index. This serialization preserves the id's of each tag collection. /// </summary> /// <param name="stream">The target stream.</param> /// <param name="tagsIndex">The tags index to serialize.</param> public static void Serialize(Stream stream, ITagsIndex tagsIndex) { int begin = (int)stream.Position; // build a string index. ObjectTable<string> stringTable = new ObjectTable<string>(false); // convert tag collections to simpler objects. List<KeyValuePair<uint, List<KeyValuePair<uint, uint>>>> tagsIndexList = new List<KeyValuePair<uint,List<KeyValuePair<uint,uint>>>>(); for (uint tagId = 0; tagId < tagsIndex.Max; tagId++) { TagsCollection tagsCollection = tagsIndex.Get(tagId); if (tagsCollection != null) { // convert the tags collection to a list and add to the tag index. List<KeyValuePair<uint, uint>> tagsList = new List<KeyValuePair<uint, uint>>(); foreach (Tag tag in tagsCollection) { uint keyId = stringTable.Add(tag.Key); uint valueId = stringTable.Add(tag.Value); tagsList.Add(new KeyValuePair<uint, uint>( keyId, valueId)); } tagsIndexList.Add(new KeyValuePair<uint, List<KeyValuePair<uint, uint>>>(tagId, tagsList)); } } // do the serialization. TagIndexSerializer.Serialize(begin, stream, tagsIndexList, stringTable); // clear everything. tagsIndexList.Clear(); }