Skip to content

Commit

Permalink
Compile-time option for float ZOrder (systemed#486)
Browse files Browse the repository at this point in the history
  • Loading branch information
systemed authored Mar 31, 2023
1 parent 06e0b28 commit 4a85c60
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ To do that, you use these methods:
* `node:Attribute(key,value)` or `node:Attribute(key,value)`: add an attribute to the most recently written layer.
* `node:AttributeNumeric(key,value)`, `node:AttributeBoolean(key,value)` (and `way:`...): for numeric/boolean columns.
* `node:Id()` or `way:Id()`: get the OSM ID of the current object.
* `node:ZOrder(number)` or `way:ZOrder(number)`: Set a numeric value (default 0, 1-byte unsigned integer) used to sort features within a layer. Use this feature to ensure a proper rendering order if the rendering engine itself does not support sorting. Sorting is not supported across layers merged with `write_to`. Features with different z-order are not merged if `combine_below` or `combine_polygons_below` is used.
* `node:ZOrder(number)` or `way:ZOrder(number)`: Set a numeric value (default 0, 1-byte signed integer) used to sort features within a layer. Use this feature to ensure a proper rendering order if the rendering engine itself does not support sorting. Sorting is not supported across layers merged with `write_to`. Features with different z-order are not merged if `combine_below` or `combine_polygons_below` is used.
* `node:MinZoom(zoom)` or `way:MinZoom(zoom)`: set the minimum zoom level (0-15) at which this object will be written. Note that the JSON layer configuration minimum still applies (so `:MinZoom(5)` will have no effect if your layer only starts at z6).
* `way:Length()` and `way:Area()`: return the length (metres)/area (square metres) of the current object. Requires recent Boost.
* `way:Centroid()`: return the lat/lon of the centre of the current object as a two-element Lua table (element 1 is lat, 2 is lon).
Expand Down
10 changes: 10 additions & 0 deletions docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,13 @@ The docker container can be run like this:
docker run -v /Users/Local/Downloads/:/srv -i -t --rm tilemaker /srv/germany-latest.osm.pbf --output=/srv/germany.mbtiles

Keep in mind to map the volume your .osm.pbf files are in to a path within your docker container, as seen in the example above.

### Compile-time options

tilemaker has two compile-time options that increase memory usage but may be useful in certain circumstances. You can include them when building like this:

make "CONFIG=-DFLOAT_Z_ORDER"

FLOAT_Z_ORDER allows you to use a full range of ZOrder values in your Lua script, rather than being restricted to single-byte integer (-127 to 127).

FAT_TILE_INDEX allows you to generate vector tiles at zoom level 17 or greater. You almost certainly don't need to do this. Vector tiles are usually generated up to zoom 14 (sometimes 15), and then the browser/app client uses the vector data to scale up at subsequent zoom levels.
1 change: 1 addition & 0 deletions include/osm_lua_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class OsmLuaProcessing {
void AttributeBooleanWithMinZoom(const std::string &key, const bool val, const char minzoom);
void MinZoom(const double z);
void ZOrder(const double z);
void ZOrderWithScale(const double z, const double scale);

// Relation scan support
kaguya::optional<int> NextRelation();
Expand Down
12 changes: 10 additions & 2 deletions include/output_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
#include "osmformat.pb.h"
#include "vector_tile.pb.h"

#ifdef FLOAT_Z_ORDER
typedef float ZOrder;
#else
typedef int8_t ZOrder;
#endif

enum OutputGeometryType : unsigned int { POINT_, LINESTRING_, MULTILINESTRING_, POLYGON_ };

#define OSMID_TYPE_OFFSET 40
Expand Down Expand Up @@ -46,16 +52,18 @@ class OutputObject {
public:
NodeID objectID : 42; // id of way (linestring/polygon) or node (point)
uint_least8_t layer : 8; // what layer is it in?
int8_t z_order : 8; // z_order: used for sorting features within layers
ZOrder z_order ; // z_order: used for sorting features within layers
OutputGeometryType geomType : 2; // point, linestring, polygon
unsigned minZoom : 4;

AttributeStoreRef attributes;

void setZOrder(const int z) {
void setZOrder(const ZOrder z) {
#ifndef FLOAT_Z_ORDER
if (z <= -127 || z >= 127) {
throw std::runtime_error("z_order is limited to 1 byte signed integer.");
}
#endif
z_order = z;
}

Expand Down
16 changes: 15 additions & 1 deletion src/osm_lua_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ OsmLuaProcessing::OsmLuaProcessing(
.addOverloadedFunctions("AttributeNumeric", &OsmLuaProcessing::AttributeNumeric, &OsmLuaProcessing::AttributeNumericWithMinZoom)
.addOverloadedFunctions("AttributeBoolean", &OsmLuaProcessing::AttributeBoolean, &OsmLuaProcessing::AttributeBooleanWithMinZoom)
.addFunction("MinZoom", &OsmLuaProcessing::MinZoom)
.addFunction("ZOrder", &OsmLuaProcessing::ZOrder)
.addOverloadedFunctions("ZOrder", &OsmLuaProcessing::ZOrder, &OsmLuaProcessing::ZOrderWithScale)
.addFunction("Accept", &OsmLuaProcessing::Accept)
.addFunction("NextRelation", &OsmLuaProcessing::NextRelation)
.addFunction("FindInRelation", &OsmLuaProcessing::FindInRelation)
Expand Down Expand Up @@ -501,7 +501,21 @@ void OsmLuaProcessing::MinZoom(const double z) {
// Set z_order
void OsmLuaProcessing::ZOrder(const double z) {
if (outputs.size()==0) { ProcessingError("Can't set z_order if no Layer set"); return; }
#ifdef FLOAT_Z_ORDER
outputs.back().first->setZOrder(make_valid<float>(z));
#else
outputs.back().first->setZOrder(make_valid<int>(z));
#endif
}

// Set z_order (variant with scaling)
void OsmLuaProcessing::ZOrderWithScale(const double z, const double scale) {
if (outputs.size()==0) { ProcessingError("Can't set z_order if no Layer set"); return; }
#ifdef FLOAT_Z_ORDER
outputs.back().first->setZOrder(make_valid<float>(z));
#else
outputs.back().first->setZOrder(make_valid<int>(z/scale*127));
#endif
}

// Read scanned relations
Expand Down

0 comments on commit 4a85c60

Please sign in to comment.