diff --git a/README.md b/README.md index 8494b1e..421da8b 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The map can optionally animate if you specify the following parameters: ### Language -By default, map labels appear in your preferred language according to [your browser preferences](https://www.w3.org/International/questions/qa-lang-priorities#changing). You can also override this preference by setting the `language` parameter to an ISO 639 language code. For example, add `&language=grc&date=-0999` to see [Middle Babylon labeled in Ancient Greek](https://embed.openhistoricalmap.org/#map=14/32.5423/44.42123&language=grc&date=-0999) or `&language=la&date=-0999` to see it [in Latin](https://embed.openhistoricalmap.org/#map=14/32.5423/44.42123&date=-0999&language=la) instead of the contemporary cuneiform. If OHM doesn’t have the name of a place in this preferred language, the label appears in the contemporary local language as a last resort. To force the display of names in contemporary local languages, set the `language` parameter to `mul` (the ISO 639 code for multilingual content). +By default, map labels appear in your preferred language according to [your browser preferences](https://www.w3.org/International/questions/qa-lang-priorities#changing). You can also override this preference by setting the `language` parameter to an [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag) (such as an ISO 639 language code). For example, add `&language=grc&date=-0999` to see [Middle Babylon labeled in Ancient Greek](https://embed.openhistoricalmap.org/#map=14/32.5423/44.42123&language=grc&date=-0999) or `&language=la&date=-0999` to see it [in Latin](https://embed.openhistoricalmap.org/#map=14/32.5423/44.42123&date=-0999&language=la) instead of the contemporary cuneiform. If OHM doesn’t have the name of a place in this preferred language, the label appears in the contemporary local language as a last resort. To force the display of names in contemporary local languages, set the `language` parameter to `mul` (the ISO 639 code for multilingual content). ## Embedding diff --git a/index.js b/index.js index 2bc5d16..23ceb61 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ import { filterByDate, dateRangeFromISODate } from '@openhistoricalmap/maplibre-gl-dates'; import maplibregl from 'maplibre-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; -import MapboxLanguage from '@mapbox/mapbox-gl-language'; +import { localizeStyle, getLocales } from '@americana/diplomat'; var attribution = 'OpenHistoricalMap'; var stylesByLayer = { @@ -45,23 +45,6 @@ addEventListener('load', function () { map.addControl(new maplibregl.GlobeControl(), 'top-left'); map.addControl(new maplibregl.FullscreenControl(), 'top-left'); - let languageCode = params.get('language'); - let language = new MapboxLanguage({ - defaultLanguage: languageCode, - supportedLanguages: languageCode ? [languageCode] : undefined, - languageSource: 'osm', - getLanguageField: (languageCode) => { - if (languageCode === 'mul') { - return 'name'; - } else { - // Optimistically follow the pattern in the tiler tag mapping without hard-coding the specific table columns. - // https://github.com/OpenHistoricalMap/ohm-deploy/blob/main/images/tiler-server/config/languages.sql - return 'name_' + languageCode.replace('-', '_').toLowerCase(); - } - }, - }); - map.addControl(language); - let markerLongitude = parseFloat(params.get('mlon')), markerLatitude = parseFloat(params.get('mlat')), @@ -82,6 +65,10 @@ addEventListener('load', function () { .addTo(map); } + let localizationOptions = { + localizedNamePropertyFormat: "name_$1", + }; + map.once('styledata', function (event) { if (params.get('projection')) { map.setProjection({ @@ -96,6 +83,13 @@ addEventListener('load', function () { let date = params.get('date') || new Date(); filterByDate(map, date); + + localizeStyle(map, getLocales(), { + ...localizationOptions, + sourceLayers: ["place_points_centroids"], + glossLocalNames: true, + }); + localizeStyle(map, getLocales(), localizationOptions); }); addEventListener('hashchange', function (event) { @@ -106,13 +100,7 @@ addEventListener('load', function () { let oldLanguageCode = oldParams.get('language'); let newLanguageCode = newParams.get('language'); if (oldLanguageCode !== newLanguageCode) { - if (!language.supportedLanguages.includes(newLanguageCode)) { - // mapbox-gl-language assumes a limited set of language fields that is known in advance, as is the case with the Mapbox Streets source. But OHM tiles support hundreds of sparsely populated fields. - language.supportedLanguages.push(newLanguageCode); - } - let newStyle = language.setLanguage(map.getStyle(), newLanguageCode); - // Style diffing seems to miss changes to expression variable values for some reason. - map.setStyle(newStyle, { diff: false }); + localizeStyle(map, getLocales(), localizationOptions); } if (oldParams.get('projection') !== newParams.get('projection')) { @@ -137,6 +125,10 @@ addEventListener('load', function () { }); }); +addEventListener("languagechange", function (event) { + localizeStyle(map, getLocales(), localizationOptions); +}); + function upgradeLegacyHash() { var hash = location.hash.substring(1); if (!hash.includes('=')) { diff --git a/package-lock.json b/package-lock.json index 11b8b1e..752d762 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "CC0-1.0", "dependencies": { - "@mapbox/mapbox-gl-language": "^1.0.1", + "@americana/diplomat": "^0.3.0", "@mapbox/mapbox-gl-rtl-text": "^0.3.0", "@openhistoricalmap/maplibre-gl-dates": "^1.3.0", "maplibre-gl": "^5.13.0" @@ -19,6 +19,15 @@ "shx": "^0.4.0" } }, + "node_modules/@americana/diplomat": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@americana/diplomat/-/diplomat-0.3.0.tgz", + "integrity": "sha512-+bMNzOpFCR+GdiMbjA6n0R6h/muIu9JzdKsooq5cPqBtdPc3+eH7CiQkr5w4RqXNRUWe4P1iArrqTyze7AKqAw==", + "license": "CC0-1.0", + "peerDependencies": { + "maplibre-gl": "^5.13.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", @@ -482,35 +491,12 @@ "node": ">= 0.6" } }, - "node_modules/@mapbox/mapbox-gl-language": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-language/-/mapbox-gl-language-1.0.1.tgz", - "integrity": "sha512-gL58ojl7gaWLfbSISoB2QJEfTK3j+NKvPH9og0r+c3bd5BNqhY19Eb4OPfDc5+dGmjW03LhtZBc4n2b7Xn8kjA==", - "license": "BSD-3-Clause", - "peerDependencies": { - "mapbox-gl": ">=0.29.0" - } - }, "node_modules/@mapbox/mapbox-gl-rtl-text": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-rtl-text/-/mapbox-gl-rtl-text-0.3.0.tgz", "integrity": "sha512-OwQplFqAAEYRobrTKm2wiVP+wcpUVlgXXiUMNQ8tcm5gPN5SQRXFADmITdQOaec4LhDhuuFchS7TS8ua8dUl4w==", "license": "BSD-2-Clause" }, - "node_modules/@mapbox/mapbox-gl-supported": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-3.0.0.tgz", - "integrity": "sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==", - "license": "BSD-3-Clause", - "peer": true - }, - "node_modules/@mapbox/point-geometry": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", - "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==", - "license": "ISC", - "peer": true - }, "node_modules/@mapbox/tiny-sdf": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.7.tgz", @@ -523,16 +509,6 @@ "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", "license": "BSD-2-Clause" }, - "node_modules/@mapbox/vector-tile": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", - "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "@mapbox/point-geometry": "~0.1.0" - } - }, "node_modules/@mapbox/whoots-js": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", @@ -683,32 +659,6 @@ "@types/geojson": "*" } }, - "node_modules/@types/mapbox__point-geometry": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", - "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==", - "license": "MIT", - "peer": true - }, - "node_modules/@types/mapbox__vector-tile": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", - "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/geojson": "*", - "@types/mapbox__point-geometry": "*", - "@types/pbf": "*" - } - }, - "node_modules/@types/pbf": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", - "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", - "license": "MIT", - "peer": true - }, "node_modules/@types/supercluster": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", @@ -731,13 +681,6 @@ "node": ">=8" } }, - "node_modules/cheap-ruler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cheap-ruler/-/cheap-ruler-4.0.0.tgz", - "integrity": "sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==", - "license": "ISC", - "peer": true - }, "node_modules/cross-spawn": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", @@ -775,13 +718,6 @@ "which": "bin/which" } }, - "node_modules/csscolorparser": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", - "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==", - "license": "MIT", - "peer": true - }, "node_modules/earcut": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", @@ -899,13 +835,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT", - "peer": true - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -966,13 +895,6 @@ "node": ">= 6" } }, - "node_modules/grid-index": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", - "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==", - "license": "ISC", - "peer": true - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -986,27 +908,6 @@ "node": ">= 0.4" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -1088,55 +989,6 @@ "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", "license": "ISC" }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "license": "MIT", - "peer": true - }, - "node_modules/mapbox-gl": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.5.2.tgz", - "integrity": "sha512-KUrmDmLFKPp3MSsWGNTH5uvtYwJknV+eFJ+vxiN6hqKpzbme37z+JfYs5Mehs3CgFaIV/pUdnEV9UPUZJPuS+Q==", - "license": "SEE LICENSE IN LICENSE.txt", - "peer": true, - "workspaces": [ - "src/style-spec", - "test/build/typings" - ], - "dependencies": { - "@mapbox/jsonlint-lines-primitives": "^2.0.2", - "@mapbox/mapbox-gl-supported": "^3.0.0", - "@mapbox/point-geometry": "^0.1.0", - "@mapbox/tiny-sdf": "^2.0.6", - "@mapbox/unitbezier": "^0.0.1", - "@mapbox/vector-tile": "^1.3.1", - "@mapbox/whoots-js": "^3.1.0", - "@types/geojson": "^7946.0.14", - "@types/mapbox__vector-tile": "^1.3.4", - "cheap-ruler": "^4.0.0", - "csscolorparser": "~1.0.3", - "earcut": "^3.0.0", - "fflate": "^0.8.1", - "geojson-vt": "^4.0.2", - "gl-matrix": "^3.4.3", - "grid-index": "^1.1.0", - "kdbush": "^4.0.2", - "lodash.clonedeep": "^4.5.0", - "murmurhash-js": "^1.0.0", - "pbf": "^3.2.1", - "potpack": "^2.0.0", - "quickselect": "^3.0.0", - "rw": "^1.3.3", - "serialize-to-js": "^3.1.2", - "supercluster": "^8.0.1", - "tiny-lru": "^11.2.11", - "tinyqueue": "^3.0.0", - "tweakpane": "^4.0.4", - "vt-pbf": "^3.1.3" - } - }, "node_modules/maplibre-gl": { "version": "5.13.0", "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.13.0.tgz", @@ -1300,20 +1152,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pbf": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", - "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "ieee754": "^1.1.12", - "resolve-protobuf-schema": "^2.1.0" - }, - "bin": { - "pbf": "bin/pbf" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1470,16 +1308,6 @@ "semver": "bin/semver" } }, - "node_modules/serialize-to-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.1.2.tgz", - "integrity": "sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -1578,16 +1406,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tiny-lru": { - "version": "11.2.11", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.2.11.tgz", - "integrity": "sha512-27BIW0dIWTYYoWNnqSmoNMKe5WIbkXsc0xaCQHd3/3xT2XMuMJrzHdrO9QBFR14emBz1Bu0dOAs2sCBBrvgPQA==", - "license": "BSD-3-Clause", - "peer": true, - "engines": { - "node": ">=12" - } - }, "node_modules/tinyqueue": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", @@ -1607,28 +1425,6 @@ "node": ">=8.0" } }, - "node_modules/tweakpane": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tweakpane/-/tweakpane-4.0.4.tgz", - "integrity": "sha512-RkWD54zDlEbnN01wQPk0ANHGbdCvlJx/E8A1QxhTfCbX+ROWos1Ws2MnhOm39aUGMOh+36TjUwpDmLfmwTr1Fg==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/cocopon" - } - }, - "node_modules/vt-pbf": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", - "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@mapbox/point-geometry": "0.1.0", - "@mapbox/vector-tile": "^1.3.1", - "pbf": "^3.2.1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index cf1745e..481ba22 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "shx": "^0.4.0" }, "dependencies": { - "@mapbox/mapbox-gl-language": "^1.0.1", + "@americana/diplomat": "^0.3.0", "@mapbox/mapbox-gl-rtl-text": "^0.3.0", "@openhistoricalmap/maplibre-gl-dates": "^1.3.0", "maplibre-gl": "^5.13.0"