Skip to content

Commit 497aa7d

Browse files
committed
Boost 1.89+ fix
2 parents edb862c + f3d730e commit 497aa7d

10 files changed

Lines changed: 235 additions & 154 deletions

File tree

CMakeLists.txt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,20 @@ IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
3131
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
3232
ENDIF ()
3333

34-
find_package(Boost 1.66 REQUIRED COMPONENTS system filesystem program_options)
34+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
35+
set(Boost_USE_DEBUG_RUNTIME true)
36+
else()
37+
set(Boost_USE_DEBUG_RUNTIME false)
38+
endif()
39+
40+
set(BOOST_HAS_SYSTEM false)
41+
42+
find_package(Boost 1.89 QUIET COMPONENTS filesystem program_options)
43+
44+
if(NOT Boost_FOUND)
45+
find_package(Boost 1.66 REQUIRED COMPONENTS system filesystem program_options)
46+
set(BOOST_HAS_SYSTEM true)
47+
endif()
3548

3649
find_package(libshp REQUIRED)
3750

@@ -111,6 +124,7 @@ file(GLOB tilemaker_src_files
111124
src/tag_map.cpp
112125
src/tile_coordinates_set.cpp
113126
src/tile_data.cpp
127+
src/tile_sorting.cpp
114128
src/tilemaker.cpp
115129
src/tile_worker.cpp
116130
src/visvalingam.cpp
@@ -125,7 +139,10 @@ target_link_libraries(tilemaker
125139
shapelib::shp
126140
SQLite::SQLite3
127141
Rapidjson::rapidjson
128-
Boost::system Boost::filesystem Boost::program_options)
142+
Boost::filesystem Boost::program_options)
143+
if(BOOST_HAS_SYSTEM)
144+
target_link_libraries(tilemaker Boost::system)
145+
endif()
129146

130147
include(CheckCxxAtomic)
131148
if(NOT HAVE_CXX11_ATOMIC)

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ tilemaker: \
129129
src/tag_map.o \
130130
src/tile_coordinates_set.o \
131131
src/tile_data.o \
132+
src/tile_sorting.o \
132133
src/tilemaker.o \
133134
src/tile_worker.o \
134135
src/visvalingam.o \

include/append_vector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "mmap_allocator.h"
55
#include <vector>
66
#include <queue>
7+
#include <cstdint>
78

89
// Tilemaker collects OutputObjects in a list that
910
// - spills to disk

include/output_object.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
#include <string>
77
#include <map>
88
#include <memory>
9-
#include "geom.h"
109
#include "coordinates.h"
1110
#include "attribute_store.h"
12-
#include "osm_store.h"
1311
#include <vtzero/builder.hpp>
1412

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

include/tile_data.h

Lines changed: 8 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,22 @@
66
#include <set>
77
#include <vector>
88
#include <memory>
9-
#include <boost/sort/sort.hpp>
10-
#include "output_object.h"
119
#include "append_vector.h"
1210
#include "clip_cache.h"
1311
#include "mmap_allocator.h"
1412
#include "tile_coordinates_set.h"
15-
16-
#define TILE_DATA_ID_SIZE 34
13+
#include "tile_data_base.h"
1714

1815
typedef std::vector<class TileDataSource *> SourceList;
1916

2017
class TileBbox;
2118

22-
// We cluster output objects by z6 tile
23-
#define CLUSTER_ZOOM 6
24-
#define CLUSTER_ZOOM_WIDTH (1 << CLUSTER_ZOOM)
25-
#define CLUSTER_ZOOM_AREA (CLUSTER_ZOOM_WIDTH * CLUSTER_ZOOM_WIDTH)
26-
27-
// TileDataSource indexes which tiles have objects in them. The indexed zoom
28-
// is at most z14; we'll clamp to z14 if the base zoom is higher than z14.
29-
//
30-
// As a result, we need at most 15 bits to store an X/Y coordinate. For efficiency,
31-
// we bucket the world into 4,096 z6 tiles, which each contain some number of
32-
// z14 objects. This lets us use only 8 bits to store an X/Y coordinate.
33-
//
34-
// Because index zoom is lower than base zoom in the case where base zoom is
35-
// z15+, we'll get false positives when looking up objects in the index,
36-
// since, e.g., a single z14 tile covers 4 z15 tiles.
37-
//
38-
// This is OK: when writing the z15 tile, there's a clipping step that will filter
39-
// out the false positives.
40-
typedef uint8_t Z6Offset;
41-
42-
struct OutputObjectXY {
43-
OutputObject oo;
44-
Z6Offset x;
45-
Z6Offset y;
46-
};
47-
48-
struct OutputObjectXYID {
49-
OutputObject oo;
50-
Z6Offset x;
51-
Z6Offset y;
52-
uint64_t id;
53-
};
19+
template<typename OO> void sortOutputObjects(
20+
const unsigned int indexZoom,
21+
const size_t threadNum,
22+
typename AppendVectorNS::AppendVector<OO>::Iterator begin,
23+
typename AppendVectorNS::AppendVector<OO>::Iterator end
24+
);
5425

