Browse Source

Added cut action for polyline

pull/14155/head
LeoMorgan113 11 months ago
parent
commit
f332096288
  1. 96
      ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/polylines-data-layer.ts
  2. 2
      ui-ngx/src/app/modules/home/components/widget/lib/maps/data-layer/trips-data-layer.ts
  3. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.html
  4. 45
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.ts
  5. 45
      ui-ngx/src/app/shared/models/widget/maps/map.models.ts
  6. 4
      ui-ngx/src/assets/locale/locale.constant-en_US.json

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

@ -157,12 +157,29 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
if (this.dataLayer.isEditEnabled()) {
this.enablePolylineEditMode();
buttons.push(
{
id: 'cut',
title: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polygon.cut'),
iconClass: 'tb-cut',
click: (e, button) => {
const map = this.dataLayer.getMap().getMap();
if (!map.pm.globalCutModeEnabled()) {
this.disablePolylineRotateMode();
this.disablePolylineEditMode();
this.enablePolylineCutMode(button);
} else {
this.disablePolylineCutMode(button);
this.enablePolylineEditMode();
}
}
},
{
id: 'rotate',
title: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polyline.rotate'),
iconClass: 'tb-rotate',
click: (e, button) => {
if (!this.polyline.pm.rotateEnabled()) {
this.disablePolylineCutMode();
this.disablePolylineEditMode();
this.enablePolylineRotateMode(button);
} else {
@ -184,7 +201,13 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
}
protected canDeselect(cancel = false): boolean {
if (this.polyline.pm.rotateEnabled()) {
const map = this.dataLayer.getMap().getMap();
if (map.pm.globalCutModeEnabled()) {
if (cancel) {
this.disablePolylineCutMode();
}
return false;
} else if (this.polyline.pm.rotateEnabled()) {
if (cancel) {
this.disablePolylineRotateMode();
}
@ -223,6 +246,69 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
map.getEditToolbar().getButton('remove')?.setDisabled(true);
}
private enablePolylineCutMode(cutButton?: L.TB.ToolbarButton) {
this.polylineContainer.closePopup();
this.editing = true;
this.polyline.options.bubblingMouseEvents = true;
this.polyline.setStyle({
...this.polylineStyleInfo.style, dashArray: '5 5', weight: 3,
color: '#3388ff', opacity: 1, fillColor: '#3388ff', fillOpacity: 0.2
});
this.addItemClass('tb-cut-mode');
this.polyline.once('pm:cut', (e) => {
if (e.layer instanceof L.Polyline) {
this.polylineContainer.removeLayer(this.polyline);
this.polyline = L.polyline(e.layer.getLatLngs() as L.LatLngExpression[] | L.LatLngExpression[][], {
...this.polylineStyleInfo.style,
snapIgnore: !this.dataLayer.isSnappable(),
bubblingMouseEvents: !this.dataLayer.isEditMode()
});
this.polyline.addTo(this.polylineContainer);
}
// @ts-ignore
e.layer._pmTempLayer = true;
e.layer.remove();
this.polylineContainer.removeLayer(this.polyline);
// @ts-ignore
this.polyline._pmTempLayer = false;
this.polyline.addTo(this.polylineContainer);
this.updateSelectedState();
cutButton?.setActive(false);
this.savePolylineCoordinates()
});
const map = this.dataLayer.getMap().getMap();
map.pm.setLang('en', {
tooltips: {
firstVertex: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polyline.polyline-place-first-point-cut-hint'),
finishLine: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polyline.finish-polyline-cut-hint')
}
}, 'en');
map.pm.enableGlobalCutMode({
// @ts-ignore
layersToCut: [this.polyline]
});
// @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) {
this.disablePolylineCutMode(cutButton);
this.enablePolylineEditMode();
}
});
}
private disablePolylineCutMode(cutButton?: L.TB.ToolbarButton) {
this.editing = false;
this.polyline.options.bubblingMouseEvents = !this.dataLayer.isEditMode();
this.polyline.setStyle({...this.polylineStyleInfo.style, dashArray: null});
this.removeItemClass('tb-cut-mode');
this.polyline.off('pm:cut');
const map = this.dataLayer.getMap().getMap();
map.pm.disableGlobalCutMode();
cutButton?.setActive(false);
}
private enablePolylineRotateMode(rotateButton?: L.TB.ToolbarButton) {
this.polylineContainer.closePopup();
this.editing = true;
@ -250,6 +336,13 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
if (coordinates.length === 1) {
coordinates = coordinates[0] as TbPolylineCoordinates;
}
if (this.polyline instanceof L.Rectangle && !isCutPolygon(coordinates)) {
const bounds = this.polyline.getBounds();
const boundsArray = [bounds.getNorthWest(), bounds.getNorthEast(), bounds.getSouthWest(), bounds.getSouthEast()];
if (coordinates.every(point => boundsArray.find(boundPoint => boundPoint.equals(point as L.LatLng)) !== undefined)) {
coordinates = [bounds.getNorthWest(), bounds.getSouthEast()];
}
}
this.dataLayer.savePolylineCoordinates(this.data, coordinates).subscribe();
}
@ -279,7 +372,6 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
this.editModeUpdated();
}
}
}
export class TbPolylineDataLayer extends TbShapesDataLayer<PolylinesDataLayerSettings, TbPolylineDataLayer> {

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

@ -44,7 +44,7 @@ import { MarkerDataProcessor } from '@home/components/widget/lib/maps/data-layer
type TripRouteData = {[time: number]: FormattedData<TbMapDatasource>};
interface PointItem {
export interface PointItem {
point: L.CircleMarker;
tooltip?: L.Popup;
}

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.html

@ -390,8 +390,6 @@
</ng-template>
</mat-expansion-panel>
</div>
</ng-container>
<ng-container *ngIf="['trips', 'polylines'].includes(dataLayerType)">
<div class="tb-form-panel tb-slide-toggle stroked">
<mat-expansion-panel class="tb-settings" [expanded]="dataLayerFormGroup.get('showPoints').value"
[disabled]="!dataLayerFormGroup.get('showPoints').value">

45
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.ts

@ -306,24 +306,6 @@ export class MapDataLayerDialogComponent extends DialogComponent<MapDataLayerDia
this.dialogTitle = 'widgets.maps.data-layer.polyline.polyline-configuration';
this.dataLayerEditTitle = 'widgets.maps.data-layer.polyline.edit';
this.dataLayerFormGroup.addControl('polylineKey', this.fb.control(polylineShapeDataLayer.polylineKey, Validators.required));
// this.dataLayerFormGroup.addControl('usePathDecorator', this.fb.control(polylineShapeDataLayer.usePathDecorator));
// this.dataLayerFormGroup.addControl('pathDecoratorSymbol', this.fb.control(polylineShapeDataLayer.pathDecoratorSymbol, Validators.required));
// this.dataLayerFormGroup.addControl('pathDecoratorSymbolSize', this.fb.control(polylineShapeDataLayer.pathDecoratorSymbolSize, [Validators.required, Validators.min(0)]));
// this.dataLayerFormGroup.addControl('pathDecoratorSymbolColor', this.fb.control(polylineShapeDataLayer.pathDecoratorSymbolColor));
// this.dataLayerFormGroup.addControl('pathDecoratorOffset', this.fb.control(polylineShapeDataLayer.pathDecoratorOffset, [Validators.required, Validators.min(0)]));
// this.dataLayerFormGroup.addControl('pathEndDecoratorOffset', this.fb.control(polylineShapeDataLayer.pathEndDecoratorOffset, [Validators.required, Validators.min(0)]));
// this.dataLayerFormGroup.addControl('pathDecoratorRepeat', this.fb.control(polylineShapeDataLayer.pathDecoratorRepeat, [Validators.required, Validators.min(0)]));
this.dataLayerFormGroup.addControl('showPoints', this.fb.control(polylineShapeDataLayer.showPoints));
this.dataLayerFormGroup.addControl('pointSize', this.fb.control(polylineShapeDataLayer.pointSize, [Validators.required, Validators.min(0)]));
this.dataLayerFormGroup.addControl('pointColor', this.fb.control(polylineShapeDataLayer.pointColor, Validators.required));
this.dataLayerFormGroup.addControl('pointTooltip', this.fb.control(polylineShapeDataLayer.pointTooltip));
merge(
// this.dataLayerFormGroup.get('usePathDecorator').valueChanges,
this.dataLayerFormGroup.get('showPoints').valueChanges).pipe(
takeUntilDestroyed(this.destroyRef)
).subscribe(() =>
this.updateValidators()
);
break;
}
this.dataLayerFormGroup.get('dsType').valueChanges.pipe(
@ -473,33 +455,6 @@ export class MapDataLayerDialogComponent extends DialogComponent<MapDataLayerDia
this.dataLayerFormGroup.get('pointColor').disable({emitEvent: false});
this.dataLayerFormGroup.get('pointTooltip').disable({emitEvent: false});
}
} else if (this.dataLayerType === 'polylines') {
// const usePathDecorator: boolean = this.dataLayerFormGroup.get('usePathDecorator').value;
const showPoints: boolean = this.dataLayerFormGroup.get('showPoints').value;
// if (usePathDecorator) {
// this.dataLayerFormGroup.get('pathDecoratorSymbol').enable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorSymbolSize').enable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorSymbolColor').enable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorOffset').enable({emitEvent: false});
// this.dataLayerFormGroup.get('pathEndDecoratorOffset').enable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorRepeat').enable({emitEvent: false});
// } else {
// this.dataLayerFormGroup.get('pathDecoratorSymbol').disable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorSymbolSize').disable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorSymbolColor').disable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorOffset').disable({emitEvent: false});
// this.dataLayerFormGroup.get('pathEndDecoratorOffset').disable({emitEvent: false});
// this.dataLayerFormGroup.get('pathDecoratorRepeat').disable({emitEvent: false});
// }
if (showPoints) {
this.dataLayerFormGroup.get('pointSize').enable({emitEvent: false});
this.dataLayerFormGroup.get('pointColor').enable({emitEvent: false});
this.dataLayerFormGroup.get('pointTooltip').enable({emitEvent: false});
} else {
this.dataLayerFormGroup.get('pointSize').disable({emitEvent: false});
this.dataLayerFormGroup.get('pointColor').disable({emitEvent: false});
this.dataLayerFormGroup.get('pointTooltip').disable({emitEvent: false});
}
}
}

