/// <summary> /// Converts the PBF node into an OsmSharp-node. /// </summary> public static OsmSharp.Node DecodeNode(PrimitiveBlock block, OsmSharp.IO.PBF.Node pbfNode) { var node = new OsmSharp.Node(); Encoder.DecodeNode(block, pbfNode, node); return(node); }
/// <summary> /// Encodes an OsmSharp-node into a PBF-node. /// </summary> public static OsmSharp.IO.PBF.Node EncodeNode(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, OsmSharp.IO.PBF.Node pbfNode, OsmSharp.Node node) { pbfNode.id = node.Id.Value; pbfNode.info = new Info(); pbfNode.info.version = 0; if (node.ChangeSetId.HasValue) { pbfNode.info.changeset = node.ChangeSetId.Value; } else { pbfNode.info.changeset = 0; } if (node.TimeStamp.HasValue) { pbfNode.info.timestamp = Encoder.EncodeTimestamp(node.TimeStamp.Value, block.date_granularity); } else { pbfNode.info.timestamp = 0; } if (node.UserId.HasValue) { pbfNode.info.uid = (int)node.UserId.Value; } else { pbfNode.info.uid = 0; } pbfNode.info.user_sid = Encoder.EncodeString(block, reverseStringTable, node.UserName); if (node.Version.HasValue) { pbfNode.info.version = (int)node.Version.Value; } else { pbfNode.info.version = 0; } pbfNode.lat = Encoder.EncodeLatLon(node.Latitude.Value, block.lat_offset, block.granularity); pbfNode.lon = Encoder.EncodeLatLon(node.Longitude.Value, block.lon_offset, block.granularity); if (node.Tags != null) { foreach (var tag in node.Tags) { pbfNode.keys.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Key)); pbfNode.vals.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Value)); } } else { pbfNode.keys.Clear(); pbfNode.vals.Clear(); } return(pbfNode); }
public void TestEncodeNode() { var block = new PrimitiveBlock(); block.date_granularity = 1000; block.granularity = 100; block.lat_offset = 0; block.lon_offset = 0; var node = new OsmSharp.Node(); node.Id = 1; node.ChangeSetId = 1; node.Latitude = 10; node.Longitude = 11; node.Tags = new OsmSharp.Tags.TagsCollection(); node.Tags.Add("name", "Ben"); node.TimeStamp = DateTime.Now; node.UserId = 1; node.UserName = "******"; node.Version = 1; node.Visible = true; var pbfNode = Encoder.EncodeNode(block, new Dictionary <string, int>(), node); Assert.IsNotNull(pbfNode); Assert.AreEqual(1, pbfNode.id); Assert.AreEqual(Encoder.EncodeLatLon(10, block.lat_offset, block.granularity), pbfNode.lat); Assert.AreEqual(Encoder.EncodeLatLon(11, block.lon_offset, block.granularity), pbfNode.lon); Assert.AreEqual(1, pbfNode.info.changeset); Assert.AreEqual(Encoder.EncodeTimestamp(node.TimeStamp.Value, block.date_granularity), pbfNode.info.timestamp); Assert.AreEqual(1, pbfNode.info.uid); Assert.AreEqual("Ben", System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.info.user_sid])); Assert.AreEqual(1, pbfNode.info.version); Assert.AreEqual(1, pbfNode.keys.Count); Assert.AreEqual("name", System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.keys[0]])); Assert.AreEqual(1, pbfNode.vals.Count); Assert.AreEqual("Ben", System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.vals[0]])); }
/// <summary> /// Encodes an OsmSharp-node into a PBF-node. /// </summary> public static OsmSharp.IO.PBF.Node EncodeNode(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, OsmSharp.Node node) { var pbfNode = new OsmSharp.IO.PBF.Node(); Encoder.EncodeNode(block, reverseStringTable, pbfNode, node); return(pbfNode); }
/// <summary> /// Converts the PBF node into an OsmSharp-node. /// </summary> /// <returns></returns> public static OsmSharp.Node DecodeNode(PrimitiveBlock block, OsmSharp.IO.PBF.Node pbfNode, OsmSharp.Node node) { // clear old data. if (node.Tags != null) { // clear tags. node.Tags.Clear(); } if (node.Tags == null) { // create tags collection. node.Tags = new TagsCollection(); } // set new stuff. node.ChangeSetId = pbfNode.info.changeset; node.Id = pbfNode.id; node.Latitude = Encoder.DecodeLatLon(pbfNode.lat, block.lat_offset, block.granularity); node.Longitude = Encoder.DecodeLatLon(pbfNode.lon, block.lon_offset, block.granularity); for (var i = 0; i < pbfNode.keys.Count; i++) { node.Tags.Add(new Tag() { Key = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.keys[i]]), Value = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.vals[i]]) }); } if (pbfNode.info != null) { // add the metadata if any. node.TimeStamp = Encoder.DecodeTimestamp(pbfNode.info.timestamp, block.date_granularity); node.Visible = true; node.Version = pbfNode.info.version; node.UserId = pbfNode.info.uid; node.UserName = null; if (block.stringtable != null) { node.UserName = System.Text.Encoding.UTF8.GetString(block.stringtable.s[pbfNode.info.user_sid]); } } node.Visible = true; return(node); }
private static void EncodeDenseNode(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, DenseNodes groupDense, OsmSharp.Node current, OsmSharp.Node previous) { groupDense.id.Add(current.Id.Value - previous.Id.Value); var currentLat = Encoder.EncodeLatLon(current.Latitude.Value, block.lat_offset, block.granularity); var currentLon = Encoder.EncodeLatLon(current.Longitude.Value, block.lat_offset, block.granularity); var previousLat = Encoder.EncodeLatLon(previous.Latitude.Value, block.lat_offset, block.granularity); var previousLon = Encoder.EncodeLatLon(previous.Longitude.Value, block.lat_offset, block.granularity); groupDense.lat.Add(currentLat - previousLat); groupDense.lon.Add(currentLon - previousLon); if (current.Tags != null) { foreach (var nodeTag in current.Tags) { groupDense.keys_vals.Add(Encoder.EncodeString(block, reverseStringTable, nodeTag.Key)); groupDense.keys_vals.Add(Encoder.EncodeString(block, reverseStringTable, nodeTag.Value)); } groupDense.keys_vals.Add(0); } if (groupDense.denseinfo != null) { groupDense.denseinfo.changeset.Add(current.ChangeSetId.Value - previous.ChangeSetId.Value); var currentTimeStamp = Encoder.EncodeTimestamp(current.TimeStamp.Value, block.date_granularity); var previousTimeStamp = previous.TimeStamp == null ? 0 : Encoder.EncodeTimestamp(previous.TimeStamp.Value, block.date_granularity); groupDense.denseinfo.timestamp.Add(currentTimeStamp - previousTimeStamp); groupDense.denseinfo.uid.Add((int)(current.UserId.Value - previous.UserId.Value)); groupDense.denseinfo.version.Add(current.Version.Value - previous.Version.Value); var previousUserNameId = previous.UserName == null ? 0 : Encoder.EncodeString(block, reverseStringTable, previous.UserName); var currentUserNameId = Encoder.EncodeString(block, reverseStringTable, current.UserName); groupDense.denseinfo.user_sid.Add(currentUserNameId - previousUserNameId); } }
/// <summary> /// Encodes the nodes into the given block. /// </summary> public static void Encode(this PrimitiveBlock block, Dictionary <string, int> reverseStringTable, List <OsmGeo> osmGeos, bool compressed) { var groupIdx = 0; var i = 0; if (block.stringtable != null && block.stringtable.s != null) { block.stringtable.s.Clear(); } while (i < osmGeos.Count) { PrimitiveGroup group = null; if (groupIdx < block.primitivegroup.Count) { // get the existing group and clear it's data. group = block.primitivegroup[groupIdx]; if (group == null) { group = new PrimitiveGroup(); } if (group.dense != null) { if (group.dense.denseinfo != null) { if (group.dense.denseinfo.changeset != null) { group.dense.denseinfo.changeset.Clear(); } if (group.dense.denseinfo.timestamp != null) { group.dense.denseinfo.timestamp.Clear(); } if (group.dense.denseinfo.uid != null) { group.dense.denseinfo.uid.Clear(); } if (group.dense.denseinfo.user_sid != null) { group.dense.denseinfo.user_sid.Clear(); } if (group.dense.denseinfo.version != null) { group.dense.denseinfo.version.Clear(); } } if (group.dense.id != null) { group.dense.id.Clear(); } if (group.dense.keys_vals != null) { group.dense.keys_vals.Clear(); } if (group.dense.lat != null) { group.dense.lat.Clear(); } if (group.dense.lon != null) { group.dense.lon.Clear(); } } if (group.changesets != null) { group.changesets.Clear(); } //if (group.nodes != null) { group.nodes.Clear(); } if (group.ways != null) { group.ways.Clear(); } if (group.relations != null) { group.relations.Clear(); } } else { // add a new group. group = new PrimitiveGroup(); block.primitivegroup.Add(group); } // build group. var currentNodeCount = 0; var groupType = osmGeos[i].Type; var previousNode = new OsmSharp.Node { Id = 0, Longitude = 0, Latitude = 0, ChangeSetId = 0, TimeStamp = null, UserId = 0, UserName = null, Version = 0 }; if (groupType == OsmGeoType.Node && compressed && group.dense == null) { group.dense = new DenseNodes { denseinfo = new DenseInfo() }; } while (i < osmGeos.Count && osmGeos[i].Type == groupType) { switch (groupType) { case OsmGeoType.Node: if (compressed) { var currentNode = osmGeos[i] as OsmSharp.Node; Encoder.EncodeDenseNode(block, reverseStringTable, group.dense, currentNode, previousNode); previousNode = currentNode; } else { if (currentNodeCount < group.nodes.Count) { // overwrite existing. Encoder.EncodeNode(block, reverseStringTable, group.nodes[currentNodeCount], osmGeos[i] as OsmSharp.Node); } else { // write new. group.nodes.Add(Encoder.EncodeNode(block, reverseStringTable, osmGeos[i] as OsmSharp.Node)); } currentNodeCount++; } break; case OsmGeoType.Way: group.ways.Add(Encoder.EncodeWay(block, reverseStringTable, osmGeos[i] as OsmSharp.Way)); break; case OsmGeoType.Relation: group.relations.Add(Encoder.EncodeRelation(block, reverseStringTable, osmGeos[i] as OsmSharp.Relation)); break; } i++; } // remove obsolete nodes. if (group.nodes != null) { while (currentNodeCount < group.nodes.Count) { group.nodes.RemoveAt(currentNodeCount); } } // move to the next group. groupIdx++; } while (groupIdx < block.primitivegroup.Count) { block.primitivegroup.RemoveAt(groupIdx); } }
/// <summary> /// Read a map from a stream /// </summary> /// <param name="stream"></param> /// <param name="originLatLong"></param> /// <param name="layerNames"></param> /// <returns></returns> public GeometryLayerTable ReadMap(Stream stream, AnglePair originLatLong, IList <string> layerNames = null) { var result = new GeometryLayerTable(); var source = new XmlOsmStreamSource(stream); var nodes = new Dictionary <long, OsmSharp.Node>(); var ways = new Dictionary <long, OsmSharp.Way>(); if (layerNames == null) { layerNames = new List <string>(); layerNames.Add("Building"); layerNames.Add("Highway"); } foreach (var element in source) { if (element.Id != null) { if (element.Type == OsmSharp.OsmGeoType.Node) { nodes.Add((long)element.Id, (OsmSharp.Node)element); } else if (element.Type == OsmSharp.OsmGeoType.Way) { ways.Add((long)element.Id, (OsmSharp.Way)element); } //TODO: Relations? } } foreach (var way in ways.Values) { var pts = new List <Vector>(way.Nodes.Length); for (int i = 0; i < way.Nodes.Length; i++) { long nodeID = way.Nodes[i]; if (nodes.ContainsKey(nodeID)) { OsmSharp.Node node = nodes[nodeID]; pts.Add(node.Position(originLatLong)); } } VertexGeometry geometry = null; if (pts.Count == 2) { geometry = new Line(pts[0], pts[1]); } else if (pts.Count > 2) { geometry = new PolyLine(pts); //TODO: Areas } if (geometry != null) { string layerName = "Miscellaneous"; //Assign layer according to keys: if (way.Tags != null) { foreach (string name in layerNames) { string lName = name.ToLower(); if (way.Tags.ContainsKey(lName)) { string value = way.Tags[lName]; if (LayerSeparator != null && !string.IsNullOrWhiteSpace(value) && value != "yes") { layerName = name + LayerSeparator + value; } else { layerName = name; } break; } } if (ExtrudeBuildings) { if (geometry is Curve && way.Tags.ContainsKey("height")) { string heightTag = way.Tags["height"]; heightTag = heightTag.TrimEnd('m').Trim(); double height; if (double.TryParse(heightTag, out height)) { // TODO: Deal with tags with different units on the end! geometry = new Extrusion((Curve)geometry, new Vector(0, 0, height)); } } if (geometry is Curve && way.Tags.ContainsKey("building:levels")) { // Height not supplied - fall back to storeys: string levelsTag = way.Tags["building:levels"]; double levels; if (double.TryParse(levelsTag, out levels)) { geometry = new Extrusion((Curve)geometry, new Vector(0, 0, levels * StoreyHeight + ByStoreysExtraHeight)); } } if (geometry is Curve && DefaultBuildingHeight > 0 && way.Tags.ContainsKey("building")) { // No indication of height supplied - fall back to default: geometry = new Extrusion((Curve)geometry, new Vector(0, 0, DefaultBuildingHeight)); } } } var layer = result.GetOrCreate(layerName); layer.Add(geometry); } } return(result); }
/// <summary> /// Projects the position of the node to mercator. /// </summary> /// <param name="node">The OSM node.</param> /// <returns>The X/Y position on a Mercator map.</returns> public Point Project(OsmSharp.Node node) => Project(node.Latitude.Value, node.Longitude.Value);
/// <summary> /// Converts the PBF node into an OsmSharp-node. /// </summary> /// <returns></returns> public static OsmSharp.Node DecodeNode(PrimitiveBlock block, OsmSharp.IO.PBF.Node pbfNode, OsmSharp.Node node) { // clear old data. if (node.Tags != null) { // clear tags. node.Tags.Clear(); } if (node.Tags == null) { // create tags collection. node.Tags = new TagsCollection(0); } // set new stuff. node.ChangeSetId = pbfNode.info.changeset; node.Id = pbfNode.id; node.Latitude = Encoder.DecodeLatLon(pbfNode.lat, block.lat_offset, block.granularity); node.Longitude = Encoder.DecodeLatLon(pbfNode.lon, block.lon_offset, block.granularity); for (var i = 0; i < pbfNode.keys.Count; i++) { var key = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.keys[i]]); var value = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.vals[i]]); if (!node.Tags.TryAdd(key, value)) { // Addition of the tag failed Logger.Log("invalid tag", TraceEventType.Error, $"Could not add tag `{key}={value}` to the tagscollection of osm.org/node/{node.Id} - possible duplicate keys?"); } } if (pbfNode.info != null) { // add the metadata if any. node.TimeStamp = Encoder.DecodeTimestamp(pbfNode.info.timestamp, block.date_granularity); node.Visible = true; node.Version = pbfNode.info.version; node.UserId = pbfNode.info.uid; node.UserName = null; if (block.stringtable != null) { node.UserName = System.Text.Encoding.UTF8.GetString(block.stringtable.s[pbfNode.info.user_sid]); } } node.Visible = true; return(node); }