UI: New maps V3
This commit is contained in:
parent
36f990cf15
commit
7f4a0ef48f
@ -101,7 +101,8 @@
|
||||
"node_modules/tooltipster/dist/css/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-shadow.min.css",
|
||||
"node_modules/jstree-bootstrap-theme/dist/themes/proton/style.min.css",
|
||||
"node_modules/leaflet/dist/leaflet.css",
|
||||
"src/app/modules/home/components/widget/lib/maps/markers.scss",
|
||||
"src/app/modules/home/components/widget/lib/maps/map.scss",
|
||||
"src/app/modules/home/components/widget/lib/maps-legacy/markers.scss",
|
||||
"src/app/modules/home/components/widget/lib/home-page/home-page.scss",
|
||||
"node_modules/leaflet.markercluster/dist/MarkerCluster.css",
|
||||
"node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css",
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
///
|
||||
|
||||
import L, { LeafletMouseEvent } from 'leaflet';
|
||||
import { CircleData, WidgetCircleSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { functionValueCalculator, parseWithTranslation } from '@home/components/widget/lib/maps/common-maps-utils';
|
||||
import LeafletMap from '@home/components/widget/lib/maps/leaflet-map';
|
||||
import { createTooltip } from '@home/components/widget/lib/maps/maps-utils';
|
||||
import { CircleData, WidgetCircleSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { functionValueCalculator, parseWithTranslation } from '@home/components/widget/lib/maps-legacy/common-maps-utils';
|
||||
import LeafletMap from '@home/components/widget/lib/maps-legacy/leaflet-map';
|
||||
import { createTooltip } from '@home/components/widget/lib/maps-legacy/maps-utils';
|
||||
import { FormattedData } from '@shared/models/widget.models';
|
||||
import { fillDataPattern, processDataPattern, safeExecuteTbFunction } from '@core/utils';
|
||||
|
||||
@ -43,8 +43,8 @@ import {
|
||||
isJSON,
|
||||
isValidLatLng,
|
||||
LabelSettings
|
||||
} from '@home/components/widget/lib/maps/maps-utils';
|
||||
import { checkLngLat, createLoadingDiv } from '@home/components/widget/lib/maps/common-maps-utils';
|
||||
} from '@home/components/widget/lib/maps-legacy/maps-utils';
|
||||
import { checkLngLat, createLoadingDiv } from '@home/components/widget/lib/maps-legacy/common-maps-utils';
|
||||
import { WidgetContext } from '@home/models/widget-component.models';
|
||||
import {
|
||||
deepClone,
|
||||
@ -60,7 +60,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import {
|
||||
SelectEntityDialogComponent,
|
||||
SelectEntityDialogData
|
||||
} from '@home/components/widget/lib/maps/dialogs/select-entity-dialog.component';
|
||||
} from '@home/components/widget/lib/maps-legacy/dialogs/select-entity-dialog.component';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { FormattedData, ReplaceInfo } from '@shared/models/widget.models';
|
||||
import { ImagePipe } from '@shared/pipe/image.pipe';
|
||||
@ -14,7 +14,7 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import LeafletMap from '@home/components/widget/lib/maps/leaflet-map';
|
||||
import LeafletMap from '@home/components/widget/lib/maps-legacy/leaflet-map';
|
||||
|
||||
export interface MapWidgetInterface {
|
||||
map?: LeafletMap;
|
||||
@ -23,7 +23,7 @@ import { Datasource, DatasourceData, FormattedData, WidgetActionDescriptor } fro
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { UtilsService } from '@core/services/utils.service';
|
||||
import { EntityDataPageLink } from '@shared/models/query/query.models';
|
||||
import { providerClass } from '@home/components/widget/lib/maps/providers/public-api';
|
||||
import { providerClass } from '@home/components/widget/lib/maps-legacy/providers/public-api';
|
||||
import { isDefined, isDefinedAndNotNull, parseTbFunction } from '@core/utils';
|
||||
import L from 'leaflet';
|
||||
import { firstValueFrom, forkJoin, from, Observable, of } from 'rxjs';
|
||||
@ -18,7 +18,7 @@ import L from 'leaflet';
|
||||
import { GenericFunction, ShowTooltipAction, WidgetToolipSettings } from './map-models';
|
||||
import { Datasource, FormattedData } from '@app/shared/models/widget.models';
|
||||
import { fillDataPattern, isDefinedAndNotNull, isString, processDataPattern, safeExecuteTbFunction } from '@core/utils';
|
||||
import { parseWithTranslation } from '@home/components/widget/lib/maps/common-maps-utils';
|
||||
import { parseWithTranslation } from '@home/components/widget/lib/maps-legacy/common-maps-utils';
|
||||
import { CompiledTbFunction } from '@shared/models/js-function.models';
|
||||
|
||||
export function createTooltip(target: L.Layer,
|
||||
@ -20,7 +20,7 @@ import { functionValueCalculator, parseWithTranslation } from './common-maps-uti
|
||||
import { WidgetPolygonSettings } from './map-models';
|
||||
import { FormattedData } from '@shared/models/widget.models';
|
||||
import { fillDataPattern, processDataPattern, safeExecuteTbFunction } from '@core/utils';
|
||||
import LeafletMap from '@home/components/widget/lib/maps/leaflet-map';
|
||||
import LeafletMap from '@home/components/widget/lib/maps-legacy/leaflet-map';
|
||||
|
||||
export class Polygon {
|
||||
|
||||
@ -19,7 +19,7 @@ import L, { PolylineDecorator, PolylineDecoratorOptions, Symbol } from 'leaflet'
|
||||
import 'leaflet-polylinedecorator';
|
||||
|
||||
import { WidgetPolylineSettings } from './map-models';
|
||||
import { functionValueCalculator } from '@home/components/widget/lib/maps/common-maps-utils';
|
||||
import { functionValueCalculator } from '@home/components/widget/lib/maps-legacy/common-maps-utils';
|
||||
import { FormattedData } from '@shared/models/widget.models';
|
||||
|
||||
export class Polyline {
|
||||
@ -25,7 +25,7 @@ import {
|
||||
} from '../map-models';
|
||||
import { combineLatest, Observable, of, ReplaySubject, switchMap } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { calculateNewPointCoordinate, loadImageWithAspect } from '@home/components/widget/lib/maps/common-maps-utils';
|
||||
import { calculateNewPointCoordinate, loadImageWithAspect } from '@home/components/widget/lib/maps-legacy/common-maps-utils';
|
||||
import { WidgetContext } from '@home/models/widget-component.models';
|
||||
import { DataSet, DatasourceType, FormattedData, widgetType } from '@shared/models/widget.models';
|
||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
||||
@ -20,7 +20,7 @@ import { GoogleMap } from './google-map';
|
||||
import { HEREMap } from './here-map';
|
||||
import { ImageMap } from './image-map';
|
||||
import { Type } from '@angular/core';
|
||||
import LeafletMap from '@home/components/widget/lib/maps/leaflet-map';
|
||||
import LeafletMap from '@home/components/widget/lib/maps-legacy/leaflet-map';
|
||||
|
||||
export const providerClass: { [key: string]: Type<LeafletMap> } = {
|
||||
'openstreet-map': OpenStreetMap,
|
||||
@ -0,0 +1,90 @@
|
||||
import {
|
||||
defaultOpenStreetMapLayerSettings,
|
||||
MapLayerSettings,
|
||||
MapProvider, OpenStreetLayerType,
|
||||
OpenStreetMapLayerSettings, openStreetMapLayerTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map.models';
|
||||
import { WidgetContext } from '@home/models/widget-component.models';
|
||||
import { DeepPartial } from '@shared/models/common';
|
||||
import { mergeDeep } from '@core/utils';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe';
|
||||
import L from 'leaflet';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
export abstract class TbMapLayer<S extends MapLayerSettings> {
|
||||
|
||||
static fromSettings(ctx: WidgetContext,
|
||||
inputSettings: DeepPartial<MapLayerSettings>) {
|
||||
|
||||
switch (inputSettings.provider) {
|
||||
case MapProvider.google:
|
||||
break;
|
||||
case MapProvider.openstreet:
|
||||
return new TbOpenStreetMapLayer(ctx, inputSettings);
|
||||
case MapProvider.tencent:
|
||||
break;
|
||||
case MapProvider.here:
|
||||
break;
|
||||
case MapProvider.custom:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected settings: S;
|
||||
|
||||
protected constructor(protected ctx: WidgetContext,
|
||||
protected inputSettings: DeepPartial<MapLayerSettings>) {
|
||||
this.settings = mergeDeep({} as S, this.defaultSettings(), this.inputSettings as S);
|
||||
}
|
||||
|
||||
protected abstract defaultSettings(): S;
|
||||
|
||||
protected title(): string {
|
||||
const customTranslate = this.ctx.$injector.get(CustomTranslatePipe);
|
||||
if (this.settings.label) {
|
||||
return customTranslate.transform(this.settings.label);
|
||||
} else {
|
||||
return this.generateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract generateTitle(): string;
|
||||
|
||||
protected abstract createLayer(): Observable<L.Layer>;
|
||||
|
||||
public loadLayer(): Observable<{title: string, layer: L.Layer}> {
|
||||
return this.createLayer().pipe(
|
||||
map((layer) => {
|
||||
return {
|
||||
title: this.title(),
|
||||
layer
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TbOpenStreetMapLayer extends TbMapLayer<OpenStreetMapLayerSettings> {
|
||||
|
||||
constructor(protected ctx: WidgetContext,
|
||||
protected inputSettings: DeepPartial<MapLayerSettings>) {
|
||||
super(ctx, inputSettings);
|
||||
}
|
||||
|
||||
protected defaultSettings(): OpenStreetMapLayerSettings {
|
||||
return defaultOpenStreetMapLayerSettings;
|
||||
}
|
||||
|
||||
protected generateTitle(): string {
|
||||
const layerType = OpenStreetLayerType[this.settings.layerType];
|
||||
return this.ctx.translate.instant(openStreetMapLayerTranslationMap.get(layerType));
|
||||
}
|
||||
|
||||
protected createLayer(): Observable<L.Layer> {
|
||||
const layer = L.tileLayer.provider(OpenStreetLayerType[this.settings.layerType]);
|
||||
return of(layer);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
|
||||
Copyright © 2016-2024 The Thingsboard Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<div class="tb-map-panel" [style.padding]="padding" [style]="backgroundStyle$ | async">
|
||||
<div class="tb-map-overlay" [style]="overlayStyle"></div>
|
||||
<ng-container *ngIf="widgetComponent.dashboardWidget.showWidgetTitlePanel">
|
||||
<ng-container *ngTemplateOutlet="widgetTitlePanel"></ng-container>
|
||||
</ng-container>
|
||||
<div #mapElement>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright © 2016-2024 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.tb-map-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 20px 24px 24px 24px;
|
||||
> div:not(.tb-map-overlay) {
|
||||
z-index: 1;
|
||||
}
|
||||
.tb-map-overlay {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
bottom: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
div.tb-widget-title {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Renderer2,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { mapWidgetDefaultSettings, MapWidgetSettings } from '@home/components/widget/lib/maps/map-widget.models';
|
||||
import { WidgetContext } from '@home/models/widget-component.models';
|
||||
import { Observable } from 'rxjs';
|
||||
import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/widget-settings.models';
|
||||
import { TbMap } from '@home/components/widget/lib/maps/map';
|
||||
import { MapSetting } from '@home/components/widget/lib/maps/map.models';
|
||||
import { WidgetComponent } from '@home/components/widget/widget.component';
|
||||
import { ImagePipe } from '@shared/pipe/image.pipe';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-map-widget',
|
||||
templateUrl: './map-widget.component.html',
|
||||
styleUrls: ['./map-widget.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MapWidgetComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
@ViewChild('mapElement', {static: false})
|
||||
mapElement: ElementRef<HTMLElement>;
|
||||
|
||||
settings: MapWidgetSettings;
|
||||
|
||||
@Input()
|
||||
ctx: WidgetContext;
|
||||
|
||||
@Input()
|
||||
widgetTitlePanel: TemplateRef<any>;
|
||||
|
||||
backgroundStyle$: Observable<ComponentStyle>;
|
||||
overlayStyle: ComponentStyle = {};
|
||||
padding: string;
|
||||
|
||||
private map: TbMap<MapSetting>;
|
||||
|
||||
constructor(public widgetComponent: WidgetComponent,
|
||||
private imagePipe: ImagePipe,
|
||||
private sanitizer: DomSanitizer,
|
||||
private renderer: Renderer2,
|
||||
private cd: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.ctx.$scope.mapWidget = this;
|
||||
this.settings = {...mapWidgetDefaultSettings, ...this.ctx.settings};
|
||||
|
||||
this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer);
|
||||
this.overlayStyle = overlayStyle(this.settings.background.overlay);
|
||||
this.padding = this.settings.background.overlay.enabled ? undefined : this.settings.padding;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.map = TbMap.fromSettings(this.ctx, this.settings, this.mapElement.nativeElement);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.map) {
|
||||
this.map.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public onInit() {
|
||||
const borderRadius = this.ctx.$widgetElement.css('borderRadius');
|
||||
this.overlayStyle = {...this.overlayStyle, ...{borderRadius}};
|
||||
this.cd.detectChanges();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { defaultMapSettings, MapSetting } from '@home/components/widget/lib/maps/map.models';
|
||||
import { BackgroundSettings, BackgroundType } from '@shared/models/widget-settings.models';
|
||||
import { mergeDeep } from '@core/utils';
|
||||
|
||||
export interface MapWidgetSettings extends MapSetting {
|
||||
background: BackgroundSettings;
|
||||
padding: string;
|
||||
}
|
||||
|
||||
export const mapWidgetDefaultSettings: MapWidgetSettings =
|
||||
mergeDeep({} as MapWidgetSettings, defaultMapSettings as MapWidgetSettings, {
|
||||
background: {
|
||||
type: BackgroundType.color,
|
||||
color: '#fff',
|
||||
overlay: {
|
||||
enabled: false,
|
||||
color: 'rgba(255,255,255,0.72)',
|
||||
blur: 3
|
||||
}
|
||||
},
|
||||
padding: '12px'
|
||||
} as MapWidgetSettings);
|
||||
@ -0,0 +1,310 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { DataKey, DatasourceType } from '@shared/models/widget.models';
|
||||
import { EntityType } from '@shared/models/entity-type.models';
|
||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
||||
import { mergeDeep } from '@core/utils';
|
||||
|
||||
export enum MapType {
|
||||
geoMap = 'geoMap',
|
||||
image = 'image'
|
||||
}
|
||||
|
||||
export interface MapDataSourceSettings {
|
||||
dsType: DatasourceType;
|
||||
dsEntityType?: EntityType;
|
||||
dsEntityId?: string;
|
||||
dsEntityAliasId?: string;
|
||||
dsFilterId?: string;
|
||||
}
|
||||
|
||||
export interface MapDataLayerSettings extends MapDataSourceSettings {
|
||||
additionalDataKeys?: DataKey[];
|
||||
group?: string;
|
||||
}
|
||||
|
||||
export interface MarkersDataLayerSettings extends MapDataLayerSettings {
|
||||
xKey: DataKey;
|
||||
yKey: DataKey;
|
||||
}
|
||||
|
||||
export const defaultMarkersDataLayerSettings = (mapType: MapType): MarkersDataLayerSettings => ({
|
||||
dsType: DatasourceType.entity,
|
||||
xKey: {
|
||||
name: MapType.geoMap === mapType ? 'latitude' : 'xPos',
|
||||
label: MapType.geoMap === mapType ? 'latitude' : 'xPos',
|
||||
type: DataKeyType.attribute
|
||||
},
|
||||
yKey: {
|
||||
name: MapType.geoMap === mapType ? 'longitude' : 'yPos',
|
||||
label: MapType.geoMap === mapType ? 'longitude' : 'yPos',
|
||||
type: DataKeyType.attribute
|
||||
}
|
||||
});
|
||||
|
||||
export interface PolygonsDataLayerSettings extends MapDataLayerSettings {
|
||||
polygonKey: DataKey;
|
||||
}
|
||||
|
||||
export const defaultPolygonsDataLayerSettings: PolygonsDataLayerSettings = {
|
||||
dsType: DatasourceType.entity,
|
||||
polygonKey: {
|
||||
name: 'perimeter',
|
||||
label: 'perimeter',
|
||||
type: DataKeyType.attribute
|
||||
}
|
||||
};
|
||||
|
||||
export interface CirclesDataLayerSettings extends MapDataLayerSettings {
|
||||
circleKey: DataKey;
|
||||
}
|
||||
|
||||
export const defaultCirclesDataLayerSettings: CirclesDataLayerSettings = {
|
||||
dsType: DatasourceType.entity,
|
||||
circleKey: {
|
||||
name: 'perimeter',
|
||||
label: 'perimeter',
|
||||
type: DataKeyType.attribute
|
||||
}
|
||||
};
|
||||
|
||||
export interface AdditionalMapDataSourceSettings extends MapDataSourceSettings {
|
||||
dataKeys: DataKey[];
|
||||
}
|
||||
|
||||
export enum MapControlsPosition {
|
||||
topleft = 'topleft',
|
||||
topright = 'topright',
|
||||
bottomleft = 'bottomleft',
|
||||
bottomright = 'bottomright'
|
||||
}
|
||||
|
||||
export enum MapZoomAction {
|
||||
scroll = 'scroll',
|
||||
doubleClick = 'doubleClick',
|
||||
controlButtons = 'controlButtons'
|
||||
}
|
||||
|
||||
export interface BaseMapSettings {
|
||||
mapType: MapType;
|
||||
markers: MarkersDataLayerSettings[];
|
||||
polygons: PolygonsDataLayerSettings[];
|
||||
circles: CirclesDataLayerSettings[];
|
||||
additionalDataSources: AdditionalMapDataSourceSettings[];
|
||||
controlsPosition: MapControlsPosition;
|
||||
zoomActions: MapZoomAction[];
|
||||
fitMapBounds: boolean;
|
||||
useDefaultCenterPosition: boolean;
|
||||
defaultCenterPosition?: string;
|
||||
defaultZoomLevel: number;
|
||||
mapPageSize: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_MAP_PAGE_SIZE = 16384;
|
||||
export const DEFAULT_ZOOM_LEVEL = 8;
|
||||
|
||||
export const defaultBaseMapSettings: BaseMapSettings = {
|
||||
mapType: MapType.geoMap,
|
||||
markers: [],
|
||||
polygons: [],
|
||||
circles: [],
|
||||
additionalDataSources: [],
|
||||
controlsPosition: MapControlsPosition.topleft,
|
||||
zoomActions: [MapZoomAction.scroll, MapZoomAction.doubleClick, MapZoomAction.controlButtons],
|
||||
fitMapBounds: true,
|
||||
useDefaultCenterPosition: false,
|
||||
defaultCenterPosition: '0,0',
|
||||
defaultZoomLevel: null,
|
||||
mapPageSize: DEFAULT_MAP_PAGE_SIZE
|
||||
};
|
||||
|
||||
export enum MapProvider {
|
||||
google = 'google-map',
|
||||
openstreet = 'openstreet-map',
|
||||
here = 'here',
|
||||
tencent = 'tencent-map',
|
||||
custom = 'custom'
|
||||
}
|
||||
|
||||
export interface MapLayerSettings {
|
||||
label?: string;
|
||||
provider: MapProvider;
|
||||
}
|
||||
|
||||
export enum GoogleLayerType {
|
||||
roadmap = 'roadmap',
|
||||
satellite = 'satellite',
|
||||
hybrid = 'hybrid',
|
||||
terrain = 'terrain'
|
||||
}
|
||||
|
||||
export interface GoogleMapLayerSettings extends MapLayerSettings {
|
||||
provider: MapProvider.google;
|
||||
layerType: GoogleLayerType;
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
export const defaultGoogleMapLayerSettings: GoogleMapLayerSettings = {
|
||||
provider: MapProvider.google,
|
||||
layerType: GoogleLayerType.roadmap,
|
||||
apiKey: 'AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q'
|
||||
};
|
||||
|
||||
export enum OpenStreetLayerType {
|
||||
openStreetMapnik = 'OpenStreetMap.Mapnik',
|
||||
openStreetHot = 'OpenStreetMap.HOT',
|
||||
esriWorldStreetMap = 'Esri.WorldStreetMap',
|
||||
esriWorldTopoMap = 'Esri.WorldTopoMap',
|
||||
esriWorldImagery = 'Esri.WorldImagery',
|
||||
cartoDbPositron = 'CartoDB.Positron',
|
||||
cartoDbDarkMatter = 'CartoDB.DarkMatter'
|
||||
}
|
||||
|
||||
export const openStreetMapLayerTranslationMap = new Map<OpenStreetLayerType, string>(
|
||||
[
|
||||
[OpenStreetLayerType.openStreetMapnik, 'widgets.maps.openstreet-provider-mapnik'],
|
||||
[OpenStreetLayerType.openStreetHot, 'widgets.maps.openstreet-provider-hot'],
|
||||
[OpenStreetLayerType.esriWorldStreetMap, 'widgets.maps.openstreet-provider-esri-street'],
|
||||
[OpenStreetLayerType.esriWorldTopoMap, 'widgets.maps.openstreet-provider-esri-topo'],
|
||||
[OpenStreetLayerType.esriWorldImagery, 'widgets.maps.openstreet-provider-esri-imagery'],
|
||||
[OpenStreetLayerType.cartoDbPositron, 'widgets.maps.openstreet-provider-cartodb-positron'],
|
||||
[OpenStreetLayerType.cartoDbDarkMatter, 'widgets.maps.openstreet-provider-cartodb-dark-matter']
|
||||
]
|
||||
);
|
||||
|
||||
export interface OpenStreetMapLayerSettings extends MapLayerSettings {
|
||||
provider: MapProvider.openstreet;
|
||||
layerType: OpenStreetLayerType;
|
||||
}
|
||||
|
||||
export const defaultOpenStreetMapLayerSettings: OpenStreetMapLayerSettings = {
|
||||
provider: MapProvider.openstreet,
|
||||
layerType: OpenStreetLayerType.openStreetMapnik
|
||||
}
|
||||
|
||||
export enum HereLayerType {
|
||||
hereNormalDay = 'HERE.normalDay',
|
||||
hereNormalNight = 'HERE.normalNight',
|
||||
hereHybridDay = 'HERE.hybridDay',
|
||||
hereTerrainDay = 'HERE.terrainDay'
|
||||
}
|
||||
|
||||
export interface HereMapLayerSettings extends MapLayerSettings {
|
||||
provider: MapProvider.here;
|
||||
layerType: HereLayerType;
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
export const defaultHereMapLayerSettings: HereMapLayerSettings = {
|
||||
provider: MapProvider.here,
|
||||
layerType: HereLayerType.hereNormalDay,
|
||||
apiKey: 'kVXykxAfZ6LS4EbCTO02soFVfjA7HoBzNVVH9u7nzoE'
|
||||
}
|
||||
|
||||
export enum TencentLayerType {
|
||||
roadmap = 'roadmap',
|
||||
satellite = 'satellite',
|
||||
hybrid = 'hybrid'
|
||||
}
|
||||
|
||||
export interface TencentMapLayerSettings extends MapLayerSettings {
|
||||
provider: MapProvider.tencent;
|
||||
layerType: TencentLayerType
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
export const defaultTencentMapLayerSettings: TencentMapLayerSettings = {
|
||||
provider: MapProvider.tencent,
|
||||
layerType: TencentLayerType.roadmap,
|
||||
apiKey: '84d6d83e0e51e481e50454ccbe8986b'
|
||||
}
|
||||
|
||||
export interface CustomMapLayerSettings extends MapLayerSettings {
|
||||
provider: MapProvider.custom;
|
||||
tileUrl: string;
|
||||
}
|
||||
|
||||
export const defaultCustomMapLayerSettings: CustomMapLayerSettings = {
|
||||
provider: MapProvider.custom,
|
||||
tileUrl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
||||
}
|
||||
|
||||
export const defaultMapLayerSettings = (provider: MapProvider): MapLayerSettings => {
|
||||
switch (provider) {
|
||||
case MapProvider.google:
|
||||
return defaultGoogleMapLayerSettings;
|
||||
case MapProvider.openstreet:
|
||||
return defaultOpenStreetMapLayerSettings;
|
||||
case MapProvider.here:
|
||||
return defaultHereMapLayerSettings;
|
||||
case MapProvider.tencent:
|
||||
return defaultTencentMapLayerSettings;
|
||||
case MapProvider.custom:
|
||||
return defaultCustomMapLayerSettings;
|
||||
}
|
||||
};
|
||||
|
||||
export const defaultMapLayers: MapLayerSettings[] = (Object.keys(OpenStreetLayerType) as OpenStreetLayerType[]).map(type => ({
|
||||
provider: MapProvider.openstreet,
|
||||
layerType: type
|
||||
}));
|
||||
|
||||
export interface GeoMapSettings extends BaseMapSettings {
|
||||
layers?: MapLayerSettings[];
|
||||
}
|
||||
|
||||
export const defaultGeoMapSettings: GeoMapSettings = {
|
||||
mapType: MapType.geoMap,
|
||||
layers: mergeDeep([], defaultMapLayers),
|
||||
...mergeDeep({} as BaseMapSettings, defaultBaseMapSettings)
|
||||
};
|
||||
|
||||
export enum ImageSourceType {
|
||||
image = 'image',
|
||||
attribute = 'attribute'
|
||||
}
|
||||
|
||||
export interface ImageMapSettings extends BaseMapSettings {
|
||||
imageSourceType?: ImageSourceType;
|
||||
imageUrl?: string;
|
||||
imageEntityAlias?: string;
|
||||
imageUrlAttribute?: string;
|
||||
}
|
||||
|
||||
export const defaultImageMapSettings: ImageMapSettings = {
|
||||
mapType: MapType.image,
|
||||
imageSourceType: ImageSourceType.image,
|
||||
imageUrl: 'data:image/svg+xml;base64,PHN2ZyBpZD0ic3ZnMiIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTAwIiB3aWR0aD0iMTAwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgdmlld0JveD0iMCAwIDEwMCAxMDAiPgogPGcgaWQ9ImxheWVyMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtOTUyLjM2KSI+CiAgPHJlY3QgaWQ9InJlY3Q0Njg0IiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBoZWlnaHQ9Ijk5LjAxIiB3aWR0aD0iOTkuMDEiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiB5PSI5NTIuODYiIHg9Ii40OTUwNSIgc3Ryb2tlLXdpZHRoPSIuOTkwMTAiIGZpbGw9IiNlZWUiLz4KICA8dGV4dCBpZD0idGV4dDQ2ODYiIHN0eWxlPSJ3b3JkLXNwYWNpbmc6MHB4O2xldHRlci1zcGFjaW5nOjBweDt0ZXh0LWFuY2hvcjptaWRkbGU7dGV4dC1hbGlnbjpjZW50ZXIiIGZvbnQtd2VpZ2h0PSJib2xkIiB4bWw6c3BhY2U9InByZXNlcnZlIiBmb250LXNpemU9IjEwcHgiIGxpbmUtaGVpZ2h0PSIxMjUlIiB5PSI5NzAuNzI4MDkiIHg9IjQ5LjM5NjQ3NyIgZm9udC1mYW1pbHk9IlJvYm90byIgZmlsbD0iIzY2NjY2NiI+PHRzcGFuIGlkPSJ0c3BhbjQ2OTAiIHg9IjUwLjY0NjQ3NyIgeT0iOTcwLjcyODA5Ij5JbWFnZSBiYWNrZ3JvdW5kIDwvdHNwYW4+PHRzcGFuIGlkPSJ0c3BhbjQ2OTIiIHg9IjQ5LjM5NjQ3NyIgeT0iOTgzLjIyODA5Ij5pcyBub3QgY29uZmlndXJlZDwvdHNwYW4+PC90ZXh0PgogIDxyZWN0IGlkPSJyZWN0NDY5NCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgaGVpZ2h0PSIxOS4zNiIgd2lkdGg9IjY5LjM2IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgeT0iOTkyLjY4IiB4PSIxNS4zMiIgc3Ryb2tlLXdpZHRoPSIuNjM5ODYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+Cg==',
|
||||
...mergeDeep({} as BaseMapSettings, defaultBaseMapSettings)
|
||||
}
|
||||
|
||||
export type MapSetting = GeoMapSettings & ImageMapSettings;
|
||||
|
||||
export const defaultMapSettings: MapSetting = defaultGeoMapSettings;
|
||||
|
||||
export function parseCenterPosition(position: string | [number, number]): [number, number] {
|
||||
if (typeof (position) === 'string') {
|
||||
const parts = position.split(',');
|
||||
if (parts.length === 2) {
|
||||
return [Number(parts[0]), Number(parts[1])];
|
||||
}
|
||||
}
|
||||
if (typeof (position) === 'object') {
|
||||
return position;
|
||||
}
|
||||
return [0, 0];
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
.tb-map-layout {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
&.tb-sidebar-left {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
&.tb-sidebar-right {
|
||||
flex-direction: row;
|
||||
}
|
||||
.tb-map {
|
||||
flex: 1;
|
||||
}
|
||||
.tb-map-sidebar {
|
||||
}
|
||||
}
|
||||
196
ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts
Normal file
196
ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts
Normal file
@ -0,0 +1,196 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import {
|
||||
BaseMapSettings,
|
||||
DEFAULT_ZOOM_LEVEL,
|
||||
defaultGeoMapSettings,
|
||||
defaultImageMapSettings,
|
||||
GeoMapSettings,
|
||||
ImageMapSettings,
|
||||
MapSetting,
|
||||
MapType,
|
||||
MapZoomAction,
|
||||
parseCenterPosition
|
||||
} from '@home/components/widget/lib/maps/map.models';
|
||||
import { WidgetContext } from '@home/models/widget-component.models';
|
||||
import { mergeDeep } from '@core/utils';
|
||||
import { DeepPartial } from '@shared/models/common';
|
||||
import L from 'leaflet';
|
||||
import { forkJoin, Observable, of } from 'rxjs';
|
||||
import { TbMapLayer } from '@home/components/widget/lib/maps/map-layer';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
export abstract class TbMap<S extends BaseMapSettings> {
|
||||
|
||||
static fromSettings(ctx: WidgetContext,
|
||||
inputSettings: DeepPartial<MapSetting>,
|
||||
mapElement: HTMLElement): TbMap<MapSetting> {
|
||||
switch (inputSettings.mapType) {
|
||||
case MapType.geoMap:
|
||||
return new TbGeoMap(ctx, inputSettings, mapElement);
|
||||
case MapType.image:
|
||||
return new TbImageMap(ctx, inputSettings, mapElement);
|
||||
}
|
||||
}
|
||||
|
||||
protected settings: S;
|
||||
protected map: L.Map;
|
||||
|
||||
protected defaultCenterPosition: [number, number];
|
||||
protected bounds: L.LatLngBounds;
|
||||
protected layerControl: L.Control.Layers;
|
||||
|
||||
protected mapElement: HTMLElement;
|
||||
protected sidebarElement: HTMLElement;
|
||||
|
||||
protected constructor(protected ctx: WidgetContext,
|
||||
protected inputSettings: DeepPartial<S>,
|
||||
protected containerElement: HTMLElement) {
|
||||
this.settings = mergeDeep({} as S, this.defaultSettings(), this.inputSettings as S);
|
||||
$(containerElement).empty();
|
||||
$(containerElement).addClass('tb-map-layout');
|
||||
if (this.settings.controlsPosition.endsWith('left')) {
|
||||
$(containerElement).addClass('tb-sidebar-left');
|
||||
} else {
|
||||
$(containerElement).addClass('tb-sidebar-right');
|
||||
}
|
||||
const mapElement = $('<div class="tb-map"></div>');
|
||||
const sidebarElement = $('<div class="tb-map-sidebar"></div>');
|
||||
$(containerElement).append(mapElement);
|
||||
$(containerElement).append(sidebarElement);
|
||||
|
||||
this.mapElement = mapElement[0];
|
||||
this.sidebarElement = sidebarElement[0];
|
||||
|
||||
this.defaultCenterPosition = parseCenterPosition(this.settings.defaultCenterPosition);
|
||||
|
||||
this.layerControl = L.control.layers({}, {}, {position: this.settings.controlsPosition, collapsed: true});
|
||||
this.createMap().subscribe((map) => {
|
||||
this.map = map;
|
||||
this.initMap();
|
||||
});
|
||||
L.TB = {
|
||||
sidebar: (s) => { return null;}
|
||||
};
|
||||
}
|
||||
|
||||
private initMap() {
|
||||
this.map.zoomControl.setPosition(this.settings.controlsPosition);
|
||||
this.layerControl.addTo(this.map);
|
||||
this.map.on('move', () => {
|
||||
this.ctx.updatePopoverPositions();
|
||||
});
|
||||
this.map.on('zoomstart', () => {
|
||||
this.ctx.setPopoversHidden(true);
|
||||
});
|
||||
this.map.on('zoomend', () => {
|
||||
this.ctx.setPopoversHidden(false);
|
||||
this.ctx.updatePopoverPositions();
|
||||
setTimeout(() => {
|
||||
this.ctx.updatePopoverPositions();
|
||||
});
|
||||
});
|
||||
if (this.settings.useDefaultCenterPosition) {
|
||||
this.map.panTo(this.defaultCenterPosition);
|
||||
this.bounds = this.map.getBounds();
|
||||
} else {
|
||||
this.bounds = new L.LatLngBounds(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract defaultSettings(): S;
|
||||
|
||||
protected abstract createMap(): Observable<L.Map>;
|
||||
|
||||
public destroy() {
|
||||
if (this.map) {
|
||||
this.map.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TbGeoMap extends TbMap<GeoMapSettings> {
|
||||
|
||||
constructor(protected ctx: WidgetContext,
|
||||
protected inputSettings: DeepPartial<GeoMapSettings>,
|
||||
protected containerElement: HTMLElement) {
|
||||
super(ctx, inputSettings, containerElement);
|
||||
}
|
||||
|
||||
protected defaultSettings(): GeoMapSettings {
|
||||
return defaultGeoMapSettings;
|
||||
}
|
||||
|
||||
protected createMap(): Observable<L.Map> {
|
||||
const theMap = L.map(this.mapElement, {
|
||||
scrollWheelZoom: this.settings.zoomActions.includes(MapZoomAction.scroll),
|
||||
doubleClickZoom: this.settings.zoomActions.includes(MapZoomAction.doubleClick),
|
||||
zoomControl: this.settings.zoomActions.includes(MapZoomAction.controlButtons)
|
||||
}).setView(this.defaultCenterPosition, this.settings.defaultZoomLevel || DEFAULT_ZOOM_LEVEL);
|
||||
return this.loadLayers().pipe(
|
||||
map((layers) => {
|
||||
if (layers.length) {
|
||||
const layer = layers[0];
|
||||
layer.layer.addTo(theMap);
|
||||
if (layers.length > 1) {
|
||||
layers.forEach(l => {
|
||||
this.layerControl.addBaseLayer(l.layer, l.title);
|
||||
});
|
||||
}
|
||||
}
|
||||
return theMap;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private loadLayers(): Observable<{title: string, layer: L.Layer}[]> {
|
||||
const layers = this.settings.layers.map(settings => TbMapLayer.fromSettings(this.ctx, settings));
|
||||
return forkJoin(layers.map(layer => layer.loadLayer()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class TbImageMap extends TbMap<ImageMapSettings> {
|
||||
|
||||
private maxZoom = 4;
|
||||
|
||||
constructor(protected ctx: WidgetContext,
|
||||
protected inputSettings: DeepPartial<ImageMapSettings>,
|
||||
protected mapElement: HTMLElement) {
|
||||
super(ctx, inputSettings, mapElement);
|
||||
}
|
||||
|
||||
protected defaultSettings(): ImageMapSettings {
|
||||
return defaultImageMapSettings;
|
||||
}
|
||||
|
||||
protected createMap(): Observable<L.Map> {
|
||||
const map = L.map(this.mapElement, {
|
||||
scrollWheelZoom: this.settings.zoomActions.includes(MapZoomAction.scroll),
|
||||
doubleClickZoom: this.settings.zoomActions.includes(MapZoomAction.doubleClick),
|
||||
zoomControl: this.settings.zoomActions.includes(MapZoomAction.controlButtons),
|
||||
minZoom: 1,
|
||||
maxZoom: this.maxZoom,
|
||||
zoom: 1,
|
||||
crs: L.CRS.Simple,
|
||||
attributionControl: false
|
||||
}).setView(this.defaultCenterPosition, this.settings.defaultZoomLevel || DEFAULT_ZOOM_LEVEL);
|
||||
return of(map);
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ import {
|
||||
CircleSettings,
|
||||
ShowTooltipAction,
|
||||
showTooltipActionTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { Widget } from '@shared/models/widget.models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@ -29,7 +29,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CommonMapSettings, MapProviders } from '@home/components/widget/lib/maps/map-models';
|
||||
import { CommonMapSettings, MapProviders } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { Widget } from '@shared/models/widget.models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ import {
|
||||
GoogleMapProviderSettings,
|
||||
GoogleMapType,
|
||||
googleMapTypeProviderTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -33,7 +33,7 @@ import {
|
||||
HereMapProvider,
|
||||
HereMapProviderSettings,
|
||||
hereMapProviderTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { isDefinedAndNotNull } from '@core/utils';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ImageMapProviderSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { ImageMapProviderSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { IAliasController } from '@core/api/widget-api.models';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { catchError, map, mergeMap, publishReplay, refCount, startWith, tap } from 'rxjs/operators';
|
||||
|
||||
@ -28,7 +28,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MapEditorSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { MapEditorSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ import {
|
||||
mapProviderTranslationMap,
|
||||
OpenStreetMapProviderSettings,
|
||||
TencentMapProviderSettings
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { extractType } from '@core/utils';
|
||||
import { IAliasController } from '@core/api/widget-api.models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@ -46,7 +46,7 @@ import {
|
||||
PolygonSettings,
|
||||
PolylineSettings,
|
||||
UnitedMapSettings
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { extractType } from '@core/utils';
|
||||
import { IAliasController } from '@core/api/widget-api.models';
|
||||
import { Widget } from '@shared/models/widget.models';
|
||||
|
||||
@ -19,7 +19,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.m
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { defaultMapSettings } from 'src/app/modules/home/components/widget/lib/maps/map-models';
|
||||
import { defaultMapSettings } from 'src/app/modules/home/components/widget/lib/maps-legacy/map-models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-map-widget-settings',
|
||||
|
||||
@ -29,7 +29,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MarkerClusteringSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { MarkerClusteringSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import {
|
||||
MapProviders,
|
||||
MarkersSettings, ShowTooltipAction, showTooltipActionTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ import {
|
||||
OpenStreetMapProvider,
|
||||
OpenStreetMapProviderSettings,
|
||||
openStreetMapProviderTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -33,7 +33,7 @@ import {
|
||||
PolygonSettings,
|
||||
ShowTooltipAction,
|
||||
showTooltipActionTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { Widget } from '@shared/models/widget.models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@ -28,7 +28,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PolylineSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { PolylineSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.m
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { defaultMapSettings } from 'src/app/modules/home/components/widget/lib/maps/map-models';
|
||||
import { defaultMapSettings } from 'src/app/modules/home/components/widget/lib/maps-legacy/map-models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-route-map-widget-settings',
|
||||
|
||||
@ -33,7 +33,7 @@ import {
|
||||
TencentMapProviderSettings,
|
||||
TencentMapType,
|
||||
tencentMapTypeProviderTranslationMap
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -29,7 +29,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { TripAnimationCommonSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { TripAnimationCommonSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { Widget } from '@shared/models/widget.models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@ -29,7 +29,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { TripAnimationMarkerSettings } from '@home/components/widget/lib/maps/map-models';
|
||||
import { TripAnimationMarkerSettings } from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ import {
|
||||
PolylineDecoratorSymbol,
|
||||
polylineDecoratorSymbolTranslationMap,
|
||||
PolylineSettings
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ import {
|
||||
PolylineDecoratorSymbol,
|
||||
polylineDecoratorSymbolTranslationMap,
|
||||
PolylineSettings
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { WidgetService } from '@core/http/widget.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ import {
|
||||
PointsSettings,
|
||||
PolygonSettings,
|
||||
PolylineSettings
|
||||
} from 'src/app/modules/home/components/widget/lib/maps/map-models';
|
||||
} from 'src/app/modules/home/components/widget/lib/maps-legacy/map-models';
|
||||
import { extractType } from '@core/utils';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -31,7 +31,7 @@ import {
|
||||
defaultTripAnimationSettings,
|
||||
MapProviders,
|
||||
WidgetUnitedTripAnimationSettings
|
||||
} from '@home/components/widget/lib/maps/map-models';
|
||||
} from '@home/components/widget/lib/maps-legacy/map-models';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { WidgetContext } from '@app/modules/home/models/widget-component.models';
|
||||
import {
|
||||
@ -39,7 +39,7 @@ import {
|
||||
getRatio,
|
||||
interpolateOnLineSegment,
|
||||
parseWithTranslation
|
||||
} from '@home/components/widget/lib/maps/common-maps-utils';
|
||||
} from '@home/components/widget/lib/maps-legacy/common-maps-utils';
|
||||
import { FormattedData, WidgetConfig } from '@shared/models/widget.models';
|
||||
import moment from 'moment';
|
||||
import {
|
||||
@ -51,7 +51,7 @@ import {
|
||||
parseTbFunction,
|
||||
safeExecuteTbFunction
|
||||
} from '@core/utils';
|
||||
import { MapWidgetInterface } from '@home/components/widget/lib/maps/map-widget.interface';
|
||||
import { MapWidgetInterface } from '@home/components/widget/lib/maps-legacy/map-widget.interface';
|
||||
import { firstValueFrom, from } from 'rxjs';
|
||||
|
||||
interface DataMap {
|
||||
@ -123,7 +123,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
import('@home/components/widget/lib/maps/map-widget2').then(
|
||||
import('@home/components/widget/lib/maps-legacy/map-widget2').then(
|
||||
(mod) => {
|
||||
this.mapWidget = new mod.MapWidgetController(MapProviders.openstreet, false, this.ctx, this.mapContainer.nativeElement, false,
|
||||
() => {
|
||||
@ -378,4 +378,4 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
}
|
||||
}
|
||||
|
||||
export let TbTripAnimationWidget = TripAnimationComponent;
|
||||
export const TbTripAnimationWidget = TripAnimationComponent;
|
||||
|
||||
@ -186,7 +186,7 @@ export class WidgetComponentService {
|
||||
(window as any).TbCanvasDigitalGauge = mod.TbCanvasDigitalGauge;
|
||||
}))
|
||||
);
|
||||
widgetModulesTasks.push(from(import('@home/components/widget/lib/maps/map-widget2')).pipe(
|
||||
widgetModulesTasks.push(from(import('@home/components/widget/lib/maps-legacy/map-widget2')).pipe(
|
||||
tap((mod) => {
|
||||
(window as any).TbMapWidgetV2 = mod.TbMapWidgetV2;
|
||||
}))
|
||||
|
||||
@ -39,7 +39,7 @@ import { EdgesOverviewWidgetComponent } from '@home/components/widget/lib/edges-
|
||||
import { JsonInputWidgetComponent } from '@home/components/widget/lib/json-input-widget.component';
|
||||
import { QrCodeWidgetComponent } from '@home/components/widget/lib/qrcode-widget.component';
|
||||
import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-widget.component';
|
||||
import { SelectEntityDialogComponent } from '@home/components/widget/lib/maps/dialogs/select-entity-dialog.component';
|
||||
import { SelectEntityDialogComponent } from '@home/components/widget/lib/maps-legacy/dialogs/select-entity-dialog.component';
|
||||
import { HomePageWidgetsModule } from '@home/components/widget/lib/home-page/home-page-widgets.module';
|
||||
import { WIDGET_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens';
|
||||
import { FlotWidgetComponent } from '@home/components/widget/lib/flot-widget.component';
|
||||
@ -88,6 +88,7 @@ import {
|
||||
import { EllipsisChipListDirective } from '@shared/directives/ellipsis-chip-list.directive';
|
||||
import { ScadaSymbolWidgetComponent } from '@home/components/widget/lib/scada/scada-symbol-widget.component';
|
||||
import { TwoSegmentButtonWidgetComponent } from '@home/components/widget/lib/button/two-segment-button-widget.component';
|
||||
import { MapWidgetComponent } from '@home/components/widget/lib/maps/map-widget.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -141,7 +142,8 @@ import { TwoSegmentButtonWidgetComponent } from '@home/components/widget/lib/but
|
||||
LabelValueCardWidgetComponent,
|
||||
UnreadNotificationWidgetComponent,
|
||||
NotificationTypeFilterPanelComponent,
|
||||
ScadaSymbolWidgetComponent
|
||||
ScadaSymbolWidgetComponent,
|
||||
MapWidgetComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -202,7 +204,8 @@ import { TwoSegmentButtonWidgetComponent } from '@home/components/widget/lib/but
|
||||
LabelValueCardWidgetComponent,
|
||||
UnreadNotificationWidgetComponent,
|
||||
NotificationTypeFilterPanelComponent,
|
||||
ScadaSymbolWidgetComponent
|
||||
ScadaSymbolWidgetComponent,
|
||||
MapWidgetComponent
|
||||
],
|
||||
providers: [
|
||||
{provide: WIDGET_COMPONENTS_MODULE_TOKEN, useValue: WidgetComponentsModule},
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
|
||||
import { interval } from 'rxjs';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { HistorySelectSettings } from '@app/modules/home/components/widget/lib/maps/map-models';
|
||||
import { HistorySelectSettings } from '@app/modules/home/components/widget/lib/maps-legacy/map-models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-history-selector',
|
||||
|
||||
3
ui-ngx/src/typings/leaflet-extend-tb.d.ts
vendored
3
ui-ngx/src/typings/leaflet-extend-tb.d.ts
vendored
@ -21,4 +21,7 @@ declare module 'leaflet' {
|
||||
interface MarkerOptions {
|
||||
tbMarkerData?: FormattedData;
|
||||
}
|
||||
namespace TB {
|
||||
function sidebar(selector: string): Control;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user