Offline-capable geomap, meant for storing location bookmarks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: update icon and docs

+30 -1769
+1
.gitignore
··· 2 2 .DS_Store 3 3 dist 4 4 data/osm 5 + data/shapefiles
-2
README.md
··· 8 8 - User can download regional maps via the app 9 9 - Downloaded maps are displayed offline, and overlay the world basemap 10 10 11 - ![screenshot](./docs/screenshot.png) 12 - 13 11 ## Technologies for App 14 12 15 13 - **[civility](https://jsr.io/@civility)**: PWA build system and service worker framework used to bundle the app and manage offline caching
+5 -1
civility.json
··· 3 3 "type": "pwa", 4 4 "root": "./www", 5 5 "outdir": "./www/dist", 6 - "static": "./www/static" 6 + "static": "./www/static", 7 + "icon": { 8 + "source": "./www/static/brand/icon.png", 9 + "output": "./www/dist/icons" 10 + } 7 11 }
-20
docs/README.md
··· 1 - # Docs 2 - 3 - This dir holds some auxillary information and scripts for the project. 4 - 5 - ## geofabrik 6 - 7 - Basically, to fully realize a project like this, we will need scripts to organize the different downloadable regions, and also to find the urls for us to download. This doesn't include region naming/localization, so maybe need to figure that out later. 8 - 9 - The files we need are: 10 - 11 - 1. `[insert-region]-latest.osm.pbf`: map data 12 - 2. `[insert-region].poly`: the borders of each region 13 - 14 - ## tilemaker 15 - 16 - We want tilemaker to create tiles that are compatible with our protomaps styles. Basically, you just need these files in the directory when you need to process your pbf: 17 - 18 - ``` 19 - tilemaker monaco-latest.osm.pbf monaco.pmtiles 20 - ```
-73
docs/geofabrik/get-geofabrik-regions.ts
··· 1 - /** 2 - * All of these regions should have a `.poly` and a `-latest.osm.pbf` file 3 - * associated to them. 4 - */ 5 - import * as cheerio from 'npm:cheerio' 6 - 7 - const baseURL = 'https://download.geofabrik.de/' 8 - const regions = new Set() 9 - 10 - // antarctica has no children, so not in baseRegions, but add to regions 11 - const baseRegions = [ 12 - 'australia-oceania', 13 - 'asia', 14 - 'africa', 15 - 'central-america', 16 - 'europe', 17 - 'north-america', 18 - 'south-america', 19 - ] 20 - 21 - baseRegions.concat(['antarctica']) 22 - .forEach((region) => regions.add(region)) 23 - 24 - const responses = baseRegions.map(fetchRegion) 25 - 26 - await Promise.all(responses) 27 - const regionsArray = [...regions] 28 - Deno.writeTextFile('regions.txt', regionsArray.sort().join('\n') + '\n') 29 - 30 - async function fetchRegion(region: string) { 31 - console.log('fetching: ', region) 32 - const url = baseURL + '/' + region 33 - const resp = await fetch(url) 34 - const html = await resp.text() 35 - const { directories, polyFiles } = await parseGeofabrikDirectory(html) 36 - polyFiles 37 - .forEach((file) => regions.add(region + '/' + file.replace('.poly', ''))) 38 - 39 - const childrenResp = directories.map( 40 - (name) => { 41 - const childName = name.replace(/^\//, '').replace(/\/$/, '') 42 - if (!regions.has(childName)) { 43 - return fetchRegion(region + '/' + childName) 44 - } 45 - }, 46 - ) 47 - await Promise.all(childrenResp) 48 - } 49 - 50 - async function parseGeofabrikDirectory(html: string) { 51 - const $ = cheerio.load(html) 52 - const rows = $('tr') 53 - 54 - const directories: string[] = [] 55 - const polyFiles: string[] = [] 56 - 57 - rows.each((_, row) => { 58 - const href = $(row).find('td a').first().attr('href') 59 - 60 - if (!href) return 61 - 62 - if (href.endsWith('/') && (href !== '/') && !href.endsWith('-updates/')) { 63 - directories.push(href) 64 - } else if (href.endsWith('.poly')) { 65 - polyFiles.push(href.replace('/', '')) 66 - } 67 - }) 68 - 69 - return { 70 - directories, 71 - polyFiles, 72 - } 73 - }
-500
docs/geofabrik/regions.txt
··· 1 - africa 2 - africa/algeria 3 - africa/angola 4 - africa/benin 5 - africa/botswana 6 - africa/burkina-faso 7 - africa/burundi 8 - africa/cameroon 9 - africa/canary-islands 10 - africa/cape-verde 11 - africa/central-african-republic 12 - africa/chad 13 - africa/comores 14 - africa/congo-brazzaville 15 - africa/congo-democratic-republic 16 - africa/djibouti 17 - africa/egypt 18 - africa/equatorial-guinea 19 - africa/eritrea 20 - africa/ethiopia 21 - africa/gabon 22 - africa/ghana 23 - africa/guinea 24 - africa/guinea-bissau 25 - africa/ivory-coast 26 - africa/kenya 27 - africa/lesotho 28 - africa/liberia 29 - africa/libya 30 - africa/madagascar 31 - africa/malawi 32 - africa/mali 33 - africa/mauritania 34 - africa/mauritius 35 - africa/morocco 36 - africa/mozambique 37 - africa/namibia 38 - africa/niger 39 - africa/nigeria 40 - africa/rwanda 41 - africa/saint-helena-ascension-and-tristan-da-cunha 42 - africa/sao-tome-and-principe 43 - africa/senegal-and-gambia 44 - africa/seychelles 45 - africa/sierra-leone 46 - africa/somalia 47 - africa/south-africa 48 - africa/south-africa-and-lesotho 49 - africa/south-sudan 50 - africa/sudan 51 - africa/swaziland 52 - africa/tanzania 53 - africa/togo 54 - africa/tunisia 55 - africa/uganda 56 - africa/zambia 57 - africa/zimbabwe 58 - antarctica 59 - asia 60 - asia/afghanistan 61 - asia/armenia 62 - asia/azerbaijan 63 - asia/bangladesh 64 - asia/bhutan 65 - asia/cambodia 66 - asia/china 67 - asia/china/anhui 68 - asia/china/beijing 69 - asia/china/chongqing 70 - asia/china/fujian 71 - asia/china/gansu 72 - asia/china/guangdong 73 - asia/china/guangxi 74 - asia/china/guizhou 75 - asia/china/hainan 76 - asia/china/hebei 77 - asia/china/heilongjiang 78 - asia/china/henan 79 - asia/china/hong-kong 80 - asia/china/hubei 81 - asia/china/hunan 82 - asia/china/inner-mongolia 83 - asia/china/jiangsu 84 - asia/china/jiangxi 85 - asia/china/jilin 86 - asia/china/liaoning 87 - asia/china/macau 88 - asia/china/ningxia 89 - asia/china/qinghai 90 - asia/china/shaanxi 91 - asia/china/shandong 92 - asia/china/shanghai 93 - asia/china/shanxi 94 - asia/china/sichuan 95 - asia/china/tianjin 96 - asia/china/tibet 97 - asia/china/xinjiang 98 - asia/china/yunnan 99 - asia/china/zhejiang 100 - asia/east-timor 101 - asia/gcc-states 102 - asia/india 103 - asia/india/central-zone 104 - asia/india/eastern-zone 105 - asia/india/north-eastern-zone 106 - asia/india/northern-zone 107 - asia/india/southern-zone 108 - asia/india/western-zone 109 - asia/indonesia 110 - asia/indonesia/java 111 - asia/indonesia/kalimantan 112 - asia/indonesia/maluku 113 - asia/indonesia/nusa-tenggara 114 - asia/indonesia/papua 115 - asia/indonesia/sulawesi 116 - asia/indonesia/sumatra 117 - asia/iran 118 - asia/iraq 119 - asia/israel-and-palestine 120 - asia/japan 121 - asia/japan/chubu 122 - asia/japan/chugoku 123 - asia/japan/hokkaido 124 - asia/japan/kansai 125 - asia/japan/kanto 126 - asia/japan/kyushu 127 - asia/japan/shikoku 128 - asia/japan/tohoku 129 - asia/jordan 130 - asia/kazakhstan 131 - asia/kyrgyzstan 132 - asia/laos 133 - asia/lebanon 134 - asia/malaysia-singapore-brunei 135 - asia/maldives 136 - asia/mongolia 137 - asia/myanmar 138 - asia/nepal 139 - asia/north-korea 140 - asia/pakistan 141 - asia/philippines 142 - asia/russia-asian-part 143 - asia/south-korea 144 - asia/sri-lanka 145 - asia/syria 146 - asia/taiwan 147 - asia/tajikistan 148 - asia/thailand 149 - asia/turkmenistan 150 - asia/uzbekistan 151 - asia/vietnam 152 - asia/yemen 153 - australia-oceania 154 - australia-oceania/american-oceania 155 - australia-oceania/australia 156 - australia-oceania/cook-islands 157 - australia-oceania/fiji 158 - australia-oceania/ile-de-clipperton 159 - australia-oceania/kiribati 160 - australia-oceania/marshall-islands 161 - australia-oceania/micronesia 162 - australia-oceania/nauru 163 - australia-oceania/new-caledonia 164 - australia-oceania/new-zealand 165 - australia-oceania/niue 166 - australia-oceania/palau 167 - australia-oceania/papua-new-guinea 168 - australia-oceania/pitcairn-islands 169 - australia-oceania/polynesie-francaise 170 - australia-oceania/samoa 171 - australia-oceania/solomon-islands 172 - australia-oceania/tokelau 173 - australia-oceania/tonga 174 - australia-oceania/tuvalu 175 - australia-oceania/vanuatu 176 - australia-oceania/wallis-et-futuna 177 - central-america 178 - central-america/bahamas 179 - central-america/belize 180 - central-america/costa-rica 181 - central-america/cuba 182 - central-america/el-salvador 183 - central-america/guatemala 184 - central-america/haiti-and-domrep 185 - central-america/honduras 186 - central-america/jamaica 187 - central-america/nicaragua 188 - central-america/panama 189 - europe 190 - europe/albania 191 - europe/alps 192 - europe/andorra 193 - europe/austria 194 - europe/azores 195 - europe/belarus 196 - europe/belgium 197 - europe/bosnia-herzegovina 198 - europe/britain-and-ireland 199 - europe/bulgaria 200 - europe/croatia 201 - europe/cyprus 202 - europe/czech-republic 203 - europe/dach 204 - europe/denmark 205 - europe/estonia 206 - europe/faroe-islands 207 - europe/finland 208 - europe/france 209 - europe/france/alsace 210 - europe/france/aquitaine 211 - europe/france/auvergne 212 - europe/france/basse-normandie 213 - europe/france/bourgogne 214 - europe/france/bretagne 215 - europe/france/centre 216 - europe/france/champagne-ardenne 217 - europe/france/corse 218 - europe/france/franche-comte 219 - europe/france/guadeloupe 220 - europe/france/guyane 221 - europe/france/haute-normandie 222 - europe/france/ile-de-france 223 - europe/france/languedoc-roussillon 224 - europe/france/limousin 225 - europe/france/lorraine 226 - europe/france/martinique 227 - europe/france/mayotte 228 - europe/france/midi-pyrenees 229 - europe/france/nord-pas-de-calais 230 - europe/france/pays-de-la-loire 231 - europe/france/picardie 232 - europe/france/poitou-charentes 233 - europe/france/provence-alpes-cote-d-azur 234 - europe/france/reunion 235 - europe/france/rhone-alpes 236 - europe/georgia 237 - europe/germany 238 - europe/germany/baden-wuerttemberg 239 - europe/germany/baden-wuerttemberg/freiburg-regbez 240 - europe/germany/baden-wuerttemberg/karlsruhe-regbez 241 - europe/germany/baden-wuerttemberg/stuttgart-regbez 242 - europe/germany/baden-wuerttemberg/tuebingen-regbez 243 - europe/germany/bayern 244 - europe/germany/bayern/mittelfranken 245 - europe/germany/bayern/niederbayern 246 - europe/germany/bayern/oberbayern 247 - europe/germany/bayern/oberfranken 248 - europe/germany/bayern/oberpfalz 249 - europe/germany/bayern/schwaben 250 - europe/germany/bayern/unterfranken 251 - europe/germany/berlin 252 - europe/germany/brandenburg 253 - europe/germany/bremen 254 - europe/germany/hamburg 255 - europe/germany/hessen 256 - europe/germany/mecklenburg-vorpommern 257 - europe/germany/niedersachsen 258 - europe/germany/nordrhein-westfalen 259 - europe/germany/nordrhein-westfalen/arnsberg-regbez 260 - europe/germany/nordrhein-westfalen/detmold-regbez 261 - europe/germany/nordrhein-westfalen/duesseldorf-regbez 262 - europe/germany/nordrhein-westfalen/koeln-regbez 263 - europe/germany/nordrhein-westfalen/muenster-regbez 264 - europe/germany/rheinland-pfalz 265 - europe/germany/saarland 266 - europe/germany/sachsen 267 - europe/germany/sachsen-anhalt 268 - europe/germany/schleswig-holstein 269 - europe/germany/thueringen 270 - europe/great-britain 271 - europe/great-britain/united-kingdom 272 - europe/greece 273 - europe/guernsey-jersey 274 - europe/hungary 275 - europe/iceland 276 - europe/ireland-and-northern-ireland 277 - europe/isle-of-man 278 - europe/italy 279 - europe/italy/centro 280 - europe/italy/isole 281 - europe/italy/nord-est 282 - europe/italy/nord-ovest 283 - europe/italy/sud 284 - europe/kosovo 285 - europe/latvia 286 - europe/liechtenstein 287 - europe/lithuania 288 - europe/luxembourg 289 - europe/macedonia 290 - europe/malta 291 - europe/moldova 292 - europe/monaco 293 - europe/montenegro 294 - europe/netherlands 295 - europe/netherlands/drenthe 296 - europe/netherlands/flevoland 297 - europe/netherlands/friesland 298 - europe/netherlands/gelderland 299 - europe/netherlands/groningen 300 - europe/netherlands/limburg 301 - europe/netherlands/noord-brabant 302 - europe/netherlands/noord-holland 303 - europe/netherlands/overijssel 304 - europe/netherlands/utrecht 305 - europe/netherlands/zeeland 306 - europe/netherlands/zuid-holland 307 - europe/norway 308 - europe/poland 309 - europe/poland/dolnoslaskie 310 - europe/poland/kujawsko-pomorskie 311 - europe/poland/lodzkie 312 - europe/poland/lubelskie 313 - europe/poland/lubuskie 314 - europe/poland/malopolskie 315 - europe/poland/mazowieckie 316 - europe/poland/opolskie 317 - europe/poland/podkarpackie 318 - europe/poland/podlaskie 319 - europe/poland/pomorskie 320 - europe/poland/slaskie 321 - europe/poland/swietokrzyskie 322 - europe/poland/warminsko-mazurskie 323 - europe/poland/wielkopolskie 324 - europe/poland/zachodniopomorskie 325 - europe/portugal 326 - europe/romania 327 - europe/serbia 328 - europe/slovakia 329 - europe/slovenia 330 - europe/spain 331 - europe/spain/andalucia 332 - europe/spain/aragon 333 - europe/spain/asturias 334 - europe/spain/cantabria 335 - europe/spain/castilla-la-mancha 336 - europe/spain/castilla-y-leon 337 - europe/spain/cataluna 338 - europe/spain/ceuta 339 - europe/spain/extremadura 340 - europe/spain/galicia 341 - europe/spain/islas-baleares 342 - europe/spain/la-rioja 343 - europe/spain/madrid 344 - europe/spain/melilla 345 - europe/spain/murcia 346 - europe/spain/navarra 347 - europe/spain/pais-vasco 348 - europe/spain/valencia 349 - europe/sweden 350 - europe/switzerland 351 - europe/turkey 352 - europe/ukraine 353 - europe/united-kingdom 354 - europe/united-kingdom/england 355 - europe/united-kingdom/england/bedfordshire 356 - europe/united-kingdom/england/berkshire 357 - europe/united-kingdom/england/bristol 358 - europe/united-kingdom/england/buckinghamshire 359 - europe/united-kingdom/england/cambridgeshire 360 - europe/united-kingdom/england/cheshire 361 - europe/united-kingdom/england/cornwall 362 - europe/united-kingdom/england/cumbria 363 - europe/united-kingdom/england/derbyshire 364 - europe/united-kingdom/england/devon 365 - europe/united-kingdom/england/dorset 366 - europe/united-kingdom/england/durham 367 - europe/united-kingdom/england/east-sussex 368 - europe/united-kingdom/england/east-yorkshire-with-hull 369 - europe/united-kingdom/england/essex 370 - europe/united-kingdom/england/gloucestershire 371 - europe/united-kingdom/england/greater-london 372 - europe/united-kingdom/england/greater-manchester 373 - europe/united-kingdom/england/hampshire 374 - europe/united-kingdom/england/herefordshire 375 - europe/united-kingdom/england/hertfordshire 376 - europe/united-kingdom/england/isle-of-wight 377 - europe/united-kingdom/england/kent 378 - europe/united-kingdom/england/lancashire 379 - europe/united-kingdom/england/leicestershire 380 - europe/united-kingdom/england/lincolnshire 381 - europe/united-kingdom/england/london/enfield 382 - europe/united-kingdom/england/merseyside 383 - europe/united-kingdom/england/norfolk 384 - europe/united-kingdom/england/north-yorkshire 385 - europe/united-kingdom/england/northamptonshire 386 - europe/united-kingdom/england/northumberland 387 - europe/united-kingdom/england/nottinghamshire 388 - europe/united-kingdom/england/oxfordshire 389 - europe/united-kingdom/england/rutland 390 - europe/united-kingdom/england/shropshire 391 - europe/united-kingdom/england/somerset 392 - europe/united-kingdom/england/south-yorkshire 393 - europe/united-kingdom/england/staffordshire 394 - europe/united-kingdom/england/suffolk 395 - europe/united-kingdom/england/surrey 396 - europe/united-kingdom/england/tyne-and-wear 397 - europe/united-kingdom/england/warwickshire 398 - europe/united-kingdom/england/west-midlands 399 - europe/united-kingdom/england/west-sussex 400 - europe/united-kingdom/england/west-yorkshire 401 - europe/united-kingdom/england/wiltshire 402 - europe/united-kingdom/england/worcestershire 403 - europe/united-kingdom/scotland 404 - europe/united-kingdom/wales 405 - north-america 406 - north-america/canada 407 - north-america/canada/alberta 408 - north-america/canada/british-columbia 409 - north-america/canada/manitoba 410 - north-america/canada/new-brunswick 411 - north-america/canada/newfoundland-and-labrador 412 - north-america/canada/northwest-territories 413 - north-america/canada/nova-scotia 414 - north-america/canada/nunavut 415 - north-america/canada/ontario 416 - north-america/canada/prince-edward-island 417 - north-america/canada/quebec 418 - north-america/canada/saskatchewan 419 - north-america/canada/yukon 420 - north-america/greenland 421 - north-america/mexico 422 - north-america/us 423 - north-america/us-midwest 424 - north-america/us-northeast 425 - north-america/us-pacific 426 - north-america/us-south 427 - north-america/us-west 428 - north-america/us/alabama 429 - north-america/us/alaska 430 - north-america/us/arizona 431 - north-america/us/arkansas 432 - north-america/us/california 433 - north-america/us/california/norcal 434 - north-america/us/california/socal 435 - north-america/us/colorado 436 - north-america/us/connecticut 437 - north-america/us/delaware 438 - north-america/us/district-of-columbia 439 - north-america/us/florida 440 - north-america/us/georgia 441 - north-america/us/hawaii 442 - north-america/us/idaho 443 - north-america/us/illinois 444 - north-america/us/indiana 445 - north-america/us/iowa 446 - north-america/us/kansas 447 - north-america/us/kentucky 448 - north-america/us/louisiana 449 - north-america/us/maine 450 - north-america/us/maryland 451 - north-america/us/massachusetts 452 - north-america/us/michigan 453 - north-america/us/minnesota 454 - north-america/us/mississippi 455 - north-america/us/missouri 456 - north-america/us/montana 457 - north-america/us/nebraska 458 - north-america/us/nevada 459 - north-america/us/new-hampshire 460 - north-america/us/new-jersey 461 - north-america/us/new-mexico 462 - north-america/us/new-york 463 - north-america/us/north-carolina 464 - north-america/us/north-dakota 465 - north-america/us/ohio 466 - north-america/us/oklahoma 467 - north-america/us/oregon 468 - north-america/us/pennsylvania 469 - north-america/us/puerto-rico 470 - north-america/us/rhode-island 471 - north-america/us/south-carolina 472 - north-america/us/south-dakota 473 - north-america/us/tennessee 474 - north-america/us/texas 475 - north-america/us/us-virgin-islands 476 - north-america/us/utah 477 - north-america/us/vermont 478 - north-america/us/virginia 479 - north-america/us/washington 480 - north-america/us/west-virginia 481 - north-america/us/wisconsin 482 - north-america/us/wyoming 483 - south-america 484 - south-america/argentina 485 - south-america/bolivia 486 - south-america/brazil 487 - south-america/brazil/centro-oeste 488 - south-america/brazil/nordeste 489 - south-america/brazil/norte 490 - south-america/brazil/sudeste 491 - south-america/brazil/sul 492 - south-america/chile 493 - south-america/colombia 494 - south-america/ecuador 495 - south-america/guyana 496 - south-america/paraguay 497 - south-america/peru 498 - south-america/suriname 499 - south-america/uruguay 500 - south-america/venezuela
docs/screenshot.png

