Tento článek je zaměřen na začínající vývojáře Angularu, kteří chtějí integrovat Leaflet do svých aplikací. Integrace závislostí třetích stran do Angularu může být od triviální až po problematickou. Zatímco Leaflet se kloní spíše k triviální stránce, mapy, které se plynule přizpůsobují velikosti prohlížeče, mohou představovat určité problémy s nastavením vzhledem k životnímu cyklu Angularu.
Než začnete s dekonstrukcí, nasměrujte svůj spřátelený prohlížeč v sousedství na následující Github.
Nyní můžete projekt sledovat nebo jej forknout a použít jako základ pro své vlastní aplikace.
Základní informace
Tento návod předpokládá malé množství předchozích znalostí o Leafletu, ale ne více, než je vyjádřeno v příručce Leaflet Quickstart Guide.
ArcGis se používá pro tiling v aplikaci, o které pojednává tento článek (balíček esri-leaflet se instaluje z npm).
Instalace Angularu
Po všudypřítomné instalaci npm je třeba udělat jen velmi málo. Potřebné styly Leaflet jsou k dispozici prostřednictvím souboru angular.json,
"styles": ,
S @types/leaflet jsem měl smíšené výsledky, takže tato aplikace pro jednoduchost nevyužívá typování. Dlaždice Leaflet a ESRI se importují, jak je uvedeno níže,
import * as esri from 'esri-leaflet';
import * as L from 'leaflet';
Například mapa Leaflet je dočasně typována jako libovolná; klidně si typování upevněte jako cvičení po dekonstrukci výukového programu.
Souřadnice středu mapy jsou důležité pro inicializaci mapy. Mnohé demoverze tuto informaci kódují natvrdo. Jako alternativu tento tutoriál ilustruje, jak injektovat souřadnice středu mapy pomocí Angular Injection Tokens.
Souřadnice je dvourozměrný bod na mapě reprezentovaný zeměpisnou šířkou a délkou. Token InjectionToken pro souřadnici lze vytvořit podle obrázku v souboru /src/app/tokens.ts,
import { InjectionToken } from '@angular/core';
export const INIT_COORDS = new InjectionToken<{lat: number, long: number}>('INIT_COORDS');
INIT_COORDS se používá v /src/app/app.module.ts souboru provést skutečné zajištění (nebo definici) (šířky/délky),
providers: ,
Tím se definice středu mapy přesune na nejvyšší úroveň v aplikaci Angular (kde je snadno viditelná a téměř se sama dokumentuje).
Chcete-li tuto souřadnici injektovat do aplikace, importujte INIT_COORDS ze souboru tokens a injektujte z konstruktoru třídy. To je znázorněno v souboru /src/app/map.component.ts (primární komponenta mapy v tomto tutoriálu),
constructor( @Inject(INIT_COORDS) protected _initCoords: {lat: number, long: number} )
Komponenta mapy
Aplikace, kterou se zabývá tento článek, zobrazuje mapu s pevnou výškou a šířkou přesahující celé okno prohlížeče. Mapa se překresluje při změně velikosti okna. Některé značky se vykreslují také nad dlaždicemi mapy.
Mapa je integrována do aplikace prostřednictvím šablony hlavní komponenty aplikace, jak je uvedeno níže
/src/app/app.component.html
<app-map ="markers"></app-map>
a zdrojový kód komponenty mapy se nachází v /src/app/maps/map.component.ts .
Mapa je vykreslena do kontejneru (DIV), který se aktuálně nachází v šabloně komponenty mapy,
/src/app/maps/map.component.html
<div>
<div>
<div #primaryMap ="currentHeight" ="currentWidth"></div>
<map-control class="map-control"></map-control>
<div class="mouse-coords">
<span></span>
<span ="mcText"></span>
</div>
</div>
</div>
Jsou-li šířka a výška obsahujícího DIV pevně stanoveny, pak lze dlaždice mapy vykreslit v počátečním bodě životního cyklu komponenty. Pro předávání proměnné šířky a výšky jsou možné dva přístupy, outside-in a inside-out. Metoda outside-in definuje angulární vstupy pro šířku a výšku. Za předávání šířky a výšky komponentě mapy je zodpovědná nadřazená komponenta. Přístup inside-out definuje šířku a výšku uvnitř komponenty mapy a „předává“ tyto informace její šabloně. Většina aplikací používá přístup outside-in. Tento výukový program používá pro ilustraci metodu inside-out. Jako cvičení upravte kód tak, abyste změnili předávání šířky a výšky.
Proměnná šířka a výška přináší některé jemné problémy ve vztahu k vykreslování mapy. Je lákavé provádět vše, co souvisí s nastavením Leafletu, v obsluze on-init, a to obvykle funguje s pevnou šířkou a výškou. Vzhledem k tomu, že v tomto návodu se šířka mapy mění s velikostí prohlížeče, je lepší oddělit proces inicializace mapy mezi obsluhami životního cyklu on-init a after-view-init. To ilustrují následující segmenty kódu z /src/app/maps/map.component.ts .
Nejprve je identifikace obsahujícího DIV pro inicializaci mapy přenesena na ViewChild,
@ViewChild('primaryMap', {static: true}) protected mapDivRef: ElementRef;
protected mapDiv: HTMLDivElement;
Většina nastavení mapy se provádí v ngOnInit,
public ngOnInit(): void
{
// Reference to DIV containing map is used in Leaflet initialization
this.mapDiv = this.mapDivRef.nativeElement;
this.__initializeMap();
this.__renderMap();
this.__showMarkers();
}
Invalidace velikosti mapy je odložena na ngAfterViewInit, kdy je k dispozici plná šířka a výška potřebná pro fungování dlaždic mapy. Proměnná map odkazuje na mapu Leaflet vytvořenou v obslužné rutině ngOnInit.
public ngAfterViewInit(): void
{
this.map.invalidateSize();
this.__initMapHandlers();
}
Všimněte si, že obslužná rutina aktualizace velikosti mapy přepočítává proměnné třídy currentWidth a currentHeight, které jsou vázány na styly DIV, jež řídí šířku a výšku mapového DIV. Leaflet používá tyto informace o šířce/výšce k opětovnému nastevení a vykreslení mapy.
Protože definice šířky/výšky mapy a změna velikosti mapy při změně okna jsou řešeny interně v komponentě mapy, je přidána jednoduchá obsluha změny velikosti okna.
@HostListener('window:resize', )
protected __onResize(event: any): void
{
this.__updateMapSize();
this.map.invalidateSize();
}
Tuto obsluhu by také mohla zpracovávat externí služba, která by byla spuštěna mimo Angular a byla by odhlášena. Pokud bude dostatečný zájem, poskytnu výukový program, který tuto techniku ilustruje.
Mapové ovládací prvky
Leaflet sice umožňuje používat vlastní ovládací prvky, ale jako mapové ovládací prvky můžete použít i komponenty Angular. Vytvořte komponentu Angular a použijte CSS pro pozicování. Použil jsem to v několika projektech pro velmi přizpůsobené ovládací prvky zoomu. Podívejte se do složky /src/app/maps/map-control, kde najdete kostru, kterou můžete použít jako výchozí bod.
Podívejte se do /src/app/maps/map.component.scss, kde najdete příslušné stylování.
Pozor na z-index
Pokud se zdá, že dlaždice nebo jiný aspekt zobrazení mapy nefunguje, může to být problém s z-indexem. V minulosti jsem musel přemapovávat z-indexy jednoduše kvůli změně poskytovatele dlaždic nebo dokonce kvůli přechodu z Angularu 7 na Angular 8!“
Mapové značky
Do mapy lze přidávat značky se známými souřadnicemi. Definujte souřadnice a poté pro každou z nich vytvořte ikonu letáku. Souřadnice značek pro tento výukový program jsou definovány v hlavní komponentě aplikace,
/src/app/app.component.ts
public markers: {lat: number, long: number}; // Map markers (relevance depends on map center)
constructor()
{
// some map markers
this.markers = ;
}
a jsou předány jako vstup Angular Component,
/src/app/app.component.html
<app-map ="markers"></app-map>
Značky se vykreslují v komponentě mapy,
/src/app/maps/map.component.ts
protected __showMarkers(): void
{
if (this.markers !== undefined && this.markers != null && this.markers.length > 0)
{
// Add markers
const icon = L.icon({
iconUrl: MapIconOptions.mapIcon,
iconSize: MapIconOptions.iconSize,
iconAnchor: MapIconOptions.iconAnchor,
shadowUrl: MapIconOptions.mapShadowIcon,
shadowSize: MapIconOptions.shadowSize,
shadowAnchor: MapIconOptions.shadowAnchor,
});
const n: number = this.markers.length;
let i: number;
let m: L.marker;
let x: number;
let y: number;
for (i = 0; i < n; ++i) {
x = this.markers.lat;
y = this.markers.long;
if (x !== undefined && !isNaN(x) && y !== undefined && !isNaN(y))
{
// okay to add the icon
m = L.marker(, {icon: icon}).addTo(this.map);
}
else
{
// implement your own error handling
console.log('MARKER ERROR, Marker number: ', (i+1), 'x: ', x, ' y: ', y);
}
}
}
}
Interaktivita
Bylo pro vás přidáno několik obsluh pro základní interaktivitu mapy, konkrétně kliknutí myší a pohyb myší. Druhá jmenovaná aktualizuje aktuální polohu mapy (šířka/délka) na základě polohy myši.
/src/app/maps/map.component.ts
protected __onMapMouseMove(evt: any): void
{
const lat: string = evt.latlng.lat.toFixed(3);
const long: string = evt.latlng.lng.toFixed(3);
this.mcText = `Latitude: ${lat} Longitude: ${long}`;
}
Řetězec odrážející aktuální polohu se zobrazuje v šabloně komponenty mapy,
/src/app/maps/map.component.html
<div class="mouse-coords">
<span></span>
<span ="mcText"></span>
</div>
Výsledek
Sestavte aplikaci a měli byste pozorovat něco podobného tomuto snímku obrazovky,