1
0
Fork 0
mirror of https://github.com/systemed/tilemaker synced 2025-02-21 13:24:09 +01:00
tilemaker/include/pbf_processor.h
Colin Dellow d3de0fb4b1 warn when --compact used on non-renumbered PBF
A future commit will make it safe to do so, but it's still
memory-inefficient to use --compact on a non-renumbered PBF
2024-01-26 19:56:51 -05:00

134 lines
4 KiB
C++

/*! \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