Jednoduchý průvodce mapami Angular Leaflet

Leaflet je jedním z hlavních mapovacích frameworků založených na Javascriptu. Je široce používán napříč celým průmyslem k přidávání interaktivních map na webové stránky a do aplikací.

Je však složité jej začlenit do aplikací Angular.io. Nehraje si totiž úplně dobře ani s Angularem, ani s Typescriptem. Poté, co jsem zažil dobrodružství při migraci webu založeného na mapách Leaflet do systému Angular 8, mi bylo jasné, že pro tento úkol neexistuje žádná skutečně dobrá reference. Tyto příspěvky jsou mým pokusem o zdokumentování získaných poznatků. (UPDATE: Ačkoli byl tento článek napsán pro Angular 8 – aplikace a metody stále fungují i v Angularu 11).

Tento příspěvek bude mít více částí :

  • Základy (tento příspěvek),
  • Přidávání ovládacích prvků,
  • Funkce & Dynamické ovládací prvky,
  • Vlastní ovládací prvky, a
  • Přechod na PWA – service workers a další

Cílem tohoto seriálu je, abyste byli schopni vytvořit mapu Leaflet v projektu založeném na Angular-CLI bez potíží, zmatků a slepých uliček.

Ukázalo se, že ačkoli přidání Leafletu do Angular.io není výrazně obtížné, je velmi „piplavé“, protože Leaflet není k Angularu (ani Typescriptu) nijak zvlášť přátelský. Leaflet používá globální Lstrukturu proměnných a .extend metody, které matou TS. Zpracovává také množství událostí, které by aplikace Angular dostaly na kolena, kdyby byly podrobeny detekci změn.

Naštěstí existuje dobrý výchozí bod v @asymmetrik/ngx-leaflet. Ten poskytuje v podstatě šablonovité nastavení pro základní mapy. obsahuje také několik dobrých návodů na základní mapování (zde a zde), ale zdá se, že ztratili zájem dříve, než se dostali k těžkým věcem.

Začínáme

Podle dokumentace je třeba nainstalovat :

npm install leaflet
npm install @types/leaflet
npm install @asymmetrik/ngx-leaflet

a přidat importy do app.module.ts.

V tuto chvíli – můžete do aplikace přidat v podstatě jednoduchou mapu, takže si možná říkáte, co to bylo za povyk – ale k tomu se ještě dostaneme.

Komplikovaný CSS

Nejprve si musíme říct něco o CSS. Ngx-leaflet spouští Leaflet mimo samotný Angular – což chápu jako nejlepší způsob, jak se vyhnout tomu, aby události Leafletu způsobovaly vícenásobné události změn v Angularu.

Nejspíš kvůli tomu však Leaflet nezapadá do systému zapouzdření CSS Angular.io a všechny odkazy na CSS musí být na globální úrovni.

Obvykle to znamená, že CSS Leafletu přidáte do souboru angular.json takto

{
...
"styles": ,
...
}

nebo do souboru styles.css:

@import "./node_modules/leaflet/dist/leaflet.css"

To platí i pro listy stylů pro jednotlivé ovládací prvky, což se stává únavným, protože v Leafletu má každý ovládací prvek vlastní CSS. Zjistil jsem, že nejlepší je přidat CSS Leafletu do angular.json a CSS jednotlivých ovládacích prvků do styles.css především kvůli lepší čitelnosti.

Všimněte si, že v obou případech by měl být soubor leaflet.css zpracován před ostatními CSS ve styles.css. Jinak nebude CSS pro ovládací prvky efektivní.

Kompilátorové komplikace

Tady také začínáme narážet na jednu z prvních komplikací kompilátoru.

Takto vytvořené aplikace založené na leafletu fungují pro ng build a fungují s "aot": true , ale zdá se, že špatně fungují pro výchozí konfiguracing build --prod.

Zdá se, že je to kolem optimalizace a myslím, že možná až na základě třesení stromu. Po několika experimentech jsem zjistil, že ng build --prod funguje spolehlivě, pokud je "buildOptimizer": false v angular.json.

Nenechte se chytit do L

Většina návodů a dokumentace vám řekne, že je potřeba přenést globální proměnnou L do typescriptu pomocí následujícího importu :

import * as L from 'leaflet'

To je pravda, pokud chcete použít existující JS kód přímo v TS, ale zjistil jsem, že pokud jste načetli @types/leaflet, můžete importovat typedefy podle jména z 'leaflet' (např.např. import {Map} from 'leaflet' a vše funguje podle očekávání. Díky tomu je váš TS kód mnohem čitelnější a, no, TS-ovský!“

Jednoduchá mapa

Takže. Pojďme vytvořit naši mapu. V následujícím příkladu vytvářím mapu OpenStreetMap (protože na ní moje aplikace pracuje) jako samostatnou komponentu. Na této úrovni se to může zdát jako práce navíc, ale jak uvidíme později, umožňuje nám to vytvořit komponentu mapy s dalšími funkcemi, které lze opakovaně použít na více místech v toku aplikace.

Tato komponenta ve výchozím nastavení používá vrstvu OSM a globální zobrazení v možnostech – ačkoli možnosti jsou nastaveny jako @Inputs(), takže výchozí nastavení může být přepsáno nadřazenou komponentou.

Komponenta mapy také vysílá události, když je mapa připravena, aby k ní mohly přistupovat další části aplikace, a po události zoomu s novou úrovní přiblížení. Můžete také emitovat další události, například události přesunu a vrstvy – ale tohle moje aplikace potřebovala a myslím, že to demonstruje princip. V dalších částech budeme používat události mapy a přiblížení.

Mapa se přidá do domény pomocí direktivy ngx-leaflet v HTML komponenty.

Nakonec se komponenta použije tak, že se do nadřazeného HTML přidá následující:

<app-osm-map
="options"
(map$)="receiveMap($event)"
(zoom$)="receiveZoom($event)"
></app-osm-map>

Přečtěte si to další

.