Přeskočit obsah

Pokročilejší práce s knihovnou Leaflet

GeoJSON

GeoJSON (Geographic JavaScript Object Notation) je otevřený formát pro ukládání a výměnu geografických dat. Tento formát je navržený tak, aby reprezentoval geografické prvky s jejich neprostorovými atributy.

Je založený na standardu JSON (JavaScript Object Notation), což ho činí čitelným pro lidi i stroje a snadno zpracovatelným v různých programovacích jazycích.

Struktura formátu GeoJSON

  • type – specifikace typu objektu geometrie nebo kolekce souřadnic (FeatureCollection)

  • geometry – určení prostoroví reprezentace dat (např. bod, linie, polygon)

  • properties – atributy nebo metadata vztahující se k dané geometrii

  • coordinates – zeměpisné souřadnice bodu či lomových bodů ([zeměpisná délka (longitude), šířka (latitude), nadmořská výška])

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [125.6, 10.1]
    },
    "properties": {
        "name": "Dinagat Islands"
    }
}

Typy geometrie GeoJSON

  • Point – bod

  • LineString – linie

  • Polygon – polygon

  • MultiPoint – sada několika bodů

  • MultiLineString – sada několika linií

  • MultiPolygon – sada několika polygonů

  • Feature – geometrické objekty s přidanými parametry

  • FeatureCollection – sada několika Feature

Lepší pochopení struktury vytváření geodat ve formátu GeoJSON můžeme získat při využití platformy geojson.io.

Platforma geojson.io

 TopoJSON

TopoJSON je nadstavba GeoJSON, která se liší tím, že neukládá opakující se informace o topologii sousedních prvků, což vede k menší velikosti souboru a efektivnější práci s geoprostorovými daty.

Například společná hranice dvou států (Česka a Německa) se uloží pouze jednou. V GeoJSONu by se tato hranice uložila dvakrát (jednou pro polygon Česka, podruhé pro polygon Německa). Je tím pádem vhodný pro využití u větších datových sad či při nutnosti zachování topologie.

Datová struktura je naopak v porovnání s GeoJSONem složitější.

Více informací: https://github.com/topojson/topojson

Načtení dat z GeoJSON do mapové aplikace

Toto cvičení navazuje na závěr předchozího cvičení. Začínáme tedy s kódem z minulé hodiny, který je vypsán v nabídce níže. Kód se však bude výrazně měnit, takže doporučujeme vytvořit kopii dat z minulé hodiny do nové složky, ve které budete pracovat. Takto si zachováte postup z obou hodin uložený.

 Stav kódu na začátku cvičení
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([50.104, 14.388], 13);

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přiání OpenTopoMap do mapy
//otm.addTo(map);

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Body s textovými informacemi
var points = [
    { coords: [50.104, 14.388], text: "FSv ČVUT v Praze" },
    { coords: [50.091, 14.402], text: "Pražský hrad" },
    { coords: [50.082, 14.426], text: "metro Můstek" },
    { coords: [50.106, 14.437], text: "vlak Praha Holešovice-zastávka" }
];

// Linie propojující několik bodů 
var line = L.polyline(points.map(p => p.coords), {color: "red", weight: 10}).addTo(map);

// Polygon se zadanými vrcholy
var polygon = L.polygon(points.map(p => p.coords), {color: "blue", weight: 3, fillColor: "lightblue", fillOpacity: "0.8"}).addTo(map);

// Pop-up pro polygon
polygon.bindPopup("Toto je polygon");

// Vytvoření vrstvy pro markery
var markersLayer = L.layerGroup();

// Přidání markerů s popisky pro každý bod
points.forEach(function(point) {
    L.marker(point.coords).bindPopup(point.text).addTo(markersLayer);
});

// Vložení skupiny bodů do mapy
markersLayer.addTo(map);

// Nastavení parametrů vlastního markeru
var blackMarker = L.icon({
    iconUrl: '/assets/cerny_popup.png', // Umístění obrázku na disku
    iconSize:     [60, 60], // Velikost ikony v px
    iconAnchor:   [0, 80], // Pozice, na které se zobrazí ikona - vůči bodu
    popupAnchor:  [30, -100] // Pozice, ze které se popup otevře - vůči bodu
});

