| | | 1 | | using System.Collections.Generic; |
| | | 2 | | using System.Globalization; |
| | | 3 | | using System.IO; |
| | | 4 | | using System.Text; |
| | | 5 | | using System.Text.Json; |
| | | 6 | | using Itinero.Geo; |
| | | 7 | | using Itinero.MapMatching.Model; |
| | | 8 | | using Itinero.Network; |
| | | 9 | | using Itinero.Snapping; |
| | | 10 | | |
| | | 11 | | namespace Itinero.MapMatching.IO.GeoJson; |
| | | 12 | | |
| | | 13 | | public static class GraphModelExtensions |
| | | 14 | | { |
| | | 15 | | public static string ToGeoJson(this GraphModel graphModel, RoutingNetwork routingNetwork) |
| | 0 | 16 | | { |
| | 0 | 17 | | using var stream = new MemoryStream(); |
| | 0 | 18 | | using (var jsonWriter = new Utf8JsonWriter(stream)) |
| | 0 | 19 | | { |
| | 0 | 20 | | jsonWriter.WriteFeatureCollectionStart(); |
| | 0 | 21 | | jsonWriter.WriteFeatures(graphModel, routingNetwork); |
| | 0 | 22 | | jsonWriter.WriteFeatureCollectionEnd(); |
| | 0 | 23 | | } |
| | | 24 | | |
| | 0 | 25 | | return Encoding.UTF8.GetString(stream.ToArray()); |
| | 0 | 26 | | } |
| | | 27 | | |
| | | 28 | | public static void WriteFeatures(this Utf8JsonWriter jsonWriter, GraphModel graphModel, RoutingNetwork routingNetwor |
| | 0 | 29 | | { |
| | 0 | 30 | | var track = graphModel.Track; |
| | 0 | 31 | | jsonWriter.WriteFeatures(track); |
| | | 32 | | |
| | 0 | 33 | | for (var n = 0; n < graphModel.Count; n++) |
| | 0 | 34 | | { |
| | 0 | 35 | | var node = graphModel.GetNode(n); |
| | 0 | 36 | | if (node.SnapPoint == null) continue; |
| | | 37 | | |
| | 0 | 38 | | var nodeLocation = node.SnapPoint.Value.LocationOnNetwork(routingNetwork); |
| | 0 | 39 | | jsonWriter.WriteFeatureStart(); |
| | 0 | 40 | | jsonWriter.WriteGeometryStart(); |
| | 0 | 41 | | jsonWriter.WritePoint((nodeLocation)); |
| | 0 | 42 | | jsonWriter.WriteProperties(new (string key, string value)[] |
| | 0 | 43 | | { |
| | 0 | 44 | | ("type", "node"), |
| | 0 | 45 | | ("node-id", n.ToString()), |
| | 0 | 46 | | ("track-point-id", node.TrackPoint?.ToString() ?? string.Empty), |
| | 0 | 47 | | ("snappoint-edge-id", node.SnapPoint.Value.EdgeId.ToString()), |
| | 0 | 48 | | ("snappoint-offset", node.SnapPoint.Value.Offset.ToString()), |
| | 0 | 49 | | ("cost", node.Cost.ToString(CultureInfo.InvariantCulture)) |
| | 0 | 50 | | }); |
| | 0 | 51 | | jsonWriter.WriteFeatureEnd(); |
| | | 52 | | |
| | 0 | 53 | | if (node.TrackPoint == null) continue; |
| | 0 | 54 | | var trackPoint = track[node.TrackPoint.Value]; |
| | | 55 | | |
| | 0 | 56 | | jsonWriter.WriteFeatureStart(); |
| | 0 | 57 | | jsonWriter.WriteGeometryStart(); |
| | 0 | 58 | | jsonWriter.WriteLineString(new[] |
| | 0 | 59 | | { |
| | 0 | 60 | | nodeLocation, |
| | 0 | 61 | | (trackPoint.Location.longitude, trackPoint.Location.latitude, null) |
| | 0 | 62 | | }); |
| | 0 | 63 | | var length = |
| | 0 | 64 | | nodeLocation.DistanceEstimateInMeter( |
| | 0 | 65 | | (trackPoint.Location.longitude, trackPoint.Location.latitude, null)); |
| | 0 | 66 | | jsonWriter.WriteProperties(new (string key, string value)[] |
| | 0 | 67 | | { |
| | 0 | 68 | | ("type", "node-offset"), |
| | 0 | 69 | | ("node-id", n.ToString()), |
| | 0 | 70 | | ("track-point-id", node.TrackPoint.Value.ToString()), |
| | 0 | 71 | | ("snappoint-offset", node.SnapPoint.Value.Offset.ToString()), |
| | 0 | 72 | | ("length", length.ToString(CultureInfo.InvariantCulture)), |
| | 0 | 73 | | ("cost", node.Cost.ToString(CultureInfo.InvariantCulture)) |
| | 0 | 74 | | }); |
| | 0 | 75 | | jsonWriter.WriteFeatureEnd(); |
| | | 76 | | |
| | 0 | 77 | | var edges = graphModel.GetNeighbours(n); |
| | 0 | 78 | | foreach (var edge in edges) |
| | 0 | 79 | | { |
| | 0 | 80 | | var node1 = graphModel.GetNode(edge.Node1); |
| | 0 | 81 | | if (node1.SnapPoint == null) continue; |
| | 0 | 82 | | var node2 = graphModel.GetNode(edge.Node2); |
| | 0 | 83 | | if (node2.SnapPoint == null) continue; |
| | | 84 | | |
| | 0 | 85 | | var node1Location = node1.SnapPoint.Value.LocationOnNetwork(routingNetwork); |
| | 0 | 86 | | var node2Location = node2.SnapPoint.Value.LocationOnNetwork(routingNetwork); |
| | 0 | 87 | | length = |
| | 0 | 88 | | node1Location.DistanceEstimateInMeter( |
| | 0 | 89 | | node2Location); |
| | | 90 | | |
| | 0 | 91 | | jsonWriter.WriteFeatureStart(); |
| | 0 | 92 | | jsonWriter.WriteGeometryStart(); |
| | 0 | 93 | | jsonWriter.WriteLineString(new[] |
| | 0 | 94 | | { |
| | 0 | 95 | | node1Location, |
| | 0 | 96 | | node2Location |
| | 0 | 97 | | }); |
| | 0 | 98 | | var attributes = new List<(string key, string value)> |
| | 0 | 99 | | { |
| | 0 | 100 | | ("cost", edge.Cost.ToString(CultureInfo.InvariantCulture)), |
| | 0 | 101 | | ("node-id1", edge.Node1.ToString()), |
| | 0 | 102 | | ("node-id2", edge.Node2.ToString()), |
| | 0 | 103 | | ("track-point-1", node1.TrackPoint?.ToString() ?? string.Empty), |
| | 0 | 104 | | ("track-point-2", node2.TrackPoint?.ToString() ?? string.Empty), |
| | 0 | 105 | | ("length", length.ToString(CultureInfo.InvariantCulture)) |
| | 0 | 106 | | }; |
| | 0 | 107 | | if (edge.Attributes != null) attributes.AddRange(edge.Attributes); |
| | 0 | 108 | | jsonWriter.WriteProperties(attributes); |
| | 0 | 109 | | jsonWriter.WriteFeatureEnd(); |
| | 0 | 110 | | } |
| | 0 | 111 | | } |
| | 0 | 112 | | } |
| | | 113 | | } |