• Announcing #Leaflet 1.1.0

    http://leafletjs.com/2017/06/27/leaflet-1.1.0.html

    We have released Leaflet version 1.1.0, the first version built with ES6 modules - a big step forward ensuring Leaflet is up to date with how modern JavaScript is written. For users upgrading to this release, this change should not make a difference, while it offers the possibility to import individual parts of Leaflet individually if your app is built with ES6. As a consequence, 1.1.0 is also the first version built without Leaflet’s now deprecated custom build system, in favor of using Rollup.

    Also new in this release is the new L.VideoOverlay class, allowing overlaying video on your #maps.

    http://leafletjs.com/examples/video-overlay

    We also managed to fix over 30 bugs with the help of about 20 different contributors: see the full changelog for details.

  • Création de panoramas (grandes images) au moyen de leaflet.js, script bash de génération des tuiles avec ImageMagick
    http://panos.tetraconcept.com/ilduomo.html

    Premier test d’utilisation de #leaflet.js pour afficher des panoramas...

    Les utilisations qu’en font les habitués de SeenThis (je pense aux oeuvres de madmeg par exemple) m’ont titillé... et les congés ont été propices à ce genre de réalisations.

    Ici, donc, « Il Duomo » de la cathédrale de Florence. Il est loin d’être parfait... mais il permet d’avoir une idée de l’oeuvre.

    Je me suis inspiré de cet article de blog, dont j’ai transcrit le script ruby en bash, pour le fun... :
    http://omarriott.com/aux/leaflet-js-non-geographical-imagery
    Et de celui-là, qui m’a permis de corriger des soucis dans l’utilisation de leaflet tel qu’indiqué par le premier site :
    http://getsite.org.ua/en/build-site/php-maptiler-simple-map-tiles-generator
    Et enfin de ce tuto du site officiel :
    http://leafletjs.com/examples/quick-start.html

    Il faudra j’imagine que je pense à faire en sorte que mon image d’origine ait une taille multiple de 256 pour ne pas avoir ce résultat moche au niveau de zoom le plus faible... à moins qu’il n’y ait une option dédiée...

    La prochaine étape est d’industrialiser... J’ai une dizaine de panoramas à mettre en ligne de la sorte :-D

    • Mon « industrialisation artisanale » consiste à disposer d’un script qui me crée les tuiles pour les 5 niveaux de zoom que je souhaite utiliser. Le script a besoin d’un paramètre, le nom du fichier image grand format. Il crée dans le répertoire actif les 5 répertoires, un par niveau de zoom. Tout cela est totalement dépendant de ImageMagick.

      Aucune vérification d’erreur... c’est vraiment très sommaire. Mais ça fonctionne...

      Le script redimensionne les images pour que les dimensions soient des multiples de 256, en comblant les espaces vides par du blanc.

      #!/bin/bash

      source_file=$1
      tmp_dir=./tmp/
      mkdir $tmp_dir

      tile_width=256
      tile_height=256

      minZ=13
      maxZ=18

      for ((z=$maxZ;z>=$minZ;z--))
      do

       dest_file=${tmp_dir}zoom_${z}.jpg

       if [ $z -eq $maxZ ]; then
         image_width=`identify -format %w $source_file`
         image_height=`identify -format %h $source_file`

         image_width=$(((($image_width+$tile_width-1)/$tile_width)*$tile_width))
         image_height=$(((($image_height+$tile_height-1)/$tile_height)*$tile_height))

         convert -size ${image_width}x${image_height} -quality 80 xc:white $dest_file
         composite -gravity NorthWest $source_file $dest_file $dest_file
         #source_file=$dest_file
       fi

       if [ $z -ne $maxZ ]; then
         image_width=`identify -format %w $source_file`
         image_height=`identify -format %h $source_file`
         image_width=$(($image_width/(2**(maxZ-$z))))
         image_height=$(($image_height/(2**(maxZ-$z))))
         convert -resize ${image_width}x${image_height} $source_file $dest_file

         image_width=$(((($image_width+$tile_width-1)/$tile_width)*$tile_width))
         image_height=$(((($image_height+$tile_height-1)/$tile_height)*$tile_height))

         temp_file=${tmp_dir}zoom_${z}_temp.jpg
         convert -size ${image_width}x${image_height} -quality 80 xc:white $temp_file
         composite -gravity NorthWest $dest_file $temp_file $dest_file
       fi

       mkdir ./${z}/

       convert -crop 256x256 +repage $dest_file ./${z}/tiles_%d.png

       image_width=`identify -format %w $dest_file`
       image_height=`identify -format %h $dest_file`

       echo $image_width $image_height

       tiles_per_column=$((($image_width+$tile_width-1)/$tile_width))
       tiles_per_row=$((($image_height+$tile_height-1)/$tile_height))

       total_tiles=$(($tiles_per_column*$tiles_per_row))

       n=0
       row=0
       column=0
       for (( i=$n; i<$total_tiles; i++ ))
       do
         filename=./${z}/tiles_${i}.png
         target=./${z}/map_${column}_${row}.png

         cp -f $filename $target

         column=$(($column + 1))
         if [ $column -ge $tiles_per_column ]; then
           column=0
           row=$(($row + 1))
         fi
       done
       rm -f ./${z}/tiles_*.png

      done

      rm -rf $tmp_dir

      Le fichier html qui va utiliser les images est conçu peu ou prou de la sorte. Il convient de personnaliser les variables mapW et mapH avec les vraies dimensions en pixel de l’image la plus grande.

      <html>
      <head>
      <title>Pirates</title>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <meta charset="utf-8">
      <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
      <link rel="stylesheet" href="resources/map.css" />
      </head>
      <body bgcolor="#ffffff">
      <div id="map"></div>
      <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
      <script language="javascript" type="text/javascript">
       var maxZ = 18;
       var minZ = 13;
       var mapW = 7424;
       var mapH = 6144;
       var mapName = 'pirates';
      </script>
      <script src="resources/map.js"></script>
      </body>
      </html>

      Le fichier map.css est très simple... Il permet d’avoir un fond blanc dans le conteneur principal :

      #map { width:100%;height:100%; }
      .leaflet-container { background: #fff; }

      Et le fichier map.js contient le code qui initialise l’ensemble. Les tuiles sont attendues dans le répertoire nommé comme la variable « mapName ».

       var map = L.map('map',{center: [0, 0], maxZoom: maxZ, minZoom: minZ, crs: L.CRS.Simple}).setView([0, 0], Math.floor((maxZ + minZ) / 2));

       var southWest = map.unproject([0, mapH], map.getMaxZoom());
       var northEast = map.unproject([mapW, 0], map.getMaxZoom());
       map.setMaxBounds(new L.LatLngBounds(southWest, northEast));

       L.tileLayer('/' + mapName + '/{z}/map_{x}_{y}.png', {attribution: '&copy; BigGrizzly <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'}).addTo(map);
    • J’ai buté un moment sur les niveaux de zoom. Je voulais mettre 20 comme niveau le plus élevé, donc de 15 à 20. Et les niveaux 19 et 20 ne s’affichaient pas. Pas d’erreurs, aucune tuile chargée. J’ai tout baissé de 13 à 18 et... hop, tout s’est remis à fonctionner (parce que oui, sur mon premier prototype, ça fonctionnait jusqu’à 20...).
      Rien trouvé dans la documentation au sujet du fonctionnement du zoom.

    • tu devrais faire un gist ce serait plus pratique :)

      Sinon pour les niveaux de zoom, je crois que 18 est la valeur maximum permise par la plupart des logiciels. J’avais eu la même idée que toi au départ, et au final je me suis ramené à z=0 : cadre contenant l’image entièrement dans 256x256.

      Ce qui fait que je calcule tout de z=0 à 4, 5, 6 ou 7 selon la taille de l’image (7 => 256 * 2^7 = 32768px de côté). J’ai l’idée pour la suite de mettre plusieurs images sur une même map (pour faire une galerie), mais je passerai alors par le format mbtiles pour renuméroter / déplacer mes tuiles, à coups de UPDATE sql.

    • Bien vu le composite qui te permet de ne pas avoir de « demi-tuiles » en bas et à droite ; dans mon script je fais la même chose mais, tu verras, je le fais sur chaque tuile, et non pas sur l’image source. Il faudrait voir ce qui est le plus rapide (sur les très très grosses images j’ai facilement 2 ou 3 heures de traitement…).

    • Je n’ai pas de traitement qui dure plus de quelques minutes, mais je n’ai pas d’images énormes non plus à priori, en général < à 200Mpx.

      Oui, fonctionner à l’envers, 0 puis augmenter, c’est plus malin en effet... pour faire qq chose de paramétrable.

      Mais... là, je doute qu’après mes congés, je reprenne du temps avant un moment sur ce sujet. Enfin... Jusqu’aux prochaines vacances... où j’aurais décidé de me trimballer un pied photo, pour faire un pano de la mort au 300mm sur 360° :-D

    • Test du jour, image de 350Mpx (35Kx8K), vue sur Lyon au 300mm... Le traitement le plus long (10-15 minutes, je ne sais pas) a été la recomposition par MS ICE... Mine de rien, il a occupé 3,6Go en RAM, et autant sur le disque le temps du traitement. Idem pour le premier découpage par ImageMagick, ensuite, sur le serveur Debian... Là, pas plus de 5 minutes pour le premier découpage (le plus grand).

      http://panos.tetraconcept.com/lyon2.html