45
ui-ngx/src/app/shared/models/widget/maps/map.models.ts

@ -443,7 +443,13 @@ export const pathDecoratorSymbolTranslationMap = new Map<PathDecoratorSymbol, st
]
);
export interface PathDataLayerSettings {
export interface TripsDataLayerSettings extends MarkersDataLayerSettings {
showMarker: boolean;
rotateMarker: boolean;
offsetAngle: number;
showPath: boolean;
pathStrokeWeight?: number;
pathStrokeColor?: DataLayerColorSettings;
usePathDecorator?: boolean;
pathDecoratorSymbol?: PathDecoratorSymbol;
pathDecoratorSymbolSize?: number;
@ -457,15 +463,6 @@ export interface PathDataLayerSettings {
pointTooltip?: DataLayerTooltipSettings;
}
export interface TripsDataLayerSettings extends MarkersDataLayerSettings, PathDataLayerSettings {
showMarker: boolean;
rotateMarker: boolean;
offsetAngle: number;
showPath: boolean;
pathStrokeWeight?: number;
pathStrokeColor?: DataLayerColorSettings;
}
export const defaultTripsDataLayerSettings = (mapType: MapType, functionsOnly = false): TripsDataLayerSettings => mergeDeep(
defaultMarkersDataSourceSettings(mapType, true, functionsOnly) as TripsDataLayerSettings,
defaultBaseTripsDataLayerSettings(mapType) as TripsDataLayerSettings);
@ -673,7 +670,7 @@ export const defaultBaseCirclesDataLayerSettings = (mapType: MapType): Partial<C
tooltip: {show: false, pattern: '<b>${entityName}</b><br/><br/><b>TimeStamp:</b> ${ts:7}'}
} as Partial<CirclesDataLayerSettings>)
export interface PolylinesDataLayerSettings extends ShapeDataLayerSettings, PathDataLayerSettings {
export interface PolylinesDataLayerSettings extends ShapeDataLayerSettings {
polylineKey: DataKey;
}
@ -699,31 +696,7 @@ export const defaultBasePolylinesDataLayerSettings = (mapType: MapType): Partial
type: DataLayerColorType.constant,
color: '#3388ff',
},
strokeWeight: 3,
// usePathDecorator: false,
// pathDecoratorSymbol: PathDecoratorSymbol.arrowHead,
// pathDecoratorSymbolSize: 10,
// pathDecoratorSymbolColor: '#307FE5',
// pathDecoratorOffset: 20,
// pathEndDecoratorOffset: 20,
// pathDecoratorRepeat: 20,
showPoints: false,
pointSize: 10,
pointColor: {
type: DataLayerColorType.constant,
color: '#307FE5',
},
pointTooltip: {
show: false,
trigger: DataLayerTooltipTrigger.click,
autoclose: true,
type: DataLayerPatternType.pattern,
pattern: mapType === MapType.geoMap ?
'<b>${entityName}</b><br/><br/><b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}<br/><b>End Time:</b> ${maxTime}<br/><b>Start Time:</b> ${minTime}'
: '<b>${entityName}</b><br/><br/><b>X Pos:</b> ${xPos:2}<br/><b>Y Pos:</b> ${yPos:2}<br/><b>End Time:</b> ${maxTime}<br/><b>Start Time:</b> ${minTime}',
offsetX: 0,
offsetY: -1
},
strokeWeight: 3
} as Partial<PolylinesDataLayerSettings>, defaultBaseDataLayerSettings(mapType),
{
label: {show: false},

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

@ -8643,7 +8643,9 @@
"draw-polyline": "Draw polyline",
"polyline-place-first-point-hint-with-entity": "Polyline for '{{entityName}}': click to place first point",
"polyline-place-first-point-hint": "Polyline: click to place first point",
"finish-polyline-hint": "Polyline for '{{entityName}}': click to finish drawing"
"finish-polyline-hint": "Polyline for '{{entityName}}': click to finish drawing",
"polyline-place-first-point-cut-hint": "Click to place first point",
"finish-polyline-cut-hint": "Click first marker to finish and save"
},
"select-entity": "Select entity",
"select-entity-hint": "Hint: after selection click at the map to set position"

Loading…
Cancel
Save