Skip to content

Commit 0ebc1d7

Browse files
authored
Simple key/value store (#817)
1 parent e582f9d commit 0ebc1d7

File tree

5 files changed

+35
-9
lines changed

5 files changed

+35
-9
lines changed

docs/CONFIGURATION.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ Your Lua file can supply these functions for tilemaker to call:
124124
2. (optional) `way_keys`, a list of those OSM tags which indicate that a way should be processed
125125
3. `node_function()`, a function to process an OSM node and add it to layers
126126
4. `way_function()`, a function to process an OSM way and add it to layers
127-
5. (optional) `init_function(name)`, a function to initialize Lua logic
127+
5. (optional) `init_function(name, is_first)`, a function to initialize Lua logic
128128
6. (optional) `exit_function`, a function to finalize Lua logic (useful to show statistics)
129129
7. (optional) `relation_scan_function`, a function to determine whether your Lua file wishes to process the given relation
130130
8. (optional) `relation_function`, a function to process an OSM relation and add it to layers
@@ -184,7 +184,7 @@ If your Lua file causes an error due to mistaken syntax, you can test it at the
184184

185185
`way_keys` is similar, but for ways. For ways, you may also wish to express the filter in terms of the tag value, or as an inversion. For example, to exclude buildings: `way_keys = {"~building"}`. To build a map only of major roads: `way_keys = {"highway=motorway", "highway=trunk", "highway=primary", "highway=secondary"}`
186186

187-
`init_function(name)` and `exit_function` are called at the start and end of processing (once per thread). You can use this to output statistics or even to read a small amount of external data.
187+
`init_function(name, is_first)` and `exit_function` are called at the start and end of processing (once per thread). You can use this to output statistics or even to read a small amount of external data. `is_first` will be true only the first time `init_function` is called.
188188

189189
Other functions are described below and in RELATIONS.md.
190190

@@ -243,3 +243,11 @@ To enable these functions, set `index` to true in your shapefile layer definitio
243243
`CoveredBy` and `FindCovering` work similarly but check if the object is covered by a shapefile layer object.
244244

245245
`AreaIntersecting` returns the area of the current way's intersection with the shapefile layer. You can use this to find whether a water body is already represented in a shapefile ocean layer.
246+
247+
### Lua key/value store
248+
249+
tilemaker has a simple key/value store accessible from Lua which you can use to bring in external data. The same store is used across all processing threads.
250+
251+
Read your data from file, using [Lua's I/O functions](https://www.lua.org/pil/21.1.html), in `init_function` (checking that `is_first` is set for the first run only). Set a key/value pair with `SetData(key,value)` - for example `SetData("name","Bill")`. Both key and value should be strings.
252+
253+
You can then retrieve the value within `way_function` or similar with `GetData(key)`. If no value was found, the empty string is returned.

include/osm_lua_processing.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <string>
77
#include <sstream>
88
#include <map>
9+
#include <mutex>
910
#include "geom.h"
1011
#include "osm_store.h"
1112
#include "shared_data.h"
@@ -56,7 +57,8 @@ class OsmLuaProcessing {
5657
const class ShpMemTiles &shpMemTiles,
5758
class OsmMemTiles &osmMemTiles,
5859
AttributeStore &attributeStore,
59-
bool materializeGeometries
60+
bool materializeGeometries,
61+
bool isFirst
6062
);
6163
~OsmLuaProcessing();
6264

@@ -239,6 +241,9 @@ class OsmLuaProcessing {
239241
const TagMap* currentTags;
240242
bool isPostScanRelation; // processing a relation in postScanRelation
241243

244+
static std::unordered_map<std::string, std::string> dataStore;
245+
static std::mutex dataStoreMutex;
246+
242247
private:
243248
/// Internal: clear current cached state
244249
inline void reset() {

resources/process-openmaptiles.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ additional_languages = { }
1717
--------
1818

1919
-- Enter/exit Tilemaker
20-
function init_function()
20+
function init_function(name,is_first)
2121
end
2222
function exit_function()
2323
end

src/osm_lua_processing.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ thread_local kaguya::State *g_luaState = nullptr;
1818
thread_local OsmLuaProcessing* osmLuaProcessing = nullptr;
1919

2020
std::mutex vectorLayerMetadataMutex;
21+
std::unordered_map<std::string, std::string> OsmLuaProcessing::dataStore;
22+
std::mutex OsmLuaProcessing::dataStoreMutex;
2123

2224
void handleOsmLuaProcessingUserSignal(int signum) {
2325
osmLuaProcessing->handleUserSignal(signum);
@@ -195,6 +197,14 @@ std::string rawFindInRelation(const std::string& key) { return osmLuaProcessing-
195197
void rawAccept() { return osmLuaProcessing->Accept(); }
196198
double rawAreaIntersecting(const std::string& layerName) { return osmLuaProcessing->AreaIntersecting(layerName); }
197199

200+
void rawSetData(const std::string &key, const std::string &value) {
201+
std::lock_guard<std::mutex> lock(osmLuaProcessing->dataStoreMutex);
202+
osmLuaProcessing->dataStore[key] = value;
203+
}
204+
std::string rawGetData(const std::string &key) {
205+
auto r = osmLuaProcessing->dataStore.find(key);
206+
return r==osmLuaProcessing->dataStore.end() ? "" : r->second;
207+
}
198208

199209
bool supportsRemappingShapefiles = false;
200210

@@ -217,7 +227,8 @@ OsmLuaProcessing::OsmLuaProcessing(
217227
const class ShpMemTiles &shpMemTiles,
218228
class OsmMemTiles &osmMemTiles,
219229
AttributeStore &attributeStore,
220-
bool materializeGeometries):
230+
bool materializeGeometries,
231+
bool isFirst) :
221232
osmStore(osmStore),
222233
shpMemTiles(shpMemTiles),
223234
osmMemTiles(osmMemTiles),
@@ -273,6 +284,8 @@ OsmLuaProcessing::OsmLuaProcessing(
273284
luaState["NextRelation"] = &rawNextRelation;
274285
luaState["RestartRelations"] = &rawRestartRelations;
275286
luaState["FindInRelation"] = &rawFindInRelation;
287+
luaState["SetData"] = &rawSetData;
288+
luaState["GetData"] = &rawGetData;
276289
supportsRemappingShapefiles = !!luaState["attribute_function"];
277290
supportsReadingRelations = !!luaState["relation_scan_function"];
278291
supportsPostScanRelations = !!luaState["relation_postscan_function"];
@@ -283,7 +296,7 @@ OsmLuaProcessing::OsmLuaProcessing(
283296
// ---- Call init_function of Lua logic
284297

285298
if (!!luaState["init_function"]) {
286-
luaState["init_function"](this->config.projectName);
299+
luaState["init_function"](this->config.projectName, isFirst);
287300
}
288301
}
289302

@@ -1182,4 +1195,3 @@ std::vector<OutputObject> OsmLuaProcessing::finalizeOutputs() {
11821195
}
11831196
return list;
11841197
}
1185-

src/tilemaker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ int main(const int argc, const char* argv[]) {
253253
shpMemTiles.open();
254254

255255
OsmLuaProcessing osmLuaProcessing(osmStore, config, layers, options.luaFile,
256-
shpMemTiles, osmMemTiles, attributeStore, options.osm.materializeGeometries);
256+
shpMemTiles, osmMemTiles, attributeStore, options.osm.materializeGeometries, true);
257257

258258
// ---- Load external sources (shp/geojson)
259259

@@ -311,7 +311,7 @@ int main(const int argc, const char* argv[]) {
311311
[&]() {
312312
thread_local std::pair<std::string, std::shared_ptr<OsmLuaProcessing>> osmLuaProcessing;
313313
if (osmLuaProcessing.first != inputFile) {
314-
osmLuaProcessing = std::make_pair(inputFile, std::make_shared<OsmLuaProcessing>(osmStore, config, layers, options.luaFile, shpMemTiles, osmMemTiles, attributeStore, options.osm.materializeGeometries));
314+
osmLuaProcessing = std::make_pair(inputFile, std::make_shared<OsmLuaProcessing>(osmStore, config, layers, options.luaFile, shpMemTiles, osmMemTiles, attributeStore, options.osm.materializeGeometries, false));
315315
}
316316
return osmLuaProcessing.second;
317317
},
@@ -323,6 +323,7 @@ int main(const int argc, const char* argv[]) {
323323
attributeStore.finalize();
324324
osmMemTiles.reportSize();
325325
attributeStore.reportSize();
326+
osmLuaProcessing.dataStore.clear(); // no longer needed
326327

327328
// ---- Initialise SharedData
328329

0 commit comments

Comments
 (0)