IGNF / geoportal-extensions

French Geoportal Extensions for well-known javascript mapping libraries (Leaflet and OpenLayers)
https://ignf.github.io/geoportal-extensions/
Other
64 stars 33 forks source link

Gestion de Leaflet en package par modules #344

Open lowzonenose opened 1 year ago

lowzonenose commented 1 year ago

PLUGINS LEAFLET

Split en modules

utilisation du script webpack pour splitter en modules

$ ./node_modules/.bin/webpack --config build/webpack/webpack.config.leaflet.modules --mode=production
$ ls dist/leaflet-modules/
    Common.css    CRS.js             Isocurve.js        MousePosition.css   Route.css         WMS.js
    Common.js     ElevationPath.css  Layers.js          MousePosition.js    Route.js          WMTS.js
    Controls.css  ElevationPath.js   LayerSwitcher.css  ReverseGeocode.css  SearchEngine.css
    Controls.js   Isocurve.css       LayerSwitcher.js   ReverseGeocode.js   SearchEngine.js

taille des modules

123K  Common.css    <!-- FIXME ? -->
5,1K  Common.js     <!-- FIXME ? -->
 64K  Controls.css
570K  Controls.js   <!-- INFO tous les composants avec dependances optimisées -->
163K  CRS.js
5,3K  ElevationPath.css
171K  ElevationPath.js
 24K  Isocurve.css
119K  Isocurve.js
 27K  Layers.js      <!-- INFO tous les composants avec dependances optimisées -->
 13K  LayerSwitcher.css
 60K  LayerSwitcher.js
8,2K  MousePosition.css
243K  MousePosition.js
7,5K  ReverseGeocode.css
148K  ReverseGeocode.js
 17K  Route.css
134K  Route.js
9,5K  SearchEngine.css
 93K  SearchEngine.js
 20K  WMS.js
 20K  WMTS.js

FIXME

carte des dépendances

./node_modules/.bin/webpack --config build/webpack/webpack.config.leaflet.modules --mode=none --profile --json > map-leaflet-modules.json

(nettoyer les 1ere lignes inutiles)

./node_modules/.bin/webpack-bundle-analyzer map-leaflet-modules.json

image

Utilisation des modules dans une page web

Il existe 2 modes pour intégrer les modules : Factory ou Classes

<html>
    <head>
    <link rel="stylesheet" href=".leaflet.css" />
        <script src="leaflet.js"></script>

        <script src="GpServices.js"></script>

    <script src="Layers.js"></script>
        <script src="Controls.js"></script>
        <link rel="stylesheet" href="Controls.css" />
    </head>
    <body>
        <div id="map"></div>
        <script>
        var createMap = function () {
          // on cache l'image de chargement du Géoportail.
          document.getElementById("map").style.backgroundImage = "none";

          // Création de la map
          var layer = L.geoportalLayer.WMTS({
        layer : "ORTHOIMAGERY.ORTHOPHOTOS"
          });

          var map  = L.map('map', {
        zoom : 2,
        center : L.latLng(48, 2)
          });

          layer.addTo(map);

          var iso = L.geoportalControl.Isocurve();
          map.addControl(iso);
          var layerSwitcher = L.geoportalControl.LayerSwitcher();
          map.addControl(layerSwitcher);
          var mp = L.geoportalControl.MousePosition();
          map.addControl(mp);
          var route = L.geoportalControl.Route();
          map.addControl(route);
          var reverse = L.geoportalControl.ReverseGeocode();
          map.addControl(reverse);
          var search = L.geoportalControl.SearchEngine();
          map.addControl(search);
          var measureProfil = L.geoportalControl.ElevationPath();
          map.addControl(measureProfil);
        };

        Gp.Services.getConfig({
        callbackSuffix : "",
        apiKey: "jhyvi0fgmnuxvfv0zjzorvdn",
        timeOut : 20000,
        onSuccess : createMap
        });
    </script>
    </body>