// Samostatný bod s novým značením
var markerDivokaS = L.marker([50.093, 14.324], {icon: blackMarker}).addTo(map); 
markerDivokaS.bindPopup("Zde je <b style='color: red;'>Divoká Šárka</b>");

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Zajímavá místa": markersLayer,
    "Divoká Šárka": markerDivokaS,
    "Moje linie": line, 
    "Můj polygon": polygon
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

1) Načtení bodu z GeoJSON do mapové aplikace

Nejprve načteme GeoJSON přímo v kódu jako proměnnou. Na platformě geojson.io vytvoříme jeden bod, například na pozici Prahy. K tomu využijeme první tlačítko z pravé postranní nabídky v mapě. Vygenerovaný kód v pravé části obrazovky si zkopírujeme.

Vytvoření bodu se souřadnicemi Prahy

V javascript kódu vytvoříme proměnnou, do které vložíme zkopírovaný kód z GeoJSON.

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    // Sem vložíme kód z GeoJSON
];

Po vložení bodu:

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

V další fázi je třeba přidat načtení souboru z GeoJSONu do vrstvy prahaBodLayer.

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod).addTo(map);

Před pokračováním na další kroky mapovou aplikaci pročistíme a smažeme či zakomentářujeme všechny ostatní mapové vrstvy markersLayer, markerDivokaS, line a polygon.

Mapová aplikace po pročištění kódu a načtení bodu z GeoJSON

 Stav kódu po dokončení kroku 1) Načtení bodu z GeoJSON do mapové aplikace
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([50.104, 14.388], 13);

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod).addTo(map);

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

2) Načtení externího souboru s daty

Na platformě geojson.io vytvoříme jednoduchou bodovou vrstvu s vybranými městy v Česku. Pro začátek stačí zvolit např. 4 body, přičemž každému bodu určíme hodnotu atributu nazev, do které zapíšeme název daného města. Soubor s daty stáhneme tlačítkem Save v levém horním rohu. Soubor přejmenujeme na mesta.geojson.

Stažení GeoJSONu s vytvořenými body

Takto stažený soubor je možné nahrát přímo do Leaflet, nicméně jednodušší možností je vytvoření nového js scriptu, např. mesta_GeoJSON.js, ve kterém vytvoříme proměnnou mesta a přiřadíme jí data ze staženého GeoJSONu. Nový soubor uložíme do stejné pracovní složky jako ostatní skripty.

Struktura připraveného souboru bude vypadat následovně:

var mesta = {
    "type": "FeatureCollection",
    "features": [
    {
        ... // Zde jsou ostatní načtená data z GeoJSONu
    }
    ]
};

Abychom mohli města ze souboru mesta_GeoJSON.js načíst, je potřeba skript připojit v index.html – obdobně jako ostatní použité js soubory.

Do hlavičky v html tedy přidáme:

<!-- Načtení souboru s městy GeoJSON-->
<script src="mesta_GeoJSON.js"></script>

Nyní můžeme pokračovat načtením bodů z GeoJSONu do mapy. To provededeme podobně jako při načtení samostatného bodu Prahy v předchozím kroku. Zároveň přidáme novou vrstu měst do správce vrstev.

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta).addTo(map);

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer
};

Mapová aplikace po načtení měst z GeoJSONu

Závěrem tohoto kroku si upravíme rozsah úvodního okna pro celé Česko a upravíme zobrazení měst tak, abychom byli schopni zobrazit pop-up s jejich názvy.

// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([49.860, 15.315], 8); // Výběr bodu zhruba uprostřed republiky

Popup vytvoříme obdobně jako v minulé hodině, jen je k atributu potřeba přistupovat přes feature.properties.nazev.

