/// <summary> /// Processes all ways from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessWays(PrimitiveBlock block, PrimitiveGroup group) { if (group.Ways == null) { return; } foreach (var way in group.Ways) { int refStore = 0; List<int> refs = new List<int>(way.Refs.Count); for (int i = 0; i < way.Refs.Count; i++) { refStore += (int)way.Refs[i]; refs.Add(refStore); } List<Tag> tags = new List<Tag>(); if (way.Keys != null) { for (int i = 0; i < way.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[way.Keys[i]], block.StringTable[way.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(way.Metadata, block); WayInfo parsed = new WayInfo((int)way.ID, new TagsCollection(tags), refs, metadata); _cache.Enqueue(parsed); } }
/// <summary> /// Creates a PrimitiveBlock with entities of specified type from data in tokens. /// </summary> /// <param name="entityType">The type of entity to include in PrimitiveBlock.</param> /// <returns>PrimitiveBlock with entities of specified type or null if tokens doesn't contain any entities of specified type.</returns> private PrimitiveBlock BuildPrimitiveBlock(EntityType entityType) { PrimitiveBlock result = new PrimitiveBlock(); result.PrimitiveGroup = new List<PrimitiveGroup>(); PrimitiveGroup entityGroup = null; switch (entityType) { case EntityType.Node: entityGroup = this.BuildNodesPrimitiveGroup(result.DateGranularity, result.Granularity, result.LatOffset, result.LonOffset); result.StringTable = _nodesBuffer.BuildStringTable(); _nodesBuffer.Clear(); break; case EntityType.Way: entityGroup = this.BuildWaysPrimitiveGroup(result.DateGranularity); result.StringTable = _wayBuffer.BuildStringTable(); _wayBuffer.Clear(); break; case EntityType.Relation: entityGroup = this.BuildRelationsPrimitiveGroup(result.DateGranularity); result.StringTable = _relationBuffer.BuildStringTable(); _relationBuffer.Clear(); break; } if (entityGroup == null) { return null; } result.PrimitiveGroup.Add(entityGroup); return result; }
/// <summary> /// Processes all relations from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessRelations(PrimitiveBlock block, PrimitiveGroup group) { if (group.Relations == null) { return; } foreach (var relation in group.Relations) { int memberRefStore = 0; List<RelationMemberInfo> members = new List<RelationMemberInfo>(); for (int i = 0; i < relation.MemberIds.Count; i++) { memberRefStore += (int)relation.MemberIds[i]; string role = block.StringTable[relation.RolesIndexes[i]]; EntityType memberType = 0; switch (relation.Types[i]) { case PbfRelationMemberType.Node: memberType = EntityType.Node; break; case PbfRelationMemberType.Way: memberType = EntityType.Way; break; case PbfRelationMemberType.Relation: memberType = EntityType.Relation; break; } members.Add(new RelationMemberInfo() { MemberType = memberType, Reference = memberRefStore, Role = role }); } List<Tag> tags = new List<Tag>(); if (relation.Keys != null) { for (int i = 0; i < relation.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[relation.Keys[i]], block.StringTable[relation.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(relation.Metadata, block); RelationInfo parsed = new RelationInfo((int)relation.ID, new TagsCollection(tags), members, metadata); _cache.Enqueue(parsed); } }
/// <summary> /// Processes OSM entities in Primitive group. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup to process.</param> private void ProcessPrimitiveGroup(PrimitiveBlock block, PrimitiveGroup group) { this.ProcessNodes(block, group); this.ProcessDenseNodes(block, group); this.ProcessWays(block, group); this.ProcessRelations(block, group); }
/// <summary> /// Processes all nodes in non-dense format from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessNodes(PrimitiveBlock block, PrimitiveGroup group) { if (group.Nodes == null) { return; } foreach (PbfNode node in group.Nodes) { double lat = 1E-09 * (block.LatOffset + (block.Granularity * node.Latitude)); double lon = 1E-09 * (block.LonOffset + (block.Granularity * node.Longitude)); List<Tag> tags = new List<Tag>(); if (node.Keys != null) { for (int i = 0; i < node.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[node.Keys[i]], block.StringTable[node.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(node.Metadata, block); NodeInfo parsed = new NodeInfo((int)node.ID, lat, lon, new TagsCollection(tags), metadata); _cache.Enqueue(parsed); } }
/// <summary> /// Processes entity metadata. /// </summary> /// <param name="serializedMetadata">Serilized metadata.</param> /// <param name="block">PrimitiveBlock that contains metadata being processed.</param> /// <returns>Parsed metadata.</returns> private EntityMetadata ProcessMetadata(PbfMetadata serializedMetadata, PrimitiveBlock block) { EntityMetadata metadata = null; if (this.Settings.ReadMetadata && serializedMetadata != null) { //PBF has no field for 'visible' property, true is default value for OSM entity read from PBF file metadata = new EntityMetadata() { Visible = true }; if (serializedMetadata.Changeset.HasValue) { metadata.Changeset = (int)serializedMetadata.Changeset.Value; } if (serializedMetadata.Timestamp.HasValue) { metadata.Timestamp = _unixEpoch.AddMilliseconds(serializedMetadata.Timestamp.Value * block.DateGranularity); } if (serializedMetadata.UserID.HasValue) { metadata.Uid = serializedMetadata.UserID.Value; } if (serializedMetadata.UserNameIndex.HasValue) { metadata.User = block.StringTable[serializedMetadata.UserNameIndex.Value]; } if (serializedMetadata.Version.HasValue) { metadata.Version = serializedMetadata.Version.Value; } } return metadata; }
/// <summary> /// Processes all nodes in dense format from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessDenseNodes(PrimitiveBlock block, PrimitiveGroup group) { if (group.DenseNodes == null) { return; } long idStore = 0; long latStore = 0; long lonStore = 0; int keyValueIndex = 0; long timestampStore = 0; long changesetStore = 0; int userIdStore = 0; int usernameIdStore = 0; for (int i = 0; i < group.DenseNodes.Id.Count; i++) { idStore += group.DenseNodes.Id[i]; lonStore += group.DenseNodes.Longitude[i]; latStore += group.DenseNodes.Latitude[i]; double lat = 1E-09 * (block.LatOffset + (block.Granularity * latStore)); double lon = 1E-09 * (block.LonOffset + (block.Granularity * lonStore)); List<Tag> tags = new List<Tag>(); if (group.DenseNodes.KeysVals.Count > 0) { while (group.DenseNodes.KeysVals[keyValueIndex] != 0) { string key = block.StringTable[group.DenseNodes.KeysVals[keyValueIndex++]]; string value = block.StringTable[group.DenseNodes.KeysVals[keyValueIndex++]]; tags.Add(new Tag(key, value)); } //Skip '0' used as delimiter keyValueIndex++; } EntityMetadata metadata = null; if (this.Settings.ReadMetadata && group.DenseNodes.DenseInfo != null) { timestampStore += group.DenseNodes.DenseInfo.Timestamp[i]; changesetStore += group.DenseNodes.DenseInfo.Changeset[i]; userIdStore += group.DenseNodes.DenseInfo.UserId[i]; usernameIdStore += group.DenseNodes.DenseInfo.UserNameIndex[i]; metadata = new EntityMetadata() { Changeset = (int)changesetStore, Timestamp = _unixEpoch.AddMilliseconds(timestampStore * block.DateGranularity), Uid = userIdStore, User = block.StringTable[usernameIdStore], Version = group.DenseNodes.DenseInfo.Version[i], Visible = true }; if (group.DenseNodes.DenseInfo.Visible.Count > 0) { metadata.Visible = group.DenseNodes.DenseInfo.Visible[i]; } } NodeInfo parsed = new NodeInfo((int)idStore, lat, lon, new TagsCollection(tags), metadata); _cache.Enqueue(parsed); } }