5526
template<typename OO> void finalizeObjects(
5627
const std::string& name,
@@ -88,52 +59,7 @@ template<typename OO> void finalizeObjects(
8859
if (objectIt->oo.minZoom < CLUSTER_ZOOM)
8960
lowZoom[i].push_back(*objectIt);
9061

91-
// If the user is doing a a small extract, there are few populated
92-
// entries in `object`.
93-
//
94-
// e.g. Colorado has ~9 z6 tiles, 1 of which has 95% of its output
95-
// objects.
96-
//
97-
// This optimizes for the small extract case by doing:
98-
// - for each vector in objects
99-
// - do a multi-threaded sort of vector
100-
//
101-
// For small extracts, this ensures that all threads are used even if
102-
// only a handful of entries in `objects` are non-empty.
103-
//
104-
// For a global extract, this will have some overhead of repeatedly
105-
// setting up/tearing down threads. In that case, it would be
106-
// better to assign chunks of `objects` to each thread.
107-
//
108-
// That's a future performance improvement, so deferring for now.
109-
boost::sort::block_indirect_sort(
110-
it->begin(),
111-
it->end(),
112-
[indexZoom](const OO& a, const OO& b) {
113-
// Cluster by parent zoom, so that a subsequent search
114-
// can find a contiguous range of entries for any tile
115-
// at zoom 6 or higher.
116-
const size_t aX = a.x;
117-
const size_t aY = a.y;
118-
const size_t bX = b.x;
119-
const size_t bY = b.y;
120-
for (size_t z = CLUSTER_ZOOM; z <= indexZoom; z++) {
121-
const auto aXz = aX / (1 << (indexZoom - z));
122-
const auto bXz = bX / (1 << (indexZoom - z));
123-
if (aXz != bXz)
124-
return aXz < bXz;
125-
126-
const auto aYz = aY / (1 << (indexZoom - z));
127-
const auto bYz = bY / (1 << (indexZoom - z));
128-
129-
if (aYz != bYz)
130-
return aYz < bYz;
131-
}
132-
133-
return false;
134-
},
135-
threadNum
136-
);
62+
sortOutputObjects<OO>(indexZoom, threadNum, it->begin(), it->end());
13763
}
13864

13965
std::cout << std::endl;

include/tile_data_base.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef _TILE_DATA_BASE_H
2+
#define _TILE_DATA_BASE_H
3+
4+
#include <cstdint>
5+
#include "output_object.h"
6+
7+
#define TILE_DATA_ID_SIZE 34
8+
9+
// We cluster output objects by z6 tile
10+
#define CLUSTER_ZOOM 6
11+
#define CLUSTER_ZOOM_WIDTH (1 << CLUSTER_ZOOM)
12+
#define CLUSTER_ZOOM_AREA (CLUSTER_ZOOM_WIDTH * CLUSTER_ZOOM_WIDTH)
13+
14+
// TileDataSource indexes which tiles have objects in them. The indexed zoom
15+
// is at most z14; we'll clamp to z14 if the base zoom is higher than z14.
16+
//
17+
// As a result, we need at most 15 bits to store an X/Y coordinate. For efficiency,
18+
// we bucket the world into 4,096 z6 tiles, which each contain some number of
19+
// z14 objects. This lets us use only 8 bits to store an X/Y coordinate.
20+
//
21+
// Because index zoom is lower than base zoom in the case where base zoom is
22+
// z15+, we'll get false positives when looking up objects in the index,
23+
// since, e.g., a single z14 tile covers 4 z15 tiles.
24+
//
25+
// This is OK: when writing the z15 tile, there's a clipping step that will filter
26+
// out the false positives.
27+
typedef uint8_t Z6Offset;
28+
29+
struct OutputObjectXY {
30+
OutputObject oo;
31+
Z6Offset x;
32+
Z6Offset y;
33+
};
34+
35+
struct OutputObjectXYID {
36+
OutputObject oo;
37+
Z6Offset x;
38+
Z6Offset y;
39+
uint64_t id;
40+
};
41+
42+
#endif //_TILE_DATA_BASE_H

src/osm_store.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <unordered_map>
77

88
#include <ciso646>
9-
#include <boost/sort/sort.hpp>
109
#include "node_store.h"
1110
#include "way_store.h"
1211

src/tile_data.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ void populateTilesAtZoom(
394394
}
395395
}
396396

397+
void sortOutputObjectIDs(
398+
const std::vector<bool>& sortOrders,
399+
std::vector<OutputObjectID>& data
400+
);
401+
397402
std::vector<OutputObjectID> TileDataSource::getObjectsForTile(
398403
const std::vector<bool>& sortOrders,
399404
unsigned int zoom,
@@ -402,23 +407,7 @@ std::vector<OutputObjectID> TileDataSource::getObjectsForTile(
402407
std::vector<OutputObjectID> data;
403408
collectObjectsForTile(zoom, coordinates, data);
404409
collectLargeObjectsForTile(zoom, coordinates, data);
405-
406-
// Lexicographic comparison, with the order of: layer, geomType, attributes, and objectID.
407-
// Note that attributes is preferred to objectID.
408-
// It is to arrange objects with the identical attributes continuously.
409-
// Such objects will be merged into one object, to reduce the size of output.
410-
boost::sort::pdqsort(data.begin(), data.end(), [&sortOrders](const OutputObjectID& x, const OutputObjectID& y) -> bool {
411-
if (x.oo.layer < y.oo.layer) return true;
412-
if (x.oo.layer > y.oo.layer) return false;
413-
if (x.oo.z_order < y.oo.z_order) return sortOrders[x.oo.layer];
414-
if (x.oo.z_order > y.oo.z_order) return !sortOrders[x.oo.layer];
415-
if (x.oo.geomType < y.oo.geomType) return true;
416-
if (x.oo.geomType > y.oo.geomType) return false;
417-
if (x.oo.attributes < y.oo.attributes) return true;
418-
if (x.oo.attributes > y.oo.attributes) return false;
419-
if (x.oo.objectID < y.oo.objectID) return true;
420-
return false;
421-
});
410+
sortOutputObjectIDs(sortOrders, data);
422411
data.erase(unique(data.begin(), data.end()), data.end());
423412
return data;
424413
}

0 commit comments

Comments
 (0)