Níže je vypsaný kód pro obyčejný pop-up vypisující pouze atribut (v komentáři) a upravený pop-up, který využívá html zápis. Pokud se odkazujeme přímo na hodnoty atributu, pak je nutné ve výpisu popupu využít zpětné uvozovky (backquote) ` (Alt + ý).

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta, {
onEachFeature: function (feature, layer) {
    if (feature.properties && feature.properties.nazev) {
        // layer.bindPopup(feature.properties.nazev); // Obyčejný popup
        layer.bindPopup(`Jméno města je <b>${feature.properties.nazev}</b>`); // Vylepšený popup
    }
}
}).addTo(map);

Přidání pop-upu pro výpis hodnoty atributu "název"

 Stav kódu po dokončení kroku 2) Načtení externího souboru s daty
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Načtení souboru s městy GeoJSON-->
    <script src="mesta_GeoJSON.js"></script>

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([49.860, 15.315], 8); // Výběr bodu zhruba uprostřed republiky

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod).addTo(map);

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta, {
onEachFeature: function (feature, layer) {
    if (feature.properties && feature.properties.nazev) {
        // layer.bindPopup(feature.properties.nazev); // Obyčejný popup
        layer.bindPopup(`Jméno města je <b>${feature.properties.nazev}</b>`); // Vylepšený popup
    }
}
}).addTo(map);

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

Tvorba kartogramu

Více informací o tvorbě kartogramu v Leaflet je na stránkách dokumentace.

1) Připojení dat ORP

Nyní se dostaneme k načtení polygonů ORP s atributy. Je potřeba vytvořit nový js soubor, např. ORP_GeoJSON.js, ve kterém bude vložený GeoJSON s ORP, který jsme si dopředu připravili v GIS. Postup připojení bude velmi podobný jako v případě bodů měst.

Jeho struktura bude následující:

var ORP = {"type":"FeatureCollection","features":
[
    ... // Zde jsou ostatní načtená data z GeoJSONu 
]
};

Připojení v hlavičce index.html:

<!-- Načtení souboru s ORP GeoJSON-->
<script src="ORP_GeoJSON.js"></script>

Provedeme jednoduché načtení polygonů ORP do aplikace.

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP).addTo(map);

Zobrazení polygonů ORP v mapové aplikaci

 Stav kódu po dokončení kroku 1) Připojení dat ORP
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Načtení souboru s městy GeoJSON-->
    <script src="mesta_GeoJSON.js"></script>

    <!-- Načtení souboru s ORP GeoJSON-->
    <script src="ORP_GeoJSON.js"></script>

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([49.860, 15.315], 8); // Výběr bodu zhruba uprostřed republiky

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod).addTo(map);

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta, {
onEachFeature: function (feature, layer) {
    if (feature.properties && feature.properties.nazev) {
        // layer.bindPopup(feature.properties.nazev); // Obyčejný popup
        layer.bindPopup(`Jméno města je <b>${feature.properties.nazev}</b>`); // Vylepšený popup
    }
}
}).addTo(map);

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP).addTo(map);

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

2) Základní statický kartogram

Pro vytvoření kartogramu je potřeba nejprve upravit načítání bodů z GeoJSONu.

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP,{
    style: kartogram, 
}).addTo(map);

Po přiřazení stylu kartogram do vrstvy ORPLayer bude potřeba vytvořit barvnou stupnici pro kartogram. Pro představu o rozsahu dat můžeme využít náhled v GISu.

V tomto příkladu budeme pracovat s hustotou obyvatelstva v jednotlivých ORP, ale je možné použít jiný vhodný relativní atribut. Barevnou stupnici můžeme vytvořit pomocí nástroje ColorBrewer.

// Vytvoření barevné stupnice
function getColor(d) {
return d > 1000 ? '#800026' :
        d > 500  ? '#BD0026' :
        d > 200  ? '#E31A1C' :
        d > 100  ? '#FC4E2A' :
        d > 50   ? '#FD8D3C' :
        d > 20   ? '#FEB24C' :
                    '#FFEDA0'; // Výchozí barva
}

Pro vytvoření statického kartogramu je nutné ještě definovat jeho styl, ve kterém určíme atribut, který chceme vizualizovat. Dále můžeme upravit styl vrstvy (průhlednost, ohraničení apod.).

// Styl kartogramu
function kartogram(feature) {
return {
    fillColor: getColor(feature.properties.HUSTOTA), // Styl na základě atributu "HUSTOTA"
    weight: 1,
    opacity: 1,
    color: 'white',
    fillOpacity: 0.7
};
}

Závěrem pouze odstraníme vykreslování bodových vrstev při načtení mapy – ponecháme je pouze v seznamu vrstev (smazáním příslušných .addTo(map)). Do seznamu přidáme nově vytvořenou vrstvu kartogramu ORPLayer.

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer,
    "Hustota obyvatelstva": ORPLayer
};

Vytvoření statického (neinteraktivního) kartogramu

 Stav kódu po dokončení kroku 2) Základní statický kartogram
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Načtení souboru s městy GeoJSON-->
    <script src="mesta_GeoJSON.js"></script>

    <!-- Načtení souboru s ORP GeoJSON-->
    <script src="ORP_GeoJSON.js"></script>

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([49.860, 15.315], 8); // Výběr bodu zhruba uprostřed republiky

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod);

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta, {
onEachFeature: function (feature, layer) {
    if (feature.properties && feature.properties.nazev) {
        // layer.bindPopup(feature.properties.nazev); // Obyčejný popup
        layer.bindPopup(`Jméno města je <b>${feature.properties.nazev}</b>`); // Vylepšený popup
    }
}
});

// Vytvoření barevné stupnice
function getColor(d) {
return d > 1000 ? '#800026' :
        d > 500  ? '#BD0026' :
        d > 200  ? '#E31A1C' :
        d > 100  ? '#FC4E2A' :
        d > 50   ? '#FD8D3C' :
        d > 20   ? '#FEB24C' :
                    '#FFEDA0'; // Výchozí barva
}

// Styl kartogramu
function kartogram(feature) {
return {
    fillColor: getColor(feature.properties.HUSTOTA), // Styl na základě atributu "HUSTOTA"
    weight: 1,
    opacity: 1,
    color: 'white',
    fillOpacity: 0.7
};
}

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP,{
    style: kartogram 
}).addTo(map);

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer,
    "Hustota obyvatelstva": ORPLayer
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

3) Interaktivní kartogram

Nyní statický kartogram upravíme tak, aby byl interaktivní, a tedy vhodný pro webovou mapovou aplikaci.

V první řadě nastavíme zvýraznění a výběr polygonu po najetí kurzoru myši.

// Výběr prvku po najetí kurzorem myši
function highlightFeature(e) {
    var layer = e.target;

    // Úprava stylu vybraného prvku = jeho zvýraznění
    layer.setStyle({
        weight: 5,
        color: '#666',
        dashArray: '',
        fillOpacity: 0.7
    });

    layer.bringToFront();
}

Dále přidáme přiblížení mapy na vybraný polygon po kliknutí levého tlačítka myši.

// Přiblížení na vybraný polygon po kliknutí myší
function zoomToFeature(e) {
    map.fitBounds(e.target.getBounds());
}

Abychom byli schopni přistupovat k jednotlivým prvkům kartogramu, je potřeba vytvořit funkci onEachFeature, ve které definujeme procesy výběru polygonu a přiblížení na něj.

// Přístup k jednotlivým polygonů ve vrstvě
function onEachFeature(feature, layer) {
    layer.on({
        mouseover: highlightFeature,
        click: zoomToFeature
    });
}

Pro vytvoření funkčního kódu musíme přiřadit funkci onEachFeature do definice vrstvy:

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP,{
    style: kartogram, 
    onEachFeature: onEachFeature
}).addTo(map);

Při otestování aplikace v současném stavu zjistíme, že se vybrané polygony nevypínají, tzn. zůstávají stále zvýrazněné.

ORP zůstávají vybrané i po přejetí myši na jiný polygon

V kódu je potřeba přidat ošetření tohoto stavu tak, aby se styl daného polygonu resetoval do základního nastavení.

// Resetování stylu kartogramu po zrušení jeho výběru myší
function resetHighlight(e) {
    ORPLayer.resetStyle(e.target);
}

Pro správné fungování je nutné nově vytvořenou funkci resetHighlight přidat do funkce onEachFeature.

// Přístup k jednotlivým polygonů ve vrstvě
function onEachFeature(feature, layer) {
layer.on({
    mouseover: highlightFeature,
    mouseout: resetHighlight,
    click: zoomToFeature
});
}

Aplikace následně funguje správně, tedy po najejí myši se vybere vždy jeden polygon. Ten se po změně výběru opět skryje a zvýrazní se další vybraný polygon.

Interaktivní výběr prvku v mapě

 Stav kódu po dokončení kroku 3) Interaktivní kartogram
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Načtení souboru s městy GeoJSON-->
    <script src="mesta_GeoJSON.js"></script>

    <!-- Načtení souboru s ORP GeoJSON-->
    <script src="ORP_GeoJSON.js"></script>

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([49.860, 15.315], 8); // Výběr bodu zhruba uprostřed republiky

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod);

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta, {
onEachFeature: function (feature, layer) {
    if (feature.properties && feature.properties.nazev) {
        // layer.bindPopup(feature.properties.nazev); // Obyčejný popup
        layer.bindPopup(`Jméno města je <b>${feature.properties.nazev}</b>`); // Vylepšený popup
    }
}
});

// Vytvoření barevné stupnice
function getColor(d) {
return d > 1000 ? '#800026' :
        d > 500  ? '#BD0026' :
        d > 200  ? '#E31A1C' :
        d > 100  ? '#FC4E2A' :
        d > 50   ? '#FD8D3C' :
        d > 20   ? '#FEB24C' :
                    '#FFEDA0'; // Výchozí barva
}

// Styl kartogramu
function kartogram(feature) {
return {
    fillColor: getColor(feature.properties.HUSTOTA), // Styl na základě atributu "HUSTOTA"
    weight: 1,
    opacity: 1,
    color: 'white',
    fillOpacity: 0.7
};
}

// Výběr prvku po najetí kurzorem myši
function highlightFeature(e) {
var layer = e.target;

// Úprava stylu vybraného prvku = jeho zvýraznění
layer.setStyle({
    weight: 5,
    color: '#666',
    dashArray: '',
    fillOpacity: 0.7
});

layer.bringToFront();
}

// Přiblížení na vybraný polygon po kliknutí myší
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}

// Resetování stylu kartogramu po zrušení jeho výběru myší
function resetHighlight(e) {
ORPLayer.resetStyle(e.target);
}

// Přístup k jednotlivým polygonů ve vrstvě
function onEachFeature(feature, layer) {
layer.on({
    mouseover: highlightFeature,
    mouseout: resetHighlight,
    click: zoomToFeature
});
}

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP,{
style: kartogram, 
onEachFeature: onEachFeature
}).addTo(map);

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer,
    "Hustota obyvatelstva": ORPLayer
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

4) Přidání pop-upu a legendy

Nejprve vypíšeme informace o vybraném prvku z mapy do samostatného divu, který vytvoříme přímo pomocí js.

V informačním pop-upu se vypíše text, který bude využívat dva atributy polygonů z GeoJSONu - NAZEV a HUSTOTA (zaokrouhlíme na 2 des. místa).

// Vytvoření pop-upu s informacemi o vybraném prvku v mapě
var info = L.control();

info.onAdd = function (map) {
    this._div = L.DomUtil.create('div', 'info'); // Vytvoří div s třídou "info"
    this.update();
    return this._div;
};

// Funkce pro aktualizaci po-upu na základě předaných vlastností prvku
info.update = function (props) {
    this._div.innerHTML = '<h4>Hustota obyvatel</h4>' +  (props ?
        '<b>' + props.NAZEV + '</b><br />' + props.HUSTOTA.toFixed(2) + ' obyv. / km<sup>2</sup>'
        : 'Vyber ORP'); // Výpis, pokud není vybraný prvek
};

Výsledná aplikace by měla vypadat zhruba takto. V pravém horním rohu se vypisují vybrané atributy zvoleného polygonu, nicméně je potřeba vytvořit styl daného divu.

Výpis atributů vybraného prvku

Úprava stylu divu s pop-upem v souboru style.css:

/* Div třídy info */
.info {
    padding: 6px 8px;
    font: 14px/16px Arial, Helvetica, sans-serif;
    background: white;
    background: rgba(255,255,255,0.8);
    box-shadow: 0 0 15px rgba(0,0,0,0.2);
    border-radius: 5px;
}

/* Nadpis v divu info */
.info h4 {
    margin: 0 0 5px;
    color: #777;
}

Upravený styl pop-upu pro výpis informací o prvku

V posledním kroku přidáme legendu a upravíme její styl.

// Vytvoření legendy a nastavení její pozice
var legend = L.control({position: 'bottomright'});

legend.onAdd = function (map) {

    var div = L.DomUtil.create('div', 'info legend'),
        grades = [0, 20, 50, 100, 200, 500, 1000], // Hranice intervalů - stejné jako v nastavení stylu kartogramu
        labels = [];

    // Procházení intervalů hustoty - pro každý interval se vygeneruje štítek s barevným čtvercem.
    for (var i = 0; i < grades.length; i++) {
        div.innerHTML +=
            '<i style="background:' + getColor(grades[i] + 1) + '"></i> ' +
            grades[i] + (grades[i + 1] ? '&ndash;' + grades[i + 1] + '<br>' : '+');
    }

    return div;
};

// Přidání legendy do mapy
legend.addTo(map);

Pro správné zobrazení všech součástí legendy musíme upravit style.css.

/* Úprava stylu legendy*/
.legend {
    line-height: 18px;
    color: #555;
}

/* Zobrazení čtverců s barvou stylu každého atributu */
.legend i {
    width: 18px;
    height: 18px;
    float: left;
    margin-right: 8px;
    opacity: 0.7;
}

Finální mapa se zobrazenou legendou

 Stav kódu po dokončení kroku 4) Přidání pop-upu a legendy
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">

    <!-- Načtení souboru s městy GeoJSON-->
    <script src="mesta_GeoJSON.js"></script>

    <!-- Načtení souboru s ORP GeoJSON-->
    <script src="ORP_GeoJSON.js"></script>

    <!-- Externí připojení CSS symbologie Leaflet-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>


    <!-- Externí připojení JS knihovny -> vložit až po připojení CSS souboru -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""></script>

    <title>Moje první Leaflet mapa</title> 
</head>
<body> 

    <h1>Pěkná mapa v Leafletu</h1> 

    <div id="map"></div>
    <script src="script.js"></script>

</body>
</html>
// Nastavení mapy, jejího středu a úrovně přiblížení
var map = L.map('map').setView([49.860, 15.315], 8); // Výběr bodu zhruba uprostřed republiky

// Určení podkladové mapy, maximální úrovně přiblížení a zdroje dat
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

// Definice podkladové OpenTopoMap
var otm = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    maxZoom: 17,
    attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});

// Přidání ortofota jako WMS služby, určení vrstvy, formátu a průhlednosti
var ortofoto = L.tileLayer.wms("https://ags.cuzk.gov.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer", {
    layers: "0", 
    format: "image/png",
    transparent: true,
    attribution: "&copy ČÚZK"
});

// Načtení bodu z GeoJSON zápisu
var prahaBod = [
    {
        "type": "FeatureCollection",
        "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
            "coordinates": [
                14.41581389404206,
                50.0970543797564
            ],
            "type": "Point"
            }
        }
        ]
    }
];

// Přiřazení GeoJSONu do mapové vrstvy a její přidání do mapy
var prahaBodLayer = L.geoJSON(prahaBod);

// Načtení GeoJSONu z proměnné "mesta" uložené v souboru "mesta_GeoJSON.js"
var mestaLayer = L.geoJSON(mesta, {
onEachFeature: function (feature, layer) {
    if (feature.properties && feature.properties.nazev) {
        // layer.bindPopup(feature.properties.nazev); // Obyčejný popup
        layer.bindPopup(`Jméno města je <b>${feature.properties.nazev}</b>`); // Vylepšený popup
    }
}
});

// Vytvoření barevné stupnice
function getColor(d) {
return d > 1000 ? '#800026' :
        d > 500  ? '#BD0026' :
        d > 200  ? '#E31A1C' :
        d > 100  ? '#FC4E2A' :
        d > 50   ? '#FD8D3C' :
        d > 20   ? '#FEB24C' :
                    '#FFEDA0'; // Výchozí barva
}

// Styl kartogramu
function kartogram(feature) {
return {
    fillColor: getColor(feature.properties.HUSTOTA), // Styl na základě atributu "HUSTOTA"
    weight: 1,
    opacity: 1,
    color: 'white',
    fillOpacity: 0.7
};
}

// Výběr prvku po najetí kurzorem myši
function highlightFeature(e) {
var layer = e.target;

// Úprava stylu vybraného prvku = jeho zvýraznění
layer.setStyle({
    weight: 5,
    color: '#666',
    dashArray: '',
    fillOpacity: 0.7
});

layer.bringToFront();
info.update(layer.feature.properties);
}

// Přiblížení na vybraný polygon po kliknutí myší
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}

// Resetování stylu kartogramu po zrušení jeho výběru myší
function resetHighlight(e) {
ORPLayer.resetStyle(e.target);
info.update();
}

// Přístup k jednotlivým polygonů ve vrstvě
function onEachFeature(feature, layer) {
layer.on({
    mouseover: highlightFeature,
    mouseout: resetHighlight,
    click: zoomToFeature
});
}

// Načtení GeoJSONu s polygony ORP do mapy
var ORPLayer = L.geoJSON(ORP,{
style: kartogram, 
onEachFeature: onEachFeature
}).addTo(map);


// Vytvoření pop-upu s informacemi o vybraném prvku v mapě
var info = L.control();

info.onAdd = function (map) {
    this._div = L.DomUtil.create('div', 'info'); // Vytvoří div s třídou "info"
    this.update();
    return this._div;
};

// Funkce pro aktualizaci po-upu na základě předaných vlastností prvku
info.update = function (props) {
    this._div.innerHTML = '<h4>Hustota obyvatel</h4>' +  (props ?
        '<b>' + props.NAZEV + '</b><br />' + props.HUSTOTA.toFixed(2) + ' obyv. / km<sup>2</sup>'
        : 'Vyber ORP'); // Výpis, pokud není vybraný prvek
};

// Vložení info pop-upu do mapy
info.addTo(map); 

// Vytvoření legendy a nastavení její pozice
var legend = L.control({position: 'bottomright'});

legend.onAdd = function (map) {

    var div = L.DomUtil.create('div', 'info legend'),
        grades = [0, 20, 50, 100, 200, 500, 1000], // Hranice intervalů - stejné jako v nastavení stylu kartogramu
        labels = [];

    // Procházení intervalů hustoty - pro každý interval se vygeneruje štítek s barevným čtvercem.
    for (var i = 0; i < grades.length; i++) {
        div.innerHTML +=
            '<i style="background:' + getColor(grades[i] + 1) + '"></i> ' +
            grades[i] + (grades[i + 1] ? '&ndash;' + grades[i + 1] + '<br>' : '+');
    }

    return div;
};

// Přidání legendy do mapy
legend.addTo(map);

// Proměnná uchovávající podkladové mapy, mezi kterými chceme přepínat
var baseMaps = {
    "OpenStreetMap": osm, // "popis mapy": nazevPromenne
    "OpenTopoMap": otm,
    "Ortofoto ČR": ortofoto
};

// Proměnná uchovávající mapové vrstvy, které chceme zobrazovat a skrývat
var overlayMaps = {
    "Praha": prahaBodLayer,
    "Města": mestaLayer,
    "Hustota obyvatelstva": ORPLayer
};

// Grafické přepínání podkladových map
var layerControl = L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);
/* Velikost mapového okna */
#map {
    height: 800px;
    width: 60%;
}

/* Div třídy info */
.info {
    padding: 6px 8px;
    font: 14px/16px Arial, Helvetica, sans-serif;
    background: white;
    background: rgba(255,255,255,0.8);
    box-shadow: 0 0 15px rgba(0,0,0,0.2);
    border-radius: 5px;
}

/* Nadpis v divu info */
.info h4 {
    margin: 0 0 5px;
    color: #777;
}

/* Úprava stylu legendy*/
.legend {
    line-height: 18px;
    color: #555;
}

/* Zobrazení čtverců s barvou stylu každého atributu */
.legend i {
    width: 18px;
    height: 18px;
    float: left;
    margin-right: 8px;
    opacity: 0.7;
}