Browse Source

UI: Map - implement map items draw/placement.

pull/12723/head
Igor Kulikov 2 years ago
parent
commit
ab465bf651
  1. 34
      ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/circles-data-layer.ts
  2. 38
      ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/map-data-layer.ts
  3. 29
      ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/markers-data-layer.ts
  4. 80
      ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/polygons-data-layer.ts
  5. 15
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map.scss
  6. 135
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts
  7. 17
      ui-ngx/src/assets/locale/locale.constant-en_US.json

34
ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/circles-data-layer.ts

@ -25,7 +25,12 @@ import { TbShapesDataLayer } from '@home/components/widget/lib/maps/data-layer/s
import { TbMap } from '@home/components/widget/lib/maps/map';
import { Observable } from 'rxjs';
import { isNotEmptyStr } from '@core/utils';
import { MapDataLayerType, TbDataLayerItem } from '@home/components/widget/lib/maps/data-layer/map-data-layer';
import {
MapDataLayerType,
TbDataLayerItem,
UnplacedMapDataItem
} from '@home/components/widget/lib/maps/data-layer/map-data-layer';
import { map } from 'rxjs/operators';
class TbCircleDataLayerItem extends TbDataLayerItem<CirclesDataLayerSettings, TbCirclesDataLayer> {
@ -134,8 +139,8 @@ class TbCircleDataLayerItem extends TbDataLayerItem<CirclesDataLayerSettings, Tb
return this.dataLayer.getCtx().translate.instant('widgets.maps.data-layer.circle.remove-circle-for', {entityName: this.data.entityName});
}
protected removeDataItem(): void {
this.dataLayer.saveCircleCoordinates(this.data, null, null);
protected removeDataItem(): Observable<any> {
return this.dataLayer.saveCircleCoordinates(this.data, null, null);
}
public isEditing() {
@ -149,7 +154,7 @@ class TbCircleDataLayerItem extends TbDataLayerItem<CirclesDataLayerSettings, Tb
private saveCircleCoordinates() {
const center = this.circle.getLatLng();
const radius = this.circle.getRadius();
this.dataLayer.saveCircleCoordinates(this.data, center, radius);
this.dataLayer.saveCircleCoordinates(this.data, center, radius).subscribe();
}
private updateCircleShape(data: FormattedData<TbMapDatasource>) {
@ -178,6 +183,21 @@ export class TbCirclesDataLayer extends TbShapesDataLayer<CirclesDataLayerSettin
return MapDataLayerType.circle;
}
public placeItem(item: UnplacedMapDataItem, layer: L.Layer): void {
if (layer instanceof L.Circle) {
const center = layer.getLatLng();
const radius = layer.getRadius();
this.saveCircleCoordinates(item.entity, center, radius).subscribe(
(converted) => {
item.entity[this.settings.circleKey.label] = JSON.stringify(converted);
this.createItemFromUnplaced(item);
}
);
} else {
console.warn('Unable to place item, layer is not a circle.');
}
}
protected setupDatasource(datasource: TbMapDatasource): TbMapDatasource {
datasource.dataKeys.push(this.settings.circleKey);
return datasource;
@ -204,7 +224,7 @@ export class TbCirclesDataLayer extends TbShapesDataLayer<CirclesDataLayerSettin
return this.map.circleDataToCoordinates(circleData);
}
public saveCircleCoordinates(data: FormattedData<TbMapDatasource>, center: L.LatLng, radius: number): void {
public saveCircleCoordinates(data: FormattedData<TbMapDatasource>, center: L.LatLng, radius: number): Observable<TbCircleData> {
const converted = center ? this.map.coordinatesToCircleData(center, radius) : null;
const circleData = [
{
@ -212,6 +232,8 @@ export class TbCirclesDataLayer extends TbShapesDataLayer<CirclesDataLayerSettin
value: converted
}
];
this.map.saveItemData(data.$datasource, circleData).subscribe();
return this.map.saveItemData(data.$datasource, circleData).pipe(
map(() => converted)
);
}
}

38
ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/map-data-layer.ts

@ -148,7 +148,9 @@ export abstract class TbDataLayerItem<S extends MapDataLayerSettings = MapDataLa
id: 'remove',
title: this.removeDataItemTitle(),
click: () => {
this.removeDataItem();
this.removeDataItem().subscribe(
() => this.dataLayer.removeItem(this.data.entityId)
);
},
iconClass: 'tb-remove'
});
@ -246,7 +248,7 @@ export abstract class TbDataLayerItem<S extends MapDataLayerSettings = MapDataLa
protected abstract removeDataItemTitle(): string;
protected abstract removeDataItem(): void;
protected abstract removeDataItem(): Observable<any>;
private createTooltip(datasource: TbMapDatasource) {
this.tooltip = L.popup();
@ -552,15 +554,31 @@ export abstract class TbMapDataLayer<S extends MapDataLayerSettings = MapDataLay
}
});
toDelete.forEach((key) => {
const item = this.layerItems.get(key);
item.remove();
this.layerItems.delete(key);
this.removeItem(key);
});
if (updatedItems.length) {
this.layerItemsUpdated(updatedItems);
}
}
public removeItem(key: string): void {
const item = this.layerItems.get(key);
if (item) {
item.remove();
this.layerItems.delete(key);
}
}
protected createItemFromUnplaced(unplacedItem: UnplacedMapDataItem): void {
const index = this.unplacedItems.indexOf(unplacedItem);
if (index > -1) {
this.unplacedItems.splice(index, 1);
const layerItem = this.createLayerItem(unplacedItem.entity, this.map.getData());
this.layerItems.set(unplacedItem.entity.entityId, layerItem);
this.map.enabledDataLayersUpdated();
}
}
public invalidateCoordinates(): void {
this.layerItems.forEach(item => item.invalidateCoordinates());
}
@ -612,9 +630,11 @@ export abstract class TbMapDataLayer<S extends MapDataLayerSettings = MapDataLay
}
public enableEditMode() {
if (!this.editMode) {
this.editMode = true;
this.updateItemsEditMode();
if (this.editable) {
if (!this.editMode) {
this.editMode = true;
this.updateItemsEditMode();
}
}
}
@ -631,6 +651,8 @@ export abstract class TbMapDataLayer<S extends MapDataLayerSettings = MapDataLay
public abstract dataLayerType(): MapDataLayerType;
public abstract placeItem(item: UnplacedMapDataItem, layer: L.Layer): void;
protected abstract defaultBaseSettings(map: TbMap<any>): Partial<S>;
protected abstract doSetup(): Observable<any>;

29
ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/markers-data-layer.ts

@ -61,7 +61,7 @@ import { DomSanitizer } from '@angular/platform-browser';
import {
MapDataLayerType,
TbDataLayerItem,
TbMapDataLayer
TbMapDataLayer, UnplacedMapDataItem
} from '@home/components/widget/lib/maps/data-layer/map-data-layer';
import { TbImageMap } from '@home/components/widget/lib/maps/image-map';
@ -176,8 +176,8 @@ class TbMarkerDataLayerItem extends TbDataLayerItem<MarkersDataLayerSettings, Tb
return this.dataLayer.getCtx().translate.instant('widgets.maps.data-layer.marker.remove-marker-for', {entityName: this.data.entityName});
}
protected removeDataItem(): void {
this.dataLayer.saveMarkerLocation(this.data, null);
protected removeDataItem(): Observable<any> {
return this.dataLayer.saveMarkerLocation(this.data, null);
}
public isEditing() {
@ -190,7 +190,7 @@ class TbMarkerDataLayerItem extends TbDataLayerItem<MarkersDataLayerSettings, Tb
private saveMarkerLocation() {
const location = this.marker.getLatLng();
this.dataLayer.saveMarkerLocation(this.data, location);
this.dataLayer.saveMarkerLocation(this.data, location).subscribe();
}
private updateMarkerLocation(data: FormattedData<TbMapDatasource>, dsData: FormattedData<TbMapDatasource>[]) {
@ -452,6 +452,21 @@ export class TbMarkersDataLayer extends TbMapDataLayer<MarkersDataLayerSettings,
return MapDataLayerType.marker;
}
public placeItem(item: UnplacedMapDataItem, layer: L.Layer): void {
if (layer instanceof L.Marker) {
const position = layer.getLatLng();
this.saveMarkerLocation(item.entity, position).subscribe(
(converted) => {
item.entity[this.settings.xKey.label] = converted.x;
item.entity[this.settings.yKey.label] = converted.y;
this.createItemFromUnplaced(item);
}
);
} else {
console.warn('Unable to place item, layer is not a marker.');
}
}
protected createDataLayerContainer(): FeatureGroup {
if (this.settings.markerClustering?.enable) {
return this.createMarkersClusterContainer();
@ -645,7 +660,7 @@ export class TbMarkersDataLayer extends TbMapDataLayer<MarkersDataLayerSettings,
}
}
public saveMarkerLocation(data: FormattedData<TbMapDatasource>, position: L.LatLng): void {
public saveMarkerLocation(data: FormattedData<TbMapDatasource>, position: L.LatLng): Observable<{x: number; y: number}> {
const converted = this.map.latLngToLocationData(position);
const locationData = [
{
@ -657,7 +672,9 @@ export class TbMarkersDataLayer extends TbMapDataLayer<MarkersDataLayerSettings,
value: converted.y
}
];
this.map.saveItemData(data.$datasource, locationData).subscribe();
return this.map.saveItemData(data.$datasource, locationData).pipe(
map(() => converted)
);
}
}

80
ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/polygons-data-layer.ts

@ -26,7 +26,12 @@ import { TbShapesDataLayer } from '@home/components/widget/lib/maps/data-layer/s
import { TbMap } from '@home/components/widget/lib/maps/map';
import { Observable } from 'rxjs';
import { isNotEmptyStr, isString } from '@core/utils';
import { MapDataLayerType, TbDataLayerItem } from '@home/components/widget/lib/maps/data-layer/map-data-layer';
import {
MapDataLayerType,
TbDataLayerItem,
UnplacedMapDataItem
} from '@home/components/widget/lib/maps/data-layer/map-data-layer';
import { map } from 'rxjs/operators';
class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings, TbPolygonsDataLayer> {
@ -184,6 +189,8 @@ class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings,
this.disablePolygonRotateMode();
}
return false;
} else if (this.editing) {
return false;
}
return true;
}
@ -192,8 +199,8 @@ class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings,
return this.dataLayer.getCtx().translate.instant('widgets.maps.data-layer.polygon.remove-polygon-for', {entityName: this.data.entityName});
}
protected removeDataItem(): void {
this.dataLayer.savePolygonCoordinates(this.data, null);
protected removeDataItem(): Observable<any> {
return this.dataLayer.savePolygonCoordinates(this.data, null);
}
public isEditing() {
@ -206,7 +213,9 @@ class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings,
private enablePolygonEditMode() {
this.polygon.on('pm:markerdragstart', () => this.editing = true);
this.polygon.on('pm:markerdragend', () => this.editing = false);
this.polygon.on('pm:markerdragend', () => setTimeout(() => {
this.editing = false;
}) );
this.polygon.on('pm:edit', () => this.savePolygonCoordinates());
this.polygon.pm.enable();
const map = this.dataLayer.getMap();
@ -230,18 +239,18 @@ class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings,
color: '#3388ff', opacity: 1, fillColor: '#3388ff', fillOpacity: 0.2});
this.addItemClass('tb-cut-mode');
this.polygon.once('pm:cut', (e) => {
if (this.polygon instanceof L.Rectangle) {
this.polygonContainer.removeLayer(this.polygon);
// @ts-ignore
this.polygon = L.polygon(e.layer.getLatLngs(), {
...this.polygonStyle,
snapIgnore: !this.dataLayer.isSnappable(),
bubblingMouseEvents: !this.dataLayer.isEditMode()
});
this.polygon.addTo(this.polygonContainer);
} else {
// @ts-ignore
this.polygon.setLatLngs(e.layer.getLatLngs());
if (e.layer instanceof L.Polygon) {
if (this.polygon instanceof L.Rectangle) {
this.polygonContainer.removeLayer(this.polygon);
this.polygon = L.polygon(e.layer.getLatLngs(), {
...this.polygonStyle,
snapIgnore: !this.dataLayer.isSnappable(),
bubblingMouseEvents: !this.dataLayer.isEditMode()
});
this.polygon.addTo(this.polygonContainer);
} else {
this.polygon.setLatLngs(e.layer.getLatLngs());
}
}
// @ts-ignore
e.layer._pmTempLayer = true;
@ -257,15 +266,17 @@ class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings,
const map = this.dataLayer.getMap().getMap();
map.pm.setLang('en', {
tooltips: {
firstVertex: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.firstVertex-cut'),
continueLine: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.continueLine-cut'),
finishPoly: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.finishPoly-cut')
firstVertex: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.polygon-place-first-point-cut-hint'),
continueLine: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.continue-polygon-cut-hint'),
finishPoly: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.finish-polygon-cut-hint')
}
}, 'en');
map.pm.enableGlobalCutMode({
// @ts-ignore
layersToCut: [this.polygon]
});
// @ts-ignore
L.DomUtil.addClass(map.pm.Draw.Cut._hintMarker.getTooltip()._container, 'tb-place-item-label');
cutButton?.setActive(true);
map.once('pm:globalcutmodetoggled', (e) => {
if (!e.enabled) {
@ -320,7 +331,7 @@ class TbPolygonDataLayerItem extends TbDataLayerItem<PolygonsDataLayerSettings,
coordinates = [bounds.getNorthWest(), bounds.getSouthEast()];
}
}
this.dataLayer.savePolygonCoordinates(this.data, coordinates);
this.dataLayer.savePolygonCoordinates(this.data, coordinates).subscribe();
}
private updatePolygonShape(data: FormattedData<TbMapDatasource>) {
@ -360,6 +371,29 @@ export class TbPolygonsDataLayer extends TbShapesDataLayer<PolygonsDataLayerSett
return MapDataLayerType.polygon;
}
public placeItem(item: UnplacedMapDataItem, layer: L.Layer): void {
if (layer instanceof L.Polygon) {
let coordinates: TbPolygonCoordinates;
if (layer instanceof L.Rectangle) {
const bounds = layer.getBounds();
coordinates = [bounds.getNorthWest(), bounds.getSouthEast()];
} else {
coordinates = layer.getLatLngs();
if (coordinates.length === 1) {
coordinates = coordinates[0] as TbPolygonCoordinates;
}
}
this.savePolygonCoordinates(item.entity, coordinates).subscribe(
(converted) => {
item.entity[this.settings.polygonKey.label] = JSON.stringify(converted);
this.createItemFromUnplaced(item);
}
);
} else {
console.warn('Unable to place item, layer is not a polygon.');
}
}
protected setupDatasource(datasource: TbMapDatasource): TbMapDatasource {
datasource.dataKeys.push(this.settings.polygonKey);
return datasource;
@ -390,7 +424,7 @@ export class TbPolygonsDataLayer extends TbShapesDataLayer<PolygonsDataLayerSett
return this.map.polygonDataToCoordinates(rawPolyData);
}
public savePolygonCoordinates(data: FormattedData<TbMapDatasource>, coordinates: TbPolygonCoordinates): void {
public savePolygonCoordinates(data: FormattedData<TbMapDatasource>, coordinates: TbPolygonCoordinates): Observable<TbPolygonRawCoordinates> {
const converted = coordinates ? this.map.coordinatesToPolygonData(coordinates) : null;
const polygonData = [
{
@ -398,6 +432,8 @@ export class TbPolygonsDataLayer extends TbShapesDataLayer<PolygonsDataLayerSett
value: converted
}
];
this.map.saveItemData(data.$datasource, polygonData).subscribe();
return this.map.saveItemData(data.$datasource, polygonData).pipe(
map(() => converted)
);
}
}

15
ui-ngx/src/app/modules/home/components/widget/lib/maps/map.scss

@ -81,7 +81,7 @@
div.tb-control-text {
width: auto;
background: transparent;
font-family: Roboto;
font-family: Roboto, "Helvetica Neue", sans-serif;
font-size: 12px;
font-style: normal;
font-weight: 500;
@ -240,6 +240,19 @@
background: none;
box-shadow: none;
}
.tb-place-item-label {
border: none;
box-shadow: none;
border-radius: 4px;
background: rgba(0,0,0,0.56);
backdrop-filter: blur(4px);
padding: 4px 8px;
color: #fff;
font-family: Roboto, "Helvetica Neue", sans-serif;
font-size: 12px;
font-style: normal;
font-weight: 400;
}
}
.tb-map-sidebar {
.tb-layers, .tb-groups {

135
ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts

@ -33,7 +33,7 @@ import { formattedDataFormDatasourceData, isDefinedAndNotNull, mergeDeepIgnoreAr
import { DeepPartial } from '@shared/models/common';
import L from 'leaflet';
import { forkJoin, Observable, of } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
import { switchMap, tap } from 'rxjs/operators';
import '@home/components/widget/lib/maps/leaflet/leaflet-tb';
import {
MapDataLayerType,
@ -106,7 +106,11 @@ export abstract class TbMap<S extends BaseMapSettings> {
private tooltipInstances: TooltipInstancesData[] = [];
private currentPopover: TbPopoverComponent;
private isAddingItem = false;
private currentAddButton: L.TB.ToolbarButton;
private get isPlacingItem(): boolean {
return !!this.currentAddButton;
}
protected constructor(protected ctx: WidgetContext,
protected inputSettings: DeepPartial<S>,
@ -283,7 +287,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
});
if (this.dataLayers.some(dl => dl.isEditable())) {
this.map.pm.setGlobalOptions({ snappable: false } as L.PM.GlobalOptions);
this.map.pm.setGlobalOptions({ snappable: false });
this.map.pm.applyGlobalOptions();
}
@ -358,13 +362,14 @@ export abstract class TbMap<S extends BaseMapSettings> {
private placeMarker(e: MouseEvent, button: L.TB.ToolbarButton): void {
this.placeItem(e, button, this.addMarkerDataLayers,
(entity) => {
this.map.pm.setLang('en', {
tooltips: {
placeMarker: this.ctx.translate.instant('widgets.maps.data-layer.marker.place-marker-hint', {entityName: entity.entity.entityDisplayName})
}
}, 'en');
this.map.pm.enableDraw('Marker');
const hintText = this.ctx.translate.instant('widgets.maps.data-layer.marker.place-marker-hint', {entityName: entity.entity.entityDisplayName});
// @ts-ignore
this.map.pm.Draw.Marker._hintMarker.setTooltipContent(hintText);
},
(entity, layer) => {
(entity.dataLayer as TbMarkersDataLayer).saveMarkerLocation(entity.entity, (layer as L.Marker).getLatLng());
L.DomUtil.addClass(this.map.pm.Draw.Marker._hintMarker.getTooltip()._container, 'tb-place-item-label');
}
);
}
@ -372,9 +377,15 @@ export abstract class TbMap<S extends BaseMapSettings> {
private drawRectangle(e: MouseEvent, button: L.TB.ToolbarButton): void {
this.placeItem(e, button, this.addPolygonDataLayers,
(entity) => {
},
(entity, layer) => {
this.map.pm.setLang('en', {
tooltips: {
firstVertex: this.ctx.translate.instant('widgets.maps.data-layer.polygon.rectangle-place-first-point-hint', {entityName: entity.entity.entityDisplayName}),
finishRect: this.ctx.translate.instant('widgets.maps.data-layer.polygon.finish-rectangle-hint', {entityName: entity.entity.entityDisplayName})
}
}, 'en');
this.map.pm.enableDraw('Rectangle');
// @ts-ignore
L.DomUtil.addClass(this.map.pm.Draw.Rectangle._hintMarker.getTooltip()._container, 'tb-place-item-label');
}
);
}
@ -382,9 +393,16 @@ export abstract class TbMap<S extends BaseMapSettings> {
private drawPolygon(e: MouseEvent, button: L.TB.ToolbarButton): void {
this.placeItem(e, button, this.addPolygonDataLayers,
(entity) => {
},
(entity, layer) => {
this.map.pm.setLang('en', {
tooltips: {
firstVertex: this.ctx.translate.instant('widgets.maps.data-layer.polygon.polygon-place-first-point-hint', {entityName: entity.entity.entityDisplayName}),
continueLine: this.ctx.translate.instant('widgets.maps.data-layer.polygon.continue-polygon-hint', {entityName: entity.entity.entityDisplayName}),
finishPoly: this.ctx.translate.instant('widgets.maps.data-layer.polygon.finish-polygon-hint', {entityName: entity.entity.entityDisplayName})
}
}, 'en');
this.map.pm.enableDraw('Polygon');
// @ts-ignore
L.DomUtil.addClass(this.map.pm.Draw.Polygon._hintMarker.getTooltip()._container, 'tb-place-item-label');
}
);
}
@ -392,22 +410,25 @@ export abstract class TbMap<S extends BaseMapSettings> {
private drawCircle(e: MouseEvent, button: L.TB.ToolbarButton): void {
this.placeItem(e, button, this.addCircleDataLayers,
(entity) => {
},
(entity, layer) => {
this.map.pm.setLang('en', {
tooltips: {
startCircle: this.ctx.translate.instant('widgets.maps.data-layer.circle.place-circle-center-hint', {entityName: entity.entity.entityDisplayName}),
finishCircle: this.ctx.translate.instant('widgets.maps.data-layer.circle.finish-circle-hint', {entityName: entity.entity.entityDisplayName}),
}
}, 'en');
this.map.pm.enableDraw('Circle');
// @ts-ignore
L.DomUtil.addClass(this.map.pm.Draw.Circle._hintMarker.getTooltip()._container, 'tb-place-item-label');
}
);
}
private placeItem(e: MouseEvent, button: L.TB.ToolbarButton, dataLayers: TbMapDataLayer[],
prepareDrawMode: (entity: UnplacedMapDataItem) => void,
saveLocation: (entity: UnplacedMapDataItem, layer: L.Layer) => void): void {
if (this.isAddingItem) {
prepareDrawMode: (entity: UnplacedMapDataItem) => void): void {
if (this.isPlacingItem) {
return;
}
button.setActive(true);
this.deselectItem(false, true);
this.isAddingItem = true;
this.updatePlaceItemState(button);
const items = mergeUnplacedDataItemsArrays(dataLayers.filter(dl => dl.isEnabled()).map(dl => dl.getUnplacedItems())).sort((entity1, entity2) => {
return entity1.entity.entityDisplayName.localeCompare(entity2.entity.entityDisplayName);
});
@ -418,23 +439,22 @@ export abstract class TbMap<S extends BaseMapSettings> {
this.map.off('pm:create');
this.map.pm.disableDraw();
this.dataLayers.forEach(dl => dl.enableEditMode());
button.setActive(false);
this.isAddingItem = false;
this.updatePlaceItemState();
this.editToolbar.close();
};
this.map.once('pm:create', (e) => {
saveLocation(entity, e.layer);
entity.dataLayer.placeItem(entity, e.layer);
// @ts-ignore
e.layer._pmTempLayer = true;
e.layer.remove();
finishAdd();
});
this.dataLayers.forEach(dl => dl.disableEditMode());
prepareDrawMode(entity);
this.dataLayers.forEach(dl => dl.disableEditMode());
this.editToolbar.open([
{
id: 'cancel',
@ -445,8 +465,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
}
], false);
} else {
button.setActive(false);
this.isAddingItem = false;
this.updatePlaceItemState();
}
});
}
@ -478,6 +497,17 @@ export abstract class TbMap<S extends BaseMapSettings> {
}
}
private updatePlaceItemState(addButton?: L.TB.ToolbarButton): void {
if (addButton) {
this.deselectItem(false, true);
addButton.setActive(true);
} else if (this.currentAddButton) {
this.currentAddButton.setActive(false);
}
this.currentAddButton = addButton;
this.updateAddButtonsStates();
}
private createdControlButtonTooltip(root: HTMLElement, side: TooltipPositioningSide) {
import('tooltipster').then(() => {
let tooltipData = this.tooltipInstances.find(d => d.root === root);
@ -562,7 +592,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
const mapBounds = this.map.getBounds();
if (bounds.isValid() && (!this.bounds || !this.bounds.isValid() || !this.bounds.equals(bounds) && this.settings.fitMapBounds && !mapBounds.contains(bounds))) {
this.bounds = bounds;
if (!this.ignoreUpdateBounds && !this.isAddingItem) {
if (!this.ignoreUpdateBounds && !this.isPlacingItem) {
this.fitBounds(bounds);
}
}
@ -592,17 +622,32 @@ export abstract class TbMap<S extends BaseMapSettings> {
}
private updateAddButtonsStates() {
if (this.addMarkerButton) {
this.addMarkerButton.setDisabled(!this.addMarkerDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
if (this.addRectangleButton) {
this.addRectangleButton.setDisabled(!this.addPolygonDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
if (this.addPolygonButton) {
this.addPolygonButton.setDisabled(!this.addPolygonDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
if (this.addCircleButton) {
this.addCircleButton.setDisabled(!this.addCircleDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
if (this.currentAddButton) {
if (this.addMarkerButton && this.addMarkerButton !== this.currentAddButton) {
this.addMarkerButton.setDisabled(true);
}
if (this.addRectangleButton && this.addRectangleButton !== this.currentAddButton) {
this.addRectangleButton.setDisabled(true);
}
if (this.addPolygonButton && this.addPolygonButton !== this.currentAddButton) {
this.addPolygonButton.setDisabled(true);
}
if (this.addCircleButton && this.addCircleButton !== this.currentAddButton) {
this.addCircleButton.setDisabled(true);
}
} else {
if (this.addMarkerButton) {
this.addMarkerButton.setDisabled(!this.addMarkerDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
if (this.addRectangleButton) {
this.addRectangleButton.setDisabled(!this.addPolygonDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
if (this.addPolygonButton) {
this.addPolygonButton.setDisabled(!this.addPolygonDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
if (this.addCircleButton) {
this.addCircleButton.setDisabled(!this.addCircleDataLayers.some(dl => dl.isEnabled() && dl.hasUnplacedItems()));
}
}
}
@ -700,7 +745,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
}
public selectItem(item: TbDataLayerItem, cancel = false, force = false): boolean {
if (this.isAddingItem) {
if (this.isPlacingItem) {
return false;
}
let deselected = true;
@ -727,10 +772,6 @@ export abstract class TbMap<S extends BaseMapSettings> {
return this.selectItem(null, cancel, force);
}
public getSelectedDataItem(): TbDataLayerItem {
return this.selectedDataItem;
}
public getEditToolbar(): L.TB.BottomToolbarControl {
return this.editToolbar;
}

17
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -7732,11 +7732,16 @@
"remove-polygon-for": "Remove polygon for '{{entityName}}'",
"cut": "Cut polygon area",
"rotate": "Rotate polygon",
"firstVertex-cut": "Click to place first point",
"continueLine-cut": "Click to continue drawing",
"finishPoly-cut": "Click first marker to finish and save",
"draw-rectangle": "Draw rectangle",
"draw-polygon": "Draw polygon"
"draw-polygon": "Draw polygon",
"polygon-place-first-point-cut-hint": "Click to place first point",
"continue-polygon-cut-hint": "Click to continue drawing",
"finish-polygon-cut-hint": "Click first marker to finish and save",
"polygon-place-first-point-hint": "Polygon for '{{entityName}}': click to place first point",
"continue-polygon-hint": "Polygon for '{{entityName}}': click to continue drawing",
"finish-polygon-hint": "Polygon for '{{entityName}}': click first marker to finish and save",
"rectangle-place-first-point-hint": "Rectangle for '{{entityName}}': click to place first point",
"finish-rectangle-hint": "Rectangle for '{{entityName}}': click to finish and save"
},
"circle": {
"circle-key": "Circle key",
@ -7747,7 +7752,9 @@
"remove-circle": "Remove circle",
"edit": "Edit circle",
"remove-circle-for": "Remove circle for '{{entityName}}'",
"draw-circle": "Draw circle"
"draw-circle": "Draw circle",
"place-circle-center-hint": "Circle for '{{entityName}}': click to place circle center",
"finish-circle-hint": "Circle for '{{entityName}}': click to finish and save circle"
},
"select-entity": "Select entity",
"select-entity-hint": "Hint: after selection click at the map to set position"

Loading…
Cancel
Save