Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extend NextRelation/FindInRelation to nodes #632

Merged
merged 13 commits into from
Jan 7, 2024
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 @@ -114,6 +114,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 @@ -133,6 +134,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 @@ -163,6 +165,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
Loading