├── .gitignore ├── Makefile ├── MapServer ├── Makefile ├── Readme.md ├── epsg ├── mapcache_mvt.xml ├── ne.map └── paths.txt ├── README.md ├── bench ├── httpbench.lua ├── paths.txt └── results │ ├── Makefile │ ├── http-quick.g │ ├── http.g │ ├── seed-quick.g │ └── seed.g ├── data ├── .gitignore ├── Dockerfile ├── Makefile ├── ne_extracts_3857.gpkg └── setup-db.sh ├── docker-compose.yml ├── maps ├── map-countries.html ├── natural-earth-countries.json ├── nginx-server.conf ├── style-screenshot.jpg ├── tilejson-ms.json └── tilejson-t-rex.json ├── martin ├── Makefile ├── README.md └── config.yaml ├── t-rex ├── Makefile ├── README.md ├── map-countries.html └── mvtbench.toml ├── template ├── Makefile └── README.md └── tiles └── .gitignore /.gitignore: -------------------------------------------------------------------------------- 1 | *.csv 2 | *.jpg 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | tilecache = ./tiles 2 | 3 | .PHONY: bench 4 | bench: 5 | @#Handle file permissions 6 | chmod go+rw $(tilecache) 7 | touch bench/results/results_http.csv 8 | 9 | cd t-rex && make bench 10 | cd MapServer && make bench 11 | 12 | cd bench/results && make 13 | 14 | quick_bench: 15 | @#Handle file permissions 16 | chmod go+rw $(tilecache) 17 | touch bench/results/results_http_quick.csv 18 | 19 | cd t-rex && make quick_bench 20 | cd MapServer && make quick_bench 21 | 22 | cd bench/results && make quick 23 | 24 | clean_tilecache: 25 | rm -rf $(tilecache)/* 26 | 27 | clean_results: 28 | cd bench/results && make clean 29 | -------------------------------------------------------------------------------- /MapServer/Makefile: -------------------------------------------------------------------------------- 1 | sw = mapserver 2 | exec = docker-compose run --rm mapcache 3 | result_prefix = ../bench/results/results_ 4 | ts = $(shell date '+%Y-%m-%dT%TZ') 5 | region_bbox = 596820,5674685,3346107,8169590 6 | tilecache = ../tiles 7 | 8 | quick_bench: 9 | # Seeding benchmarks 10 | make data_ready clean_tilecache 11 | make mapserver_ready 12 | make bench_seed_region tile_stats clean_tilecache 13 | make bench_seed_region_4 tile_stats 14 | # Tile serving benchmarks (with seeded tilecache) 15 | make mvtserver_teardown 16 | make mvtserver_ready bench_http duration=5 csv=http_quick.csv mvtserver_teardown 17 | make data_teardown 18 | 19 | bench: 20 | # Seeding benchmarks 21 | make data_ready clean_tilecache 22 | make mapserver_ready 23 | make bench_seed tile_stats clean_tilecache 24 | make bench_seed_4 tile_stats 25 | # Tile serving benchmarks (with seeded tilecache) 26 | make mvtserver_teardown 27 | make mvtserver_ready bench_http mvtserver_teardown 28 | make data_teardown 29 | 30 | mapviewer: 31 | docker-compose up nginx-ms 32 | # Open viewer at http://localhost:8088/map-countries.html 33 | 34 | # Seeding benchmarks 35 | 36 | data_ready: 37 | docker-compose up -d mvtbenchdb 38 | 39 | data_teardown: 40 | docker-compose stop mvtbenchdb 41 | 42 | mapserver_ready: data_ready 43 | docker-compose up -d mapserver 44 | 45 | mapserver_teardown: 46 | docker-compose stop mapserver 47 | 48 | bench_seed: $(result_prefix)seed.csv 49 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< $(exec) mapcache_seed -c /etc/mapcache/mapcache.xml -t ms_mvt -z 1,6 50 | @echo Statistics written to $< 51 | 52 | bench_seed_4: $(result_prefix)seed_4.csv 53 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< $(exec) mapcache_seed -c /etc/mapcache/mapcache.xml -t ms_mvt -z 1,6 -n 4 54 | @echo Statistics written to $< 55 | 56 | # Tile serving benchmarks 57 | 58 | mvtserver_ready: mapserver_ready 59 | docker-compose up -d mapcache 60 | 61 | mvtserver_teardown: 62 | docker-compose stop mapcache 63 | 64 | csv = http.csv 65 | wkr_cmd = docker run --rm --user=$$UID --net=host -e SW="$(sw)" -e CSV_NAME=$(csv) -e CONNECTIONS=[CONN] -v $$PWD/../bench:/bench -v $$PWD/paths.txt:/paths.txt:ro williamyeh/wrk -H 'Accept-Encoding: gzip' -H 'Connection: keep-alive' 66 | duration = 20 67 | 68 | bench_http: 69 | @# From first entry only title is displayed on plot 70 | $(wkr_cmd:[CONN]=1) --latency -d 1 -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 71 | $(wkr_cmd:[CONN]=1) --latency -d $(duration) -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 72 | $(wkr_cmd:[CONN]=4) --latency -d $(duration) -c 4 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 73 | $(wkr_cmd:[CONN]=32) --latency -d $(duration) -c 32 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 74 | $(wkr_cmd:[CONN]=64) --latency -d $(duration) -c 64 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 75 | $(wkr_cmd:[CONN]=128) --latency -d $(duration) -c 128 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 76 | $(wkr_cmd:[CONN]=256) --latency -d $(duration) -c 256 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 77 | @echo >>$(result_prefix)${csv} 78 | @echo >>$(result_prefix)${csv} 79 | @echo Statistics written to $(result_prefix)${csv} 80 | 81 | # Quick benchmarks 82 | 83 | bench_seed_region: $(result_prefix)seed_region.csv 84 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< $(exec) mapcache_seed -c /etc/mapcache/mapcache.xml -t ms_mvt -z 1,6 -e $(region_bbox) 85 | @echo Statistics written to result_$@.csv 86 | 87 | bench_seed_region_4: $(result_prefix)seed_region_4.csv 88 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< $(exec) mapcache_seed -c /etc/mapcache/mapcache.xml -t ms_mvt -z 1,6 -n 4 -e $(region_bbox) 89 | @echo Statistics written to $< 90 | 91 | # Helpers 92 | 93 | $(result_prefix)seed.csv: 94 | echo "#time_started,software,real,user,sys" >$@ 95 | 96 | $(result_prefix)seed_4.csv: 97 | echo "#time_started,software,real,user,sys" >$@ 98 | 99 | $(result_prefix)seed_region.csv: 100 | echo "#time_started,software,real,user,sys" >$@ 101 | 102 | $(result_prefix)seed_region_4.csv: 103 | echo "#time_started,software,real,user,sys" >$@ 104 | 105 | tile_stats: 106 | find $(tilecache)/ms_mvt -name '*mvt' | wc -l 107 | du -s $(tilecache)/ms_mvt 108 | docker-compose run gdal ogrinfo -al -so /var/data/tiles/ms_mvt/6/34/21.mvt 109 | 110 | clean_tilecache: 111 | @# Delete files as user www-data 112 | docker-compose run --rm --entrypoint /bin/rm mapcache "-rf" "/var/sig/tiles/ms_mvt" 113 | -------------------------------------------------------------------------------- /MapServer/Readme.md: -------------------------------------------------------------------------------- 1 | MapServer 2 | ========= 3 | 4 | * Homepage: https://mapserver.org/ 5 | * Source repository: https://github.com/mapserver/mapserver 6 | -------------------------------------------------------------------------------- /MapServer/mapcache_mvt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MVT Mapcache Service 5 | MVT Benchmark Test MapServer 6 | 7 | 8 | 9 | /var/sig/tiles 10 | 11 | 12 | 13 | 14 | mvt 15 | application/vnd.mapbox-vector-tile 16 | 17 | 18 | 19 | 20 | 21 | application/vnd.mapbox-vector-tile 22 | ne_countries 23 | /etc/mapserver/mapserver.map 24 | 25 | 26 | 27 | http://mapserver:8080/ 28 | 29 | 30 | 31 | 32 | ne_mvt 33 | g 34 | disk 35 | MVT 36 | 37 | 38 | MVT 39 | 40 | 41 | 42 | 43 | 44 | assemble 45 | bilinear 46 | PNG 47 | 4096 48 | 49 | 50 | report 51 | /var/sig/tiles 52 | 53 | -------------------------------------------------------------------------------- /MapServer/ne.map: -------------------------------------------------------------------------------- 1 | MAP 2 | NAME 'ne_countries' 3 | SIZE 500 500 4 | MAXSIZE 4096 5 | PROJECTION 6 | "+init=epsg:3857" 7 | END 8 | OUTPUTFORMAT 9 | NAME "png8" 10 | DRIVER AGG/PNG8 11 | MIMETYPE "image/png; mode=8bit" 12 | IMAGEMODE RGB 13 | EXTENSION "png" 14 | FORMATOPTION "QUANTIZE_FORCE=on" 15 | FORMATOPTION "QUANTIZE_COLORS=256" 16 | FORMATOPTION "GAMMA=0.75" 17 | TRANSPARENT ON 18 | END 19 | 20 | OUTPUTFORMAT 21 | NAME "mvt" 22 | DRIVER MVT 23 | #FORMATOPTION "EXTENT=512" # default is 4096 24 | FORMATOPTION "EDGE_BUFFER=20" 25 | END 26 | 27 | WEB 28 | METADATA 29 | wms_enable_request "*" 30 | MVT_SIZE '512' 31 | WMS_TITLE 'Test mapfile for MVT development.' 32 | WMS_ONLINERESOURCE 'http://localhost/cgi-bin/mapserv?' 33 | WMS_SRS 'epsg:3857 epsg:4326' 34 | END 35 | END 36 | 37 | LAYER 38 | NAME "country" 39 | TYPE POLYGON 40 | STATUS ON 41 | CONNECTIONTYPE postgis 42 | PROCESSING "CLOSE_CONNECTION=DEFER" 43 | CONNECTION "user=mvtbench password=mvtbench dbname=mvtbench host=mvtbenchdb" 44 | DATA "wkb_geometry from (SELECT ogc_fid, name, adm0_a3, abbrev, mapcolor7, wkb_geometry FROM ne_10m_admin_0_countries) as temp using unique ogc_fid using SRID=3857" 45 | EXTENT -20037508.342789 -34679773.785951 20037508.342789 18428920.012950 # added to improve perfomance 46 | DUMP true 47 | METADATA 48 | "wms_title" "country" 49 | "wms_srs" "epsg:4326 epsg:3857 epsg:900913" 50 | "wms_feature_info_mime_type" "text/html" 51 | "gml_include_items" "adm0_a3,mapcolor7" # default WxS behavior is to expose no attributes so we need to be explicit 52 | "gml_mapcolor7_type" "integer" # Otherwise things are treated as strings 53 | END 54 | PROJECTION 55 | "init=epsg:3857" 56 | END 57 | CLASS 58 | STYLE 59 | OUTLINECOLOR 200 50 100 60 | WIDTH 0.4 61 | END 62 | END 63 | END 64 | 65 | LAYER 66 | NAME "country-name" 67 | TYPE POINT 68 | STATUS ON 69 | CONNECTIONTYPE postgis 70 | PROCESSING "CLOSE_CONNECTION=DEFER" 71 | CONNECTION "user=mvtbench password=mvtbench dbname=mvtbench host=mvtbenchdb" 72 | DATA "wkb_geometry from (SELECT ogc_fid, wkb_geometry, abbrev, name FROM ne_10m_admin_0_country_points) as temp using unique ogc_fid using SRID=3857" 73 | EXTENT -19729044.151792 -15878634.348995 19872743.796075 12257650.087343 # added to improve perfomance 74 | DUMP true 75 | METADATA 76 | "wms_title" "country-name" 77 | "wms_srs" "epsg:4326 epsg:3857 epsg:900913" 78 | "wms_feature_info_mime_type" "text/html" 79 | "gml_include_items" "abbrev,name" # default WxS behavior is to expose no attributes so we need to be explicit 80 | END 81 | PROJECTION 82 | "init=epsg:3857" 83 | END 84 | CLASS 85 | STYLE 86 | COLOR 200 50 100 87 | SIZE 1 88 | END 89 | END 90 | END 91 | 92 | # [[tileset.layer]] 93 | # name = "geo-lines" 94 | # geometry_field = "wkb_geometry" 95 | # geometry_type = "MULTILINESTRING" 96 | # srid = 3857 97 | # buffer_size = 0 98 | # simplify = false 99 | 100 | #### [[tileset.layer.query]] 101 | #### # ne_50m_geographic_lines 102 | #### minzoom = 1 103 | #### maxzoom = 4 104 | #### sql = """SELECT wkb_geometry, name FROM ne_50m_geographic_lines WHERE wkb_geometry && !bbox!""" 105 | #### [[tileset.layer.query]] 106 | #### # ne_10m_geographic_lines 107 | #### minzoom = 5 108 | #### sql = """SELECT wkb_geometry, name FROM ne_10m_geographic_lines WHERE wkb_geometry && !bbox!""" 109 | 110 | LAYER 111 | NAME "geo-lines" # 1 112 | TYPE LINE 113 | STATUS ON 114 | CONNECTIONTYPE postgis 115 | PROCESSING "CLOSE_CONNECTION=DEFER" 116 | CONNECTION "user=mvtbench password=mvtbench dbname=mvtbench host=mvtbenchdb" 117 | DATA "wkb_geometry from (SELECT ogc_fid, wkb_geometry, name FROM ne_50m_geographic_lines) as temp using unique ogc_fid using SRID=3857" 118 | EXTENT -20037508.342789 -108777091.702336 20037508.342789 108777091.692373 # added to improve perfomance 119 | # zoom level 1 - 4 120 | MINSCALE 27733946.6058614 # from steve L.'s calc 121 | DUMP true 122 | METADATA 123 | "wms_title" "geo-lines" 124 | "wms_srs" "epsg:4326 epsg:3857 epsg:900913" 125 | "wms_feature_info_mime_type" "text/html" 126 | "gml_include_items" "name" # default WxS behavior is to expose no attributes so we need to be explicit 127 | END 128 | PROJECTION 129 | "init=epsg:3857" 130 | END 131 | CLASS 132 | STYLE 133 | COLOR 200 50 100 134 | SIZE 1 135 | END 136 | END 137 | END 138 | 139 | 140 | LAYER 141 | NAME "geo-lines" # 2 142 | TYPE LINE 143 | STATUS ON 144 | CONNECTIONTYPE postgis 145 | PROCESSING "CLOSE_CONNECTION=DEFER" 146 | CONNECTION "user=mvtbench password=mvtbench dbname=mvtbench host=mvtbenchdb" 147 | DATA "wkb_geometry from (SELECT ogc_fid, wkb_geometry, name FROM ne_10m_geographic_lines) as temp using unique ogc_fid using SRID=3857" 148 | EXTENT -20037508.342789 -108777091.702336 20037508.342789 108777091.692373 # added to improve perfomance 149 | DUMP true 150 | # zoom level 5 - 6 151 | # from steve L.'s calc 152 | MINSCALE 6933486.65146535 153 | MAXSCALE 27733946.6058614 154 | METADATA 155 | "wms_title" "geo-lines" 156 | "wms_srs" "epsg:4326 epsg:3857 epsg:900913" 157 | "wms_feature_info_mime_type" "text/html" 158 | "gml_include_items" "name" # default WxS behavior is to expose no attributes so we need to be explicit 159 | END 160 | PROJECTION 161 | "init=epsg:3857" 162 | END 163 | CLASS 164 | STYLE 165 | COLOR 200 50 100 166 | SIZE 1 167 | END 168 | END 169 | END 170 | 171 | # [[tileset.layer]] 172 | # name = "land-border-country" 173 | # geometry_field = "wkb_geometry" 174 | # geometry_type = "MULTILINESTRING" 175 | # fid_field = "ogc_fid" 176 | # srid = 3857 177 | # buffer_size = 0 178 | # simplify = true 179 | 180 | #### [[tileset.layer.query]] 181 | #### # ne_10m_admin_0_boundary_lines_land 182 | #### sql = """SELECT wkb_geometry FROM ne_10m_admin_0_boundary_lines_land WHERE min_zoom::integer <= !zoom! AND wkb_geometry && !bbox!""" 183 | 184 | LAYER 185 | NAME "land-border-country" 186 | TYPE LINE 187 | STATUS ON 188 | CONNECTIONTYPE postgis 189 | PROCESSING "CLOSE_CONNECTION=DEFER" 190 | CONNECTION "user=mvtbench password=mvtbench dbname=mvtbench host=mvtbenchdb" 191 | DATA "wkb_geometry from (SELECT ogc_fid, wkb_geometry FROM ne_10m_admin_0_boundary_lines_land) as temp using unique ogc_fid using SRID=3857" 192 | EXTENT -15696665.873520 -7385370.408338 15693557.650216 11093271.780665 # added to improve perfomance 193 | DUMP true 194 | METADATA 195 | "wms_title" "land-border-country" 196 | "wms_srs" "epsg:4326 epsg:3857 epsg:900913" 197 | "wms_feature_info_mime_type" "text/html" 198 | # "gml_include_items" "ogc_fid" 199 | END 200 | PROJECTION 201 | "init=epsg:3857" 202 | END 203 | CLASS 204 | STYLE 205 | COLOR 200 50 100 206 | WIDTH 1 207 | END 208 | END 209 | END 210 | 211 | # [[tileset.layer]] 212 | # name = "state" 213 | # geometry_field = "wkb_geometry" 214 | # geometry_type = "MULTILINESTRING" 215 | # srid = 3857 216 | # buffer_size = 0 217 | # simplify = true 218 | 219 | #### [[tileset.layer.query]] 220 | #### sql = """SELECT wkb_geometry, adm0_a3 FROM ne_10m_admin_1_states_provinces_lines WHERE min_zoom::integer <= !zoom! AND wkb_geometry && !bbox!""" 221 | 222 | LAYER 223 | NAME "state" 224 | TYPE LINE 225 | STATUS ON 226 | CONNECTIONTYPE postgis 227 | PROCESSING "CLOSE_CONNECTION=DEFER" 228 | CONNECTION "user=mvtbench password=mvtbench dbname=mvtbench host=mvtbenchdb" 229 | DATA "wkb_geometry from (SELECT ogc_fid, wkb_geometry, adm0_a3 FROM ne_10m_admin_1_states_provinces_lines) as temp using unique ogc_fid using SRID=3857" 230 | EXTENT -19830129.664953 -6317536.489545 19864809.763624 16305918.534663 # added to improve perfomance 231 | DUMP true 232 | METADATA 233 | "wms_title" "state" 234 | "wms_srs" "epsg:4326 epsg:3857 epsg:900913" 235 | "wms_feature_info_mime_type" "text/html" 236 | "gml_include_items" "adm0_a3" # default WxS behavior is to expose no attributes so we need to be explicit 237 | END 238 | PROJECTION 239 | "init=epsg:3857" 240 | END 241 | CLASS 242 | STYLE 243 | COLOR 200 50 100 244 | WIDTH 1 245 | END 246 | END 247 | END 248 | 249 | 250 | END # Map end 251 | -------------------------------------------------------------------------------- /MapServer/paths.txt: -------------------------------------------------------------------------------- 1 | /mapcache/gmaps/ms_mvt@g/0/0/0.mvt 2 | /mapcache/gmaps/ms_mvt@g/1/1/0.mvt 3 | /mapcache/gmaps/ms_mvt@g/2/2/1.mvt 4 | /mapcache/gmaps/ms_mvt@g/3/4/2.mvt 5 | /mapcache/gmaps/ms_mvt@g/4/8/4.mvt 6 | /mapcache/gmaps/ms_mvt@g/4/8/5.mvt 7 | /mapcache/gmaps/ms_mvt@g/4/9/4.mvt 8 | /mapcache/gmaps/ms_mvt@g/4/9/5.mvt 9 | /mapcache/gmaps/ms_mvt@g/5/16/10.mvt 10 | /mapcache/gmaps/ms_mvt@g/5/16/11.mvt 11 | /mapcache/gmaps/ms_mvt@g/5/16/9.mvt 12 | /mapcache/gmaps/ms_mvt@g/5/17/10.mvt 13 | /mapcache/gmaps/ms_mvt@g/5/17/11.mvt 14 | /mapcache/gmaps/ms_mvt@g/5/17/9.mvt 15 | /mapcache/gmaps/ms_mvt@g/5/18/10.mvt 16 | /mapcache/gmaps/ms_mvt@g/5/18/11.mvt 17 | /mapcache/gmaps/ms_mvt@g/5/18/9.mvt 18 | /mapcache/gmaps/ms_mvt@g/6/32/18.mvt 19 | /mapcache/gmaps/ms_mvt@g/6/32/19.mvt 20 | /mapcache/gmaps/ms_mvt@g/6/32/20.mvt 21 | /mapcache/gmaps/ms_mvt@g/6/32/21.mvt 22 | /mapcache/gmaps/ms_mvt@g/6/32/22.mvt 23 | /mapcache/gmaps/ms_mvt@g/6/33/18.mvt 24 | /mapcache/gmaps/ms_mvt@g/6/33/19.mvt 25 | /mapcache/gmaps/ms_mvt@g/6/33/20.mvt 26 | /mapcache/gmaps/ms_mvt@g/6/33/21.mvt 27 | /mapcache/gmaps/ms_mvt@g/6/33/22.mvt 28 | /mapcache/gmaps/ms_mvt@g/6/34/18.mvt 29 | /mapcache/gmaps/ms_mvt@g/6/34/19.mvt 30 | /mapcache/gmaps/ms_mvt@g/6/34/20.mvt 31 | /mapcache/gmaps/ms_mvt@g/6/34/21.mvt 32 | /mapcache/gmaps/ms_mvt@g/6/34/22.mvt 33 | /mapcache/gmaps/ms_mvt@g/6/35/18.mvt 34 | /mapcache/gmaps/ms_mvt@g/6/35/19.mvt 35 | /mapcache/gmaps/ms_mvt@g/6/35/20.mvt 36 | /mapcache/gmaps/ms_mvt@g/6/35/21.mvt 37 | /mapcache/gmaps/ms_mvt@g/6/35/22.mvt 38 | /mapcache/gmaps/ms_mvt@g/6/36/18.mvt 39 | /mapcache/gmaps/ms_mvt@g/6/36/19.mvt 40 | /mapcache/gmaps/ms_mvt@g/6/36/20.mvt 41 | /mapcache/gmaps/ms_mvt@g/6/36/21.mvt 42 | /mapcache/gmaps/ms_mvt@g/6/36/22.mvt 43 | /mapcache/gmaps/ms_mvt@g/6/37/18.mvt 44 | /mapcache/gmaps/ms_mvt@g/6/37/19.mvt 45 | /mapcache/gmaps/ms_mvt@g/6/37/20.mvt 46 | /mapcache/gmaps/ms_mvt@g/6/37/21.mvt 47 | /mapcache/gmaps/ms_mvt@g/6/37/22.mvt 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MVT Benchmark 2 | ============= 3 | 4 | Benchmark for MVT vector tile creation and delivery from a PostGIS database. 5 | 6 | The benchmark uses a minimal subset of the [NaturalEarth](http://www.naturalearthdata.com/) 4.1 data set. 7 | 8 | Measurement targets: 9 | * How long does it take to generate all tiles (single node / multiple nodes) 10 | * How many requests/s does the tile server deliver in web server mode 11 | 12 | 13 | Tileset definition 14 | ------------------ 15 | 16 | * Tileset name: `ne_countries` 17 | * Maxzoom level for tile data: 6 18 | * Tile size: 4096 19 | * Tile format: MVT V2 gzipped (gzip recommended, but not mandatory) 20 | * SRS (data and tiles): EPSG:3857 (Web Mercator) 21 | 22 | Layer definition: 23 | 24 | | Name | Geom. type | Buffer | Simplify | Table | Attributes | Conditions | 25 | |--------------------|-----------------|--------|----------|---------------------------------------|--------------------|-----------------| 26 | | country | MULTIPOLYGON | 3 | yes | ne_10m_admin_0_countries | adm0_a3, mapcolor7 | min_zoom <= {z} | 27 | | country-name | POINT | 0 | no | ne_10m_admin_0_country_points | abbrev, name | - | 28 | | geo-lines (z=1..4) | MULTILINESTRING | 0 | no | ne_50m_geographic_lines | name | - | 29 | | geo-lines (z=5..6) | MULTILINESTRING | 0 | no | ne_10m_geographic_lines | name | - | 30 | | land-border-country| MULTILINESTRING | 0 | yes | ne_10m_admin_0_boundary_lines_land | - | min_zoom <= {z} | 31 | | state | MULTILINESTRING | 0 | yes | ne_10m_admin_1_states_provinces_lines | adm0_a3 | min_zoom <= {z} | 32 | 33 | 34 | Display style 35 | ------------- 36 | 37 | A reference Mapbox GL JS style for the produced tiles is [natural-earth-countries.json](maps/natural-earth-countries.json). 38 | 39 | Screenshot: 40 | 41 | ![natural-earth-countries](maps/style-screenshot.jpg) 42 | 43 | 44 | Run benchmark 45 | ------------- 46 | 47 | Requirements: 48 | * Make 49 | * Docker & docker-compose 50 | * gnuplot 51 | 52 | Quick benchmark: 53 | 54 | make quick_bench 55 | 56 | Full benchmark: 57 | 58 | make bench 59 | 60 | Graph: 61 | 62 | x-www-browser bench/results/*.jpg 63 | 64 | Display map: 65 | 66 | cd t-rex; make mapviewer 67 | 68 | or 69 | 70 | cd MapServer; make mapviewer 71 | 72 | Open http://localhost:8088/map-countries.html 73 | 74 | Avoid browser caching by using a private window in Firefox e.g. 75 | 76 | 77 | Add a new software 78 | ------------------ 79 | 80 | * Copy the skeletion directory to a new directory named after your software 81 | * Add a configuration for your software to create a tileset following the definition above 82 | * Adapt the Makefile or add a script to run the benchmarks with your software, using docker containters, if possible 83 | * Add calls to the project Makefile from the top level Makefile 84 | * Open a pull request on Github 85 | 86 | 87 | Reference database 88 | ------------------ 89 | 90 | The database can be started within a Docker container with 91 | 92 | docker-compose up -d mvtbenchdb 93 | 94 | PostgreSQL is running on Port 5432 within Docker and is mapped to `127.0.0.1:5439` on the Docker host. 95 | 96 | * DB user: `mvtbench` 97 | * DB password: `mvtbench` 98 | 99 | 100 | Connection example: 101 | 102 | PGPASSWORD=mvtbench psql -h 127.0.0.1 -p 5439 -U mvtbench 103 | 104 | 105 | Local DB Setup 106 | -------------- 107 | 108 | # Set Postgresql environment variables when needed: PGHOST, PGPORT, PGUSER, PGPASSWORD 109 | cd data 110 | make createdb 111 | 112 | Import GeoPackage with ogr2ogr: 113 | 114 | make gpkgrestore 115 | -------------------------------------------------------------------------------- /bench/httpbench.lua: -------------------------------------------------------------------------------- 1 | -- Resource: https://github.com/timotta/wrk-scripts/blob/master/multiplepaths.lua 2 | 3 | -- Initialize the pseudo random number generator 4 | -- Resource: http://lua-users.org/wiki/MathLibraryTutorial 5 | math.randomseed(os.time()) 6 | math.random(); math.random(); math.random() 7 | 8 | -- Shuffle array 9 | -- Returns a randomly shuffled array 10 | function shuffle(paths) 11 | local j, k 12 | local n = #paths 13 | 14 | for i = 1, n do 15 | j, k = math.random(n), math.random(n) 16 | paths[j], paths[k] = paths[k], paths[j] 17 | end 18 | 19 | return paths 20 | end 21 | 22 | -- Load URL paths from the file 23 | function load_url_paths_from_file(file) 24 | lines = {} 25 | 26 | -- Check if the file exists 27 | -- Resource: http://stackoverflow.com/a/4991602/325852 28 | local f=io.open(file,"r") 29 | if f~=nil then 30 | io.close(f) 31 | else 32 | -- Return the empty array 33 | return lines 34 | end 35 | 36 | -- If the file exists loop through all its lines 37 | -- and add them into the lines array 38 | for line in io.lines(file) do 39 | if not (line == '') then 40 | lines[#lines + 1] = line 41 | end 42 | end 43 | 44 | return shuffle(lines) 45 | end 46 | 47 | -- Load URL paths from file 48 | paths = load_url_paths_from_file("/paths.txt") 49 | 50 | -- Check if at least one path was found in the file 51 | if #paths <= 0 then 52 | print("multiplepaths: No paths found. You have to create a file paths.txt with one path per line") 53 | os.exit() 54 | end 55 | 56 | --print("multiplepaths: Found " .. #paths .. " paths") 57 | 58 | -- Initialize the paths array iterator 59 | counter = 0 60 | 61 | request = function() 62 | -- Get the next paths array element 63 | url_path = paths[counter] 64 | 65 | -- 66 | counter = counter + 1 67 | 68 | -- If the counter is longer than the paths array length then reset it 69 | if counter > #paths then 70 | counter = 0 71 | end 72 | 73 | -- Return the request object with the current URL path 74 | return wrk.format(nil, url_path) 75 | end 76 | 77 | 78 | done = function(summary, latency, requests) 79 | -- open output file 80 | local fn = "/bench/results/results_" .. os.getenv("CSV_NAME") 81 | local f = io.open(fn,"r") 82 | local newcsv = (f==nil) 83 | if f~=nil then 84 | io.close(f) 85 | end 86 | 87 | f = io.open(fn, "a+") 88 | if newcsv then 89 | f:write("#time_started,software,connections,min_requests,max_requests,mean_requests,min_latency,max_latency,mean_latency,stdev,50th,90th,99th,99.999th,duration,requests,bytes,request_per_sec,connect_errors,read_errors,write_errors,status_errors,timeouts\n") 90 | end 91 | f:write(string.format("%s,%s,%d,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%d,%d,%f,%d,%d,%d,%d,%d\n", 92 | os.date("!%Y-%m-%dT%TZ"), 93 | os.getenv("SW"), 94 | os.getenv("CONNECTIONS"), 95 | requests.min, -- per-thread request rate 96 | requests.max, 97 | requests.mean, 98 | latency.min, -- per-request latency 99 | latency.max, 100 | latency.mean, 101 | latency.stdev, 102 | 103 | latency:percentile(50), -- 50percentile latency 104 | latency:percentile(90), -- 90percentile latency 105 | latency:percentile(99), -- 99percentile latency 106 | latency:percentile(99.999), -- 99.999percentile latency 107 | 108 | summary["duration"], -- duration of the benchmark 109 | summary["requests"], -- total requests during the benchmark 110 | summary["bytes"], -- total received bytes during the benchmark 111 | 112 | summary["requests"]/(summary["duration"]/1000000), -- Total requests/sec 113 | 114 | summary["errors"]["connect"], -- total socket connection errors 115 | summary["errors"]["read"], -- total socket read errors 116 | summary["errors"]["write"], -- total socket write errors 117 | summary["errors"]["status"], -- total socket write errors 118 | summary["errors"]["timeout"] -- total request timeouts 119 | )) 120 | 121 | f:close() 122 | end 123 | -------------------------------------------------------------------------------- /bench/paths.txt: -------------------------------------------------------------------------------- 1 | /ne_countries/0/0/0.pbf 2 | /ne_countries/1/1/0.pbf 3 | /ne_countries/2/2/1.pbf 4 | /ne_countries/3/4/2.pbf 5 | /ne_countries/4/8/4.pbf 6 | /ne_countries/4/8/5.pbf 7 | /ne_countries/4/9/4.pbf 8 | /ne_countries/4/9/5.pbf 9 | /ne_countries/5/16/10.pbf 10 | /ne_countries/5/16/11.pbf 11 | /ne_countries/5/16/9.pbf 12 | /ne_countries/5/17/10.pbf 13 | /ne_countries/5/17/11.pbf 14 | /ne_countries/5/17/9.pbf 15 | /ne_countries/5/18/10.pbf 16 | /ne_countries/5/18/11.pbf 17 | /ne_countries/5/18/9.pbf 18 | /ne_countries/6/32/18.pbf 19 | /ne_countries/6/32/19.pbf 20 | /ne_countries/6/32/20.pbf 21 | /ne_countries/6/32/21.pbf 22 | /ne_countries/6/32/22.pbf 23 | /ne_countries/6/33/18.pbf 24 | /ne_countries/6/33/19.pbf 25 | /ne_countries/6/33/20.pbf 26 | /ne_countries/6/33/21.pbf 27 | /ne_countries/6/33/22.pbf 28 | /ne_countries/6/34/18.pbf 29 | /ne_countries/6/34/19.pbf 30 | /ne_countries/6/34/20.pbf 31 | /ne_countries/6/34/21.pbf 32 | /ne_countries/6/34/22.pbf 33 | /ne_countries/6/35/18.pbf 34 | /ne_countries/6/35/19.pbf 35 | /ne_countries/6/35/20.pbf 36 | /ne_countries/6/35/21.pbf 37 | /ne_countries/6/35/22.pbf 38 | /ne_countries/6/36/18.pbf 39 | /ne_countries/6/36/19.pbf 40 | /ne_countries/6/36/20.pbf 41 | /ne_countries/6/36/21.pbf 42 | /ne_countries/6/36/22.pbf 43 | /ne_countries/6/37/18.pbf 44 | /ne_countries/6/37/19.pbf 45 | /ne_countries/6/37/20.pbf 46 | /ne_countries/6/37/21.pbf 47 | /ne_countries/6/37/22.pbf 48 | -------------------------------------------------------------------------------- /bench/results/Makefile: -------------------------------------------------------------------------------- 1 | all: seed.jpg http.jpg 2 | 3 | quick: seed-quick.jpg http-quick.jpg 4 | 5 | seed.jpg: seed.g results_seed.csv results_seed_4.csv 6 | gnuplot seed.g 7 | 8 | seed-quick.jpg: seed-quick.g results_seed_region.csv results_seed_region_4.csv 9 | gnuplot seed-quick.g 10 | 11 | http.jpg: http.g results_http.csv 12 | gnuplot http.g 13 | 14 | http-quick.jpg: http-quick.g results_http_quick.csv 15 | gnuplot http-quick.g 16 | 17 | clean: 18 | rm -f *.csv 19 | -------------------------------------------------------------------------------- /bench/results/http-quick.g: -------------------------------------------------------------------------------- 1 | set terminal jpeg 2 | set output "http-quick.jpg" 3 | 4 | # Where to place the legend/key 5 | set key left top 6 | # Draw gridlines oriented on the y axis 7 | set grid y 8 | set ylabel "Requests/s" 9 | set logscale x 10 | set xlabel "Connections" 11 | set xtics (1,4,32,64,128,256) 12 | 13 | # Use CSV delimiter instead of spaces (default) 14 | set datafile separator ',' 15 | 16 | # graph title 17 | set title "Tile serving" 18 | plot for [i=0:*] "results_http_quick.csv" index i using 3:18 \ 19 | with linespoints title columnheader(2) 20 | -------------------------------------------------------------------------------- /bench/results/http.g: -------------------------------------------------------------------------------- 1 | set terminal jpeg 2 | set output "http.jpg" 3 | 4 | # Where to place the legend/key 5 | set key left top 6 | # Draw gridlines oriented on the y axis 7 | set grid y 8 | set ylabel "Requests/s" 9 | set logscale x 10 | set xlabel "Connections" 11 | set xtics (1,4,32,64,128,256) 12 | 13 | # Use CSV delimiter instead of spaces (default) 14 | set datafile separator ',' 15 | 16 | # graph title 17 | set title "Tile serving" 18 | plot for [i=0:*] "results_http.csv" index i using 3:18 \ 19 | with linespoints title columnheader(2) 20 | -------------------------------------------------------------------------------- /bench/results/seed-quick.g: -------------------------------------------------------------------------------- 1 | set terminal jpeg 2 | set output "seed-quick.jpg" 3 | 4 | set multiplot layout 2,1 5 | 6 | # Where to place the legend/key 7 | set key left top 8 | # Draw gridlines oriented on the y axis 9 | set grid y 10 | # Specify that the y-series data is time data 11 | set ydata time 12 | set yrange [0:] 13 | # Specify the *input* format of the time data 14 | set timefmt "%M:%S" 15 | # Specify the *output* format for the y-axis tick labels 16 | set format y "%.1tS" 17 | set xtics auto 18 | set ylabel "duration (s)" 19 | 20 | # Use CSV delimiter instead of spaces (default) 21 | set datafile separator ',' 22 | 23 | # graph title 24 | set title "seed region" 25 | unset key 26 | plot "results_seed_region.csv" using (1):3:(0):2 with boxplot 27 | 28 | set title "seed region 4 nodes" 29 | unset key 30 | plot "results_seed_region_4.csv" using (1):3:(0):2 with boxplot 31 | 32 | unset multiplot 33 | -------------------------------------------------------------------------------- /bench/results/seed.g: -------------------------------------------------------------------------------- 1 | set terminal jpeg 2 | set output "seed.jpg" 3 | 4 | set multiplot layout 2,1 5 | 6 | # Where to place the legend/key 7 | set key left top 8 | # Draw gridlines oriented on the y axis 9 | set grid y 10 | # Specify that the y-series data is time data 11 | set ydata time 12 | set yrange [0:] 13 | # Specify the *input* format of the time data 14 | set timefmt "%M:%S" 15 | # Specify the *output* format for the y-axis tick labels 16 | set format y "%.1tS" 17 | set xtics auto 18 | set ylabel "duration (s)" 19 | 20 | # Use CSV delimiter instead of spaces (default) 21 | set datafile separator ',' 22 | 23 | # graph title 24 | set title "seed" 25 | unset key 26 | plot "results_seed.csv" using (1):3:(0):2 with boxplot 27 | 28 | set title "seed 4 nodes" 29 | unset key 30 | plot "results_seed_4.csv" using (1):3:(0):2 with boxplot 31 | 32 | unset multiplot 33 | -------------------------------------------------------------------------------- /data/.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | packages 3 | -------------------------------------------------------------------------------- /data/Dockerfile: -------------------------------------------------------------------------------- 1 | # PostgreSQL/PostGIS database with benchmark data 2 | 3 | FROM postgis/postgis:16-3.4 4 | 5 | RUN apt-get update &&\ 6 | DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y make gdal-bin \ 7 | && apt-get clean \ 8 | && rm -rf /var/lib/apt/lists/* 9 | 10 | ENV POSTGRES_DB=mvtbench 11 | ENV POSTGRES_USER=mvtbench 12 | ENV POSTGRES_PASSWORD=mvtbench 13 | 14 | COPY ne_extracts_3857.gpkg Makefile / 15 | COPY setup-db.sh /docker-entrypoint-initdb.d/ 16 | -------------------------------------------------------------------------------- /data/Makefile: -------------------------------------------------------------------------------- 1 | DBNAME = mvtbench 2 | TAG = v1.2 3 | 4 | createdb: 5 | psql postgres -c "DROP DATABASE IF EXISTS $(DBNAME)" 6 | psql postgres -c "CREATE DATABASE $(DBNAME)" 7 | psql $(DBNAME) -c "CREATE EXTENSION postgis" 8 | 9 | gpkgrestore: 10 | ogr2ogr -lco GEOMETRY_NAME=wkb_geometry -f PostgreSQL PG:dbname=$(DBNAME) ne_extracts_3857.gpkg 11 | 12 | dockerbuild: 13 | docker build -t sourcepole/mvtbenchdb . 14 | docker tag sourcepole/mvtbenchdb sourcepole/mvtbenchdb:$(TAG) 15 | -------------------------------------------------------------------------------- /data/ne_extracts_3857.gpkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pka/mvt-benchmark/d5377063730e5b35a0daedfc852b579cbd125f3e/data/ne_extracts_3857.gpkg -------------------------------------------------------------------------------- /data/setup-db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | make gpkgrestore 5 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | mvtbenchdb: 4 | #build: 5 | # context: ./data 6 | image: sourcepole/mvtbenchdb:v1.2 7 | ports: 8 | - "127.0.0.1:5439:5432" 9 | 10 | t-rex: 11 | image: sourcepole/t-rex:v0.14.3 12 | ports: 13 | - "127.0.0.1:6767:6767" 14 | volumes: 15 | - ./t-rex:/var/data/in:ro 16 | - ./tiles:/var/data/tiles 17 | - ./maps:/var/data/maps:ro 18 | 19 | mapserver: 20 | # https://github.com/camptocamp/docker-mapserver/tree/7.2 21 | image: camptocamp/mapserver:latest 22 | user: www-data 23 | ports: 24 | - "127.0.0.1:8080:8080" 25 | volumes: 26 | - ./MapServer/ne.map:/etc/mapserver/mapserver.map:ro 27 | - ./MapServer/epsg:/usr/share/proj/epsg:ro 28 | 29 | mapcache: 30 | # https://github.com/camptocamp/docker-mapcache 31 | image: camptocamp/mapcache:latest 32 | user: www-data 33 | ports: 34 | - "127.0.0.1:6767:8080" 35 | volumes: 36 | - ./MapServer/mapcache_mvt.xml:/etc/mapcache/mapcache.xml:ro 37 | - ./tiles:/var/sig/tiles 38 | 39 | martin: 40 | image: urbica/martin:latest 41 | command: ["martin", "--config=/config.yaml"] 42 | ports: 43 | - "127.0.0.1:3000:3080" 44 | volumes: 45 | - ./martin/config.yaml:/config.yaml:ro 46 | 47 | gdal: 48 | image: osgeo/gdal:alpine-small-latest 49 | volumes: 50 | - ./tiles:/var/data/tiles 51 | # docker-compose run gdal ogrinfo -al -so /var/data/tiles/ne_countries/6/34/21.pbf 52 | 53 | nginx-t-rex: 54 | image: nginx:alpine 55 | ports: 56 | - "127.0.0.1:8088:80" 57 | volumes: 58 | - ./maps/nginx-server.conf:/etc/nginx/conf.d/default.conf:ro 59 | - ./maps:/usr/share/nginx/html:ro 60 | - ./maps/tilejson-t-rex.json:/data/tiles.json:ro 61 | - ./tiles:/data/tiles:ro 62 | # docker-compose up nginx 63 | # xdg-open http://localhost:8088/ 64 | 65 | nginx-ms: 66 | image: nginx:alpine 67 | ports: 68 | - "127.0.0.1:8088:80" 69 | volumes: 70 | - ./maps/nginx-server.conf:/etc/nginx/conf.d/default.conf:ro 71 | - ./maps:/usr/share/nginx/html:ro 72 | - ./maps/tilejson-ms.json:/data/tiles.json:ro 73 | - ./tiles:/data/tiles:ro 74 | -------------------------------------------------------------------------------- /maps/map-countries.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 |
16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /maps/natural-earth-countries.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 8, 3 | "name": "natural-earth-countries", 4 | "metadata": { 5 | "mapbox:autocomposite": false, 6 | "mapbox:type": "template", 7 | "maputnik:renderer": "mbgljs" 8 | }, 9 | "center": [ 10 | 8.3221, 11 | 46.5928 12 | ], 13 | "zoom": 1, 14 | "bearing": 0, 15 | "pitch": 0, 16 | "sources": { 17 | "countries": { 18 | "type": "vector", 19 | "url": "/tiles.json" 20 | } 21 | }, 22 | "glyphs": "https://go-spatial.github.io/carto-assets/fonts/{fontstack}/{range}.pbf", 23 | "layers": [{ 24 | "id": "background", 25 | "type": "background", 26 | "paint": { 27 | "background-color": "#ddeeff" 28 | } 29 | },{ 30 | "id": "country-glow-outer", 31 | "type": "line", 32 | "source": "countries", 33 | "source-layer": "country", 34 | "layout": { 35 | "line-join":"round" 36 | }, 37 | "paint": { 38 | "line-color": "#226688", 39 | "line-width": 5, 40 | "line-opacity": { 41 | "stops": [[0,0],[1,0.1]] 42 | } 43 | } 44 | },{ 45 | "id": "country-glow-inner", 46 | "type": "line", 47 | "source": "countries", 48 | "source-layer": "country", 49 | "layout": { 50 | "line-join":"round" 51 | }, 52 | "paint": { 53 | "line-color": "#226688", 54 | "line-width": { 55 | "stops": [[0,1.2],[1,1.6],[2,2],[3,2.4]] 56 | }, 57 | "line-opacity": 0.8 58 | } 59 | },{ 60 | "id": "country-fill", 61 | "type": "fill", 62 | "source": "countries", 63 | "source-layer": "country", 64 | "paint": { 65 | "fill-color": { 66 | "property": "mapcolor7", 67 | "stops": [ 68 | [1, "#fdaf6b"], 69 | [2, "#fdc663"], 70 | [3, "#fae364"], 71 | [4, "#d3e46f"], 72 | [5, "#aadb78"], 73 | [6, "#a3cec5"], 74 | [7, "#ceb5cf"] 75 | ] 76 | } 77 | } 78 | },{ 79 | "id": "country-fill-special", 80 | "type": "fill", 81 | "source": "countries", 82 | "source-layer": "country", 83 | "filter":["in","adm0_a3","ATA"], 84 | "paint": { 85 | "fill-color": { 86 | "property": "adm0_a3", 87 | "type": "categorical", 88 | "stops": [ 89 | ["ATA", "#F0F8FF"] 90 | ] 91 | } 92 | } 93 | },{ 94 | "id": "geo-lines", 95 | "type": "line", 96 | "source": "countries", 97 | "source-layer": "geo-lines", 98 | "paint": { 99 | "line-color": "#226688", 100 | "line-width": { 101 | "stops": [[0,0.2],[4,1]] 102 | }, 103 | "line-dasharray":[6,2] 104 | } 105 | },{ 106 | "id": "land-border-country", 107 | "type": "line", 108 | "source": "countries", 109 | "source-layer": "land-border-country", 110 | "paint": { 111 | "line-color": "#fff", 112 | "line-width": { 113 | "base":1.5, 114 | "stops": [[0,0],[1,0.8],[2,1]] 115 | } 116 | } 117 | },{ 118 | "id": "state", 119 | "type": "line", 120 | "source": "countries", 121 | "source-layer": "state", 122 | "minzoom": 3, 123 | "filter": ["in","adm0_a3","USA","CAN","AUS"], 124 | "paint": { 125 | "line-color": "#226688", 126 | "line-opacity": 0.25, 127 | "line-dasharray":[6,2,2,2], 128 | "line-width": 1.2 129 | } 130 | },{ 131 | "id": "country-abbrev", 132 | "type": "symbol", 133 | "source": "countries", 134 | "source-layer": "country-name", 135 | "minzoom":1.8, 136 | "maxzoom":3, 137 | "layout": { 138 | "text-field": ["get", "abbrev"], 139 | "text-transform": "uppercase", 140 | "text-max-width": 20, 141 | "text-size": { 142 | "stops": [[3,10],[4,11],[5,12],[6,16]] 143 | }, 144 | "text-letter-spacing": { 145 | "stops": [[4,0],[5,1],[6,2]] 146 | }, 147 | "text-line-height": { 148 | "stops": [[5,1.2],[6,2]] 149 | } 150 | }, 151 | "paint": { 152 | "text-halo-color": "#fff", 153 | "text-halo-width": 1.5 154 | } 155 | },{ 156 | "id": "country-name", 157 | "type": "symbol", 158 | "source": "countries", 159 | "source-layer": "country-name", 160 | "minzoom":3, 161 | "layout": { 162 | "text-field": ["get", "name"], 163 | "text-transform": "uppercase", 164 | "text-max-width": 20, 165 | "text-size": { 166 | "stops": [[3,10],[4,11],[5,12],[6,16]] 167 | } 168 | }, 169 | "paint": { 170 | "text-halo-color": "#fff", 171 | "text-halo-width": 1.5 172 | } 173 | },{ 174 | "id": "geo-lines-lables", 175 | "type": "symbol", 176 | "source": "countries", 177 | "source-layer": "geo-lines", 178 | "layout": { 179 | "text-field": ["get", "name"], 180 | "text-offset": [0,1], 181 | "symbol-placement": "line", 182 | "symbol-spacing": 600, 183 | "text-size": 9 184 | }, 185 | "paint": { 186 | "text-color": "#226688", 187 | "text-halo-width": 1.5 188 | } 189 | }] 190 | } 191 | -------------------------------------------------------------------------------- /maps/nginx-server.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name localhost; 4 | 5 | #charset koi8-r; 6 | #access_log /var/log/nginx/host.access.log main; 7 | 8 | location / { 9 | root /usr/share/nginx/html; 10 | index index.html index.htm; 11 | } 12 | 13 | #error_page 404 /404.html; 14 | 15 | # redirect server error pages to the static page /50x.html 16 | # 17 | error_page 500 502 503 504 /50x.html; 18 | location = /50x.html { 19 | root /usr/share/nginx/html; 20 | } 21 | 22 | location = /tiles.json { 23 | root /data; 24 | } 25 | 26 | location ~ /tiles/.+pbf$ { 27 | root /data; 28 | try_files $uri =204; 29 | 30 | # gzip Encoding and MIME type type 31 | add_header Content-Encoding gzip; 32 | gzip off; 33 | types { application/x-protobuf pbf; } 34 | } 35 | 36 | location ~ /tiles/.+mvt$ { 37 | root /data; 38 | try_files $uri =204; 39 | 40 | types { application/x-protobuf pbf; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /maps/style-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pka/mvt-benchmark/d5377063730e5b35a0daedfc852b579cbd125f3e/maps/style-screenshot.jpg -------------------------------------------------------------------------------- /maps/tilejson-ms.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Natural Earth v4", 3 | "basename": "ne_countries", 4 | "bounds": [ 5 | -179.97277, 6 | -83.05457, 7 | 179.99366, 8 | 83.23559 9 | ], 10 | "center": [ 11 | 0.010445000000004256, 12 | 0.09050999999999476, 13 | 2 14 | ], 15 | "description": "ne_countries", 16 | "format": "pbf", 17 | "id": "ne_countries", 18 | "maxzoom": 6, 19 | "minzoom": 0, 20 | "name": "ne_countries", 21 | "scheme": "xyz", 22 | "tiles": [ 23 | "http://localhost:8088/tiles/ms_mvt/{z}/{x}/{y}.mvt" 24 | ], 25 | "vector_layers": [ 26 | { 27 | "description": "", 28 | "fields": { 29 | "adm0_a3": "", 30 | "mapcolor7": "" 31 | }, 32 | "id": "country", 33 | "maxzoom": 6, 34 | "minzoom": 0 35 | }, 36 | { 37 | "description": "", 38 | "fields": { 39 | "abbrev": "", 40 | "name": "" 41 | }, 42 | "id": "country-name", 43 | "maxzoom": 6, 44 | "minzoom": 0 45 | }, 46 | { 47 | "description": "", 48 | "fields": { 49 | "name": "" 50 | }, 51 | "id": "geo-lines", 52 | "maxzoom": 6, 53 | "minzoom": 1 54 | }, 55 | { 56 | "description": "", 57 | "fields": {}, 58 | "id": "land-border-country", 59 | "maxzoom": 6, 60 | "minzoom": 0 61 | }, 62 | { 63 | "description": "", 64 | "fields": { 65 | "adm0_a3": "" 66 | }, 67 | "id": "state", 68 | "maxzoom": 6, 69 | "minzoom": 0 70 | } 71 | ], 72 | "version": "2.0.0" 73 | } 74 | -------------------------------------------------------------------------------- /maps/tilejson-t-rex.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Natural Earth v4", 3 | "basename": "ne_countries", 4 | "bounds": [ 5 | -179.97277, 6 | -83.05457, 7 | 179.99366, 8 | 83.23559 9 | ], 10 | "center": [ 11 | 0.010445000000004256, 12 | 0.09050999999999476, 13 | 2 14 | ], 15 | "description": "ne_countries", 16 | "format": "pbf", 17 | "id": "ne_countries", 18 | "maxzoom": 6, 19 | "minzoom": 0, 20 | "name": "ne_countries", 21 | "scheme": "xyz", 22 | "tiles": [ 23 | "http://localhost:8088/tiles/ne_countries/{z}/{x}/{y}.pbf" 24 | ], 25 | "vector_layers": [ 26 | { 27 | "description": "", 28 | "fields": { 29 | "adm0_a3": "", 30 | "mapcolor7": "" 31 | }, 32 | "id": "country", 33 | "maxzoom": 6, 34 | "minzoom": 0 35 | }, 36 | { 37 | "description": "", 38 | "fields": { 39 | "abbrev": "", 40 | "name": "" 41 | }, 42 | "id": "country-name", 43 | "maxzoom": 6, 44 | "minzoom": 0 45 | }, 46 | { 47 | "description": "", 48 | "fields": { 49 | "name": "" 50 | }, 51 | "id": "geo-lines", 52 | "maxzoom": 6, 53 | "minzoom": 1 54 | }, 55 | { 56 | "description": "", 57 | "fields": {}, 58 | "id": "land-border-country", 59 | "maxzoom": 6, 60 | "minzoom": 0 61 | }, 62 | { 63 | "description": "", 64 | "fields": { 65 | "adm0_a3": "" 66 | }, 67 | "id": "state", 68 | "maxzoom": 6, 69 | "minzoom": 0 70 | } 71 | ], 72 | "version": "2.0.0" 73 | } 74 | -------------------------------------------------------------------------------- /martin/Makefile: -------------------------------------------------------------------------------- 1 | sw = martin 2 | exec = docker-compose run --rm martin 3 | result_prefix = ../bench/results/results_ 4 | ts = $(shell date '+%Y-%m-%dT%TZ') 5 | region_bbox = 5.361328,45.336702,30.058594,58.950008 6 | tilecache = ../tiles 7 | 8 | quick_bench: 9 | # Start Database 10 | make data_ready 11 | # Cleanup tile cache 12 | # 13 | # Run benchmarks within $(region_bbox) on one processor 14 | # Append the measured time to ../bench/results/results_seed_region.csv 15 | # Cleanup tile cache 16 | # Run benchmarks within $(region_bbox) on 4 processors 17 | # Append the measured time to ../bench/results/results_seed_region_4.csv 18 | # 19 | # Run tile serving benchmarks with seeded tile cache 20 | # 21 | # Cleanup tile cache 22 | # Stop Database 23 | 24 | bench: 25 | # Start Database 26 | make data_ready 27 | # Clean tile cache 28 | # 29 | # Run benchmarks on one processor 30 | # Append the measured time to ../bench/results/results_seed.csv 31 | # Clean tile cache 32 | # Run benchmarks on 4 processors 33 | # Append the measured time to ../bench/results/results_seed_4.csv 34 | # 35 | # Run tile serving benchmarks with seeded tile cache 36 | # 37 | # Cleanup tile cache 38 | # Stop Database 39 | 40 | # Seeding benchmark example/skeleton targets 41 | 42 | data_ready: 43 | docker-compose up -d mvtbenchdb 44 | 45 | data_teardown: 46 | docker-compose stop mvtbenchdb 47 | 48 | bench_seed: $(result_prefix)seed.csv 49 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< [execution parameters] 50 | @echo Statistics written to $< 51 | 52 | # Tile serving benchmark example/skeleton targets 53 | 54 | mvtserver_ready: data_ready 55 | # Run MVT server listening on http://127.0.0.1:6767 56 | docker-compose run -p 127.0.0.1:6767:6767 --rm [...] 57 | 58 | mvtserver_teardown: 59 | docker stop [...] 60 | 61 | csv = http.csv 62 | wkr_cmd = docker run --rm --user=$$UID --net=host -e SW="$(sw)" -e CSV_NAME=$(csv) -e CONNECTIONS=[CONN] -v $$PWD/../bench:/bench williamyeh/wrk -v $$PWD/../bench/paths.txt:/paths.txt:ro -H 'Accept-Encoding: gzip' -H 'Connection: keep-alive' 63 | duration = 20 64 | 65 | bench_http: 66 | @# From first entry only title is displayed on plot 67 | $(wkr_cmd:[CONN]=1) --latency -d 1 -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 68 | $(wkr_cmd:[CONN]=1) --latency -d $(duration) -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 69 | $(wkr_cmd:[CONN]=4) --latency -d $(duration) -c 4 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 70 | $(wkr_cmd:[CONN]=32) --latency -d $(duration) -c 32 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 71 | $(wkr_cmd:[CONN]=64) --latency -d $(duration) -c 64 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 72 | $(wkr_cmd:[CONN]=128) --latency -d $(duration) -c 128 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 73 | $(wkr_cmd:[CONN]=256) --latency -d $(duration) -c 256 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 74 | @echo >>$(result_prefix)${csv} 75 | @echo >>$(result_prefix)${csv} 76 | @echo Statistics written to $(result_prefix)${csv} 77 | 78 | # Helpers 79 | 80 | $(result_prefix)seed.csv: 81 | echo "#time_started,software,real,user,sys" >$@ 82 | 83 | $(result_prefix)seed_4.csv: 84 | echo "#time_started,software,real,user,sys" >$@ 85 | 86 | $(result_prefix)seed_region.csv: 87 | echo "#time_started,software,real,user,sys" >$@ 88 | 89 | $(result_prefix)seed_region_4.csv: 90 | echo "#time_started,software,real,user,sys" >$@ 91 | -------------------------------------------------------------------------------- /martin/README.md: -------------------------------------------------------------------------------- 1 | Software name 2 | ============= 3 | 4 | * Homepage: 5 | * Source repository: 6 | * Tested with version: 7 | -------------------------------------------------------------------------------- /martin/config.yaml: -------------------------------------------------------------------------------- 1 | # Database connection string 2 | connection_string: 'postgresql://mvtbench:mvtbench@mvtbenchdb/mvtbench' 3 | 4 | # Maximum connections pool size [default: 20] 5 | pool_size: 20 6 | 7 | # Connection keep alive timeout [default: 75] 8 | keep_alive: 75 9 | 10 | # Number of web server workers 11 | worker_processes: 8 12 | 13 | # The socket address to bind [default: 0.0.0.0:3000] 14 | listen_addresses: '0.0.0.0:3000' 15 | 16 | # Enable watch mode 17 | watch: true 18 | 19 | # associative arrays of table sources 20 | table_sources: 21 | public.table_source: 22 | # table source id 23 | id: public.table_source 24 | 25 | # table schema 26 | schema: public 27 | 28 | # table name 29 | table: table_source 30 | 31 | # geometry column name 32 | geometry_column: geom 33 | 34 | # geometry srid 35 | srid: 4326 36 | 37 | # tile extent in tile coordinate space 38 | extent: 4096 39 | 40 | # buffer distance in tile coordinate space to optionally clip geometries 41 | buffer: 64 42 | 43 | # boolean to control if geometries should be clipped or encoded as is 44 | clip_geom: true 45 | 46 | # geometry type 47 | geometry_type: GEOMETRY 48 | 49 | # list of columns, that should be encoded as a tile properties 50 | properties: 51 | gid: int4 52 | 53 | # associative arrays of function sources 54 | function_sources: 55 | public.function_source: 56 | # function source id 57 | id: public.function_source 58 | 59 | # schema name 60 | schema: public 61 | 62 | # function name 63 | function: function_source -------------------------------------------------------------------------------- /t-rex/Makefile: -------------------------------------------------------------------------------- 1 | sw = t-rex 2 | exec = docker-compose run --rm t-rex 3 | result_prefix = ../bench/results/results_ 4 | ts = $(shell date '+%Y-%m-%dT%TZ') 5 | region_bbox = 5.361328,45.336702,30.058594,58.950008 6 | tilecache = ../tiles 7 | 8 | quick_bench: 9 | # Seeding benchmarks 10 | make data_ready clean_tilecache 11 | make bench_seed_region tile_stats clean_tilecache 12 | make bench_seed_region_4 tile_stats 13 | # Tile serving benchmarks (with seeded tilecache) 14 | make mvtserver_teardown 15 | make mvtserver_ready bench_http duration=5 csv=http_quick.csv mvtserver_teardown 16 | make data_teardown 17 | 18 | bench: 19 | # Seeding benchmarks 20 | make data_ready clean_tilecache 21 | make bench_seed tile_stats clean_tilecache 22 | make bench_seed_4 tile_stats 23 | # Tile serving benchmarks (with seeded tilecache) 24 | make mvtserver_teardown 25 | make mvtserver_ready bench_http mvtserver_teardown 26 | make data_teardown 27 | 28 | mapviewer: 29 | docker-compose up nginx-t-rex 30 | # Open viewer at http://localhost:8088/map-countries.html 31 | 32 | # Optional benchmarks 33 | 34 | t_rex_0_8_2_quick: /tmp/t-rex-v0.8.2-x86_64-unknown-linux-gnu.deb 35 | # Seeding benchmarks 36 | make data_ready clean_tilecache 37 | TREX_DATASOURCE_URL=postgresql://mvtbench:mvtbench@127.0.0.1:5439/mvtbench make bench_seed_region exec=/usr/bin/t_rex sw="t-rex 0.8.2" tile_stats 38 | rm -rf $(tilecache)/ne_countries 39 | TREX_DATASOURCE_URL=postgresql://mvtbench:mvtbench@127.0.0.1:5439/mvtbench make bench_seed_region_4 exec=/usr/bin/t_rex sw="t-rex 0.8.2" tile_stats 40 | # Tile serving benchmarks (with seeded tilecache) 41 | make data_ready 42 | RUST_LOG=error TREX_DATASOURCE_URL=postgresql://mvtbench:mvtbench@127.0.0.1:5439/mvtbench /usr/bin/t_rex serve --config mvtbench.toml --openbrowser false & 43 | make bench_http sw="t-rex 0.8.2" duration=5 csv=http_quick.csv 44 | sleep 3 45 | make data_teardown 46 | rm -rf $(tilecache)/ne_countries 47 | 48 | t_rex_0_8_2: /tmp/t-rex-v0.8.2-x86_64-unknown-linux-gnu.deb 49 | # Seeding benchmarks 50 | make data_ready clean_tilecache 51 | TREX_DATASOURCE_URL=postgresql://mvtbench:mvtbench@127.0.0.1:5439/mvtbench make bench_seed exec=/usr/bin/t_rex sw="t-rex 0.8.2" tile_stats 52 | rm -rf $(tilecache)/ne_countries 53 | TREX_DATASOURCE_URL=postgresql://mvtbench:mvtbench@127.0.0.1:5439/mvtbench make bench_seed_4 exec=/usr/bin/t_rex sw="t-rex 0.8.2" tile_stats 54 | # Tile serving benchmarks (with seeded tilecache) 55 | make data_ready 56 | RUST_LOG=error TREX_DATASOURCE_URL=postgresql://mvtbench:mvtbench@127.0.0.1:5439/mvtbench /usr/bin/t_rex serve --config mvtbench.toml --openbrowser false & 57 | make bench_http sw="t-rex 0.8.2" 58 | sleep 3 59 | make data_teardown 60 | rm -rf $(tilecache)/ne_countries 61 | 62 | /tmp/t-rex-v0.8.2-x86_64-unknown-linux-gnu.deb: 63 | cd /tmp && curl -O -L https://github.com/t-rex-tileserver/t-rex/releases/download/v0.8.2/t-rex-v0.8.2-x86_64-unknown-linux-gnu.deb && sudo dpkg -i t-rex-v0.8.2-x86_64-unknown-linux-gnu.deb 64 | 65 | # Seeding benchmarks 66 | 67 | data_ready: 68 | docker-compose up -d mvtbenchdb 69 | 70 | data_teardown: 71 | docker-compose stop mvtbenchdb 72 | 73 | bench_seed: $(result_prefix)seed.csv 74 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< $(exec) generate --config mvtbench.toml --maxzoom=6 75 | @echo Statistics written to $< 76 | 77 | bench_seed_4: $(result_prefix)seed_4.csv 78 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< sh -c '$(exec:t-rex=--name t_rex_0 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=0 & \ 79 | $(exec:t-rex=--name t_rex_1 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=1 & \ 80 | $(exec:t-rex=--name t_rex_2 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=2 & \ 81 | $(exec:t-rex=--name t_rex_3 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=3' 82 | @echo Statistics written to $< 83 | 84 | # Tile serving benchmarks 85 | 86 | mvtserver_exec = docker-compose run -p 127.0.0.1:6767:6767 --rm --name=t_rex_serve -d t-rex 87 | 88 | mvtserver_ready: data_ready 89 | $(mvtserver_exec) serve --config mvtbench.toml --loglevel error --openbrowser false 90 | 91 | mvtserver_teardown: 92 | docker stop t_rex_serve || true 93 | docker rm t_rex_serve || true 94 | 95 | csv = http.csv 96 | wkr_cmd = docker run --rm --user=$$UID --net=host -e SW="$(sw)" -e CSV_NAME=$(csv) -e CONNECTIONS=[CONN] -v $$PWD/../bench:/bench -v $$PWD/../bench/paths.txt:/paths.txt:ro williamyeh/wrk -H 'Accept-Encoding: gzip' -H 'Connection: keep-alive' 97 | duration = 20 98 | 99 | bench_http: 100 | @# From first entry only title is displayed on plot 101 | $(wkr_cmd:[CONN]=1) --latency -d 1 -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 102 | $(wkr_cmd:[CONN]=1) --latency -d $(duration) -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 103 | $(wkr_cmd:[CONN]=4) --latency -d $(duration) -c 4 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 104 | $(wkr_cmd:[CONN]=32) --latency -d $(duration) -c 32 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 105 | $(wkr_cmd:[CONN]=64) --latency -d $(duration) -c 64 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 106 | $(wkr_cmd:[CONN]=128) --latency -d $(duration) -c 128 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 107 | $(wkr_cmd:[CONN]=256) --latency -d $(duration) -c 256 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 108 | @echo >>$(result_prefix)${csv} 109 | @echo >>$(result_prefix)${csv} 110 | @echo Statistics written to $(result_prefix)${csv} 111 | 112 | # Quick benchmarks 113 | 114 | bench_seed_region: $(result_prefix)seed_region.csv 115 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< $(exec) generate --config mvtbench.toml --maxzoom=6 --extent=$(region_bbox) 116 | @echo Statistics written to result_$@.csv 117 | 118 | bench_seed_region_4: $(result_prefix)seed_region_4.csv 119 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< sh -c '$(exec:t-rex=--name t_rex_0 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=0 --extent=$(region_bbox) & \ 120 | $(exec:t-rex=--name t_rex_1 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=1 --extent=$(region_bbox) & \ 121 | $(exec:t-rex=--name t_rex_2 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=2 --extent=$(region_bbox) & \ 122 | $(exec:t-rex=--name t_rex_3 t-rex) generate --config mvtbench.toml --maxzoom=6 --progress=false --nodes=4 --nodeno=3 --extent=$(region_bbox)' 123 | @echo Statistics written to $< 124 | 125 | # Helpers 126 | 127 | $(result_prefix)seed.csv: 128 | echo "#time_started,software,real,user,sys" >$@ 129 | 130 | $(result_prefix)seed_4.csv: 131 | echo "#time_started,software,real,user,sys" >$@ 132 | 133 | $(result_prefix)seed_region.csv: 134 | echo "#time_started,software,real,user,sys" >$@ 135 | 136 | $(result_prefix)seed_region_4.csv: 137 | echo "#time_started,software,real,user,sys" >$@ 138 | 139 | tile_stats: 140 | find $(tilecache) -name '*pbf' | wc -l 141 | du -s $(tilecache) 142 | docker-compose run gdal ogrinfo -al -so /var/data/tiles/ne_countries/6/34/21.pbf 143 | 144 | clean_tilecache: 145 | @# Delete files as user www-data 146 | docker-compose run --rm --entrypoint /bin/rm t-rex "-rf" "$(tilecache)/ne_countries" 147 | -------------------------------------------------------------------------------- /t-rex/README.md: -------------------------------------------------------------------------------- 1 | t-rex 2 | ===== 3 | 4 | * Homepage: https://t-rex.tileserver.ch/ 5 | * Source repository: https://github.com/t-rex-tileserver/t-rex 6 | -------------------------------------------------------------------------------- /t-rex/map-countries.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 |
16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /t-rex/mvtbench.toml: -------------------------------------------------------------------------------- 1 | # t-rex configuration for mvtbench 2 | 3 | [service.mvt] 4 | viewer = true 5 | 6 | [[datasource]] 7 | dbconn = "postgresql://mvtbench:mvtbench@mvtbenchdb/mvtbench" 8 | name = "pg" 9 | default = true 10 | 11 | [grid] 12 | predefined = "web_mercator" 13 | 14 | [[tileset]] 15 | name = "ne_countries" 16 | attribution = "Natural Earth v4" 17 | extent = [-179.97277, -83.05457, 179.99366, 83.23559] 18 | minzoom = 0 19 | maxzoom = 6 20 | 21 | [[tileset.layer]] 22 | name = "country" 23 | geometry_field = "wkb_geometry" 24 | geometry_type = "MULTIPOLYGON" 25 | srid = 3857 26 | buffer_size = 3 27 | simplify = true 28 | [[tileset.layer.query]] 29 | sql = """SELECT wkb_geometry, adm0_a3, mapcolor7 FROM ne_10m_admin_0_countries WHERE min_zoom::integer <= !zoom! AND wkb_geometry && !bbox!""" 30 | 31 | [[tileset.layer]] 32 | name = "country-name" 33 | geometry_field = "wkb_geometry" 34 | geometry_type = "POINT" 35 | srid = 3857 36 | buffer_size = 0 37 | [[tileset.layer.query]] 38 | sql = """SELECT wkb_geometry, abbrev, name FROM ne_10m_admin_0_country_points""" 39 | 40 | [[tileset.layer]] 41 | name = "geo-lines" 42 | geometry_field = "wkb_geometry" 43 | geometry_type = "MULTILINESTRING" 44 | srid = 3857 45 | buffer_size = 0 46 | simplify = false 47 | [[tileset.layer.query]] 48 | # ne_50m_geographic_lines 49 | minzoom = 1 50 | maxzoom = 4 51 | sql = """SELECT wkb_geometry, name FROM ne_50m_geographic_lines""" 52 | [[tileset.layer.query]] 53 | # ne_10m_geographic_lines 54 | minzoom = 5 55 | sql = """SELECT wkb_geometry, name FROM ne_10m_geographic_lines""" 56 | 57 | [[tileset.layer]] 58 | name = "land-border-country" 59 | geometry_field = "wkb_geometry" 60 | geometry_type = "MULTILINESTRING" 61 | fid_field = "ogc_fid" 62 | srid = 3857 63 | buffer_size = 0 64 | simplify = true 65 | [[tileset.layer.query]] 66 | # ne_10m_admin_0_boundary_lines_land 67 | sql = """SELECT wkb_geometry FROM ne_10m_admin_0_boundary_lines_land WHERE min_zoom::integer <= !zoom! AND wkb_geometry && !bbox!""" 68 | 69 | [[tileset.layer]] 70 | name = "state" 71 | geometry_field = "wkb_geometry" 72 | geometry_type = "MULTILINESTRING" 73 | srid = 3857 74 | buffer_size = 0 75 | simplify = true 76 | [[tileset.layer.query]] 77 | sql = """SELECT wkb_geometry, adm0_a3 FROM ne_10m_admin_1_states_provinces_lines WHERE min_zoom::integer <= !zoom! AND wkb_geometry && !bbox!""" 78 | 79 | [cache.file] 80 | base = "../tiles" 81 | baseurl = "http://example.com/tiles" 82 | 83 | [webserver] 84 | bind = "0.0.0.0" 85 | port = 6767 86 | threads = 4 87 | #cache_control_max_age = 43200 88 | 89 | [[webserver.static]] 90 | path = "/map" 91 | dir = "../maps/" 92 | -------------------------------------------------------------------------------- /template/Makefile: -------------------------------------------------------------------------------- 1 | sw = software-name 2 | exec = docker-compose run ... 3 | result_prefix = ../bench/results/results_ 4 | ts = $(shell date '+%Y-%m-%dT%TZ') 5 | region_bbox = 5.361328,45.336702,30.058594,58.950008 6 | tilecache = ../tiles 7 | 8 | quick_bench: 9 | # Start Database 10 | # Cleanup tile cache 11 | # 12 | # Run benchmarks within $(region_bbox) on one processor 13 | # Append the measured time to ../bench/results/results_seed_region.csv 14 | # Cleanup tile cache 15 | # Run benchmarks within $(region_bbox) on 4 processors 16 | # Append the measured time to ../bench/results/results_seed_region_4.csv 17 | # 18 | # Run tile serving benchmarks with seeded tile cache 19 | # 20 | # Cleanup tile cache 21 | # Stop Database 22 | 23 | bench: 24 | # Start Database 25 | # Clean tile cache 26 | # 27 | # Run benchmarks on one processor 28 | # Append the measured time to ../bench/results/results_seed.csv 29 | # Clean tile cache 30 | # Run benchmarks on 4 processors 31 | # Append the measured time to ../bench/results/results_seed_4.csv 32 | # 33 | # Run tile serving benchmarks with seeded tile cache 34 | # 35 | # Cleanup tile cache 36 | # Stop Database 37 | 38 | view_map: 39 | # docker-compose up nginx-$sw 40 | # Open viewer at http://localhost:8088/map-countries.html 41 | 42 | # Seeding benchmark example/skeleton targets 43 | 44 | data_ready: 45 | docker-compose up -d mvtbenchdb 46 | 47 | data_teardown: 48 | docker-compose stop mvtbenchdb 49 | 50 | bench_seed: $(result_prefix)seed.csv 51 | time -f "$(ts),$(sw),%E,%U,%S" -a -o $< [execution parameters] 52 | @echo Statistics written to $< 53 | 54 | # Tile serving benchmark example/skeleton targets 55 | 56 | mvtserver_ready: data_ready 57 | # Run MVT server listening on http://127.0.0.1:6767 58 | docker-compose run -p 127.0.0.1:6767:6767 --rm [...] 59 | 60 | mvtserver_teardown: 61 | docker stop [...] 62 | 63 | csv = http.csv 64 | wkr_cmd = docker run --rm --user=$$UID --net=host -e SW="$(sw)" -e CSV_NAME=$(csv) -e CONNECTIONS=[CONN] -v $$PWD/../bench:/bench williamyeh/wrk -v $$PWD/../bench/paths.txt:/paths.txt:ro -H 'Accept-Encoding: gzip' -H 'Connection: keep-alive' 65 | duration = 20 66 | 67 | bench_http: 68 | @# From first entry only title is displayed on plot 69 | $(wkr_cmd:[CONN]=1) --latency -d 1 -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 70 | $(wkr_cmd:[CONN]=1) --latency -d $(duration) -c 1 --timeout 8 -t 1 -s /bench/httpbench.lua http://127.0.0.1:6767 71 | $(wkr_cmd:[CONN]=4) --latency -d $(duration) -c 4 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 72 | $(wkr_cmd:[CONN]=32) --latency -d $(duration) -c 32 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 73 | $(wkr_cmd:[CONN]=64) --latency -d $(duration) -c 64 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 74 | $(wkr_cmd:[CONN]=128) --latency -d $(duration) -c 128 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 75 | $(wkr_cmd:[CONN]=256) --latency -d $(duration) -c 256 --timeout 8 -t 4 -s /bench/httpbench.lua http://127.0.0.1:6767 76 | @echo >>$(result_prefix)${csv} 77 | @echo >>$(result_prefix)${csv} 78 | @echo Statistics written to $(result_prefix)${csv} 79 | 80 | # Helpers 81 | 82 | $(result_prefix)seed.csv: 83 | echo "#time_started,software,real,user,sys" >$@ 84 | 85 | $(result_prefix)seed_4.csv: 86 | echo "#time_started,software,real,user,sys" >$@ 87 | 88 | $(result_prefix)seed_region.csv: 89 | echo "#time_started,software,real,user,sys" >$@ 90 | 91 | $(result_prefix)seed_region_4.csv: 92 | echo "#time_started,software,real,user,sys" >$@ 93 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | Software name 2 | ============= 3 | 4 | * Homepage: 5 | * Source repository: 6 | -------------------------------------------------------------------------------- /tiles/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | --------------------------------------------------------------------------------