private void ProcessNode(PrimitiveBlock block, Formats.Pbf.Node node) { var latitude = .000000001 * (block.lat_offset + (block.granularity * (double)node.lat)); var longitude = .000000001 * (block.lon_offset + (block.granularity * (double)node.lon)); var elementNode = new Entities.Node(); elementNode.Id = node.id; elementNode.Coordinate = new GeoCoordinate(latitude, longitude); if (node.keys.Any()) { elementNode.Tags = new TagCollection(node.keys.Count); for (int tagIdx = 0; tagIdx < node.keys.Count; tagIdx++) { var keyBytes = block.stringtable.s[(int)node.keys[tagIdx]]; string key = Encoding.UTF8.GetString(keyBytes, 0, keyBytes.Length); var valueBytes = block.stringtable.s[(int)node.vals[tagIdx]]; string value = Encoding.UTF8.GetString(valueBytes, 0, valueBytes.Length); //if (elementNode.Tags.ContainsKey(key)) // continue; elementNode.Tags.Add(key, value); } } _envelop.Extend(elementNode.Coordinate); _context.Builder.ProcessNode(elementNode, node.keys.Count); }
public void ProcessWay(Way way, int tagCount) { IndexStatistic.IncrementTotal(ElementType.Way); if (way.Id < 0) { IndexStatistic.Skip(way.Id, ElementType.Way); return; } var envelop = new Envelop(); way.Coordinates = new List <GeoCoordinate>(way.NodeIds.Count); foreach (var nodeId in way.NodeIds) { if (!_nodes.ContainsKey(nodeId)) { IndexStatistic.Skip(way.Id, ElementType.Way); return; } var coordinate = _nodes[nodeId]; way.Coordinates.Add(coordinate.Unscale()); envelop.Extend(coordinate.Latitude, coordinate.Longitude); } if (tagCount > 0) { uint offset = Store.Insert(way); Tree.Insert(offset, envelop); _wayOffsets.Add(way.Id, offset); IndexStatistic.Increment(ElementType.Way); } else { // keep it as it may be used by relation _ways.Add(way.Id, way); } }
public void ProcessRelation(Relation relation, int tagCount) { IndexStatistic.IncrementTotal(ElementType.Relation); if (relation.Id < 0) { IndexStatistic.Skip(relation.Id, ElementType.Relation); return; } var envelop = new Envelop(); // this cicle prevents us to insert ways which are part of unresolved relation foreach (var member in relation.Members) { var type = (ElementType)member.TypeId; if (type == ElementType.Node || type == ElementType.Relation || // TODO not supported yet (!_wayOffsets.ContainsKey(member.MemberId) && !_ways.ContainsKey(member.MemberId))) { // outline relations should be ignored if (type == ElementType.Relation && member.Role == "outline") { _skippedRelations.Add(member.MemberId); } _skippedRelations.Add(relation.Id); IndexStatistic.Skip(relation.Id, ElementType.Relation); return; } } foreach (var member in relation.Members) { var type = (ElementType)member.TypeId; uint memberOffset = 0; switch (type) { case ElementType.Way: Way way = null; if (_wayOffsets.ContainsKey(member.MemberId)) { memberOffset = _wayOffsets[member.MemberId]; way = Store.Get(memberOffset) as Way; } else if (_ways.ContainsKey(member.MemberId)) { way = _ways[member.MemberId]; memberOffset = Store.Insert(way); _wayOffsets.Add(member.MemberId, memberOffset); } foreach (GeoCoordinate t in way.Coordinates) { envelop.Extend(new PointEnvelop(t)); } break; default: throw new InvalidOperationException("Unknown element type!"); } // TODO merge tags? member.Offset = memberOffset; } _relations.Add(new MutableTuple <Relation, Envelop>(relation, envelop)); }