Пример #1
0
        /// <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);
        }
Пример #2
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.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);
        }
Пример #3
0
        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]]));
        }
Пример #4
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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        /// <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);
            }
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
 /// <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);
Пример #10
0
        /// <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);
        }