File: pbf_processor.h

package info (click to toggle)
tilemaker 3.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 83,488 kB
  • sloc: cpp: 29,461; ansic: 12,510; makefile: 229; ruby: 77; sh: 43
file content (134 lines) | stat: -rw-r--r-- 4,053 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*! \file */ 
#ifndef _READ_PBF_H
#define _READ_PBF_H

#include <atomic>
#include <string>
#include <unordered_set>
#include <vector>
#include <mutex>
#include <map>
#include "osm_store.h"
#include "significant_tags.h"
#include "pbf_reader.h"
#include "tag_map.h"
#include <protozero/data_view.hpp>

class OsmLuaProcessing;

extern const std::string OptionSortTypeThenID;
extern const std::string OptionLocationsOnWays;

struct BlockMetadata {
	long int offset;
	int32_t length;
	bool hasNodes;
	bool hasWays;
	bool hasRelations;

	// We use blocks as the unit of parallelism. Sometimes, a PBF only
	// has a few blocks with relations. In this case, to keep all cores
	// busy, we'll subdivide the block into chunks, and each thread
	// will only process a chunk of the block.
	size_t chunk;
	size_t chunks;
};

struct IndexedBlockMetadata: BlockMetadata {
	size_t index;
};

/**
 *\brief Reads a PBF OSM file and returns objects as a stream of events to a class derived from OsmLuaProcessing
 *
 * The output class is typically OsmMemTiles, which is derived from OsmLuaProcessing
 */
class PbfProcessor
{
public:	
	enum class ReadPhase { Nodes = 1, Ways = 2, Relations = 4, RelationScan = 8, WayScan = 16 };

	PbfProcessor(OSMStore &osmStore);

	using pbfreader_generate_output = std::function< std::shared_ptr<OsmLuaProcessing> () >;
	using pbfreader_generate_stream = std::function< std::shared_ptr<std::istream> () >;

	int ReadPbfFile(
		uint shards,
		bool hasSortTypeThenID,
		const SignificantTags& nodeKeys,
		const SignificantTags& wayKeys,
		unsigned int threadNum,
		const pbfreader_generate_stream& generate_stream,
		const pbfreader_generate_output& generate_output,
		const NodeStore& nodeStore,
		const WayStore& wayStore
	);

	// Read tags into a map from a way/node/relation
	template<typename T>
	void readTags(T &pbfObject, PbfReader::PrimitiveBlock const &pb, TagMap& tags) {
		for (uint n=0; n < pbfObject.keys.size(); n++) {
			auto keyIndex = pbfObject.keys[n];
			auto valueIndex = pbfObject.vals[n];
			tags.addTag(pb.stringTable[keyIndex], pb.stringTable[valueIndex]);
		}
	}

private:
	bool ReadBlock(
		std::istream &infile,
		OsmLuaProcessing &output,
		const BlockMetadata& blockMetadata,
		const SignificantTags& nodeKeys,
		const SignificantTags& wayKeys,
		bool locationsOnWays,
		ReadPhase phase,
		uint shard,
		uint effectiveShard
	);
	bool ReadNodes(OsmLuaProcessing& output, PbfReader::PrimitiveGroup& pg, const PbfReader::PrimitiveBlock& pb, const SignificantTags& nodeKeys);

	bool ReadWays(
		OsmLuaProcessing& output,
		PbfReader::PrimitiveGroup& pg,
		const PbfReader::PrimitiveBlock& pb,
		const SignificantTags& wayKeys,
		bool locationsOnWays,
		uint shard,
		uint effectiveShards
	);
	bool ScanWays(OsmLuaProcessing& output, PbfReader::PrimitiveGroup& pg, const PbfReader::PrimitiveBlock& pb, const SignificantTags& wayKeys);
	bool ScanRelations(OsmLuaProcessing& output, PbfReader::PrimitiveGroup& pg, const PbfReader::PrimitiveBlock& pb, const SignificantTags& wayKeys);
	bool ReadRelations(
		OsmLuaProcessing& output,
		PbfReader::PrimitiveGroup& pg,
		const PbfReader::PrimitiveBlock& pb,
		const BlockMetadata& blockMetadata,
		const SignificantTags& wayKeys,
		uint shard,
		uint effectiveShards
	);

	inline bool relationIsType(const PbfReader::Relation& rel, int typeKey, int val) {
		if (typeKey == -1 || val == -1) return false;
		auto typeI = std::find(rel.keys.begin(), rel.keys.end(), typeKey);
		if (typeI == rel.keys.end()) return false;
		int typePos = typeI - rel.keys.begin();
		return rel.vals[typePos] == val;
	}

	/// Find a string in the dictionary
	static int findStringPosition(const PbfReader::PrimitiveBlock& pb, const std::string& str);
	
	OSMStore &osmStore;
	std::mutex ioMutex;
	std::atomic<bool> compactWarningIssued;
};

int ReadPbfBoundingBox(const std::string &inputFile, double &minLon, double &maxLon, 
	double &minLat, double &maxLat, bool &hasClippingBox);

bool PbfHasOptionalFeature(const std::string& inputFile, const std::string& feature);

#endif //_READ_PBF_H