Last active
June 29, 2022 14:25
-
-
Save anartzdev/1059f82586294081baadfd2dc4dc44c0 to your computer and use it in GitHub Desktop.
Default Layer feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { IConfigMap, IMarker, tileLayers } from '@mugan86/ng-leaflet'; | |
import { Component } from '@angular/core'; | |
@Component({ | |
selector: 'app-map', | |
templateUrl: './map.component.html', | |
styleUrls: ['./map.component.css'] | |
}) | |
export class MapComponent{ | |
markers: Array<IMarker> = [ | |
{ | |
position: { | |
lat: 43.17757110078426, | |
lng: -2.3661233885984085, | |
}, | |
}, | |
{ | |
position: { | |
lat: 43.177781697765305, | |
lng: -2.367583962060063, | |
}, | |
}, | |
]; | |
config?: IConfigMap = { | |
// Usa esta capa sobrescribiendo cualquier capa en global / control de capas | |
defaultLayer: { | |
map: 'https://tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png?apikey=47455e4b0807408c87ead5d6f7a8d1c8', | |
atribution: tileLayers.baseLayers.default.atribution | |
}, | |
fitBounds: true, | |
drawRoute: { | |
active: false, | |
showControl: false | |
}, | |
markerColor: 'orange' | |
}; | |
// Para usar el global con defaultLayer (en el caso de que esté activado, si no pone la capa básica de OSM) | |
configTwo?: IConfigMap = { | |
fitBounds: true, | |
drawRoute: { | |
active: false, | |
showControl: false | |
}, | |
markerColor: 'orange' | |
}; | |
/*@Input() markers: Array<IMarker> = [{ | |
position: { | |
lat: 43.17774378506745, | |
lng: -2.4150770902633667 | |
} | |
}, | |
{ | |
position: { | |
lat: 43.177548188824325, | |
lng: -2.4145513772964478 | |
} | |
}, | |
{ | |
position: { | |
lat: 43.177274353031386, | |
lng: -2.4141544103622437 | |
} | |
}]; | |
@Input() randomMarkers: boolean = false; | |
@Input() size: { width: string, height: string } = { width: '100%', height: '600px' } | |
@Input() config?: IConfigMap = { | |
fullscreen: true, | |
ourLocation: { | |
active: true, | |
zoom: 5 | |
}, | |
zoom: { | |
default: 15 | |
}, | |
drawRoute: { | |
active: true, | |
title: 'Jabali Trail Short', | |
showControl: true | |
} | |
}; | |
*/ | |
/*markers: Array<IMarker> = [ | |
{ | |
position: { | |
lat: 43.17757110078426, | |
lng: -2.3661233885984085, | |
}, | |
}, | |
{ | |
position: { | |
lat: 43.177781697765305, | |
lng: -2.367583962060063, | |
}, | |
}, | |
]; | |
config?: IConfigMap = { | |
fitBounds: true, | |
drawRoute: { | |
active: true, | |
showControl: false | |
}, | |
markerColor: 'gold' | |
}; | |
ngOnInit() { | |
this.markers.length = 0; | |
fetch('https://raw.githubusercontent.com/leaflet-maps-course/resources/main/tracks/track.gpx') | |
.then(response => response.text()) | |
.then(data => { | |
const gpx = new gpxParser(); //Create gpxParser Object | |
gpx.parse(data); //parse gpx file from string data | |
gpx.tracks[0].points.map((point) => { | |
this.markers.push({ | |
position: { | |
lat: point.lat, | |
lng: point.lon | |
} | |
}) | |
}); | |
}); | |
}*/ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NgModule } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { MapRoutingModule } from './map-routing.module'; | |
import { MapComponent } from './map.component'; | |
import { IConfigMap, NgLeafletModule, tileLayers } from '@mugan86/ng-leaflet'; | |
const config: IConfigMap = { | |
fullscreen: true, | |
center: [40.4378698,-3.8196188], | |
zoom: { | |
position: 'topright' | |
}, | |
watermark: { | |
position: 'topleft' | |
}, | |
/*defaultLayer: { | |
map: 'https://tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png?apikey=47455e4b0807408c87ead5d6f7a8d1c8', | |
atribution: tileLayers.baseLayers.default.atribution | |
}, | |
layers: { | |
baseLayers: [{ | |
label: 'Carto - Positron', | |
map: tileLayers.baseLayers.cartoDb.map.positron, | |
atribution: tileLayers.baseLayers.cartoDb.atribution, | |
default: true | |
}, | |
{ | |
label: 'Cyclo OSM', | |
map: tileLayers.baseLayers.cycloOsm.map, | |
atribution: tileLayers.baseLayers.cycloOsm.atribution | |
}] | |
},*/ | |
drawRoute: { | |
active: true, | |
showControl: true | |
} | |
} | |
@NgModule({ | |
declarations: [ | |
MapComponent | |
], | |
imports: [ | |
CommonModule, | |
MapRoutingModule, | |
NgLeafletModule.forRoot(config, { | |
width: '100%', | |
height: '600px' | |
}) | |
] | |
}) | |
export class MapModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core'; | |
import { IMarker, IConfigMap } from './../../models'; | |
import { Controls } from '../../services/controls'; | |
import { Markers } from './../../services/markers'; | |
import { LeafletMap as Map } from './../../services/ng-leaflet-map.service'; | |
import { Map as MapObject } from 'leaflet'; | |
import { ISizeMap } from '../../models/config-map'; | |
import { DefaultConfig } from '../../services'; | |
import { DrawMap } from '../../services/draw-map'; | |
@Component({ | |
selector: 'ng-leaflet-map', | |
templateUrl: './map.component.html', | |
styles: [ | |
] | |
}) | |
export class MapComponent implements AfterViewInit { | |
/** | |
* Assign map ID that need is unique and not duplicate | |
* | |
* @required | |
*/ | |
@Input() mapId = 'map'; | |
/** | |
* Markers | |
*/ | |
@Input() markers!: Array<IMarker>; | |
/** | |
* Button contents | |
* | |
* @required | |
*/ | |
@Input() randomMarkers: boolean = false; | |
/** | |
* Specify use Map size to working map | |
* | |
* @required | |
*/ | |
@Input() size!: ISizeMap; | |
/** | |
* Use map differents configurations to custom | |
*/ | |
@Input() config?: IConfigMap; | |
/** | |
Use the loading state to indicate that the data Avatar needs is still loading. | |
*/ | |
@Output() setUpMap: EventEmitter<MapObject> = new EventEmitter<MapObject>(); | |
private map!: Map; | |
constructor(private defaultConfig: DefaultConfig) { } | |
ngOnInit() { | |
// Check if size config exist and if not exist, take default 100% w - 500px h | |
if (this.size && this.defaultConfig.get().size) { | |
console.warn('Use set size'); | |
} | |
if (!this.size && !this.defaultConfig.get().size) { | |
this.size = { | |
width: '100%', | |
height: '500px' | |
}; | |
return; | |
} | |
// Check if size config exist and if not exist, take default 100% w - 500px h | |
if (!this.size && this.defaultConfig.get().size) { | |
console.warn('Use default global size'); | |
this.size = this.defaultConfig.get().size; | |
} | |
} | |
private checkConfigs() { | |
if (!this.config && this.defaultConfig.get().config) { | |
console.warn('Use default config'); | |
this.config = this.defaultConfig.get().config; | |
return; | |
} | |
if (!this.config && !this.defaultConfig.get().config) { | |
console.warn("Use Library default configs \n" + (JSON.stringify({ | |
fullscreen: false, | |
center: [43.1824528, -2.3878554], | |
mapId: 'map', | |
zoom: true, | |
zoomValue: 12, | |
drawRoute: false | |
}, null, 2))); | |
return; | |
} | |
} | |
setConfiguration() { | |
this.checkConfigs(); | |
if (this.config && this.defaultConfig.get().config) { | |
console.warn("Overwrite defaultConfig with new set config duplicates values properties"); | |
// Rewrite | |
this.checkAndAsignDefaultConfigs() | |
} | |
} | |
private checkAndAsignDefaultConfigs() { | |
if (!this.config!.center && this.defaultConfig.get().config.center) { | |
this.config!.center = this.defaultConfig.get().config.center; | |
} | |
if (this.config!.fullscreen === undefined && this.defaultConfig.get().config.fullscreen) { | |
this.config!.fullscreen = this.defaultConfig.get().config.fullscreen; | |
} | |
if (!this.config!.scale && this.defaultConfig.get().config.scale) { | |
this.config!.scale = this.defaultConfig.get().config.scale; | |
} | |
if (!this.config!.defaultLayer && this.defaultConfig.get().config.defaultLayer) { | |
this.config!.defaultLayer = this.defaultConfig.get().config.defaultLayer; | |
} | |
if (!this.config!.layers && !this.config?.defaultLayer && this.defaultConfig.get().config.layers) { | |
this.config!.layers = this.defaultConfig.get().config.layers; | |
} | |
if (!this.config!.zoom && this.defaultConfig.get().config.zoom) { | |
this.config!.zoom = this.defaultConfig.get().config.zoom; | |
} | |
if (!this.config!.watermark && this.defaultConfig.get().config.watermark) { | |
this.config!.watermark = this.defaultConfig.get().config.watermark; | |
} | |
if (!this.config!.fitBounds && this.defaultConfig.get().config.fitBounds) { | |
this.config!.fitBounds = this.defaultConfig.get().config.fitBounds; | |
} | |
if (!this.config!.drawRoute && this.defaultConfig.get().config.drawRoute) { | |
this.config!.drawRoute = this.defaultConfig.get().config.drawRoute; | |
} | |
if (!this.config!.markerColor && this.defaultConfig.get().config.markerColor) { | |
this.config!.markerColor = this.defaultConfig.get().config.markerColor; | |
} | |
} | |
ngAfterViewInit(): void { | |
this.setConfiguration(); | |
this.map = new Map(this.config || undefined, this.mapId || undefined); | |
this.config!! && this.setControls(); | |
if (this.config && this.config!!.drawRoute && this.config!!.drawRoute!!.active) { | |
if (this.markers.length >= 3) { | |
new DrawMap(this.map.get()).drawPoints(this.markers); | |
} else { | |
console.warn('Need min 3 markers to draw correctly route'); | |
} | |
} else { | |
const markerColor = this.config!!.markerColor || 'blue'; | |
this.markers && (this.markers.length) && Markers.add(this.map.get(), this.markers, false, markerColor); | |
this.randomMarkers && Markers.add(this.map.get(), [], this.randomMarkers, markerColor); | |
this.markers && this.markers.length && this.config!.fitBounds && this.map.fitBounds(this.markers); | |
} | |
this.setUpMap.emit(this.map.get()); | |
} | |
setControls() { | |
this.config!!.scale && Controls.addScale(this.map.get(), this.config?.scale); | |
this.config!!.layers && Controls.addBaseOverLayers(this.map.get(), this.config!!.layers); | |
this.config!!.zoom && Controls.changeZoomConfig(this.map.get(), this.config?.zoom); | |
this.config!!.fullscreen && Controls.activeFullScreen(this.map.get()); | |
this.config!!.watermark && Controls.activeWatermark(this.map.get(), this.config!!.watermark); | |
this.config!!.ourLocation?.active && Controls.getOurLocation(this.map.get(), this.config?.ourLocation.zoom || 12) | |
this.config!!.drawRoute?.showControl && Controls.addTitle( | |
this.map.get(), | |
this.config!!.drawRoute.title || '', | |
this.config!!.drawRoute.subtitle || '', | |
this.config!!.drawRoute.position | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ControlPosition } from "leaflet"; | |
import { MarkerColorOptions } from "../config/markers/default"; | |
import { ILayers, IScaleOptions, IWatermarkOptions, IZoomOptions, IBaseLayer } from './controls'; | |
export interface IConfigMap { | |
markerColor?: MarkerColorOptions; | |
center?: [number, number]; | |
scale?: IScaleOptions | undefined; | |
defaultLayer?: IBaseLayer; | |
layers?: ILayers; | |
zoom?: IZoomOptions; | |
fullscreen?: boolean; | |
watermark?: IWatermarkOptions; | |
fitBounds?: boolean; | |
ourLocation?: { | |
active: boolean; | |
zoom?: number; | |
}; | |
drawRoute?: { | |
active?: boolean; | |
title?: string; | |
subtitle?: string; | |
position?: ControlPosition; | |
showControl?: boolean; | |
}; | |
} | |
export interface ISizeMap { | |
width: string; | |
height: string; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ControlPosition } from "leaflet"; | |
export interface IScaleOptions { | |
show?: boolean; | |
position?: ControlPosition; | |
maxWidth?: number; | |
metric?: boolean; | |
imperial?: boolean; | |
/** | |
* If true, the control is updated on moveend, otherwise it's always | |
* up-to-date (updated on move). Default: false | |
*/ | |
updateWhenIdle?: boolean | undefined; | |
} | |
export interface ILayers { | |
baseLayers: Array<IBaseLayer>; | |
overLayers?: Array<IOverLayer> | |
} | |
export interface IBaseLayer { | |
label?: string; | |
map: string; | |
atribution: string; | |
default?: boolean | |
} | |
export interface IOverLayer { | |
label: string; | |
map: string; | |
select: boolean | |
} | |
export interface IZoomOptions { | |
zoomInTitle?: string; | |
zoomOutTitle?: string; | |
position?: ControlPosition; | |
default?: number; | |
} | |
export interface IWatermarkOptions { | |
img?: string; | |
border?: boolean; | |
position?: ControlPosition; | |
size?: string; | |
borderColor?: string; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { control, ControlPosition, Map } from 'leaflet'; | |
import { tileLayerSelect } from '../config/tile-layers/helpers'; | |
import { IBaseLayer, IOverLayer, ILayers, IScaleOptions, IZoomOptions, IWatermarkOptions } from '../models/controls' | |
import { textContent } from '../plugins/controls'; | |
import { fullScreenMap } from '../plugins/controls/full-screen-map'; | |
import { geolocation } from '../plugins/controls/geolocation'; | |
import { watermark } from '../plugins/controls/watermark'; | |
class Controls { | |
static changeZoomConfig(map: Map, config?: IZoomOptions) { | |
control.zoom({ | |
zoomInTitle: config!!.zoomInTitle || 'Zoom in', | |
zoomOutTitle: config!!.zoomOutTitle || 'Zoom out', | |
position: config!!.position || 'topleft' | |
}).addTo(map); | |
} | |
static addScale(map: Map, config?: IScaleOptions) { | |
delete config!.show; | |
// Add Scale control after remove show property that not include in config options | |
control.scale(config).addTo(map); | |
} | |
/** | |
* Generate layers control to available users want differente layers | |
* to use in maps. | |
* @param map Map instantiate object when add control layers | |
* @param layers Layers with base and overlayers to add in map | |
* @param position control position in map | |
*/ | |
static addBaseOverLayers(map: Map, layers: ILayers, position: ControlPosition = 'topright') { | |
if (!layers.baseLayers) { | |
throw new Error("Need to add Base Layers"); | |
} | |
if (layers.baseLayers.length < 2) { | |
console.warn("Take advantage of at least two base layers to take advantage of this feature") | |
} | |
// Layers controls | |
control.layers( | |
this.groupBaseLayers( | |
layers.baseLayers, map), | |
(layers.overLayers) && this.groupOverLayers(layers.overLayers, map), { | |
position | |
}).addTo(map); | |
} | |
private static groupBaseLayers(layers: Array<IBaseLayer>, map: Map) { | |
const findDefaultLayerConfig = layers.find((layer) => layer.default) | |
const defaultLayer = tileLayerSelect(findDefaultLayerConfig!!.map, { | |
attribution: findDefaultLayerConfig!!.atribution | |
}).addTo(map); | |
return layers.reduce((a, layer) => { | |
return (!layer.default) ? ({ // Add NO default layers | |
...a, [layer.label || '']: tileLayerSelect(layer.map, { | |
attribution: layer.atribution | |
}) | |
}) : { | |
...a, ...{ [layer.label || '']: defaultLayer } // Map Default select layer | |
} | |
}, {} // Start value | |
); | |
} | |
private static groupOverLayers(layers: Array<IOverLayer>, map: Map) { | |
return layers.reduce((a, layer) => ({ | |
...a, [layer.label]: (layer.select) ? | |
tileLayerSelect(layer.map).addTo(map) : | |
tileLayerSelect(layer.map) | |
}), {}); | |
} | |
static activeFullScreen(map: Map, position?: ControlPosition) { | |
fullScreenMap({ | |
position: (position) || 'topleft' | |
}).addTo(map) | |
} | |
static activeWatermark(map: Map, config: IWatermarkOptions) { | |
watermark(config).addTo(map) | |
} | |
static getOurLocation(map: Map, zoom: number, position?: ControlPosition) { | |
geolocation({ | |
position: (position) || 'topleft', | |
zoom | |
}).addTo(map); | |
} | |
static addTitle(map: Map, title: string, subtitle: string = '', position?: ControlPosition) { | |
textContent( { | |
position: (position) || 'bottomleft', | |
title, | |
subtitle | |
}).addTo(map); | |
} | |
} | |
export { Controls } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment