Skip to content

Commit

Permalink
extend NextRelation/FindInRelation to nodes (#632)
Browse files Browse the repository at this point in the history
  • Loading branch information
cldellow authored Jan 7, 2024
1 parent 7405050 commit a600524
Show file tree
Hide file tree
Showing 11 changed files with 582 additions and 50 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ file(GLOB tilemaker_src_files
src/pbf_reader.cpp
src/pmtiles.cpp
src/pooled_string.cpp
src/relation_roles.cpp
src/sharded_node_store.cpp
src/sharded_way_store.cpp
src/shared_data.cpp
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ tilemaker: \
src/pbf_reader.o \
src/pmtiles.o \
src/pooled_string.o \
src/relation_roles.o \
src/sharded_node_store.o \
src/sharded_way_store.o \
src/shared_data.o \
Expand All @@ -134,6 +135,7 @@ test: \
test_deque_map \
test_pbf_reader \
test_pooled_string \
test_relation_roles \
test_sorted_node_store \
test_sorted_way_store

Expand Down Expand Up @@ -164,6 +166,11 @@ test_pooled_string: \
test/pooled_string.test.o
$(CXX) $(CXXFLAGS) -o test.pooled_string $^ $(INC) $(LIB) $(LDFLAGS) && ./test.pooled_string

test_relation_roles: \
src/relation_roles.o \
test/relation_roles.test.o
$(CXX) $(CXXFLAGS) -o test.relation_roles $^ $(INC) $(LIB) $(LDFLAGS) && ./test.relation_roles

test_sorted_node_store: \
src/external/streamvbyte_decode.o \
src/external/streamvbyte_encode.o \
Expand Down
36 changes: 30 additions & 6 deletions include/osm_lua_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "shp_mem_tiles.h"
#include "osm_mem_tiles.h"
#include "helpers.h"
#include "pbf_reader.h"
#include <protozero/data_view.hpp>

#include <boost/container/flat_map.hpp>
Expand Down Expand Up @@ -87,7 +88,15 @@ class OsmLuaProcessing {
* (note that we store relations as ways with artificial IDs, and that
* we use decrementing positive IDs to give a bit more space for way IDs)
*/
void setRelation(int64_t relationId, WayVec const &outerWayVec, WayVec const &innerWayVec, const tag_map_t &tags, bool isNativeMP, bool isInnerOuter);
void setRelation(
const std::vector<protozero::data_view>& stringTable,
const PbfReader::Relation& relation,
const WayVec& outerWayVec,
const WayVec& innerWayVec,
const tag_map_t& tags,
bool isNativeMP,
bool isInnerOuter
);

// ---- Metadata queries called from Lua

Expand Down Expand Up @@ -124,8 +133,12 @@ class OsmLuaProcessing {
double Length();

// Return centroid lat/lon
std::vector<double> Centroid();
Point calculateCentroid();
std::vector<double> Centroid(kaguya::VariadicArgType algorithm);

enum class CentroidAlgorithm: char { Centroid = 0, Polylabel = 1 };
CentroidAlgorithm defaultCentroidAlgorithm() const { return CentroidAlgorithm::Polylabel; }
CentroidAlgorithm parseCentroidAlgorithm(const std::string& algorithm) const;
Point calculateCentroid(CentroidAlgorithm algorithm);

enum class CorrectGeometryResult: char { Invalid = 0, Valid = 1, Corrected = 2 };
// ---- Requests from Lua to write this way/node to a vector tile's Layer
Expand Down Expand Up @@ -158,7 +171,7 @@ class OsmLuaProcessing {

// Add layer
void Layer(const std::string &layerName, bool area);
void LayerAsCentroid(const std::string &layerName);
void LayerAsCentroid(const std::string &layerName, kaguya::VariadicArgType nodeSources);

// Set attributes in a vector tile's Attributes table
void Attribute(const std::string &key, const std::string &val);
Expand All @@ -171,7 +184,13 @@ class OsmLuaProcessing {
void ZOrder(const double z);

// Relation scan support
kaguya::optional<int> NextRelation();

struct OptionalRelation {
bool done;
lua_Integer id;
std::string role;
};
OptionalRelation NextRelation();
void RestartRelations();
std::string FindInRelation(const std::string &key);
void Accept();
Expand Down Expand Up @@ -205,6 +224,8 @@ class OsmLuaProcessing {
/// Internal: clear current cached state
inline void reset() {
outputs.clear();
currentRelation = nullptr;
stringTable = nullptr;
llVecPtr = nullptr;
outerWayVecPtr = nullptr;
innerWayVecPtr = nullptr;
Expand All @@ -213,6 +234,7 @@ class OsmLuaProcessing {
polygonInited = false;
multiPolygonInited = false;
relationAccepted = false;
relationList.clear();
relationSubscript = -1;
lastStoredGeometryId = 0;
}
Expand All @@ -235,7 +257,7 @@ class OsmLuaProcessing {
bool isWay, isRelation, isClosed; ///< Way, node, relation?

bool relationAccepted; // in scanRelation, whether we're using a non-MP relation
std::vector<WayID> relationList; // in processWay, list of relations this way is in
std::vector<std::pair<WayID, uint16_t>> relationList; // in processNode/processWay, list of relations this entity is in, and its role
int relationSubscript = -1; // in processWay, position in the relation list

int32_t lon,latp; ///< Node coordinates
Expand All @@ -260,6 +282,8 @@ class OsmLuaProcessing {

std::vector<std::pair<OutputObject, AttributeSet>> outputs; // All output objects that have been created
const boost::container::flat_map<protozero::data_view, protozero::data_view, DataViewLessThan>* currentTags;
const PbfReader::Relation* currentRelation;
const std::vector<protozero::data_view>* stringTable;

std::vector<OutputObject> finalizeOutputs();

Expand Down
31 changes: 21 additions & 10 deletions include/osm_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "geom.h"
#include "coordinates.h"
#include "mmap_allocator.h"
#include "relation_roles.h"

#include <utility>
#include <vector>
Expand Down Expand Up @@ -81,14 +82,22 @@ class RelationScanStore {

private:
using tag_map_t = boost::container::flat_map<std::string, std::string>;
std::map<WayID, std::vector<WayID>> relationsForWays;
std::map<WayID, std::vector<std::pair<WayID, uint16_t>>> relationsForWays;
std::map<NodeID, std::vector<std::pair<WayID, uint16_t>>> relationsForNodes;
std::map<WayID, tag_map_t> relationTags;
mutable std::mutex mutex;
RelationRoles relationRoles;

public:
void relation_contains_way(WayID relid, WayID wayid) {
void relation_contains_way(WayID relid, WayID wayid, std::string role) {
uint16_t roleId = relationRoles.getOrAddRole(role);
std::lock_guard<std::mutex> lock(mutex);
relationsForWays[wayid].emplace_back(relid);
relationsForWays[wayid].emplace_back(std::make_pair(relid, roleId));
}
void relation_contains_node(WayID relid, NodeID nodeId, std::string role) {
uint16_t roleId = relationRoles.getOrAddRole(role);
std::lock_guard<std::mutex> lock(mutex);
relationsForNodes[nodeId].emplace_back(std::make_pair(relid, roleId));
}
void store_relation_tags(WayID relid, const tag_map_t &tags) {
std::lock_guard<std::mutex> lock(mutex);
Expand All @@ -97,9 +106,16 @@ class RelationScanStore {
bool way_in_any_relations(WayID wayid) {
return relationsForWays.find(wayid) != relationsForWays.end();
}
std::vector<WayID> relations_for_way(WayID wayid) {
bool node_in_any_relations(NodeID nodeId) {
return relationsForNodes.find(nodeId) != relationsForNodes.end();
}
std::string getRole(uint16_t roleId) const { return relationRoles.getRole(roleId); }
const std::vector<std::pair<WayID, uint16_t>>& relations_for_way(WayID wayid) {
return relationsForWays[wayid];
}
const std::vector<std::pair<WayID, uint16_t>>& relations_for_node(NodeID nodeId) {
return relationsForNodes[nodeId];
}
std::string get_relation_tag(WayID relid, const std::string &key) {
auto it = relationTags.find(relid);
if (it==relationTags.end()) return "";
Expand Down Expand Up @@ -176,14 +192,14 @@ class OSMStore
public:
NodeStore& nodes;
WayStore& ways;
RelationScanStore scannedRelations;

protected:
bool use_compact_nodes = false;
bool require_integrity = true;

RelationStore relations; // unused
UsedWays used_ways;
RelationScanStore scanned_relations;

public:

Expand Down Expand Up @@ -211,11 +227,6 @@ class OSMStore
void ensureUsedWaysInited();

using tag_map_t = boost::container::flat_map<std::string, std::string>;
void relation_contains_way(WayID relid, WayID wayid) { scanned_relations.relation_contains_way(relid,wayid); }
void store_relation_tags(WayID relid, const tag_map_t &tags) { scanned_relations.store_relation_tags(relid,tags); }
bool way_in_any_relations(WayID wayid) { return scanned_relations.way_in_any_relations(wayid); }
std::vector<WayID> relations_for_way(WayID wayid) { return scanned_relations.relations_for_way(wayid); }
std::string get_relation_tag(WayID relid, const std::string &key) { return scanned_relations.get_relation_tag(relid, key); }

void clear();
void reportSize() const;
Expand Down
Loading

0 comments on commit a600524

Please sign in to comment.