Add AttributeInteger for writing int values (#827)

This commit is contained in:
Richard Fairhurst
2025-09-29 12:22:55 +01:00
committed by GitHub
parent 617dcb037e
commit 830f85c3e1
12 changed files with 108 additions and 78 deletions
+1 -1
View File
@@ -158,7 +158,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. * `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. * `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. * `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. * `Id()`: get the OSM ID of the current object.
* `IsClosed()`: returns true if the current object is a closed area. * `IsClosed()`: returns true if the current object is a closed area.
* `IsMultiPolygon()`: returns true if the current object is a multipolygon. * `IsMultiPolygon()`: returns true if the current object is a multipolygon.
+28 -26
View File
@@ -42,7 +42,7 @@ private:
std::map<const std::string*, uint16_t, string_ptr_less_than> keys2index; 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) // AttributePair is a key/value pair (with minzoom)
#pragma pack(push, 1) #pragma pack(push, 1)
struct AttributePair { struct AttributePair {
@@ -50,32 +50,36 @@ struct AttributePair {
AttributePairType valueType : 2; AttributePairType valueType : 2;
uint8_t minzoom : 5; // Support zooms from 0..31. In practice, we expect z16 to be the biggest minzoom. uint8_t minzoom : 5; // Support zooms from 0..31. In practice, we expect z16 to be the biggest minzoom.
union { union {
float floatValue_; double doubleValue_;
PooledString stringValue_; PooledString stringValue_;
}; };
AttributePair(uint32_t keyIndex, bool value, char minzoom) 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) AttributePair(uint32_t keyIndex, const PooledString& value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::String), stringValue_(value), minzoom(minzoom) : keyIndex(keyIndex), valueType(AttributePairType::String), stringValue_(value), minzoom(minzoom)
{ {
} }
AttributePair(uint32_t keyIndex, float value, char minzoom) AttributePair(uint32_t keyIndex, double value, char minzoom)
: keyIndex(keyIndex), valueType(AttributePairType::Float), minzoom(minzoom), floatValue_(value) : 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): AttributePair(const AttributePair& other):
keyIndex(other.keyIndex), valueType(other.valueType), minzoom(other.minzoom) keyIndex(other.keyIndex), valueType(other.valueType), minzoom(other.minzoom)
{ {
if (valueType == AttributePairType::Bool || valueType == AttributePairType::Float) { if (valueType == AttributePairType::String) {
floatValue_ = other.floatValue_; stringValue_ = other.stringValue_;
return; return;
} }
stringValue_ = other.stringValue_; doubleValue_ = other.doubleValue_;
} }
AttributePair& operator=(const AttributePair& other) { AttributePair& operator=(const AttributePair& other) {
@@ -83,12 +87,12 @@ struct AttributePair {
valueType = other.valueType; valueType = other.valueType;
minzoom = other.minzoom; minzoom = other.minzoom;
if (valueType == AttributePairType::Bool || valueType == AttributePairType::Float) { if (valueType == AttributePairType::String) {
floatValue_ = other.floatValue_; stringValue_ = other.stringValue_;
return *this; return *this;
} }
stringValue_ = other.stringValue_; doubleValue_ = other.doubleValue_;
return *this; return *this;
} }
@@ -100,30 +104,25 @@ struct AttributePair {
if (valueType != other.valueType) return valueType < other.valueType; if (valueType != other.valueType) return valueType < other.valueType;
if (hasStringValue()) return pooledString() < other.pooledString(); if (hasStringValue()) return pooledString() < other.pooledString();
if (hasBoolValue()) return boolValue() < other.boolValue(); return doubleValue_ < other.doubleValue_;
if (hasFloatValue()) return floatValue() < other.floatValue();
throw std::runtime_error("Invalid type in attribute store");
} }
bool operator==(const AttributePair &other) const { bool operator==(const AttributePair &other) const {
if (minzoom!=other.minzoom || keyIndex!=other.keyIndex || valueType!=other.valueType) return false; if (minzoom!=other.minzoom || keyIndex!=other.keyIndex || valueType!=other.valueType) return false;
if (valueType == AttributePairType::String) if (valueType == AttributePairType::String) return stringValue_ == other.stringValue_;
return stringValue_ == other.stringValue_; return doubleValue_ == other.doubleValue_;
if (valueType == AttributePairType::Float || valueType == AttributePairType::Bool)
return floatValue_ == other.floatValue_;
return true;
} }
bool hasStringValue() const { return valueType == AttributePairType::String; } bool hasStringValue() const { return valueType == AttributePairType::String; }
bool hasFloatValue() const { return valueType == AttributePairType::Float; } bool hasFloatValue() const { return valueType == AttributePairType::Float; }
bool hasBoolValue() const { return valueType == AttributePairType::Bool; } bool hasBoolValue() const { return valueType == AttributePairType::Bool; }
bool hasIntValue() const { return valueType == AttributePairType::Int; }
const PooledString& pooledString() const { return stringValue_; } const PooledString& pooledString() const { return stringValue_; }
const std::string stringValue() const { return stringValue_.toString(); } const std::string stringValue() const { return stringValue_.toString(); }
float floatValue() const { return floatValue_; } float floatValue() const { return static_cast<float>(doubleValue_); }
bool boolValue() const { return floatValue_; } bool boolValue() const { return doubleValue_; }
int intValue() const { return static_cast<int64_t>(doubleValue_); }
void ensureStringIsOwned(); void ensureStringIsOwned();
@@ -162,7 +161,9 @@ struct AttributePair {
const char* data = pooledString().data(); const char* data = pooledString().data();
boost::hash_range(rv, data, data + pooledString().size()); boost::hash_range(rv, data, data + pooledString().size());
} else if(hasFloatValue()) } else if(hasFloatValue())
boost::hash_combine(rv, floatValue()); boost::hash_combine(rv, doubleValue_);
else if(hasIntValue())
boost::hash_combine(rv, doubleValue_);
else if(hasBoolValue()) else if(hasBoolValue())
boost::hash_combine(rv, boolValue()); boost::hash_combine(rv, boolValue());
else { else {
@@ -407,7 +408,8 @@ struct AttributeStore {
void finalize(); 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, 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); void addAttribute(AttributeSet& attributeSet, std::string const &key, bool v, char minzoom);
AttributeStore(): AttributeStore():
+2 -1
View File
@@ -195,8 +195,9 @@ public:
// Set attributes in a vector tile's Attributes table // Set attributes in a vector tile's Attributes table
void Attribute(const std::string &key, const protozero::data_view val, const char minzoom); 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 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 MinZoom(const double z);
void ZOrder(const double z); void ZOrder(const double z);
+8 -8
View File
@@ -93,7 +93,7 @@ function node_function()
Layer("place", false) Layer("place", false)
Attribute("class", place) Attribute("class", place)
MinZoom(mz) MinZoom(mz)
if rank then AttributeNumeric("rank", rank) end if rank then AttributeInteger("rank", rank) end
SetNameAttributes() SetNameAttributes()
return return
end end
@@ -107,7 +107,7 @@ function node_function()
if natural == "peak" or natural == "volcano" then if natural == "peak" or natural == "volcano" then
Layer("mountain_peak", false) Layer("mountain_peak", false)
SetEleAttributes() SetEleAttributes()
AttributeNumeric("rank", 1) AttributeInteger("rank", 1)
Attribute("class", natural) Attribute("class", natural)
SetNameAttributes() SetNameAttributes()
return return
@@ -256,12 +256,12 @@ function way_function()
if linkValues[highway] then if linkValues[highway] then
splitHighway = split(highway, "_") splitHighway = split(highway, "_")
highway = splitHighway[1] highway = splitHighway[1]
AttributeNumeric("ramp",1) AttributeInteger("ramp",1)
end end
local oneway = Find("oneway") local oneway = Find("oneway")
if oneway == "yes" or oneway == "1" then if oneway == "yes" or oneway == "1" then
AttributeNumeric("oneway",1) AttributeInteger("oneway",1)
end end
if oneway == "-1" then if oneway == "-1" then
-- **** TODO -- **** TODO
@@ -282,7 +282,7 @@ function way_function()
local ref = Find("ref") local ref = Find("ref")
if ref~="" then if ref~="" then
Attribute("ref",ref) Attribute("ref",ref)
AttributeNumeric("ref_length",ref:len()) AttributeInteger("ref_length",ref:len())
end end
end end
@@ -326,7 +326,7 @@ function way_function()
else else
Layer("waterway_detail", false) Layer("waterway_detail", false)
end 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) Attribute("class", waterway)
SetNameAttributes() SetNameAttributes()
SetBrunnelAttributes() SetBrunnelAttributes()
@@ -419,7 +419,7 @@ function way_function()
LayerAsCentroid("poi_detail") LayerAsCentroid("poi_detail")
SetNameAttributes() SetNameAttributes()
if write_name then rank=6 else rank=25 end if write_name then rank=6 else rank=25 end
AttributeNumeric("rank", rank) AttributeInteger("rank", rank)
end end
end end
@@ -437,7 +437,7 @@ function WritePOI(obj,class,subclass,rank)
if rank>4 then layer="poi_detail" end if rank>4 then layer="poi_detail" end
LayerAsCentroid(layer) LayerAsCentroid(layer)
SetNameAttributes(obj) SetNameAttributes(obj)
AttributeNumeric("rank", rank) AttributeInteger("rank", rank)
Attribute("class", class) Attribute("class", class)
Attribute("subclass", subclass) Attribute("subclass", subclass)
end end
+5 -5
View File
@@ -38,7 +38,7 @@ function node_function(node)
if amenity~="" then Attribute("class",amenity) if amenity~="" then Attribute("class",amenity)
else Attribute("class",shop) end else Attribute("class",shop) end
Attribute("name:latin", Find("name")) Attribute("name:latin", Find("name"))
AttributeNumeric("rank", 3) AttributeInteger("rank", 3)
end end
-- Places go to a "place" layer -- Places go to a "place" layer
@@ -48,13 +48,13 @@ function node_function(node)
Attribute("class", place) Attribute("class", place)
Attribute("name:latin", Find("name")) Attribute("name:latin", Find("name"))
if place=="city" then if place=="city" then
AttributeNumeric("rank", 4) AttributeInteger("rank", 4)
MinZoom(3) MinZoom(3)
elseif place=="town" then elseif place=="town" then
AttributeNumeric("rank", 6) AttributeInteger("rank", 6)
MinZoom(6) MinZoom(6)
else else
AttributeNumeric("rank", 9) AttributeInteger("rank", 9)
MinZoom(10) MinZoom(10)
end end
end end
@@ -86,7 +86,7 @@ function way_function()
if waterway=="stream" or waterway=="river" or waterway=="canal" then if waterway=="stream" or waterway=="river" or waterway=="canal" then
Layer("waterway", false) Layer("waterway", false)
Attribute("class", waterway) Attribute("class", waterway)
AttributeNumeric("intermittent", 0) AttributeInteger("intermittent", 0)
end end
-- Lakes and other water polygons -- Lakes and other water polygons
+16 -16
View File
@@ -177,8 +177,8 @@ function node_function()
Layer("place", false) Layer("place", false)
Attribute("class", place) Attribute("class", place)
MinZoom(mz) MinZoom(mz)
if rank then AttributeNumeric("rank", rank) end if rank then AttributeInteger("rank", rank) end
if capital then AttributeNumeric("capital", capital) end if capital then AttributeInteger("capital", capital) end
if place=="country" then if place=="country" then
local iso_a2 = Find("ISO3166-1:alpha2") local iso_a2 = Find("ISO3166-1:alpha2")
while iso_a2 == "" do while iso_a2 == "" do
@@ -203,7 +203,7 @@ function node_function()
if natural == "peak" or natural == "volcano" then if natural == "peak" or natural == "volcano" then
Layer("mountain_peak", false) Layer("mountain_peak", false)
SetEleAttributes() SetEleAttributes()
AttributeNumeric("rank", 1) AttributeInteger("rank", 1)
Attribute("class", natural) Attribute("class", natural)
SetNameAttributes() SetNameAttributes()
return return
@@ -314,7 +314,7 @@ function write_to_transportation_layer(minzoom, highway_class, subclass, ramp, s
if subclass and subclass ~= "" then if subclass and subclass ~= "" then
Attribute("subclass", subclass) Attribute("subclass", subclass)
end end
AttributeNumeric("layer", tonumber(Find("layer")) or 0, accessMinzoom) AttributeInteger("layer", tonumber(Find("layer")) or 0, accessMinzoom)
SetBrunnelAttributes() SetBrunnelAttributes()
-- We do not write any other attributes for areas. -- We do not write any other attributes for areas.
if is_area then if is_area then
@@ -322,7 +322,7 @@ function write_to_transportation_layer(minzoom, highway_class, subclass, ramp, s
return return
end end
MinZoom(minzoom) MinZoom(minzoom)
if ramp then AttributeNumeric("ramp",1) end if ramp then AttributeInteger("ramp",1) end
-- Service -- Service
if (is_rail or highway_class == "service") and (service and service ~="") then Attribute("service", service) end if (is_rail or highway_class == "service") and (service and service ~="") then Attribute("service", service) end
@@ -331,7 +331,7 @@ function write_to_transportation_layer(minzoom, highway_class, subclass, ramp, s
if is_road then if is_road then
local oneway = Find("oneway") local oneway = Find("oneway")
if oneway == "yes" or oneway == "1" then if oneway == "yes" or oneway == "1" then
AttributeNumeric("oneway",1) AttributeInteger("oneway",1)
end end
if oneway == "-1" then if oneway == "-1" then
-- **** TODO -- **** TODO
@@ -398,7 +398,7 @@ function way_function()
local pop = tonumber(Find("population")) or 0 local pop = tonumber(Find("population")) or 0
local capital = capitalLevel(Find("capital")) local capital = capitalLevel(Find("capital"))
local rank = calcRank(place, pop, nil) local rank = calcRank(place, pop, nil)
if rank then AttributeNumeric("rank", rank) end if rank then AttributeInteger("rank", rank) end
SetNameAttributes() SetNameAttributes()
end end
@@ -431,14 +431,14 @@ function way_function()
end end
Layer("boundary",false) Layer("boundary",false)
AttributeNumeric("admin_level", admin_level) AttributeInteger("admin_level", admin_level)
MinZoom(mz) MinZoom(mz)
-- disputed status (0 or 1). some styles need to have the 0 to show it. -- disputed status (0 or 1). some styles need to have the 0 to show it.
local disputed = Find("disputed") local disputed = Find("disputed")
if disputed=="yes" then if disputed=="yes" then
AttributeNumeric("disputed", 1) AttributeInteger("disputed", 1)
else else
AttributeNumeric("disputed", 0) AttributeInteger("disputed", 0)
end end
end end
@@ -543,7 +543,7 @@ function way_function()
local ref = Find("ref") local ref = Find("ref")
if ref~="" then if ref~="" then
Attribute("ref",ref) Attribute("ref",ref)
AttributeNumeric("ref_length",ref:len()) AttributeInteger("ref_length",ref:len())
end end
end end
end end
@@ -623,7 +623,7 @@ function way_function()
else else
Layer("waterway_detail", false) Layer("waterway_detail", false)
end 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) Attribute("class", waterway)
SetNameAttributes() SetNameAttributes()
SetBrunnelAttributes() SetBrunnelAttributes()
@@ -723,7 +723,7 @@ function way_function()
LayerAsCentroid("poi_detail") LayerAsCentroid("poi_detail")
SetNameAttributes() SetNameAttributes()
if write_name then rank=6 else rank=25 end if write_name then rank=6 else rank=25 end
AttributeNumeric("rank", rank) AttributeInteger("rank", rank)
end end
end end
@@ -751,17 +751,17 @@ function WritePOI(class,subclass,rank)
if rank>4 then layer="poi_detail" end if rank>4 then layer="poi_detail" end
LayerAsCentroid(layer) LayerAsCentroid(layer)
SetNameAttributes() SetNameAttributes()
AttributeNumeric("rank", rank) AttributeInteger("rank", rank)
Attribute("class", class) Attribute("class", class)
Attribute("subclass", subclass) Attribute("subclass", subclass)
-- layer defaults to 0 -- layer defaults to 0
AttributeNumeric("layer", tonumber(Find("layer")) or 0) AttributeInteger("layer", tonumber(Find("layer")) or 0)
-- indoor defaults to false -- indoor defaults to false
AttributeBoolean("indoor", (Find("indoor") == "yes")) AttributeBoolean("indoor", (Find("indoor") == "yes"))
-- level has no default -- level has no default
local level = tonumber(Find("level")) local level = tonumber(Find("level"))
if level then if level then
AttributeNumeric("level", level) AttributeInteger("level", level)
end end
end end
+7 -3
View File
@@ -59,8 +59,7 @@ const std::string& AttributeKeyStore::getKeyUnsafe(uint16_t index) const {
void AttributePair::ensureStringIsOwned() { void AttributePair::ensureStringIsOwned() {
// Before we store an AttributePair in our long-term storage, we need // Before we store an AttributePair in our long-term storage, we need
// to make sure it's not pointing to a non-long-lived std::string. // to make sure it's not pointing to a non-long-lived std::string.
if (valueType == AttributePairType::Bool || valueType == AttributePairType::Float) if (valueType != AttributePairType::String) return;
return;
stringValue_.ensureStringIsOwned(); stringValue_.ensureStringIsOwned();
} }
@@ -251,11 +250,16 @@ void AttributeStore::addAttribute(AttributeSet& attributeSet, std::string const
bool isHot = true; // All bools are eligible to be hot pairs bool isHot = true; // All bools are eligible to be hot pairs
attributeSet.addPair(pairStore.addPair(kv, isHot)); attributeSet.addPair(pairStore.addPair(kv, isHot));
} }
void AttributeStore::addAttribute(AttributeSet& attributeSet, std::string const &key, float v, char minzoom) { void AttributeStore::addAttribute(AttributeSet& attributeSet, std::string const &key, double v, char minzoom) {
AttributePair kv(keyStore.key2index(key),v,minzoom); AttributePair kv(keyStore.key2index(key),v,minzoom);
bool isHot = v >= 0 && v <= 25 && ceil(v) == v; // Whole numbers in 0..25 are eligible to be hot pairs bool isHot = v >= 0 && v <= 25 && ceil(v) == v; // Whole numbers in 0..25 are eligible to be hot pairs
attributeSet.addPair(pairStore.addPair(kv, isHot)); attributeSet.addPair(pairStore.addPair(kv, isHot));
} }
void AttributeStore::addAttribute(AttributeSet& attributeSet, std::string const &key, int v, char minzoom) {
AttributePair kv(keyStore.key2index(key),v,minzoom);
bool isHot = v >= 0 && v <= 25;
attributeSet.addPair(pairStore.addPair(kv, isHot));
}
void AttributeSet::finalize() { void AttributeSet::finalize() {
// Ensure that values are sorted, giving us a canonical representation, // Ensure that values are sorted, giving us a canonical representation,
+3 -3
View File
@@ -240,10 +240,10 @@ AttributeIndex GeoJSONProcessor::readProperties(const rapidjson::Value &pr, bool
layer.attributeMap[key] = 0; layer.attributeMap[key] = 0;
} else if (val.isType<int>()) { } else if (val.isType<int>()) {
if (key=="_minzoom") { minzoom=val; continue; } if (key=="_minzoom") { minzoom=val; continue; }
attributeStore.addAttribute(attributes, key, (float)val, 0); attributeStore.addAttribute(attributes, key, (int)val, 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
} else if (val.isType<double>()) { } else if (val.isType<double>()) {
attributeStore.addAttribute(attributes, key, (float)val, 0); attributeStore.addAttribute(attributes, key, (double)val, 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
} else if (val.isType<bool>()) { } else if (val.isType<bool>()) {
attributeStore.addAttribute(attributes, key, (bool)val, 0); attributeStore.addAttribute(attributes, key, (bool)val, 0);
@@ -267,7 +267,7 @@ AttributeIndex GeoJSONProcessor::readProperties(const rapidjson::Value &pr, bool
attributeStore.addAttribute(attributes, key, it->value.GetBool(), 0); attributeStore.addAttribute(attributes, key, it->value.GetBool(), 0);
layer.attributeMap[key] = 2; layer.attributeMap[key] = 2;
} else if (it->value.IsNumber()) { } else if (it->value.IsNumber()) {
attributeStore.addAttribute(attributes, key, it->value.GetFloat(), 0); attributeStore.addAttribute(attributes, key, it->value.GetDouble(), 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
} else { } else {
// something different, so coerce to string // something different, so coerce to string
+14 -3
View File
@@ -270,8 +270,12 @@ OsmLuaProcessing::OsmLuaProcessing(
[](const std::string &key, const protozero::data_view val, const char minzoom) { osmLuaProcessing->Attribute(key, val, minzoom); } [](const std::string &key, const protozero::data_view val, const char minzoom) { osmLuaProcessing->Attribute(key, val, minzoom); }
); );
luaState["AttributeNumeric"] = kaguya::overload( luaState["AttributeNumeric"] = kaguya::overload(
[](const std::string &key, const float val) { osmLuaProcessing->AttributeNumeric(key, val, 0); }, [](const std::string &key, const double val) { osmLuaProcessing->AttributeNumeric(key, val, 0); },
[](const std::string &key, const float val, const char minzoom) { osmLuaProcessing->AttributeNumeric(key, val, minzoom); } [](const std::string &key, const double val, const char minzoom) { osmLuaProcessing->AttributeNumeric(key, val, minzoom); }
);
luaState["AttributeInteger"] = kaguya::overload(
[](const std::string &key, const int val) { osmLuaProcessing->AttributeInteger(key, val, 0); },
[](const std::string &key, const int val, const char minzoom) { osmLuaProcessing->AttributeInteger(key, val, minzoom); }
); );
luaState["AttributeBoolean"] = kaguya::overload( luaState["AttributeBoolean"] = kaguya::overload(
[](const std::string &key, const bool val) { osmLuaProcessing->AttributeBoolean(key, val, 0); }, [](const std::string &key, const bool val) { osmLuaProcessing->AttributeBoolean(key, val, 0); },
@@ -919,7 +923,7 @@ void OsmLuaProcessing::Attribute(const string &key, const protozero::data_view v
setVectorLayerMetadata(outputs.back().first.layer, key, 0); setVectorLayerMetadata(outputs.back().first.layer, key, 0);
} }
void OsmLuaProcessing::AttributeNumeric(const string &key, const float val, const char minzoom) { void OsmLuaProcessing::AttributeNumeric(const string &key, const double val, const char minzoom) {
if (outputs.size()==0) { ProcessingError("Can't add Attribute if no Layer set"); return; } if (outputs.size()==0) { ProcessingError("Can't add Attribute if no Layer set"); return; }
removeAttributeIfNeeded(key); removeAttributeIfNeeded(key);
attributeStore.addAttribute(outputs.back().second, key, val, minzoom); attributeStore.addAttribute(outputs.back().second, key, val, minzoom);
@@ -933,6 +937,13 @@ void OsmLuaProcessing::AttributeBoolean(const string &key, const bool val, const
setVectorLayerMetadata(outputs.back().first.layer, key, 2); setVectorLayerMetadata(outputs.back().first.layer, key, 2);
} }
void OsmLuaProcessing::AttributeInteger(const string &key, const int val, const char minzoom) {
if (outputs.size()==0) { ProcessingError("Can't add Attribute if no Layer set"); return; }
removeAttributeIfNeeded(key);
attributeStore.addAttribute(outputs.back().second, key, val, minzoom);
setVectorLayerMetadata(outputs.back().first.layer, key, 3);
}
// Set minimum zoom // Set minimum zoom
void OsmLuaProcessing::MinZoom(const double z) { void OsmLuaProcessing::MinZoom(const double z) {
if (outputs.size()==0) { ProcessingError("Can't set minimum zoom if no Layer set"); return; } if (outputs.size()==0) { ProcessingError("Can't set minimum zoom if no Layer set"); return; }
+3
View File
@@ -49,6 +49,9 @@ void OutputObject::writeAttributes(
fbuilder.add_property(key, it->stringValue()); fbuilder.add_property(key, it->stringValue());
} else if (it->hasBoolValue()) { } else if (it->hasBoolValue()) {
fbuilder.add_property(key, it->boolValue()); fbuilder.add_property(key, it->boolValue());
} else if (it->hasIntValue()) {
// could potentially add ,vtzero::sint_value_type(2) to force sint encoding (efficient for -ve ints)
fbuilder.add_property(key, it->intValue());
} else if (it->hasFloatValue()) { } else if (it->hasFloatValue()) {
fbuilder.add_property(key, it->floatValue()); fbuilder.add_property(key, it->floatValue());
} }
+4 -4
View File
@@ -70,10 +70,10 @@ AttributeIndex ShpProcessor::readShapefileAttributes(
layer.attributeMap[key] = 0; layer.attributeMap[key] = 0;
} else if (val.isType<int>()) { } else if (val.isType<int>()) {
if (key=="_minzoom") { minzoom=val; continue; } if (key=="_minzoom") { minzoom=val; continue; }
attributeStore.addAttribute(attributes, key, (float)val, 0); attributeStore.addAttribute(attributes, key, (int)val, 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
} else if (val.isType<double>()) { } else if (val.isType<double>()) {
attributeStore.addAttribute(attributes, key, (float)val, 0); attributeStore.addAttribute(attributes, key, (double)val, 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
} else if (val.isType<bool>()) { } else if (val.isType<bool>()) {
attributeStore.addAttribute(attributes, key, (bool)val, 0); attributeStore.addAttribute(attributes, key, (bool)val, 0);
@@ -88,10 +88,10 @@ AttributeIndex ShpProcessor::readShapefileAttributes(
int pos = it.first; int pos = it.first;
string key = it.second; string key = it.second;
switch (columnTypeMap[pos]) { switch (columnTypeMap[pos]) {
case 1: attributeStore.addAttribute(attributes, key, (float)DBFReadIntegerAttribute(dbf, recordNum, pos), 0); case 1: attributeStore.addAttribute(attributes, key, (int)DBFReadIntegerAttribute(dbf, recordNum, pos), 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
break; break;
case 2: attributeStore.addAttribute(attributes, key, static_cast<float>(DBFReadDoubleAttribute(dbf, recordNum, pos)), 0); case 2: attributeStore.addAttribute(attributes, key, (double)DBFReadDoubleAttribute(dbf, recordNum, pos), 0);
layer.attributeMap[key] = 1; layer.attributeMap[key] = 1;
break; break;
case 3: attributeStore.addAttribute(attributes, key, strcmp(DBFReadStringAttribute(dbf, recordNum, pos), "T")==0, 0); case 3: attributeStore.addAttribute(attributes, key, strcmp(DBFReadStringAttribute(dbf, recordNum, pos), "T")==0, 0);
+17 -8
View File
@@ -14,14 +14,15 @@ MU_TEST(test_attribute_store) {
store.addAttribute(s1, "str2", std::string("a very long string"), 14); store.addAttribute(s1, "str2", std::string("a very long string"), 14);
store.addAttribute(s1, "bool1", false, 0); store.addAttribute(s1, "bool1", false, 0);
store.addAttribute(s1, "bool2", true, 0); store.addAttribute(s1, "bool2", true, 0);
store.addAttribute(s1, "float1", (float)42.0, 4); store.addAttribute(s1, "double1", (double)42.0, 4);
store.addAttribute(s1, "int1", 43, 8);
const auto s1Index = store.add(s1); const auto s1Index = store.add(s1);
mu_check(store.size() == 1); mu_check(store.size() == 1);
const auto s1Pairs = store.getUnsafe(s1Index); const auto s1Pairs = store.getUnsafe(s1Index);
mu_check(s1Pairs.size() == 5); mu_check(s1Pairs.size() == 6);
const auto str1 = std::find_if(s1Pairs.begin(), s1Pairs.end(), [&store](auto ap) { const auto str1 = std::find_if(s1Pairs.begin(), s1Pairs.end(), [&store](auto ap) {
return ap->keyIndex == store.keyStore.key2index("str1"); return ap->keyIndex == store.keyStore.key2index("str1");
}); });
@@ -51,13 +52,21 @@ MU_TEST(test_attribute_store) {
mu_check((*bool2)->hasBoolValue()); mu_check((*bool2)->hasBoolValue());
mu_check((*bool2)->boolValue() == true); mu_check((*bool2)->boolValue() == true);
const auto float1 = std::find_if(s1Pairs.begin(), s1Pairs.end(), [&store](auto ap) { const auto double1 = std::find_if(s1Pairs.begin(), s1Pairs.end(), [&store](auto ap) {
return ap->keyIndex == store.keyStore.key2index("float1"); return ap->keyIndex == store.keyStore.key2index("double1");
}); });
mu_check(float1 != s1Pairs.end()); mu_check(double1 != s1Pairs.end());
mu_check((*float1)->hasFloatValue()); mu_check((*double1)->hasFloatValue());
mu_check((*float1)->floatValue() == 42); mu_check((*double1)->floatValue() == 42);
mu_check((*float1)->minzoom == 4); mu_check((*double1)->minzoom == 4);
const auto int1 = std::find_if(s1Pairs.begin(), s1Pairs.end(), [&store](auto ap) {
return ap->keyIndex == store.keyStore.key2index("int1");
});
mu_check(int1 != s1Pairs.end());
mu_check((*int1)->hasIntValue());
mu_check((*int1)->intValue() == 43);
mu_check((*int1)->minzoom == 8);
} }
MU_TEST(test_attribute_store_reuses) { MU_TEST(test_attribute_store_reuses) {