Skip to content

Commit 06e0b28

Browse files
authored
Configurable sort order (#485)
1 parent bf64cc3 commit 06e0b28

8 files changed

Lines changed: 37 additions & 35 deletions

File tree

docs/CONFIGURATION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ You can add optional parameters to layers:
7373
* `filter_below` - filter areas by minimum size below this zoom level
7474
* `filter_area` - minimum size (in square degrees of longitude) for the zoom level `filter_below-1`
7575
* `combine_polygons_below` - merge adjacent polygons with the same attributes below this zoom level
76+
* `z_order_ascending` - sort features in ascending order by a numeric value set in the Lua processing script (defaults to `true`: specify `false` for descending order)
7677

7778
Use these options to combine different layer specs within one outputted layer. For example:
7879

include/output_object.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,6 @@ LatpLon buildNodeGeometry(OSMStore &osmStore, OutputObject const &oo, const Tile
156156

157157
bool operator==(const OutputObjectRef x, const OutputObjectRef y);
158158

159-
/**
160-
* Do lexicographic comparison, with the order of: layer, geomType, attributes, and objectID.
161-
* Note that attributes is preferred to objectID.
162-
* It is to arrange objects with the identical attributes continuously.
163-
* Such objects will be merged into one object, to reduce the size of output.
164-
*/
165-
bool operator<(const OutputObjectRef x, const OutputObjectRef y);
166-
167159
namespace vector_tile {
168160
bool operator==(const vector_tile::Tile_Value &x, const vector_tile::Tile_Value &y);
169161
bool operator<(const vector_tile::Tile_Value &x, const vector_tile::Tile_Value &y);

include/shared_data.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct LayerDef {
2424
uint filterBelow;
2525
double filterArea;
2626
uint combinePolygonsBelow;
27+
bool sortZOrderAscending;
2728
std::string source;
2829
std::vector<std::string> sourceColumns;
2930
bool allSourceColumns;
@@ -44,14 +45,14 @@ class LayerDefinition {
4445
// Define a layer (as read from the .json file)
4546
uint addLayer(std::string name, uint minzoom, uint maxzoom,
4647
uint simplifyBelow, double simplifyLevel, double simplifyLength, double simplifyRatio,
47-
uint filterBelow, double filterArea, uint combinePolygonsBelow,
48+
uint filterBelow, double filterArea, uint combinePolygonsBelow, bool sortZOrderAscending,
4849
const std::string &source,
4950
const std::vector<std::string> &sourceColumns,
5051
bool allSourceColumns,
5152
bool indexed,
5253
const std::string &indexName,
5354
const std::string &writeTo);
54-
55+
std::vector<bool> getSortOrders();
5556
rapidjson::Value serialiseToJSONValue(rapidjson::Document::AllocatorType &allocator) const;
5657
std::string serialiseToJSON() const;
5758
};

include/tile_data.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ class TileDataSource {
6868

6969
TileCoordinatesSet GetTileCoordinates(std::vector<class TileDataSource *> const &sources, unsigned int zoom);
7070

71-
std::vector<OutputObjectRef> GetTileData(std::vector<class TileDataSource *> const &sources, TileCoordinates coordinates, unsigned int zoom);
71+
std::vector<OutputObjectRef> GetTileData(std::vector<class TileDataSource *> const &sources,
72+
std::vector<bool> const &sortOrders,
73+
TileCoordinates coordinates, unsigned int zoom);
7274

7375
OutputObjectsConstItPair GetObjectsAtSubLayer(std::vector<OutputObjectRef> const &data, uint_least8_t layerNum);
7476

src/output_object.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -222,23 +222,6 @@ bool operator==(const OutputObjectRef x, const OutputObjectRef y) {
222222
x->objectID == y->objectID;
223223
}
224224

225-
// Do lexicographic comparison, with the order of: layer, geomType, attributes, and objectID.
226-
// Note that attributes is preffered to objectID.
227-
// It is to arrange objects with the identical attributes continuously.
228-
// Such objects will be merged into one object, to reduce the size of output.
229-
bool operator<(const OutputObjectRef x, const OutputObjectRef y) {
230-
if (x->layer < y->layer) return true;
231-
if (x->layer > y->layer) return false;
232-
if (x->z_order < y->z_order) return true;
233-
if (x->z_order > y->z_order) return false;
234-
if (x->geomType < y->geomType) return true;
235-
if (x->geomType > y->geomType) return false;
236-
if (x->attributes.get() < y->attributes.get()) return true;
237-
if (x->attributes.get() > y->attributes.get()) return false;
238-
if (x->objectID < y->objectID) return true;
239-
return false;
240-
}
241-
242225
namespace vector_tile {
243226
bool operator==(const vector_tile::Tile_Value &x, const vector_tile::Tile_Value &y) {
244227
std::string strx = x.SerializeAsString();

src/shared_data.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ SharedData::~SharedData() { }
1919
// Define a layer (as read from the .json file)
2020
uint LayerDefinition::addLayer(string name, uint minzoom, uint maxzoom,
2121
uint simplifyBelow, double simplifyLevel, double simplifyLength, double simplifyRatio,
22-
uint filterBelow, double filterArea, uint combinePolygonsBelow,
22+
uint filterBelow, double filterArea, uint combinePolygonsBelow, bool sortZOrderAscending,
2323
const std::string &source,
2424
const std::vector<std::string> &sourceColumns,
2525
bool allSourceColumns,
@@ -29,7 +29,7 @@ uint LayerDefinition::addLayer(string name, uint minzoom, uint maxzoom,
2929

3030
bool isWriteTo = !writeTo.empty();
3131
LayerDef layer = { name, minzoom, maxzoom, simplifyBelow, simplifyLevel, simplifyLength, simplifyRatio,
32-
filterBelow, filterArea, combinePolygonsBelow,
32+
filterBelow, filterArea, combinePolygonsBelow, sortZOrderAscending,
3333
source, sourceColumns, allSourceColumns, indexed, indexName,
3434
std::map<std::string,uint>(), isWriteTo };
3535
layers.push_back(layer);
@@ -54,6 +54,11 @@ uint LayerDefinition::addLayer(string name, uint minzoom, uint maxzoom,
5454
return layerNum;
5555
}
5656

57+
std::vector<bool> LayerDefinition::getSortOrders() {
58+
std::vector<bool> orders;
59+
for (auto &layer : layers) { orders.emplace_back(layer.sortZOrderAscending); }
60+
return orders;
61+
}
5762

5863
Value LayerDefinition::serialiseToJSONValue(rapidjson::Document::AllocatorType &allocator) const {
5964
Value layerArray(kArrayType);
@@ -191,6 +196,7 @@ void Config::readConfig(rapidjson::Document &jsonConfig, bool &hasClippingBox, B
191196
int filterBelow = it->value.HasMember("filter_below" ) ? it->value["filter_below" ].GetInt() : 0;
192197
double filterArea = it->value.HasMember("filter_area" ) ? it->value["filter_area" ].GetDouble() : 0.5;
193198
int combinePolyBelow=it->value.HasMember("combine_polygons_below") ? it->value["combine_polygons_below"].GetInt() : 0;
199+
bool sortZOrderAscending = it->value.HasMember("z_order_ascending") ? it->value["z_order_ascending"].GetBool() : true;
194200
string source = it->value.HasMember("source") ? it->value["source"].GetString() : "";
195201
vector<string> sourceColumns;
196202
bool allSourceColumns = false;
@@ -210,7 +216,7 @@ void Config::readConfig(rapidjson::Document &jsonConfig, bool &hasClippingBox, B
210216

211217
layers.addLayer(layerName, minZoom, maxZoom,
212218
simplifyBelow, simplifyLevel, simplifyLength, simplifyRatio,
213-
filterBelow, filterArea, combinePolyBelow,
219+
filterBelow, filterArea, combinePolyBelow, sortZOrderAscending,
214220
source, sourceColumns, allSourceColumns, indexed, indexName,
215221
writeTo);
216222

src/tile_data.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,31 @@ TileCoordinatesSet GetTileCoordinates(std::vector<class TileDataSource *> const
101101
return tileCoordinates;
102102
}
103103

104-
std::vector<OutputObjectRef> GetTileData(std::vector<class TileDataSource *> const &sources, TileCoordinates coordinates, unsigned int zoom)
105-
{
104+
std::vector<OutputObjectRef> GetTileData(std::vector<class TileDataSource *> const &sources,
105+
std::vector<bool> const &sortOrders, TileCoordinates coordinates,
106+
unsigned int zoom) {
106107
std::vector<OutputObjectRef> data;
107108
for(size_t i=0; i<sources.size(); i++) {
108109
sources[i]->MergeSingleTileDataAtZoom(coordinates, zoom, data);
109110
sources[i]->MergeLargeObjects(coordinates, zoom, data);
110111
}
111112

112-
boost::sort::pdqsort(data.begin(), data.end());
113+
// Lexicographic comparison, with the order of: layer, geomType, attributes, and objectID.
114+
// Note that attributes is preferred to objectID.
115+
// It is to arrange objects with the identical attributes continuously.
116+
// Such objects will be merged into one object, to reduce the size of output.
117+
boost::sort::pdqsort(data.begin(), data.end(), [&sortOrders](const OutputObjectRef x, const OutputObjectRef y) -> bool {
118+
if (x->layer < y->layer) return true;
119+
if (x->layer > y->layer) return false;
120+
if (x->z_order < y->z_order) return sortOrders[x->layer];
121+
if (x->z_order > y->z_order) return !sortOrders[x->layer];
122+
if (x->geomType < y->geomType) return true;
123+
if (x->geomType > y->geomType) return false;
124+
if (x->attributes.get() < y->attributes.get()) return true;
125+
if (x->attributes.get() > y->attributes.get()) return false;
126+
if (x->objectID < y->objectID) return true;
127+
return false;
128+
});
113129
data.erase(unique(data.begin(), data.end()), data.end());
114130
return data;
115131
}

src/tilemaker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ int main(int argc, char* argv[]) {
326326
// ---- Read all PBFs
327327

328328
PbfReader pbfReader(osmStore);
329+
std::vector<bool> sortOrders = layers.getSortOrders();
329330

330331
if (!mapsplit) {
331332
for (auto inputFile : inputFiles) {
@@ -469,7 +470,7 @@ int main(int argc, char* argv[]) {
469470
for(std::size_t i = start_index; i < end_index; ++i) {
470471
unsigned int zoom = tile_coordinates[i].first;
471472
TileCoordinates coords = tile_coordinates[i].second;
472-
outputProc(pool, sharedData, osmStore, GetTileData(sources, coords, zoom), coords, zoom);
473+
outputProc(pool, sharedData, osmStore, GetTileData(sources, sortOrders, coords, zoom), coords, zoom);
473474
}
474475

475476
const std::lock_guard<std::mutex> lock(io_mutex);

0 commit comments

Comments
 (0)