This is a binary file and will not be displayed.

-128
docs/tilemaker/config.json
··· 1 - { 2 - "layers": { 3 - "place": { "minzoom": 0, "maxzoom": 14 }, 4 - "boundary": { 5 - "minzoom": 0, 6 - "maxzoom": 14, 7 - "simplify_below": 12, 8 - "simplify_level": 0.0003, 9 - "simplify_ratio": 2, 10 - "simplify_algorithm": "visvalingam" 11 - }, 12 - 13 - "poi": { "minzoom": 12, "maxzoom": 14 }, 14 - "poi_detail": { "minzoom": 14, "maxzoom": 14, "write_to": "poi" }, 15 - 16 - "housenumber": { "minzoom": 14, "maxzoom": 14 }, 17 - 18 - "waterway": { 19 - "minzoom": 8, 20 - "maxzoom": 14, 21 - "simplify_below": 12, 22 - "simplify_level": 0.0003, 23 - "simplify_ratio": 2 24 - }, 25 - "waterway_detail": { "minzoom": 12, "maxzoom": 14, "write_to": "waterway" }, 26 - 27 - "transportation": { 28 - "minzoom": 4, 29 - "maxzoom": 14, 30 - "simplify_below": 13, 31 - "simplify_level": 0.0003 32 - }, 33 - "transportation_name": { "minzoom": 8, "maxzoom": 14 }, 34 - 35 - "building": { "minzoom": 13, "maxzoom": 14 }, 36 - 37 - "water": { 38 - "minzoom": 6, 39 - "maxzoom": 14, 40 - "simplify_below": 12, 41 - "simplify_level": 0.0003, 42 - "simplify_ratio": 2 43 - }, 44 - "ocean": { 45 - "minzoom": 0, 46 - "maxzoom": 14, 47 - "source": "coastline/water_polygons.shp", 48 - "filter_below": 12, 49 - "filter_area": 0.5, 50 - "simplify_below": 13, 51 - "simplify_level": 0.0001, 52 - "simplify_ratio": 2, 53 - "simplify_algorithm": "visvalingam", 54 - "write_to": "water" 55 - }, 56 - "water_name": { "minzoom": 14, "maxzoom": 14 }, 57 - "water_name_detail": { 58 - "minzoom": 14, 59 - "maxzoom": 14, 60 - "write_to": "water_name" 61 - }, 62 - 63 - "aeroway": { "minzoom": 11, "maxzoom": 14 }, 64 - "aerodrome_label": { "minzoom": 10, "maxzoom": 14 }, 65 - "park": { "minzoom": 11, "maxzoom": 14 }, 66 - "landuse": { 67 - "minzoom": 4, 68 - "maxzoom": 14, 69 - "simplify_below": 13, 70 - "simplify_level": 0.0003, 71 - "simplify_ratio": 2 72 - }, 73 - "urban_areas": { 74 - "minzoom": 4, 75 - "maxzoom": 8, 76 - "source": "landcover/ne_10m_urban_areas/ne_10m_urban_areas.shp", 77 - "source_columns": ["featurecla"], 78 - "simplify_below": 7, 79 - "simplify_level": 0.0003, 80 - "simplify_ratio": 2, 81 - "write_to": "landuse" 82 - }, 83 - "landcover": { 84 - "minzoom": 0, 85 - "maxzoom": 14, 86 - "simplify_below": 13, 87 - "simplify_level": 0.0003, 88 - "simplify_ratio": 2 89 - }, 90 - "ice_shelf": { 91 - "minzoom": 0, 92 - "maxzoom": 9, 93 - "source": "landcover/ne_10m_antarctic_ice_shelves_polys/ne_10m_antarctic_ice_shelves_polys.shp", 94 - "source_columns": ["featurecla"], 95 - "simplify_below": 13, 96 - "simplify_level": 0.0005, 97 - "write_to": "landcover" 98 - }, 99 - "glacier": { 100 - "minzoom": 2, 101 - "maxzoom": 9, 102 - "source": "landcover/ne_10m_glaciated_areas/ne_10m_glaciated_areas.shp", 103 - "source_columns": ["featurecla"], 104 - "simplify_below": 13, 105 - "simplify_level": 0.0005, 106 - "write_to": "landcover" 107 - }, 108 - "mountain_peak": { "minzoom": 11, "maxzoom": 14 } 109 - }, 110 - "settings": { 111 - "minzoom": 0, 112 - "maxzoom": 14, 113 - "basezoom": 14, 114 - "include_ids": false, 115 - "combine_below": 14, 116 - "name": "Tilemaker to OpenMapTiles schema", 117 - "version": "3.0", 118 - "description": "Tile config based on OpenMapTiles schema", 119 - "compress": "gzip", 120 - "filemetadata": { 121 - "tilejson": "2.0.0", 122 - "scheme": "xyz", 123 - "type": "baselayer", 124 - "format": "pbf", 125 - "tiles": ["https://example.com/liechtenstein/{z}/{x}/{y}.pbf"] 126 - } 127 - } 128 - }
-80
docs/tilemaker/filter.txt
··· 1 - # `osmium tags-filter monaco.osm.pbf -R local.txt -o monaco.osm.pbf` 2 - 3 - # Most notable landmarks: must have both Wikipedia and Wikidata entries 4 - # AND be a significant feature type 5 - ( 6 - node["wikipedia"]["wikidata"] 7 - ( 8 - ["historic"="monument"] | 9 - ["historic"="castle"] | 10 - ["historic"="fort"] | 11 - ["tourism"="attraction"] | 12 - ["tourism"="museum"] | 13 - ["amenity"="place_of_worship"] | 14 - ["leisure"="park"] 15 - ) 16 - ) | 17 - ( 18 - way["wikipedia"]["wikidata"] 19 - ( 20 - ["historic"="monument"] | 21 - ["historic"="castle"] | 22 - ["historic"="fort"] | 23 - ["tourism"="attraction"] | 24 - ["tourism"="museum"] | 25 - ["amenity"="place_of_worship"] | 26 - ["leisure"="park"] 27 - ) 28 - ) 29 - 30 - # Super notable landmarks: has Wikipedia entries in multiple languages 31 - ( 32 - node["wikipedia:en"]["wikipedia:de"]["wikipedia:fr"] | 33 - way["wikipedia:en"]["wikipedia:de"]["wikipedia:fr"] 34 - ) 35 - 36 - # Cross-reference with other importance indicators 37 - ( 38 - node["wikipedia"] 39 - ( 40 - ["tourism:visitors">100000] | # High visitor count 41 - ["protection_title"] | # Protected status 42 - ["heritage"] # Heritage listing 43 - ) 44 - ) | 45 - ( 46 - way["wikipedia"] 47 - ( 48 - ["tourism:visitors">100000] | 49 - ["protection_title"] | 50 - ["heritage"] 51 - ) 52 - ) 53 - 54 - # Your base map features... 55 - way["highway"="motorway"] 56 - way["highway"="trunk"] 57 - way["highway"="primary"] 58 - way["highway"="secondary"] 59 - way["highway"="footway"] 60 - way["building"] 61 - way["natural"="water"] 62 - way["natural"="coastline"] 63 - 64 - # Keep nodes that are part of kept ways 65 - node(w) 66 - 67 - # Remove unnecessary tags but keep important landmark info 68 - --remove-tags 69 - *, 70 - ~highway, 71 - ~building, 72 - ~natural, 73 - ~waterway, 74 - ~name, 75 - ~wikipedia, 76 - ~wikidata, 77 - ~historic, 78 - ~tourism, 79 - ~amenity, 80 - ~leisure
-947
docs/tilemaker/process.lua
··· 1 - -- Data processing based on openmaptiles.org schema 2 - -- https://openmaptiles.org/schema/ 3 - -- Copyright (c) 2016, KlokanTech.com & OpenMapTiles contributors. 4 - -- Used under CC-BY 4.0 5 - 6 - -------- 7 - -- Alter these lines to control which languages are written for place/streetnames 8 - -- 9 - -- Preferred language can be (for example) "en" for English, "de" for German, or nil to use OSM's name tag: 10 - preferred_language = nil 11 - -- This is written into the following vector tile attribute (usually "name:latin"): 12 - preferred_language_attribute = "name:latin" 13 - -- If OSM's name tag differs, then write it into this attribute (usually "name_int"): 14 - default_language_attribute = "name_int" 15 - -- Also write these languages if they differ - for example, { "de", "fr" } 16 - additional_languages = { } 17 - -------- 18 - 19 - -- Enter/exit Tilemaker 20 - function init_function() 21 - end 22 - function exit_function() 23 - end 24 - 25 - -- Implement Sets in tables 26 - function Set(list) 27 - local set = {} 28 - for _, l in ipairs(list) do set[l] = true end 29 - return set 30 - end 31 - 32 - -- Meters per pixel if tile is 256x256 33 - ZRES5 = 4891.97 34 - ZRES6 = 2445.98 35 - ZRES7 = 1222.99 36 - ZRES8 = 611.5 37 - ZRES9 = 305.7 38 - ZRES10 = 152.9 39 - ZRES11 = 76.4 40 - ZRES12 = 38.2 41 - ZRES13 = 19.1 42 - 43 - -- The height of one floor, in meters 44 - BUILDING_FLOOR_HEIGHT = 3.66 45 - -- Used to express that a feature should not end up the vector tiles 46 - INVALID_ZOOM = 99 47 - 48 - -- Process node/way tags 49 - aerodromeValues = Set { "international", "public", "regional", "military", "private" } 50 - pavedValues = Set { "paved", "asphalt", "cobblestone", "concrete", "concrete:lanes", "concrete:plates", "metal", "paving_stones", "sett", "unhewn_cobblestone", "wood" } 51 - unpavedValues = Set { "unpaved", "compacted", "dirt", "earth", "fine_gravel", "grass", "grass_paver", "gravel", "gravel_turf", "ground", "ice", "mud", "pebblestone", "salt", "sand", "snow", "woodchips" } 52 - 53 - -- Process node tags 54 - 55 - node_keys = { "addr:housenumber","aerialway","aeroway","amenity","barrier","highway","historic","leisure","natural","office","place","railway","shop","sport","tourism","waterway" } 56 - 57 - -- Get admin level which the place node is capital of. 58 - -- Returns nil in case of invalid capital and for places which are not capitals. 59 - function capitalLevel(capital) 60 - local capital_al = tonumber(capital) or 0 61 - if capital == "yes" then 62 - capital_al = 2 63 - end 64 - if capital_al == 0 then 65 - return nil 66 - end 67 - return capital_al 68 - end 69 - 70 - -- Calculate rank for place nodes 71 - -- place: value of place=* 72 - -- popuplation: population as number 73 - -- capital_al: result of capitalLevel() 74 - function calcRank(place, population, capital_al) 75 - local rank = 0 76 - if capital_al and capital_al >= 2 and capital_al <= 4 then 77 - rank = capital_al 78 - if population > 3 * 10^6 then 79 - rank = rank - 2 80 - elseif population > 1 * 10^6 then 81 - rank = rank - 1 82 - elseif population < 100000 then 83 - rank = rank + 2 84 - elseif population < 50000 then 85 - rank = rank + 3 86 - end 87 - -- Safety measure to avoid place=village/farm/... appear early (as important capital) because a mapper added capital=yes/2/3/4 88 - if place ~= "city" then 89 - rank = rank + 3 90 - -- Decrease rank further if it is not even a town. 91 - if place ~= "town" then 92 - rank = rank + 2 93 - end 94 - end 95 - return rank 96 - end 97 - if place ~= "city" and place ~= "town" then 98 - return nil 99 - end 100 - if population > 3 * 10^6 then 101 - return 1 102 - elseif population > 1 * 10^6 then 103 - return 2 104 - elseif population > 500000 then 105 - return 3 106 - elseif population > 200000 then 107 - return 4 108 - elseif population > 100000 then 109 - return 5 110 - elseif population > 75000 then 111 - return 6 112 - elseif population > 50000 then 113 - return 7 114 - elseif population > 25000 then 115 - return 8 116 - elseif population > 10000 then 117 - return 9 118 - end 119 - return 10 120 - end 121 - 122 - 123 - function node_function() 124 - -- Write 'aerodrome_label' 125 - local aeroway = Find("aeroway") 126 - if aeroway == "aerodrome" then 127 - Layer("aerodrome_label", false) 128 - SetNameAttributes() 129 - Attribute("iata", Find("iata")) 130 - SetEleAttributes() 131 - Attribute("icao", Find("icao")) 132 - 133 - local aerodrome_value = Find("aerodrome") 134 - local class 135 - if aerodromeValues[aerodrome_value] then class = aerodrome_value else class = "other" end 136 - Attribute("class", class) 137 - end 138 - -- Write 'housenumber' 139 - local housenumber = Find("addr:housenumber") 140 - if housenumber~="" then 141 - Layer("housenumber", false) 142 - Attribute("housenumber", housenumber) 143 - end 144 - 145 - -- Write 'place' 146 - -- note that OpenMapTiles has a rank for countries (1-3), states (1-6) and cities (1-10+); 147 - -- we could potentially approximate it for cities based on the population tag 148 - local place = Find("place") 149 - if place ~= "" then 150 - local mz = 13 151 - local pop = tonumber(Find("population")) or 0 152 - local capital = capitalLevel(Find("capital")) 153 - local rank = calcRank(place, pop, capital) 154 - 155 - if place == "continent" then mz=0 156 - elseif place == "country" then 157 - if pop>50000000 then rank=1; mz=1 158 - elseif pop>20000000 then rank=2; mz=2 159 - else rank=3; mz=3 end 160 - elseif place == "state" then mz=4 161 - elseif place == "province" then mz=5 162 - elseif place == "city" then mz=5 163 - elseif place == "town" and pop>8000 then mz=7 164 - elseif place == "town" then mz=8 165 - elseif place == "village" and pop>2000 then mz=9 166 - elseif place == "village" then mz=10 167 - elseif place == "borough" then mz=10 168 - elseif place == "suburb" then mz=11 169 - elseif place == "quarter" then mz=12 170 - elseif place == "hamlet" then mz=12 171 - elseif place == "neighbourhood" then mz=13 172 - elseif place == "isolated_dwelling" then mz=13 173 - elseif place == "locality" then mz=13 174 - elseif place == "island" then mz=12 175 - end 176 - 177 - Layer("place", false) 178 - Attribute("class", place) 179 - MinZoom(mz) 180 - if rank then AttributeNumeric("rank", rank) end 181 - if capital then AttributeNumeric("capital", capital) end 182 - if place=="country" then 183 - local iso_a2 = Find("ISO3166-1:alpha2") 184 - while iso_a2 == "" do 185 - local rel, role = NextRelation() 186 - if not rel then break end 187 - if role == 'label' then 188 - iso_a2 = FindInRelation("ISO3166-1:alpha2") 189 - end 190 - end 191 - Attribute("iso_a2", iso_a2) 192 - end 193 - SetNameAttributes() 194 - return 195 - end 196 - 197 - -- Write 'poi' 198 - local rank, class, subclass = GetPOIRank() 199 - if rank then WritePOI(class,subclass,rank) end 200 - 201 - -- Write 'mountain_peak' and 'water_name' 202 - local natural = Find("natural") 203 - if natural == "peak" or natural == "volcano" then 204 - Layer("mountain_peak", false) 205 - SetEleAttributes() 206 - AttributeNumeric("rank", 1) 207 - Attribute("class", natural) 208 - SetNameAttributes() 209 - return 210 - end 211 - if natural == "bay" then 212 - Layer("water_name", false) 213 - SetNameAttributes() 214 - return 215 - end 216 - end 217 - 218 - -- Process way tags 219 - 220 - majorRoadValues = Set { "motorway", "trunk", "primary" } 221 - z9RoadValues = Set { "secondary", "motorway_link", "trunk_link" } 222 - z10RoadValues = Set { "primary_link", "secondary_link" } 223 - z11RoadValues = Set { "tertiary", "tertiary_link", "busway", "bus_guideway" } 224 - -- On zoom 12, various road classes are merged into "minor" 225 - z12MinorRoadValues = Set { "unclassified", "residential", "road", "living_street" } 226 - z12OtherRoadValues = Set { "raceway" } 227 - z13RoadValues = Set { "track", "service" } 228 - manMadeRoadValues = Set { "pier", "bridge" } 229 - pathValues = Set { "footway", "cycleway", "bridleway", "path", "steps", "pedestrian", "platform" } 230 - linkValues = Set { "motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link" } 231 - pavedValues = Set { "paved", "asphalt", "cobblestone", "concrete", "concrete:lanes", "concrete:plates", "metal", "paving_stones", "sett", "unhewn_cobblestone", "wood" } 232 - unpavedValues = Set { "unpaved", "compacted", "dirt", "earth", "fine_gravel", "grass", "grass_paver", "gravel", "gravel_turf", "ground", "ice", "mud", "pebblestone", "salt", "sand", "snow", "woodchips" } 233 - railwayClasses = { rail="rail", narrow_gauge="rail", preserved="rail", funicular="rail", subway="transit", light_rail="transit", monorail="transit", tram="transit" } 234 - 235 - aerowayBuildings= Set { "terminal", "gate", "tower" } 236 - landuseKeys = Set { "school", "university", "kindergarten", "college", "library", "hospital", 237 - "railway", "cemetery", "military", "residential", "commercial", "industrial", 238 - "retail", "stadium", "pitch", "playground", "theme_park", "bus_station", "zoo" } 239 - landcoverKeys = { wood="wood", forest="wood", 240 - wetland="wetland", 241 - beach="sand", sand="sand", dune="sand", 242 - farmland="farmland", farm="farmland", orchard="farmland", vineyard="farmland", plant_nursery="farmland", 243 - glacier="ice", ice_shelf="ice", 244 - bare_rock="rock", scree="rock", 245 - fell="grass", grassland="grass", grass="grass", heath="grass", meadow="grass", allotments="grass", park="grass", village_green="grass", recreation_ground="grass", scrub="grass", shrubbery="grass", tundra="grass", garden="grass", golf_course="grass", park="grass" } 246 - 247 - -- POI key/value pairs: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/mapping.yaml 248 - poiTags = { aerialway = Set { "station" }, 249 - amenity = Set { "arts_centre", "bank", "bar", "bbq", "bicycle_parking", "bicycle_rental", "biergarten", "bus_station", "cafe", "cinema", "clinic", "college", "community_centre", "courthouse", "dentist", "doctors", "embassy", "fast_food", "ferry_terminal", "fire_station", "food_court", "fuel", "grave_yard", "hospital", "ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home", "parking", "pharmacy", "place_of_worship", "police", "post_box", "post_office", "prison", "pub", "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", "theatre", "toilets", "townhall", "university", "veterinary", "waste_basket" }, 250 - barrier = Set { "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile", "toll_booth" }, 251 - building = Set { "dormitory" }, 252 - highway = Set { "bus_stop" }, 253 - historic = Set { "monument", "castle", "ruins" }, 254 - landuse = Set { "basin", "brownfield", "cemetery", "reservoir", "winter_sports" }, 255 - leisure = Set { "dog_park", "escape_game", "garden", "golf_course", "ice_rink", "hackerspace", "marina", "miniature_golf", "park", "pitch", "playground", "sports_centre", "stadium", "swimming_area", "swimming_pool", "water_park" }, 256 - railway = Set { "halt", "station", "subway_entrance", "train_station_entrance", "tram_stop" }, 257 - shop = Set { "accessories", "alcohol", "antiques", "art", "bag", "bakery", "beauty", "bed", "beverages", "bicycle", "books", "boutique", "butcher", "camera", "car", "car_repair", "carpet", "charity", "chemist", "chocolate", "clothes", "coffee", "computer", "confectionery", "convenience", "copyshop", "cosmetics", "deli", "delicatessen", "department_store", "doityourself", "dry_cleaning", "electronics", "erotic", "fabric", "florist", "frozen_food", "furniture", "garden_centre", "general", "gift", "greengrocer", "hairdresser", "hardware", "hearing_aids", "hifi", "ice_cream", "interior_decoration", "jewelry", "kiosk", "lamps", "laundry", "mall", "massage", "mobile_phone", "motorcycle", "music", "musical_instrument", "newsagent", "optician", "outdoor", "perfume", "perfumery", "pet", "photo", "second_hand", "shoes", "sports", "stationery", "supermarket", "tailor", "tattoo", "ticket", "tobacco", "toys", "travel_agency", "video", "video_games", "watches", "weapons", "wholesale", "wine" }, 258 - sport = Set { "american_football", "archery", "athletics", "australian_football", "badminton", "baseball", "basketball", "beachvolleyball", "billiards", "bmx", "boules", "bowls", "boxing", "canadian_football", "canoe", "chess", "climbing", "climbing_adventure", "cricket", "cricket_nets", "croquet", "curling", "cycling", "disc_golf", "diving", "dog_racing", "equestrian", "fatsal", "field_hockey", "free_flying", "gaelic_games", "golf", "gymnastics", "handball", "hockey", "horse_racing", "horseshoes", "ice_hockey", "ice_stock", "judo", "karting", "korfball", "long_jump", "model_aerodrome", "motocross", "motor", "multi", "netball", "orienteering", "paddle_tennis", "paintball", "paragliding", "pelota", "racquet", "rc_car", "rowing", "rugby", "rugby_league", "rugby_union", "running", "sailing", "scuba_diving", "shooting", "shooting_range", "skateboard", "skating", "skiing", "soccer", "surfing", "swimming", "table_soccer", "table_tennis", "team_handball", "tennis", "toboggan", "volleyball", "water_ski", "yoga" }, 259 - tourism = Set { "alpine_hut", "aquarium", "artwork", "attraction", "bed_and_breakfast", "camp_site", "caravan_site", "chalet", "gallery", "guest_house", "hostel", "hotel", "information", "motel", "museum", "picnic_site", "theme_park", "viewpoint", "zoo" }, 260 - waterway = Set { "dock" } } 261 - 262 - -- POI "class" values: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/poi.yaml 263 - poiClasses = { townhall="town_hall", public_building="town_hall", courthouse="town_hall", community_centre="town_hall", 264 - golf="golf", golf_course="golf", miniature_golf="golf", 265 - fast_food="fast_food", food_court="fast_food", 266 - park="park", bbq="park", 267 - bus_stop="bus", bus_station="bus", 268 - subway_entrance="entrance", train_station_entrance="entrance", 269 - camp_site="campsite", caravan_site="campsite", 270 - laundry="laundry", dry_cleaning="laundry", 271 - supermarket="grocery", deli="grocery", delicatessen="grocery", department_store="grocery", greengrocer="grocery", marketplace="grocery", 272 - books="library", library="library", 273 - university="college", college="college", 274 - hotel="lodging", motel="lodging", bed_and_breakfast="lodging", guest_house="lodging", hostel="lodging", chalet="lodging", alpine_hut="lodging", dormitory="lodging", 275 - chocolate="ice_cream", confectionery="ice_cream", 276 - post_box="post", post_office="post", 277 - cafe="cafe", 278 - school="school", kindergarten="school", 279 - alcohol="alcohol_shop", beverages="alcohol_shop", wine="alcohol_shop", 280 - bar="bar", nightclub="bar", 281 - marina="harbor", dock="harbor", 282 - car="car", car_repair="car", taxi="car", 283 - hospital="hospital", nursing_home="hospital", clinic="hospital", 284 - grave_yard="cemetery", cemetery="cemetery", 285 - attraction="attraction", viewpoint="attraction", 286 - biergarten="beer", pub="beer", 287 - music="music", musical_instrument="music", 288 - american_football="stadium", stadium="stadium", soccer="stadium", 289 - art="art_gallery", artwork="art_gallery", gallery="art_gallery", arts_centre="art_gallery", 290 - bag="clothing_store", clothes="clothing_store", 291 - swimming_area="swimming", swimming="swimming", 292 - castle="castle", ruins="castle" } 293 - -- POI classes where class is the matching value and subclass is the value of a separate key 294 - poiSubClasses = { information="information", place_of_worship="religion", pitch="sport" } 295 - poiClassRanks = { hospital=1, railway=2, bus=3, attraction=4, harbor=5, college=6, 296 - school=7, stadium=8, zoo=9, town_hall=10, campsite=11, cemetery=12, 297 - park=13, library=14, police=15, post=16, golf=17, shop=18, grocery=19, 298 - fast_food=20, clothing_store=21, bar=22 } 299 - waterClasses = Set { "river", "riverbank", "stream", "canal", "drain", "ditch", "dock" } 300 - waterwayClasses = Set { "stream", "river", "canal", "drain", "ditch" } 301 - 302 - -- Scan relations for use in ways 303 - 304 - function relation_scan_function() 305 - if Find("type")=="boundary" and Find("boundary")=="administrative" then 306 - Accept() 307 - end 308 - end 309 - 310 - function write_to_transportation_layer(minzoom, highway_class, subclass, ramp, service, is_rail, is_road, is_area) 311 - Layer("transportation", is_area) 312 - SetZOrder() 313 - Attribute("class", highway_class) 314 - if subclass and subclass ~= "" then 315 - Attribute("subclass", subclass) 316 - end 317 - AttributeNumeric("layer", tonumber(Find("layer")) or 0, accessMinzoom) 318 - SetBrunnelAttributes() 319 - -- We do not write any other attributes for areas. 320 - if is_area then 321 - SetMinZoomByAreaWithLimit(minzoom) 322 - return 323 - end 324 - MinZoom(minzoom) 325 - if ramp then AttributeNumeric("ramp",1) end 326 - 327 - -- Service 328 - if (is_rail or highway_class == "service") and (service and service ~="") then Attribute("service", service) end 329 - 330 - local accessMinzoom = 9 331 - if is_road then 332 - local oneway = Find("oneway") 333 - if oneway == "yes" or oneway == "1" then 334 - AttributeNumeric("oneway",1) 335 - end 336 - if oneway == "-1" then 337 - -- **** TODO 338 - end 339 - local surface = Find("surface") 340 - local surfaceMinzoom = 12 341 - if pavedValues[surface] then 342 - Attribute("surface", "paved", surfaceMinzoom) 343 - elseif unpavedValues[surface] then 344 - Attribute("surface", "unpaved", surfaceMinzoom) 345 - end 346 - if Holds("access") then Attribute("access", Find("access"), accessMinzoom) end 347 - if Holds("bicycle") then Attribute("bicycle", Find("bicycle"), accessMinzoom) end 348 - if Holds("foot") then Attribute("foot", Find("foot"), accessMinzoom) end 349 - if Holds("horse") then Attribute("horse", Find("horse"), accessMinzoom) end 350 - AttributeBoolean("toll", Find("toll") == "yes", accessMinzoom) 351 - if Find("expressway") == "yes" then AttributeBoolean("expressway", true, 7) end 352 - if Holds("mtb_scale") then Attribute("mtb_scale", Find("mtb:scale"), 10) end 353 - end 354 - end 355 - 356 - -- Process way tags 357 - 358 - function way_function() 359 - local route = Find("route") 360 - local highway = Find("highway") 361 - local waterway = Find("waterway") 362 - local water = Find("water") 363 - local building = Find("building") 364 - local natural = Find("natural") 365 - local historic = Find("historic") 366 - local landuse = Find("landuse") 367 - local leisure = Find("leisure") 368 - local amenity = Find("amenity") 369 - local aeroway = Find("aeroway") 370 - local railway = Find("railway") 371 - local service = Find("service") 372 - local sport = Find("sport") 373 - local shop = Find("shop") 374 - local tourism = Find("tourism") 375 - local man_made = Find("man_made") 376 - local boundary = Find("boundary") 377 - local aerialway = Find("aerialway") 378 - local public_transport = Find("public_transport") 379 - local place = Find("place") 380 - local is_closed = IsClosed() 381 - local housenumber = Find("addr:housenumber") 382 - local write_name = false 383 - local construction = Find("construction") 384 - local is_highway_area = highway~="" and Find("area")=="yes" and is_closed 385 - 386 - -- Miscellaneous preprocessing 387 - if Find("disused") == "yes" then return end 388 - if boundary~="" and Find("protection_title")=="National Forest" and Find("operator")=="United States Forest Service" then return end 389 - if highway == "proposed" then return end 390 - if aerowayBuildings[aeroway] then building="yes"; aeroway="" end 391 - if landuse == "field" then landuse = "farmland" end 392 - if landuse == "meadow" and Find("meadow")=="agricultural" then landuse="farmland" end 393 - 394 - if place == "island" then 395 - LayerAsCentroid("place") 396 - Attribute("class", place) 397 - MinZoom(10) 398 - local pop = tonumber(Find("population")) or 0 399 - local capital = capitalLevel(Find("capital")) 400 - local rank = calcRank(place, pop, nil) 401 - if rank then AttributeNumeric("rank", rank) end 402 - SetNameAttributes() 403 - end 404 - 405 - -- Boundaries within relations 406 - -- note that we process administrative boundaries as properties on ways, rather than as single relation geometries, 407 - -- because otherwise we get multiple renderings where boundaries are coterminous 408 - local admin_level = 11 409 - local isBoundary = false 410 - while true do 411 - local rel = NextRelation() 412 - if not rel then break end 413 - isBoundary = true 414 - admin_level = math.min(admin_level, tonumber(FindInRelation("admin_level")) or 11) 415 - end 416 - 417 - -- Boundaries in ways 418 - if boundary=="administrative" then 419 - admin_level = math.min(admin_level, tonumber(Find("admin_level")) or 11) 420 - isBoundary = true 421 - end 422 - 423 - -- Administrative boundaries 424 - -- https://openmaptiles.org/schema/#boundary 425 - if isBoundary and not (Find("maritime")=="yes") then 426 - local mz = 0 427 - if admin_level>=3 and admin_level<5 then mz=4 428 - elseif admin_level>=5 and admin_level<7 then mz=8 429 - elseif admin_level==7 then mz=10 430 - elseif admin_level>=8 then mz=12 431 - end 432 - 433 - Layer("boundary",false) 434 - AttributeNumeric("admin_level", admin_level) 435 - MinZoom(mz) 436 - -- disputed status (0 or 1). some styles need to have the 0 to show it. 437 - local disputed = Find("disputed") 438 - if disputed=="yes" then 439 - AttributeNumeric("disputed", 1) 440 - else 441 - AttributeNumeric("disputed", 0) 442 - end 443 - end 444 - 445 - -- Aerialways ('transportation' and 'transportation_name') 446 - if aerialway ~= "" then 447 - write_to_transportation_layer(12, "aerialway", aerialway, false, nil, false, false, is_closed) 448 - if HasNames() then 449 - Layer("transportation_name", false) 450 - MinZoom(12) 451 - SetNameAttributes() 452 - Attribute("class", "aerialway") 453 - Attribute("subclass", aerialway) 454 - end 455 - end 456 - 457 - -- Roads ('transportation' and 'transportation_name') 458 - if highway ~= "" or public_transport == "platform" then 459 - local access = Find("access") 460 - local surface = Find("surface") 461 - 462 - local h = highway 463 - local is_road = true 464 - if h == "" then 465 - h = public_transport 466 - is_road = false 467 - end 468 - local subclass = nil 469 - local under_construction = false 470 - if highway == "construction" and construction ~= "" then 471 - h = construction 472 - under_construction = true 473 - end 474 - local minzoom = INVALID_ZOOM 475 - if majorRoadValues[h] then minzoom = 4 476 - elseif h == "trunk" then minzoom = 5 477 - elseif highway == "primary" then minzoom = 7 478 - elseif z9RoadValues[h] then minzoom = 9 479 - elseif z10RoadValues[h] then minzoom = 10 480 - elseif z11RoadValues[h] then minzoom = 11 481 - elseif z12MinorRoadValues[h] then 482 - minzoom = 12 483 - subclass = h 484 - h = "minor" 485 - elseif z12OtherRoadValues[h] then minzoom = 12 486 - elseif z13RoadValues[h] then minzoom = 13 487 - elseif pathValues[h] then 488 - minzoom = 14 489 - subclass = h 490 - h = "path" 491 - end 492 - 493 - -- Links (ramp) 494 - local ramp=false 495 - if linkValues[h] then 496 - splitHighway = split(highway, "_") 497 - highway = splitHighway[1]; h = highway 498 - ramp = true 499 - end 500 - 501 - -- Construction 502 - if under_construction then 503 - h = h .. "_construction" 504 - end 505 - 506 - -- Drop underground platforms 507 - local layer = Find("layer") 508 - local layerNumeric = tonumber(layer) 509 - if not is_road and layerNumeric ~= nil and layerNumeric < 0 then 510 - minzoom = INVALID_ZOOM 511 - end 512 - 513 - -- Drop all areas except infrastructure for pedestrians handled above 514 - if is_highway_area and h ~= "path" then 515 - minzoom = INVALID_ZOOM 516 - end 517 - 518 - -- Write to layer 519 - if minzoom <= 14 then 520 - write_to_transportation_layer(minzoom, h, subclass, ramp, service, false, is_road, is_highway_area) 521 - 522 - -- Write names 523 - if not is_closed and (HasNames() or Holds("ref")) then 524 - if h == "motorway" then 525 - minzoom = 7 526 - elseif h == "trunk" then 527 - minzoom = 8 528 - elseif h == "primary" then 529 - minzoom = 10 530 - elseif h == "secondary" then 531 - minzoom = 11 532 - elseif h == "minor" or h == "track" or h == "tertiary" then 533 - minzoom = 13 534 - else 535 - minzoom = 14 536 - end 537 - Layer("transportation_name", false) 538 - MinZoom(minzoom) 539 - SetNameAttributes() 540 - Attribute("class",h) 541 - Attribute("network","road") -- **** could also be us-interstate, us-highway, us-state 542 - if subclass then Attribute("subclass", highway) end 543 - local ref = Find("ref") 544 - if ref~="" then 545 - Attribute("ref",ref) 546 - AttributeNumeric("ref_length",ref:len()) 547 - end 548 - end 549 - end 550 - end 551 - 552 - -- Railways ('transportation' and 'transportation_name') 553 - if railway~="" then 554 - local class = railwayClasses[railway] 555 - if class then 556 - local minzoom = 14 557 - local usage = Find("usage") 558 - if railway == "rail" and service == "" then 559 - if usage == "main" then 560 - minzoom = 8 561 - else 562 - minzoom = 10 563 - end 564 - elseif railway == "narrow_gauge" and service == "" then 565 - minzoom = 10 566 - elseif railway == "light_rail" and service == "" then 567 - minzoom = 11 568 - end 569 - write_to_transportation_layer(minzoom, class, railway, false, service, true, false, is_closed) 570 - 571 - if HasNames() then 572 - Layer("transportation_name", false) 573 - SetNameAttributes() 574 - MinZoom(14) 575 - Attribute("class", class) 576 - end 577 - end 578 - end 579 - 580 - -- Pier 581 - if manMadeRoadValues[man_made] then 582 - write_to_transportation_layer(13, man_made, nil, false, nil, false, false, is_closed) 583 - end 584 - 585 - -- 'Ferry' 586 - if route=="ferry" then 587 - write_to_transportation_layer(9, "ferry", nil, false, nil, false, false, is_closed) 588 - 589 - if HasNames() then 590 - Layer("transportation_name", false) 591 - SetNameAttributes() 592 - MinZoom(12) 593 - Attribute("class", "ferry") 594 - end 595 - end 596 - 597 - -- 'Aeroway' 598 - if aeroway~="" then 599 - Layer("aeroway", is_closed) 600 - Attribute("class",aeroway) 601 - Attribute("ref",Find("ref")) 602 - write_name = true 603 - end 604 - 605 - -- 'aerodrome_label' 606 - if aeroway=="aerodrome" then 607 - LayerAsCentroid("aerodrome_label") 608 - SetNameAttributes() 609 - Attribute("iata", Find("iata")) 610 - SetEleAttributes() 611 - Attribute("icao", Find("icao")) 612 - 613 - local aerodrome = Find(aeroway) 614 - local class 615 - if aerodromeValues[aerodrome] then class = aerodrome else class = "other" end 616 - Attribute("class", class) 617 - end 618 - 619 - -- Set 'waterway' and associated 620 - if waterwayClasses[waterway] and not is_closed then 621 - if waterway == "river" and Holds("name") then 622 - Layer("waterway", false) 623 - else 624 - Layer("waterway_detail", false) 625 - end 626 - if Find("intermittent")=="yes" then AttributeNumeric("intermittent", 1) else AttributeNumeric("intermittent", 0) end 627 - Attribute("class", waterway) 628 - SetNameAttributes() 629 - SetBrunnelAttributes() 630 - elseif waterway == "boatyard" then Layer("landuse", is_closed); Attribute("class", "industrial"); MinZoom(12) 631 - elseif waterway == "dam" then Layer("building",is_closed) 632 - elseif waterway == "fuel" then Layer("landuse", is_closed); Attribute("class", "industrial"); MinZoom(14) 633 - end 634 - -- Set names on rivers 635 - if waterwayClasses[waterway] and not is_closed then 636 - if waterway == "river" and Holds("name") then 637 - Layer("water_name", false) 638 - else 639 - Layer("water_name_detail", false) 640 - MinZoom(14) 641 - end 642 - Attribute("class", waterway) 643 - SetNameAttributes() 644 - end 645 - 646 - -- Set 'building' and associated 647 - if building~="" then 648 - Layer("building", true) 649 - SetBuildingHeightAttributes() 650 - SetMinZoomByArea() 651 - end 652 - 653 - -- Set 'housenumber' 654 - if housenumber~="" then 655 - LayerAsCentroid("housenumber") 656 - Attribute("housenumber", housenumber) 657 - end 658 - 659 - -- Set 'water' 660 - if natural=="water" or leisure=="swimming_pool" or landuse=="reservoir" or landuse=="basin" or waterClasses[waterway] then 661 - if Find("covered")=="yes" or not is_closed then return end 662 - local class="lake"; if waterway~="" then class="river" end 663 - if class=="lake" and Find("wikidata")=="Q192770" then return end 664 - Layer("water",true) 665 - SetMinZoomByArea(way) 666 - Attribute("class",class) 667 - 668 - if Find("intermittent")=="yes" then Attribute("intermittent",1) end 669 - -- we only want to show the names of actual lakes not every man-made basin that probably doesn't even have a name other than "basin" 670 - -- examples for which we don't want to show a name: 671 - -- https://www.openstreetmap.org/way/25958687 672 - -- https://www.openstreetmap.org/way/27201902 673 - -- https://www.openstreetmap.org/way/25309134 674 - -- https://www.openstreetmap.org/way/24579306 675 - if Holds("name") and natural=="water" and water ~= "basin" and water ~= "wastewater" then 676 - LayerAsCentroid("water_name_detail") 677 - SetNameAttributes() 678 - SetMinZoomByArea() 679 - Attribute("class", class) 680 - end 681 - 682 - return -- in case we get any landuse processing 683 - end 684 - 685 - -- Set 'landcover' (from landuse, natural, leisure) 686 - local l = landuse 687 - if l=="" then l=natural end 688 - if l=="" then l=leisure end 689 - if landcoverKeys[l] then 690 - Layer("landcover", true) 691 - SetMinZoomByArea() 692 - Attribute("class", landcoverKeys[l]) 693 - if l=="wetland" then Attribute("subclass", Find("wetland")) 694 - else Attribute("subclass", l) end 695 - write_name = true 696 - 697 - -- Set 'landuse' 698 - else 699 - if l=="" then l=amenity end 700 - if l=="" then l=tourism end 701 - if landuseKeys[l] then 702 - Layer("landuse", true) 703 - Attribute("class", l) 704 - if l=="residential" then 705 - if Area()<ZRES8^2 then MinZoom(8) 706 - else SetMinZoomByArea() end 707 - else MinZoom(11) end 708 - write_name = true 709 - end 710 - end 711 - 712 - -- Parks 713 - -- **** name? 714 - if boundary=="national_park" then Layer("park",true); Attribute("class",boundary); SetNameAttributes() 715 - elseif leisure=="nature_reserve" then Layer("park",true); Attribute("class",leisure ); SetNameAttributes() end 716 - 717 - -- POIs ('poi' and 'poi_detail') 718 - local rank, class, subclass = GetPOIRank() 719 - if rank then WritePOI(class,subclass,rank); return end 720 - 721 - -- Catch-all 722 - if (building~="" or write_name) and Holds("name") then 723 - LayerAsCentroid("poi_detail") 724 - SetNameAttributes() 725 - if write_name then rank=6 else rank=25 end 726 - AttributeNumeric("rank", rank) 727 - end 728 - end 729 - 730 - -- Remap coastlines 731 - function attribute_function(attr,layer) 732 - if attr["featurecla"]=="Glaciated areas" then 733 - return { subclass="glacier" } 734 - elseif attr["featurecla"]=="Antarctic Ice Shelf" then 735 - return { subclass="ice_shelf" } 736 - elseif attr["featurecla"]=="Urban area" then 737 - return { class="residential" } 738 - elseif layer=="ocean" then 739 - return { class="ocean" } 740 - else 741 - return attr 742 - end 743 - end 744 - 745 - -- ========================================================== 746 - -- Common functions 747 - 748 - -- Write a way centroid to POI layer 749 - function WritePOI(class,subclass,rank) 750 - local layer = "poi" 751 - if rank>4 then layer="poi_detail" end 752 - LayerAsCentroid(layer) 753 - SetNameAttributes() 754 - AttributeNumeric("rank", rank) 755 - Attribute("class", class) 756 - Attribute("subclass", subclass) 757 - -- layer defaults to 0 758 - AttributeNumeric("layer", tonumber(Find("layer")) or 0) 759 - -- indoor defaults to false 760 - AttributeBoolean("indoor", (Find("indoor") == "yes")) 761 - -- level has no default 762 - local level = tonumber(Find("level")) 763 - if level then 764 - AttributeNumeric("level", level) 765 - end 766 - end 767 - 768 - -- Check if there are name tags on the object 769 - function HasNames() 770 - if Holds("name") then return true end 771 - local iname 772 - local main_written = name 773 - if preferred_language and Holds("name:"..preferred_language) then return true end 774 - -- then set any additional languages 775 - for i,lang in ipairs(additional_languages) do 776 - if Holds("name:"..lang) then return true end 777 - end 778 - return false 779 - end 780 - 781 - -- Set name attributes on any object 782 - function SetNameAttributes() 783 - local name = Find("name"), iname 784 - local main_written = name 785 - -- if we have a preferred language, then write that (if available), and additionally write the base name tag 786 - if preferred_language and Holds("name:"..preferred_language) then 787 - iname = Find("name:"..preferred_language) 788 - Attribute(preferred_language_attribute, iname) 789 - if iname~=name and default_language_attribute then 790 - Attribute(default_language_attribute, name) 791 - else main_written = iname end 792 - else 793 - Attribute(preferred_language_attribute, name) 794 - end 795 - -- then set any additional languages 796 - for i,lang in ipairs(additional_languages) do 797 - iname = Find("name:"..lang) 798 - if iname=="" then iname=name end 799 - if iname~=main_written then Attribute("name:"..lang, iname) end 800 - end 801 - end 802 - 803 - -- Set ele and ele_ft on any object 804 - function SetEleAttributes() 805 - local ele = Find("ele") 806 - if ele ~= "" then 807 - local meter = math.floor(tonumber(ele) or 0) 808 - local feet = math.floor(meter * 3.2808399) 809 - AttributeNumeric("ele", meter) 810 - AttributeNumeric("ele_ft", feet) 811 - end 812 - end 813 - 814 - function SetBrunnelAttributes() 815 - if Find("bridge") == "yes" or Find("man_made") == "bridge" then Attribute("brunnel", "bridge") 816 - elseif Find("tunnel") == "yes" then Attribute("brunnel", "tunnel") 817 - elseif Find("ford") == "yes" then Attribute("brunnel", "ford") 818 - end 819 - end 820 - 821 - -- Set minimum zoom level by area 822 - function SetMinZoomByArea() 823 - SetMinZoomByAreaWithLimit(0) 824 - end 825 - 826 - -- Set minimum zoom level by area but not below given minzoom 827 - function SetMinZoomByAreaWithLimit(minzoom) 828 - local area=Area() 829 - if minzoom <= 6 and area>ZRES5^2 then MinZoom(6) 830 - elseif minzoom <= 7 and area>ZRES6^2 then MinZoom(7) 831 - elseif minzoom <= 8 and area>ZRES7^2 then MinZoom(8) 832 - elseif minzoom <= 9 and area>ZRES8^2 then MinZoom(9) 833 - elseif minzoom <= 10 and area>ZRES9^2 then MinZoom(10) 834 - elseif minzoom <= 11 and area>ZRES10^2 then MinZoom(11) 835 - elseif minzoom <= 12 and area>ZRES11^2 then MinZoom(12) 836 - elseif minzoom <= 13 and area>ZRES12^2 then MinZoom(13) 837 - else MinZoom(14) end 838 - end 839 - 840 - -- Calculate POIs (typically rank 1-4 go to 'poi' z12-14, rank 5+ to 'poi_detail' z14) 841 - -- returns rank, class, subclass 842 - function GetPOIRank() 843 - local k,list,v,class,rank 844 - 845 - -- Can we find the tag? 846 - for k,list in pairs(poiTags) do 847 - if list[Find(k)] then 848 - v = Find(k) -- k/v are the OSM tag pair 849 - class = poiClasses[v] or k 850 - rank = poiClassRanks[class] or 25 851 - subclassKey = poiSubClasses[v] 852 - if subclassKey then 853 - class = v 854 - v = Find(subclassKey) 855 - end 856 - return rank, class, v 857 - end 858 - end 859 - 860 - -- Catch-all for shops 861 - local shop = Find("shop") 862 - if shop~="" then return poiClassRanks['shop'], "shop", shop end 863 - 864 - -- Nothing found 865 - return nil,nil,nil 866 - end 867 - 868 - function SetBuildingHeightAttributes() 869 - local height = tonumber(Find("height"), 10) 870 - local minHeight = tonumber(Find("min_height"), 10) 871 - local levels = tonumber(Find("building:levels"), 10) 872 - local minLevel = tonumber(Find("building:min_level"), 10) 873 - 874 - local renderHeight = BUILDING_FLOOR_HEIGHT 875 - if height or levels then 876 - renderHeight = height or (levels * BUILDING_FLOOR_HEIGHT) 877 - end 878 - local renderMinHeight = 0 879 - if minHeight or minLevel then 880 - renderMinHeight = minHeight or (minLevel * BUILDING_FLOOR_HEIGHT) 881 - end 882 - 883 - -- Fix upside-down buildings 884 - if renderHeight < renderMinHeight then 885 - renderHeight = renderHeight + renderMinHeight 886 - end 887 - 888 - AttributeNumeric("render_height", renderHeight) 889 - AttributeNumeric("render_min_height", renderMinHeight) 890 - end 891 - 892 - -- Implement z_order as calculated by Imposm 893 - -- See https://imposm.org/docs/imposm3/latest/mapping.html#wayzorder for details. 894 - function SetZOrder() 895 - local highway = Find("highway") 896 - local layer = tonumber(Find("layer")) 897 - local bridge = Find("bridge") 898 - local tunnel = Find("tunnel") 899 - local zOrder = 0 900 - if bridge ~= "" and bridge ~= "no" then 901 - zOrder = zOrder + 10 902 - elseif tunnel ~= "" and tunnel ~= "no" then 903 - zOrder = zOrder - 10 904 - end 905 - if not (layer == nil) then 906 - if layer > 7 then 907 - layer = 7 908 - elseif layer < -7 then 909 - layer = -7 910 - end 911 - zOrder = zOrder + layer * 10 912 - end 913 - local hwClass = 0 914 - -- See https://github.com/omniscale/imposm3/blob/53bb80726ca9456e4a0857b38803f9ccfe8e33fd/mapping/columns.go#L251 915 - if highway == "motorway" then 916 - hwClass = 9 917 - elseif highway == "trunk" then 918 - hwClass = 8 919 - elseif highway == "primary" then 920 - hwClass = 6 921 - elseif highway == "secondary" then 922 - hwClass = 5 923 - elseif highway == "tertiary" then 924 - hwClass = 4 925 - else 926 - hwClass = 3 927 - end 928 - zOrder = zOrder + hwClass 929 - ZOrder(zOrder) 930 - end 931 - 932 - -- ========================================================== 933 - -- Lua utility functions 934 - 935 - function split(inputstr, sep) -- https://stackoverflow.com/a/7615129/4288232 936 - if sep == nil then 937 - sep = "%s" 938 - end 939 - local t={} ; i=1 940 - for str in string.gmatch(inputstr, "([^"..sep.."]+)") do 941 - t[i] = str 942 - i = i + 1 943 - end 944 - return t 945 - end 946 - 947 - -- vim: tabstop=2 shiftwidth=2 noexpandtab
+12 -12
www/models/schema/v0.ts
··· 1 - import { z } from '@zod/zod' 1 + import { z } from '@zod/zod/mini' 2 2 3 3 export const SearchHistoryEntry = z.object({ 4 4 query: z.string(), ··· 9 9 export const Bookmark = z.object({ 10 10 id: z.string(), 11 11 name: z.string(), 12 - address: z.string().optional(), 12 + address: z.optional(z.string()), 13 13 lat: z.number(), 14 14 lng: z.number(), 15 - zoom: z.number().default(12), 16 - folderId: z.string().nullable().default(null), 15 + zoom: z._default(z.number(), 12), 16 + folderId: z._default(z.nullable(z.string()), null), 17 17 createdAt: z.string(), 18 18 }) 19 19 export type Bookmark = z.infer<typeof Bookmark> ··· 33 33 export type LastView = z.infer<typeof LastView> 34 34 35 35 export const StoreState = z.object({ 36 - version: z.string().optional(), 37 - searchHistory: z.array(SearchHistoryEntry).default([]), 38 - bookmarks: z.array(Bookmark).default([]), 39 - bookmarkFolders: z.array(BookmarkFolder).default([]), 40 - geocodingBookmarksEnabled: z.boolean().default(false), 41 - onlineSearchEnabled: z.boolean().default(true), 42 - lastView: LastView.nullable().default(null), 36 + version: z.optional(z.string()), 37 + searchHistory: z._default(z.array(SearchHistoryEntry), []), 38 + bookmarks: z._default(z.array(Bookmark), []), 39 + bookmarkFolders: z._default(z.array(BookmarkFolder), []), 40 + geocodingBookmarksEnabled: z._default(z.boolean(), false), 41 + onlineSearchEnabled: z._default(z.boolean(), true), 42 + lastView: z._default(z.nullable(LastView), null), 43 43 }) 44 44 export type StoreState = z.infer<typeof StoreState> 45 45 46 46 export const AppState = z.object({ 47 - error: z.string().nullable().default(null), 47 + error: z._default(z.nullable(z.string()), null), 48 48 }) 49 49 export type AppState = z.infer<typeof AppState>
+1 -1
www/robots.txt
··· 1 1 User-agent: * 2 - Disallow: /static/gen/ 2 + Disallow: /static/tiles/ 3 3 Disallow: /dist/
+11 -5
www/routes/map.ts
··· 14 14 // Track which sources have been registered with the protocol across navigations 15 15 const registeredSources = new Set<string>() 16 16 17 - const DETAIL_TILES = [ 18 - { name: 'monaco', filename: 'monaco.pmtiles' }, 19 - { name: 'taiwan', filename: 'taiwan.pmtiles' }, 20 - ] 17 + async function fetchTileManifest(): Promise<{ name: string; filename: string }[]> { 18 + try { 19 + const res = await fetch('/static/tiles/tiles.json') 20 + if (!res.ok) return [] 21 + const entries = await res.json() as { id: string; filename: string }[] 22 + return entries.map((e) => ({ name: e.id, filename: e.filename })) 23 + } catch { 24 + return [] 25 + } 26 + } 21 27 22 28 export class MapPage extends LitElement { 23 29 #map: maplibregl.Map | null = null ··· 298 304 299 305 async #loadCachedDetailTiles(): Promise<void> { 300 306 if (!this.#map) return 301 - for (const tile of DETAIL_TILES) { 307 + for (const tile of await fetchTileManifest()) { 302 308 if (this.#map.getSource(tile.name)) continue 303 309 const pmtiles = await getCachedPMTiles(tile.filename) 304 310 if (!pmtiles) continue
www/static/brand/icon.png

This is a binary file and will not be displayed.

www/static/brand/spec.afdesign

This is a binary file and will not be displayed.