public static int ReadBinary(byte[] buf, int ofs, out OsmNode node) { int p = 0; ulong tmp; p += ProtoBuf.ReadVarInt(buf, ofs + p, out tmp); long id = (long)tmp; p += ProtoBuf.ReadVarInt(buf, ofs + p, out tmp); int latCode = ProtoBuf.SignedInt32((uint)tmp); p += ProtoBuf.ReadVarInt(buf, ofs + p, out tmp); int lonCode = ProtoBuf.SignedInt32((uint)tmp); p += ProtoBuf.ReadVarInt(buf, ofs + p, out tmp); var values = tmp == 0 ? emptyValues : new KeyValuePair <string, string> [tmp]; for (int i = 0; i < values.Length; i++) { string key, val; p += ProtoBuf.ReadString(buf, ofs + p, out key); p += ProtoBuf.ReadString(buf, ofs + p, out val); values[i] = new KeyValuePair <string, string>(key, val); } node = new OsmNode(id, latCode, lonCode, values); return(p); }
/// <summary> /// Konstruktor /// </summary> /// <param name="node">OSM-Knoten mit der entsprechenden GPS-Position</param> public GpsPos(OsmNode node) { posX = (uint)node.lonCode + 1800000000u; posY = 900000000u - (uint)node.latCode; }
/// <summary> /// liest mehrere OSM-Knoten ein und gibt die Ergebnisse in entsprechender Reihenfolge zurück /// </summary> /// <param name="nodeIds">Knoten-IDs, welche abgefragt werden sollen</param> /// <returns>Array mit den abgefragten Knoten</returns> public OsmNode[] ReadNodes(params long[] nodeIds) { var result = new OsmNode[nodeIds.Length]; var searchNodes = Enumerable.Range(0, nodeIds.Length).Select(i => new KeyValuePair <long, int>(nodeIds[i], i)).ToArray(nodeIds.Length); Array.Sort(searchNodes, (x, y) => x.Key.CompareTo(y.Key)); var needBlobs = new List <OsmBlob>(); var lastBlob = wayIndex[0]; foreach (var nodeId in searchNodes.Select(x => x.Key)) { if (nodeId > lastBlob.maxNodeId || nodeId < lastBlob.minNodeId) { lastBlob = nodeIndex.BinarySearchSingle(x => nodeId >= x.minNodeId && nodeId <= x.maxNodeId ? 0L : x.minNodeId - nodeId); needBlobs.Add(lastBlob); } } var blobDecoder = BlobSmtDecoder(needBlobs, (blob, buf) => { try { MemArray <OsmNode> tmp; int len = PbfFast.DecodePrimitiveBlock(buf, 0, blob, out tmp); if (len != blob.rawSize) { throw new PbfParseException(); } return(tmp); } catch { return(null); } }).GetEnumerator(); MemArray <OsmNode> nodes = null; var tmpNodes = new List <MemArray <OsmNode> >(); for (int w = 0; w < searchNodes.Length; w++) { long nodeId = searchNodes[w].Key; if (nodes == null || nodes[nodes.Length - 1].id < nodeId) { if (nodes != null) { nodes.Dispose(); } nodes = null; for (int i = 0; i < tmpNodes.Count; i++) { if (nodeId >= tmpNodes[i].First().id&& nodeId <= tmpNodes[i].Last().id) { nodes = tmpNodes[i]; tmpNodes.RemoveAt(i); break; } } while (nodes == null) { blobDecoder.MoveNext(); nodes = blobDecoder.Current; if (nodeId < nodes.First().id || nodeId > nodes.Last().id) { tmpNodes.Add(nodes); nodes = null; } } Console.WriteLine("read nodes: {0:N0} / {1:N0}", w + 1, searchNodes.Length); } result[searchNodes[w].Value] = nodes.BinarySearchSingle(x => x.id - nodeId); } if (nodes != null) { nodes.Dispose(); } return(result); }