Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ To do that, you use these methods:
* `Layer(layer_name, is_area)`: write this node/way to the named layer. This is how you put objects in your vector tile. is_area (true/false) specifies whether a way should be treated as an area, or just as a linestring.
* `LayerAsCentroid(layer_name, algorithm, role, role...)`: write a single centroid point for this way to the named layer (useful for labels and POIs). Only the first argument is required. `algorithm` can be "polylabel" (default) or "centroid". The third arguments onwards specify relation roles: if you're processing a multipolygon-type relation (e.g. a boundary) and it has a "label" node member, then by adding "label" as an argument here, this will be used in preference to the calculated point.
* `Attribute(key,value,minzoom)`: add an attribute to the most recently written layer. Argument `minzoom` is optional, use it if you do not want to write the attribute on lower zoom levels.
* `AttributeNumeric(key,value,minzoom)`, `AttributeBoolean(key,value,minzoom)`: for numeric/boolean columns.
* `AttributeNumeric(key,value,minzoom)`, `AttributeInteger(key,value,minzoom)`, `AttributeBoolean(key,value,minzoom)`: for numeric (floating-point), integer and boolean columns.
* `Id()`: get the OSM ID of the current object.
* `IsClosed()`: returns true if the current object is a closed area.
* `IsMultiPolygon()`: returns true if the current object is a multipolygon.
Expand Down
54 changes: 28 additions & 26 deletions include/attribute_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,53 +42,57 @@ class AttributeKeyStore {
std::map<const std::string*, uint16_t, string_ptr_less_than> keys2index;
};