</html>
<html>
    <head>
    <link rel="stylesheet" href=".leaflet.css" />
        <script src="leaflet.js"></script>

        <script src="GpServices.js"></script>

    script src="WMTS.js"></script>

        <link rel="stylesheet" href="LayerSwitcher.css" />
        <script src="LayerSwitcher.js"></script>
        <link rel="stylesheet" href="Isocurve.css" />
        <script src="Isocurve.js"></script>
        <link rel="stylesheet" href="MousePosition.css" />
        <script src="MousePosition.js"></script>
        <link rel="stylesheet" href="Route.css" />
        <script src="Route.js"></script>
        <link rel="stylesheet" href="ReverseGeocode.css" />
        <script src="ReverseGeocode.js"></script>
        <link rel="stylesheet" href="SearchEngine.css" />
        <script src="SearchEngine.js"></script>
        <link rel="stylesheet" href="ElevationPath.css" />
        <script src="ElevationPath.js"></script>
    </head>
    <body>
        <div id="map"></div>
        <script>
        var createMap = function () {
          // on cache l'image de chargement du Géoportail.
          document.getElementById("map").style.backgroundImage = "none";

          // Création de la map
          var layer = new WMTS("http://wxs.ign.fr/jhyvi0fgmnuxvfv0zjzorvdn/geoportail/wmts", {
              paramsNative : {
                  minZoom : 1,
                  maxZoom : 21
              },
              paramsWmts   : {
                  layer   : "ORTHOIMAGERY.ORTHOPHOTOS",
                  style   : "normal",
                  format  : "image/jpeg",
                  version : "1.0.0",
                  tilematrixset : "PM"
              },
              originators  : [],
              legends      : [],
              metadata     : [],
              title        : "",
              description  : "",
              quicklookUrl : ""
          });

          var map  = L.map('map', {
        zoom : 2,
        center : L.latLng(48, 2)
          });

          layer.addTo(map);

          var iso = new Isocurve();
          map.addControl(iso);
          var layerSwitcher = new LayerSwitcher();
          map.addControl(layerSwitcher);
          var mp = new MousePosition();
          map.addControl(mp);
          var route = new Route();
          map.addControl(route);
          var reverse = new ReverseGeocode();
          map.addControl(reverse);
          var search = new SearchEngine();
          map.addControl(search);
          var measureProfil = new ElevationPath();
          map.addControl(measureProfil);
        };

        Gp.Services.getConfig({
        callbackSuffix : "",
        apiKey: "jhyvi0fgmnuxvfv0zjzorvdn",
        timeOut : 20000,
        onSuccess : createMap
        });
    </script>
    </body>
</html>

Exécution de la page de test

$ ./node_modules/.bin/webpack-dev-server --config build/webpack/webpack.config.leaflet.modules --mode=development --https --open-page samples/index-leaflet-modules-map.html --content-base . --output-public-path '/dist/leaflet-modules/' --port 9001 --open

Demo

cf. https://ignf.github.io/geoportal-extensions/

intégrer les démos des modules sur la github pages en statique. image

INFO

la publication dans le dépôt Leaflet impose d'avoir une demo. On peut donc maintenant fournir un lien !

TODO

finaliser les demos avec modules pour Leaflet / OpenLayers

Publication

script de publication (un répertoire / plugin) à exécuter via les github actions

préparation

$ cd build/scripts/release/
$ ./build-pack.sh -L

Les répertoires sont prêts pour la publication (+ tgz) :

$ cd build/scripts/release/
$ tree geoportail-extensions-leaflet-modules/
geoportal-extensions-leaflet-modules/
├── ElevationPath
├── ignf-geoportal-plugin-leaflet-elevationpath-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-isocurve-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-layers-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-layerswitcher-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-mouseposition-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-reversegeocode-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-route-2.2.7.tgz
├── ignf-geoportal-plugin-leaflet-searchengine-2.2.7.tgz
├── Isocurve
├── Layers
├── LayerSwitcher
├── MousePosition
├── ReverseGeocode
├── Route
└── SearchEngine

