Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial description of pmtilesRules new required structure #165

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 61 additions & 15 deletions docs/user-guide/creating-styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,65 @@ Working examples of `<mapml-viewer>` usage of themes and styles are [available o

## How to create a stylesheet module

A pmtiles stylesheet used in the MapML polyfill is a JavaScript module source file which exports a
single symbol, which **must be** named `pmtilesRules`:
A pmtiles stylesheet used in the MapML polyfill is a JavaScript module source file which exports
two symbols, a `pmtilesRules` Map instance, and a Promise-valued `pmtilesRulesReady`, which is resolved when
the required Sheet is loaded, per the following example:

```javascript
const sheet = new protomapsL.Sheet(`
<html>
<body>
<svg id="icon_0" width="99px" height="97px" xmlns="http://www.w3.org/2000/svg">
<image href="data:image/svg+xml;base64,PHN2ZyBpZD0iaWNvbl82NCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgICAgPGltYWdlIGhyZWY9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBWUFBQUFmOC85aEFBQUFDWEJJV1hNQUFBN0VBQUFPeEFHVkt3NGJBQUFBMlVsRVFWUjRuTldQTVdvQ1lSQ0Z2MElDZ2xZaFZnRUwzZmNyZGlsczBteVJUdkFLa2xaSXdKM2ZpTjE2aGhoeUFCRkVjZ2J2WUtFbmtCUkpiNWtFSlRheXNNdFd5WVBYRFBPOW1RZC9YcjVHSlRkc1Rhb21wdm12TzBZbVB1T1FRcjRQeE5yRXR3L29wQzdITFM1TVRFd3NEdmFPdHdOOERCRGIwenh5eklkMWJoSkQraTFLWHN4T1lJSjN2a0dZM2ozZ1BnRmVqUnRjWnVvK2ROeWVCM2l4Skt0TXZQeUNtMGc4bS9neXNYOXlsRlBoT0tUZ3hZYzVYZ2ZYRkkrVnhKMkpkeE85MUlDQmFFZU83dm44b2M2VkQzak1YT1AvNkFmS0Ywd3dXeU9Oc3dBQUFBQkpSVTVFcmtKZ2dnPT0iIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIvPgogICAgPC9zdmc+" width="99" height="97" />
</svg>
</body>
</html>
`);
const pmtilesRules = new Map();
...
pmtilesRules.set(
'https://maps4html.org/experiments/vector-tiles/pmtiles/spearfish.pmtiles?theme=light',
{ theme: { theme: 'light' } }
);
...
export { pmtilesRules };
const pmtilesRulesReady = sheet.load().then(() => {
...
pmtilesRules.set(
'https://maps4html.org/experiments/vector-tiles/pmtiles/spearfish.pmtiles?theme=light',
{ theme: { theme: 'light' } }
);
...
return pmtilesRules;
});
export { pmtilesRules, pmtilesRulesReady };
```
:::tip

Pre-defined themes that you can use include: `light`, `dark`, `white`, `grayscale` and `black`. You should include the theme name in the URL template as a parameter (even though it is not required by the pmtiles or mvt resource), so that the URL template can be made unique and distinct from other pmtilesRules keys' use of the same pmtiles or mvt resource.

:::

## The required structure of the pmtiles 'stylesheet'

The stylesheet module must export two symbols: `pmtilesRulesReady` and `pmtilesRules`.

The `pmtilesRulesReady` export must be a Promise that signals to the MapML library that
the pmttilesRules export is fully defined and ready for rendering. If your stylesheet
uses IconSymbolizer, it may be convenient to perform resource loading and processing
via the asynchronous Sheet.load() function, which itself returns a Promise object that
may be returned by your stylesheet as the pmtilesRulesReady value, as
shown in the example above. If your stylesheet does not require icons, it should
be possible to assign an already-resolved promise as the value of pmtilesRulesReady,
via Promise.resolve(), and return that.

```javascript
const pmtilesRules = new Map();
// a Map requires a key, in this case the absolute URL of the data source (but,
// can also be the absolute value of the URL _template_ for the data source),
// and an object to be mapped by the key, in this case, an object with a `theme`
// member, whose value is itself an object with a `theme` member.
pmtilesRules.set(
'https://maps4html.org/experiments/vector-tiles/pmtiles/spearfish.pmtiles?theme=light',
{ theme: { theme: 'light' } }
);
const pmtilesRulesReady = Promise.resolve();
export { pmtilesRules, pmtilesRulesReady };
```

The `pmtilesRules` export must be a [JavaScript Map-type object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), structured as follows:

- must have a unique URL template string key that will be used on the web to identify a set of rules
Expand Down Expand Up @@ -77,30 +117,36 @@ class SpearfishSymbolizer {
context.fill();
}
}
// the only other pmtilesRules keyed value besides `theme` that is supported is
// an object with a `rules` member. The value of the `rules` member is an object
// that has two optional array-valued members, `PAINT_RULES` and `LABEL_RULES`.
const pmtilesRules = new Map();
pmtilesRules.set(
'http://localhost:8080/geoserver/gwc/service/wmts/rest/spearfish/OSMTILE/{z}/{y}/{x}?format=application/vnd.mapbox-vector-tile',
{
// PAINT_RULES and LABEL_RULES are each an array of dataLayer/symbolizer objects, with optional
// function-valued `filter` member (filter is a member of the same object as
// dataLayer and symbolizer, not a property of those objects).
rules: {
PAINT_RULES: [
{
dataLayer: 'streams',
symbolizer: new M.protomapsL.LineSymbolizer({ color: 'steelblue', width: 2 })
symbolizer: new protomapsL.LineSymbolizer({ color: 'steelblue', width: 2 })
},
{
dataLayer: 'roads',
symbolizer: new M.protomapsL.LineSymbolizer({ color: 'maroon', width: 2 })
symbolizer: new protomapsL.LineSymbolizer({ color: 'maroon', width: 2 })
},
{
dataLayer: 'restricted',
symbolizer: new M.protomapsL.PolygonSymbolizer({
symbolizer: new protomapsL.PolygonSymbolizer({
fill: 'red',
opacity: 0.5
})
},
{
dataLayer: 'restricted',
symbolizer: new M.protomapsL.LineSymbolizer({ color: 'red', width: 2 })
symbolizer: new protomapsL.LineSymbolizer({ color: 'red', width: 2 })
},
{
dataLayer: 'archsites',
Expand All @@ -120,7 +166,7 @@ pmtilesRules.set(
LABEL_RULES: [
{
dataLayer: 'archsites',
symbolizer: new M.protomapsL.CenteredTextSymbolizer({
symbolizer: new protomapsL.CenteredTextSymbolizer({
labelProps: ['str1'],
fill:'white',
width:2,
Expand All @@ -139,7 +185,7 @@ export { pmtilesRules };

## Available imported symbols from protomaps-leaflet

The following imports from protomaps-leaflet are available on the `M.protomapsL` global variable e.g. `M.protomapsL.CenteredSymbolizer`, for use by your stylesheets:
The following imports from protomaps-leaflet are available on the `protomapsL` import, for use by your stylesheets:

```javascript
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,29 @@ Des exemples pratiques de l'utilisation des thèmes et des styles par `<mapml-vi

## Comment créer un module de feuille de style

Une feuille de style pmtiles utilisée dans le polyfill MapML est un fichier source de module JavaScript qui exporte un seul symbole, qui doit être nommé `pmtilesRules` :
Une feuille de style pmtiles utilisée dans le polyfill MapML est un fichier source de module JavaScript qui exporte deux symboles, une instance de « Map “ `pmtilesRules`, et une promesse `pmtilesRulesReady`, qui est résolue lorsque le « Sheet » requis est chargé, selon l'exemple suivant :

```javascript
const sheet = new protomapsL.Sheet(`
<html>
<body>
<svg id="icon_0" width="99px" height="97px" xmlns="http://www.w3.org/2000/svg">
<image href="data:image/svg+xml;base64,PHN2ZyBpZD0iaWNvbl82NCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgICAgPGltYWdlIGhyZWY9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBWUFBQUFmOC85aEFBQUFDWEJJV1hNQUFBN0VBQUFPeEFHVkt3NGJBQUFBMlVsRVFWUjRuTldQTVdvQ1lSQ0Z2MElDZ2xZaFZnRUwzZmNyZGlsczBteVJUdkFLa2xaSXdKM2ZpTjE2aGhoeUFCRkVjZ2J2WUtFbmtCUkpiNWtFSlRheXNNdFd5WVBYRFBPOW1RZC9YcjVHSlRkc1Rhb21wdm12TzBZbVB1T1FRcjRQeE5yRXR3L29wQzdITFM1TVRFd3NEdmFPdHdOOERCRGIwenh5eklkMWJoSkQraTFLWHN4T1lJSjN2a0dZM2ozZ1BnRmVqUnRjWnVvK2ROeWVCM2l4Skt0TXZQeUNtMGc4bS9neXNYOXlsRlBoT0tUZ3hZYzVYZ2ZYRkkrVnhKMkpkeE85MUlDQmFFZU83dm44b2M2VkQzak1YT1AvNkFmS0Ywd3dXeU9Oc3dBQUFBQkpSVTVFcmtKZ2dnPT0iIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIvPgogICAgPC9zdmc+" width="99" height="97" />
</svg>
</body>
</html>
`);
const pmtilesRules = new Map();
...
pmtilesRules.set(
'https://maps4html.org/experiments/vector-tiles/pmtiles/spearfish.pmtiles?theme=light',
{ theme: { theme: 'light' } }
);
...
export { pmtilesRules };
const pmtilesRulesReady = sheet.load().then(() => {
...
pmtilesRules.set(
'https://maps4html.org/experiments/vector-tiles/pmtiles/spearfish.pmtiles?theme=light',
{ theme: { theme: 'light' } }
);
...
return pmtilesRules;
});
export { pmtilesRules, pmtilesRulesReady };
```
:::tip

Expand All @@ -54,6 +66,26 @@ rendu unique et distinct des autres clés `pmtilesRules` utilisant la même ress

:::

## La structure requise de la « feuille de style » de pmtiles

Le module de feuille de style doit exporter deux symboles : `pmtilesRulesReady` et `pmtilesRules`.

L'export `pmtilesRulesReady` doit être une promesse qui signale à la bibliothèque MapML que l'export pmttilesRules est entièrement défini et prêt pour le rendu. Si votre feuille de style utilise IconSymbolizer, il peut être pratique d'effectuer le chargement et le traitement des ressources via la fonction asynchrone Sheet.load(), qui renvoie elle-même un objet Promise qui peut être renvoyé par votre feuille de style en tant que valeur pmtilesRulesReady, comme dans l'exemple ci-dessus. Si votre feuille de style ne nécessite pas d'icônes, il devrait être possible d'assigner un objet Promise déjà résolue comme valeur de pmtilesRulesReady, via Promise.resolve(), et de la retourner.

```javascript
const pmtilesRules = new Map() ;
// une Map nécessite une clé, dans ce cas l'URL absolue de la source de données (mais,
// peut aussi être la valeur absolue de l'URL _template_ de la source de données),
// et un objet à mapper par la clé, dans ce cas, un objet avec un membre `theme`
// dont la valeur est elle-même un objet avec un membre `theme`.
pmtilesRules.set(
'https://maps4html.org/experiments/vector-tiles/pmtiles/spearfish.pmtiles?theme=light',
{ theme : { theme : 'light' } }
) ;
const pmtilesRulesReady = Promise.resolve() ;
export { pmtilesRules, pmtilesRulesReady } ;
```

L'export `pmtilesRules` doit être un [JavaScript Map-type object](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Map), structuré comme suit :

- doit avoir une clé unique de type « URL template string » qui sera utilisée sur le web pour identifier un ensemble de règles
Expand Down Expand Up @@ -87,30 +119,37 @@ class SpearfishSymbolizer {
context.fill();
}
}
// la seule autre valeur de clé pmtilesRules en plus de `theme` qui est supportée est
// un objet avec un membre `rules`. La valeur du membre `rules` est un objet
// qui a deux membres optionnels de type tableau, `PAINT_RULES` et `LABEL_RULES`.
const pmtilesRules = new Map();
pmtilesRules.set(
'http://localhost:8080/geoserver/gwc/service/wmts/rest/spearfish/OSMTILE/{z}/{y}/{x}?format=application/vnd.mapbox-vector-tile',
{
// PAINT_RULES et LABEL_RULES sont chacun un tableau d'objets dataLayer/symbolizer,
// avec un membre facultatif `filter` à valeur de fonction (le filtre est
// membre du même objet que celui de l'objet dataLayer et symbolizer, et non pas
// une propriété de ces objets).
rules: {
PAINT_RULES: [
{
dataLayer: 'streams',
symbolizer: new M.protomapsL.LineSymbolizer({ color: 'steelblue', width: 2 })
symbolizer: new protomapsL.LineSymbolizer({ color: 'steelblue', width: 2 })
},
{
dataLayer: 'roads',
symbolizer: new M.protomapsL.LineSymbolizer({ color: 'maroon', width: 2 })
symbolizer: new protomapsL.LineSymbolizer({ color: 'maroon', width: 2 })
},
{
dataLayer: 'restricted',
symbolizer: new M.protomapsL.PolygonSymbolizer({
symbolizer: new protomapsL.PolygonSymbolizer({
fill: 'red',
opacity: 0.5
})
},
{
dataLayer: 'restricted',
symbolizer: new M.protomapsL.LineSymbolizer({ color: 'red', width: 2 })
symbolizer: new protomapsL.LineSymbolizer({ color: 'red', width: 2 })
},
{
dataLayer: 'archsites',
Expand All @@ -130,7 +169,7 @@ pmtilesRules.set(
LABEL_RULES: [
{
dataLayer: 'archsites',
symbolizer: new M.protomapsL.CenteredTextSymbolizer({
symbolizer: new protomapsL.CenteredTextSymbolizer({
labelProps: ['str1'],
fill:'white',
width:2,
Expand All @@ -149,7 +188,7 @@ export { pmtilesRules };

## Symboles importés disponibles à partir de protomaps-leaflet

Les importations suivantes de protomaps-leaflet sont disponibles sur la variable globale `M.protomapsL`, par exemple `M.protomapsL.CenteredSymbolizer`, pour être utilisées par vos feuilles de style :
Les importations suivantes de protomaps-leaflet sont disponibles dans l'importation `protomapsL`, pour être utilisées par vos feuilles de style :

```javascript
/*
Expand Down
Loading