enum class AttributePairType: uint8_t { String = 0, Float = 1, Bool = 2 };
enum class AttributePairType: uint8_t { String = 0, Float = 1, Bool = 2, Int = 3 };
// AttributePair is a key/value pair (with minzoom)
#pragma pack(push, 1)
struct AttributePair {
unsigned short keyIndex : 9;
AttributePairType valueType : 2;
uint8_t minzoom : 5; // Support zooms from 0..31. In practice, we expect z16 to be the biggest minzoom.
union {
float floatValue_;
double doubleValue_;
PooledString stringValue_;
};

AttributePair(uint32_t keyIndex, bool value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::Bool), minzoom(minzoom), floatValue_(value ? 1 : 0)
: keyIndex(keyIndex), valueType(AttributePairType::Bool), minzoom(minzoom), doubleValue_(value ? 1 : 0)
{
}
AttributePair(uint32_t keyIndex, const PooledString& value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::String), stringValue_(value), minzoom(minzoom)
{
}
AttributePair(uint32_t keyIndex, float value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::Float), minzoom(minzoom), floatValue_(value)
AttributePair(uint32_t keyIndex, double value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::Float), minzoom(minzoom), doubleValue_(value)
{
}
AttributePair(uint32_t keyIndex, int value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::Int), minzoom(minzoom), doubleValue_(static_cast<double>(value))
{
}

AttributePair(const AttributePair& other):
keyIndex(other.keyIndex), valueType(other.valueType), minzoom(other.minzoom)
{
if (valueType == AttributePairType::Bool || valueType == AttributePairType::Float) {
floatValue_ = other.floatValue_;
if (valueType == AttributePairType::String) {
stringValue_ = other.stringValue_;
return;
}

stringValue_ = other.stringValue_;
doubleValue_ = other.doubleValue_;
}

AttributePair& operator=(const AttributePair& other) {
keyIndex = other.keyIndex;
valueType = other.valueType;
minzoom = other.minzoom;

if (valueType == AttributePairType::Bool || valueType == AttributePairType::Float) {
floatValue_ = other.floatValue_;
if (valueType == AttributePairType::String) {
stringValue_ = other.stringValue_;
return *this;
}

stringValue_ = other.stringValue_;
doubleValue_ = other.doubleValue_;
return *this;
}

Expand All @@ -100,30 +104,25 @@ struct AttributePair {
if (valueType != other.valueType) return valueType < other.valueType;

if (hasStringValue()) return pooledString() < other.pooledString();
if (hasBoolValue()) return boolValue() < other.boolValue();
if (hasFloatValue()) return floatValue() < other.floatValue();
throw std::runtime_error("Invalid type in attribute store");
return doubleValue_ < other.doubleValue_;
}

bool operator==(const AttributePair &other) const {
if (minzoom!=other.minzoom || keyIndex!=other.keyIndex || valueType!=other.valueType) return false;
if (valueType == AttributePairType::String)
return stringValue_ == other.stringValue_;

if (valueType == AttributePairType::Float || valueType == AttributePairType::Bool)
return floatValue_ == other.floatValue_;

return true;
if (valueType == AttributePairType::String) return stringValue_ == other.stringValue_;
return doubleValue_ == other.doubleValue_;
}

bool hasStringValue() const { return valueType == AttributePairType::String; }
bool hasFloatValue() const { return valueType == AttributePairType::Float; }
bool hasBoolValue() const { return valueType == AttributePairType::Bool; }
bool hasIntValue() const { return valueType == AttributePairType::Int; }

const PooledString& pooledString() const { return stringValue_; }
const std::string stringValue() const { return stringValue_.toString(); }
float floatValue() const { return floatValue_; }
bool boolValue() const { return floatValue_; }
float floatValue() const { return static_cast<float>(doubleValue_); }
bool boolValue() const { return doubleValue_; }
int intValue() const { return static_cast<int64_t>(doubleValue_); }

void ensureStringIsOwned();

Expand Down Expand Up @@ -162,7 +161,9 @@ struct AttributePair {
const char* data = pooledString().data();
boost::hash_range(rv, data, data + pooledString().size());
} else if(hasFloatValue())
boost::hash_combine(rv, floatValue());
boost::hash_combine(rv, doubleValue_);
else if(hasIntValue())
boost::hash_combine(rv, doubleValue_);
else if(hasBoolValue())
boost::hash_combine(rv, boolValue());
else {
Expand Down Expand Up @@ -407,7 +408,8 @@ struct AttributeStore {
void finalize();

void addAttribute(AttributeSet& attributeSet, std::string const &key, const protozero::data_view v, char minzoom);
void addAttribute(AttributeSet& attributeSet, std::string const &key, float v, char minzoom);
void addAttribute(AttributeSet& attributeSet, std::string const &key, double v, char minzoom);
void addAttribute(AttributeSet& attributeSet, std::string const &key, int v, char minzoom);
void addAttribute(AttributeSet& attributeSet, std::string const &key, bool v, char minzoom);

AttributeStore():
Expand Down
3 changes: 2 additions & 1 deletion include/osm_lua_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ class OsmLuaProcessing {

// Set attributes in a vector tile's Attributes table
void Attribute(const std::string &key, const protozero::data_view val, const char minzoom);
void AttributeNumeric(const std::string &key, const float val, const char minzoom);
void AttributeNumeric(const std::string &key, const double val, const char minzoom);
void AttributeBoolean(const std::string &key, const bool val, const char minzoom);
void AttributeInteger(const std::string &key, const int val, const char minzoom);
void MinZoom(const double z);
void ZOrder(const double z);

Expand Down
16 changes: 8 additions & 8 deletions resources/process-debug.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function node_function()
Layer("place", false)
Attribute("class", place)
MinZoom(mz)
if rank then AttributeNumeric("rank", rank) end
if rank then AttributeInteger("rank", rank) end
SetNameAttributes()
return
end
Expand All @@ -107,7 +107,7 @@ function node_function()
if natural == "peak" or natural == "volcano" then
Layer("mountain_peak", false)
SetEleAttributes()
AttributeNumeric("rank", 1)
AttributeInteger("rank", 1)
Attribute("class", natural)
SetNameAttributes()
return
Expand Down Expand Up @@ -256,12 +256,12 @@ function way_function()
if linkValues[highway] then
splitHighway = split(highway, "_")
highway = splitHighway[1]
AttributeNumeric("ramp",1)
AttributeInteger("ramp",1)
end

local oneway = Find("oneway")
if oneway == "yes" or oneway == "1" then
AttributeNumeric("oneway",1)
AttributeInteger("oneway",1)
end
if oneway == "-1" then
-- **** TODO
Expand All @@ -282,7 +282,7 @@ function way_function()
local ref = Find("ref")
if ref~="" then
Attribute("ref",ref)
AttributeNumeric("ref_length",ref:len())
AttributeInteger("ref_length",ref:len())
end
end

Expand Down Expand Up @@ -326,7 +326,7 @@ function way_function()
else
Layer("waterway_detail", false)
end
if Find("intermittent")=="yes" then AttributeNumeric("intermittent", 1) else AttributeNumeric("intermittent", 0) end
if Find("intermittent")=="yes" then AttributeInteger("intermittent", 1) else AttributeInteger("intermittent", 0) end
Attribute("class", waterway)
SetNameAttributes()
SetBrunnelAttributes()
Expand Down Expand Up @@ -419,7 +419,7 @@ function way_function()
LayerAsCentroid("poi_detail")
SetNameAttributes()
if write_name then rank=6 else rank=25 end
AttributeNumeric("rank", rank)
AttributeInteger("rank", rank)
end
end

Expand All @@ -437,7 +437,7 @@ function WritePOI(obj,class,subclass,rank)
if rank>4 then layer="poi_detail" end
LayerAsCentroid(layer)
SetNameAttributes(obj)
AttributeNumeric("rank", rank)
AttributeInteger("rank", rank)
Attribute("class", class)
Attribute("subclass", subclass)
end
Expand Down
10 changes: 5 additions & 5 deletions resources/process-example.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function node_function(node)
if amenity~="" then Attribute("class",amenity)
else Attribute("class",shop) end
Attribute("name:latin", Find("name"))
AttributeNumeric("rank", 3)
AttributeInteger("rank", 3)
end

-- Places go to a "place" layer
Expand All @@ -48,13 +48,13 @@ function node_function(node)
Attribute("class", place)
Attribute("name:latin", Find("name"))
if place=="city" then
AttributeNumeric("rank", 4)
AttributeInteger("rank", 4)
MinZoom(3)
elseif place=="town" then
AttributeNumeric("rank", 6)
AttributeInteger("rank", 6)
MinZoom(6)
else
AttributeNumeric("rank", 9)
AttributeInteger("rank", 9)
MinZoom(10)
end
end
Expand Down Expand Up @@ -86,7 +86,7 @@ function way_function()
if waterway=="stream" or waterway=="river" or waterway=="canal" then
Layer("waterway", false)
Attribute("class", waterway)
AttributeNumeric("intermittent", 0)
AttributeInteger("intermittent", 0)
end

-- Lakes and other water polygons
Expand Down
32 changes: 16 additions & 16 deletions resources/process-openmaptiles.lua
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ function node_function()
Layer("place", false)
Attribute("class", place)
MinZoom(mz)
if rank then AttributeNumeric("rank", rank) end
if capital then AttributeNumeric("capital", capital) end
if rank then AttributeInteger("rank", rank) end
if capital then AttributeInteger("capital", capital) end
if place=="country" then
local iso_a2 = Find("ISO3166-1:alpha2")
while iso_a2 == "" do
Expand All @@ -203,7 +203,7 @@ function node_function()
if natural == "peak" or natural == "volcano" then
Layer("mountain_peak", false)
SetEleAttributes()
AttributeNumeric("rank", 1)
AttributeInteger("rank", 1)
Attribute("class", natural)
SetNameAttributes()
return
Expand Down Expand Up @@ -314,15 +314,15 @@ function write_to_transportation_layer(minzoom, highway_class, subclass, ramp, s
if subclass and subclass ~= "" then
Attribute("subclass", subclass)
end
AttributeNumeric("layer", tonumber(Find("layer")) or 0, accessMinzoom)
AttributeInteger("layer", tonumber(Find("layer")) or 0, accessMinzoom)
SetBrunnelAttributes()
-- We do not write any other attributes for areas.
if is_area then
SetMinZoomByAreaWithLimit(minzoom)
return
end
MinZoom(minzoom)
if ramp then AttributeNumeric("ramp",1) end
if ramp then AttributeInteger("ramp",1) end

-- Service
if (is_rail or highway_class == "service") and (service and service ~="") then Attribute("service", service) end
Expand All @@ -331,7 +331,7 @@ function write_to_transportation_layer(minzoom, highway_class, subclass, ramp, s
if is_road then
local oneway = Find("oneway")
if oneway == "yes" or oneway == "1" then
AttributeNumeric("oneway",1)
AttributeInteger("oneway",1)
end
if oneway == "-1" then
-- **** TODO
Expand Down Expand Up @@ -398,7 +398,7 @@ function way_function()
local pop = tonumber(Find("population")) or 0
local capital = capitalLevel(Find("capital"))
local rank = calcRank(place, pop, nil)
if rank then AttributeNumeric("rank", rank) end
if rank then AttributeInteger("rank", rank) end
SetNameAttributes()
end

Expand Down Expand Up @@ -431,14 +431,14 @@ function way_function()
end

Layer("boundary",false)
AttributeNumeric("admin_level", admin_level)
AttributeInteger("admin_level", admin_level)
MinZoom(mz)
-- disputed status (0 or 1). some styles need to have the 0 to show it.
local disputed = Find("disputed")
if disputed=="yes" then
AttributeNumeric("disputed", 1)
AttributeInteger("disputed", 1)
else
AttributeNumeric("disputed", 0)
AttributeInteger("disputed", 0)
end
end

Expand Down Expand Up @@ -543,7 +543,7 @@ function way_function()
local ref = Find("ref")
if ref~="" then
Attribute("ref",ref)
AttributeNumeric("ref_length",ref:len())
AttributeInteger("ref_length",ref:len())
end
end
end
Expand Down Expand Up @@ -623,7 +623,7 @@ function way_function()
else
Layer("waterway_detail", false)
end
if Find("intermittent")=="yes" then AttributeNumeric("intermittent", 1) else AttributeNumeric("intermittent", 0) end
if Find("intermittent")=="yes" then AttributeInteger("intermittent", 1) else AttributeInteger("intermittent", 0) end
Attribute("class", waterway)
SetNameAttributes()
SetBrunnelAttributes()
Expand Down Expand Up @@ -723,7 +723,7 @@ function way_function()
LayerAsCentroid("poi_detail")
SetNameAttributes()
if write_name then rank=6 else rank=25 end
AttributeNumeric("rank", rank)
AttributeInteger("rank", rank)
end
end

Expand Down Expand Up @@ -751,17 +751,17 @@ function WritePOI(class,subclass,rank)
if rank>4 then layer="poi_detail" end
LayerAsCentroid(layer)
SetNameAttributes()
AttributeNumeric("rank", rank)
AttributeInteger("rank", rank)
Attribute("class", class)
Attribute("subclass", subclass)
-- layer defaults to 0
AttributeNumeric("layer", tonumber(Find("layer")) or 0)
AttributeInteger("layer", tonumber(Find("layer")) or 0)
-- indoor defaults to false
AttributeBoolean("indoor", (Find("indoor") == "yes"))
-- level has no default
local level = tonumber(Find("level"))
if level then
AttributeNumeric("level", level)
AttributeInteger("level", level)
end
end

Expand Down
Loading
Loading