$ tree -L 2 geoportal-extensions-leaflet-modules/ElevationPath/
geoportal-extensions-leaflet-modules/ElevationPath/
├── dist
│   ├── ElevationPath.css
│   ├── ElevationPath.js
│   ├── ElevationPath-map.css
│   ├── ElevationPath-map.js
│   ├── ElevationPath-src.css
│   └── ElevationPath-src.js
├── LICENCE.md
├── package.json
├── README.md
└── src
    ├── Common
    │   ├── Controls
    │   │   ├── ElevationPathDOM.js
    │   │   └── ProfileElevationPathDOM.js
    │   └── Utils
    │       ├── AutoLoadConfig.js
    │       ├── CheckRightManagement.js
    │       ├── LoggerByDefault.js
    │       └── SelectorID.js
    └── Leaflet
        ├── Controls
        │   ├── ElevationPath.js
        │   └── Utils
        │       ├── IconDefault.js
        │       └── PositionFormater.js
        └── CSS
            └── Controls
                └── ElevationPath
                    └── GPelevationPathLeaflet.css

FIXME trouver un namespace avec les infos : ignf / geoportal / plugin / leaflet ex. @ignf-geoportal/plugin-leaflet-elevationpath

TODO

  • mettre en place des README personnalisés pour chaque widget.
  • ajouter un exemple

publication via npm

Le script nous fournit les répertoire de publication par widget. Il nous reste donc à mettre en place ou modifier le job de publication des github actions.

TODO

opération à réaliser via les github actions

Guide d’intégration dans le dépôt Leaflet

cf. https://github.com/Leaflet/Leaflet/blob/main/PLUGIN-GUIDE.md

TODO

lister les actions obligatoires pour pouvoir intégrer nos modules dans le dépôts Leaflet (ex. demo)

lowzonenose commented 1 year ago

BUG

il semble avoir un bug sur l'utilisation du contrôle Isochrone : la requête ne passe pas car le point de saisie n'est pas correctement renvoyé au service !?

azarz commented 1 year ago

Beau travail :)

Pour le CSS, pour moi ce n'est pas rédhibitoire qu'il n'y en ait qu'un : il suffit d'avoir un lien statiques (cdnjs, raw.github) et de documenter que peu importe le widget, il faut linker le CSS dans le après le CSS leaflet et avant le CSS custom.

J'essaie de regarder le souci sur isochrone

lowzonenose commented 1 year ago

RaF / Questions

@azarz / @lowzonenose

azarz commented 1 year ago

Mon avis sur les questions (aidé par https://github.com/Leaflet/Leaflet/blob/main/PLUGIN-GUIDE.md) :

RaF / Questions

@azarz / @lowzonenose

* [ ]  décision sur le **workflow** :
  > les modules sont ils automatiquement _buildés_ et _publiés_ lors des _releases_ Leaflet ?

Oui

  • [ ] choisir un namespace des modules : ex. @ignf-geoportal/plugin-leaflet-elevationpath Les plugins Leaflet sont plutôt préfixés par leaflet (https://github.com/Leaflet/Leaflet/blob/main/PLUGIN-GUIDE.md#name) Je pencherias donc plutôt sur du @ignf-geoportal/leaflet-elevationpath

  • [ ] comment gérer le fichier Common.css :

    doit il être inclus dans chaque module ou est ce un module à part entière ? Les 2 alternatives sont bien. Inclus dans chaque module permet de ne pas avoir à le linker à chaque fois, donc mon cœur penche plutôt pour cette solution.

  • [ ] doit on écrire un README spécifique à chaque module ou garde t on le README du projet ? Oui, mais extrait à partir d'une sous-partie du readme du projet (exemple, ne prendre que le paragraphe https://github.com/IGNF/geoportal-extensions/blob/develop/doc/README-leaflet.md#profil-altim%C3%A9trique-le-long-dun-tra%C3%A7%C3%A9 pour le profil alti) Je ne sais pas si c'est possible facilement...

  • [ ] doit on fournir un exemple pour chaque module ? Oui

  • [ ] doit on garder les répertoire de publication des modules sur le dépôt github ? Oui (cf Turf.js)

elias75015 commented 1 year ago

@lowzonenose @azarz Petit point à prévoir sur le sujet pour expliciter le reste à faire, et le kifékoi