diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-layer.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-layer.ts index 2953c609ce..c45a3c0ca1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-layer.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-layer.ts @@ -20,12 +20,15 @@ import { defaultGoogleMapLayerSettings, defaultHereMapLayerSettings, defaultLayerTitle, + defaultOpenFreeMapLayerSettings, defaultOpenStreetMapLayerSettings, defaultTencentMapLayerSettings, GoogleMapLayerSettings, HereMapLayerSettings, MapLayerSettings, MapProvider, + OpenFreeMapLayerSettings, + OpenFreeMapStyleType, OpenStreetMapLayerSettings, ReferenceLayerType, TencentMapLayerSettings @@ -61,6 +64,8 @@ export abstract class TbMapLayer { inputSettings: DeepPartial) { switch (inputSettings.provider) { + case MapProvider.openfreemap: + return new TbOpenFreeMapLayer(ctx, inputSettings); case MapProvider.openstreet: return new TbOpenStreetMapLayer(ctx, inputSettings); case MapProvider.google: @@ -219,6 +224,32 @@ class TbOpenStreetMapLayer extends TbMapLayer { } +const openFreeMapStyleUrl = (style: OpenFreeMapStyleType): string => + `https://tiles.openfreemap.org/styles/${style}`; + +class TbOpenFreeMapLayer extends TbMapLayer { + + constructor(protected ctx: WidgetContext, + protected inputSettings: DeepPartial) { + super(ctx, inputSettings); + } + + protected defaultSettings(): OpenFreeMapLayerSettings { + return defaultOpenFreeMapLayerSettings; + } + + protected createLayer(): Observable { + const styleUrl = openFreeMapStyleUrl(this.settings.layerType); + const layer = L.TB.MapLibreGL.mapLibreGLLayer({ + style: styleUrl, + attributionControl: { + customAttribution: 'OpenFreeMap, © OpenMapTiles, Data from OpenStreetMap' + } + }); + return of(layer); + } +} + class TbGoogleMapLayer extends TbMapLayer { static loadedApiKeysGlobal: {[key: string]: boolean} = {}; @@ -318,7 +349,20 @@ class TbCustomMapLayer extends TbMapLayer { } protected createLayer(): Observable { - const layer = L.tileLayer(this.settings.tileUrl); + if (this.settings.vectorTiles) { + const options: any = { + style: this.settings.tileUrl + }; + if (this.settings.customAttribution) { + options.attributionControl = { + customAttribution: this.settings.customAttribution + }; + } + return of(L.TB.MapLibreGL.mapLibreGLLayer(options)); + } + const layer = L.tileLayer(this.settings.tileUrl, this.settings.customAttribution ? { + attribution: this.settings.customAttribution + } : undefined); return of(layer); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.html index 4416ab2d6c..69d1abeab2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.html @@ -28,6 +28,18 @@ } + @if (MapProvider.openfreemap === layerFormGroup.get('provider').value) { + + + @for (styleType of openFreeMapStyleTypes; track styleType) { + + {{ openFreeMapStyleTranslationMap.get(styleType) | translate }} + + } + + + } @if (MapProvider.openstreet === layerFormGroup.get('provider').value) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts index 2fdd892fa9..4c128d63f8 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts @@ -49,6 +49,8 @@ import { MapProvider, mapProviders, mapProviderTranslationMap, + openFreeMapStyleTranslationMap, + openFreeMapStyleTypes, openStreetLayerTypes, openStreetMapLayerTranslationMap, tencentLayerTranslationMap, @@ -81,6 +83,10 @@ export class MapLayerRowComponent implements ControlValueAccessor, OnInit { mapProviderTranslationMap = mapProviderTranslationMap; + openFreeMapStyleTypes = openFreeMapStyleTypes; + + openFreeMapStyleTranslationMap = openFreeMapStyleTranslationMap; + openStreetLayerTypes = openStreetLayerTypes; openStreetMapLayerTranslationMap = openStreetMapLayerTranslationMap; @@ -124,6 +130,8 @@ export class MapLayerRowComponent implements ControlValueAccessor, OnInit { provider: [null, [Validators.required]], layerType: [null, [Validators.required]], tileUrl: [null, [Validators.required]], + vectorTiles: [false, []], + customAttribution: [null, []], apiKey: [null, [Validators.required]], referenceLayer: [null, []] }); @@ -216,9 +224,13 @@ export class MapLayerRowComponent implements ControlValueAccessor, OnInit { const provider: MapProvider = this.layerFormGroup.get('provider').value; if (provider === MapProvider.custom) { this.layerFormGroup.get('tileUrl').enable({emitEvent: false}); + this.layerFormGroup.get('vectorTiles').enable({emitEvent: false}); + this.layerFormGroup.get('customAttribution').enable({emitEvent: false}); this.layerFormGroup.get('layerType').disable({emitEvent: false}); } else { this.layerFormGroup.get('tileUrl').disable({emitEvent: false}); + this.layerFormGroup.get('vectorTiles').disable({emitEvent: false}); + this.layerFormGroup.get('customAttribution').disable({emitEvent: false}); this.layerFormGroup.get('layerType').enable({emitEvent: false}); } if ([MapProvider.google, MapProvider.here].includes(provider)) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.html index 28957d4b6a..6974e08150 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.html @@ -36,8 +36,29 @@ + @if (MapProvider.custom === layerFormGroup.get('provider').value) { +
+ +
+ {{ 'widgets.maps.layer.provider.custom.vector-tiles' | translate }} +
+
+
+ }
-
{{ (MapProvider.custom === layerFormGroup.get('provider').value ? 'widgets.maps.layer.provider.custom.tile-url' : 'widgets.maps.layer.layer') | translate }}
+
{{ (MapProvider.custom === layerFormGroup.get('provider').value ? (layerFormGroup.get('vectorTiles').value ? 'widgets.maps.layer.provider.custom.style-url' : 'widgets.maps.layer.provider.custom.tile-url') : 'widgets.maps.layer.layer') | translate }}
+ @if (MapProvider.openfreemap === layerFormGroup.get('provider').value) { + + + @for (styleType of openFreeMapStyleTypes; track styleType) { + + {{ openFreeMapStyleTranslationMap.get(styleType) | translate }} + + } + + + } @if (MapProvider.openstreet === layerFormGroup.get('provider').value) { @@ -117,6 +138,14 @@
+ @if (MapProvider.custom === layerFormGroup.get('provider').value) { +
+
widgets.maps.layer.provider.custom.attribution
+ + + +
+ }