Mapy 3: raphael + mapael

... Petr Blahoš, 5. 6. 2020 JavaScript

Pamatuju si, že se mi už kdysi před léty líbila myšlenka knihovny Raphaël, která generuje svg. Takže když jsem hledal způsob, jak vizualizovat místa na mapě, Raphaël byl první volba. K němu existuje plugin Mapael, a tím to máme skoro hotové. No, skoro.

Alt ctx.

Jistě, mapa není zrovna podrobná. Kdyby na ní byly aspoň silnice, byl bych rád, ale momentálně nevím, kde získat lepší. Mapael má sadu základních map, ze které jsem tuhle českou vysekal.

Práce s Mapael je trochu jiná, než jsme viděli u Google Map nebo leaflet. V nich jsme vytvářeli jednotlivé značky, a ke každé nastavili ikonu. Tady to funguje jinak. Nadefinujeme si rozsahy hodnot. Když přidáme na mapu nějaké místo, tak jí nastavíme hodnotu, ta padne do nějakého rozsahu, a podle něj se vykreslí značka. Zjednodušeně takto:

<div id="map" class="mapcontainer"><div class="map">Alt ctx.</div></div>
<script>
function makeMap() {
    var plot = {        //
      "1001": {         // Tady je definice jednotivých míst
          value: 98,    //
          latitude: 49.7477,
          longitude: 14.4025,
          href: "#",
          tooltip: { content: 'some stuff 1001' }
      },
      "1002": {
          value: 198,
          latitude: 50.0,
          longitude: 14.4025,
          href: "#",
          tooltip: { content: 'some stuff 1002' }
      }
    };
    $("#map").mapael({
        map: {
            zoom: { enabled: true },
            name: "czechia"
        },
        legend: {            //
            plot: {          // Tady definujeme ty rozsahy
                slices: [    //
                  {
                    type: "circle", size: 1,
                    max: 100,
                    attrs: { fill: "#333333", "stroke": "#FFFF00", "stroke-width": 0.1 },
                    attrsHover: {"stroke-width": 0.3 },
                    label: "0-100"
                  }, {
                    type: "square", size: 1,
                    min: 101,
                    attrs: { fill: "#666666", "stroke": "#FFFF00", "stroke-width": 0.1 },
                    attrsHover: {"stroke-width": 0.3 },
                    label: "101-150"
                  }
                ]
            }
        },
        plots: plots
    });

}
</script>

Když vytáhnu to nejdůležitější, tak ke každému rozsahu lze definovat:

  • Maximum a minimum
  • Tvar - circle nebo square, případně image, nebo svg
  • Velikost, barvu, tloušťku čáry, ...
  • Stejné atributy pro hover
  • A spoustu dalších

Pro jednotlivá místa - plots - pak zadáme:

  • GPS souřadnice
  • Hodnotu - podle ní se určí, do jakého rozsahu patří, a jak se má tím pádem vykreslit
  • A další, např. tooltip

Animace značek

Mě na tom nejvíc zajímá, jak se to bude chovat, když hodnotu u místa změníme. Na to je metoda update.

Alt ctx.

Tak tohle je bizardní. Ze čtverečku se stal čtvereček se zakulacenými rohy, nebo kolečko. A navíc nějak poskakuje. Smířím se tedy s tím, že tvar značky se měnit nedá. Dá se ale měnit barva, velikost, tlouška čar. Část toho animovacího kódu vypadá takhle.

    function updatePlot() {
        for(k in plots) {
            plots[k].value = Math.floor(Math.random() * 300);
        }
        $("#map").trigger('update', {"mapOptions": {"plots": plots}});
    }
    setInterval(updatePlot, 1000);

Dokončení

Máme tooltip, máme animaci, tak ještě bych tam rád dostal značku v SVG, a reakci na kliknutí. SVG značka lze udělat např. takovouhle definicí rozsahu:

  slices: [
    {
        type: "svg",
        path: "M 7.5,0 C 2.48,0 0,3.5 0,7.81 0,12.12 7.5,22 7.5,22 7.5,22 15,12.13 15,7.81 15,3.49 12.52,0 7.5,0 Z",
        width: 0.8,
        height: 1.1,
        min: 0, max: 100,
        attrs: { fill: "#FFFFFF", "stroke-width": 2, "stroke": "#000000" },
        label: "SVG marker"
    }
  ]

K mapě se dá přidat výchozí obsluha události click nebo dblclick. Vyzkoušíme si to. Pravděpodobně lze přidat i obsluha pro jednotlivé ploty, ale to už si vyzkoušejte sami.

    function plot_clicked() {
        console.log("plot_clicked", arguments);
    }

    $("#map").mapael({
        map: {
            zoom: { enabled: true },
            name: "czechia"
        },
        defaultPlot: {
            eventHandlers: {
                click: plot_clicked 
            }
        },
        legend: {
    // ...
Alt ctx.

Vidíme, že druhý argument je klíč do objektu plots, neboli ID toho objektu. Ten přesně potřebujeme. Všechny argumenty jsou:

  • event
  • id objektu
  • element značky v mapě
  • element textu v mapě (text jsme nepoužívali)
  • element options

Na živo

Zkuste si pohrát na jsfiddle.

Odkazy