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()) { if (this.dataLayer.isEditEnabled()) {
this.enablePolylineEditMode(); this.enablePolylineEditMode();
buttons.push( 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', id: 'rotate',
title: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polyline.rotate'), title: this.getDataLayer().getCtx().translate.instant('widgets.maps.data-layer.polyline.rotate'),
iconClass: 'tb-rotate', iconClass: 'tb-rotate',
click: (e, button) => { click: (e, button) => {
if (!this.polyline.pm.rotateEnabled()) { if (!this.polyline.pm.rotateEnabled()) {
this.disablePolylineCutMode();
this.disablePolylineEditMode(); this.disablePolylineEditMode();
this.enablePolylineRotateMode(button); this.enablePolylineRotateMode(button);
} else { } else {
@ -184,7 +201,13 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
} }
protected canDeselect(cancel = false): boolean { 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) { if (cancel) {
this.disablePolylineRotateMode(); this.disablePolylineRotateMode();
} }
@ -223,6 +246,69 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
map.getEditToolbar().getButton('remove')?.setDisabled(true); 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) { private enablePolylineRotateMode(rotateButton?: L.TB.ToolbarButton) {
this.polylineContainer.closePopup(); this.polylineContainer.closePopup();
this.editing = true; this.editing = true;
@ -250,6 +336,13 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
if (coordinates.length === 1) { if (coordinates.length === 1) {
coordinates = coordinates[0] as TbPolylineCoordinates; 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(); this.dataLayer.savePolylineCoordinates(this.data, coordinates).subscribe();
} }
@ -279,7 +372,6 @@ class TbPolylineDataLayerItem extends TbLatestDataLayerItem<PolylinesDataLayerSe
this.editModeUpdated(); this.editModeUpdated();
} }
} }
} }
export class TbPolylineDataLayer extends TbShapesDataLayer<PolylinesDataLayerSettings, TbPolylineDataLayer> { 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>}; type TripRouteData = {[time: number]: FormattedData<TbMapDatasource>};
interface PointItem { export interface PointItem {
point: L.CircleMarker; point: L.CircleMarker;
tooltip?: L.Popup; 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> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
</div> </div>
</ng-container>
<ng-container *ngIf="['trips', 'polylines'].includes(dataLayerType)">
<div class="tb-form-panel tb-slide-toggle stroked"> <div class="tb-form-panel tb-slide-toggle stroked">
<mat-expansion-panel class="tb-settings" [expanded]="dataLayerFormGroup.get('showPoints').value" <mat-expansion-panel class="tb-settings" [expanded]="dataLayerFormGroup.get('showPoints').value"
[disabled]="!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.dialogTitle = 'widgets.maps.data-layer.polyline.polyline-configuration';
this.dataLayerEditTitle = 'widgets.maps.data-layer.polyline.edit'; this.dataLayerEditTitle = 'widgets.maps.data-layer.polyline.edit';
this.dataLayerFormGroup.addControl('polylineKey', this.fb.control(polylineShapeDataLayer.polylineKey, Validators.required)); 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; break;
} }
this.dataLayerFormGroup.get('dsType').valueChanges.pipe( 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('pointColor').disable({emitEvent: false});
this.dataLayerFormGroup.get('pointTooltip').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; usePathDecorator?: boolean;
pathDecoratorSymbol?: PathDecoratorSymbol; pathDecoratorSymbol?: PathDecoratorSymbol;
pathDecoratorSymbolSize?: number; pathDecoratorSymbolSize?: number;
@ -457,15 +463,6 @@ export interface PathDataLayerSettings {
pointTooltip?: DataLayerTooltipSettings; 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( export const defaultTripsDataLayerSettings = (mapType: MapType, functionsOnly = false): TripsDataLayerSettings => mergeDeep(
defaultMarkersDataSourceSettings(mapType, true, functionsOnly) as TripsDataLayerSettings, defaultMarkersDataSourceSettings(mapType, true, functionsOnly) as TripsDataLayerSettings,
defaultBaseTripsDataLayerSettings(mapType) 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}'} tooltip: {show: false, pattern: '<b>${entityName}</b><br/><br/><b>TimeStamp:</b> ${ts:7}'}
} as Partial<CirclesDataLayerSettings>) } as Partial<CirclesDataLayerSettings>)
export interface PolylinesDataLayerSettings extends ShapeDataLayerSettings, PathDataLayerSettings { export interface PolylinesDataLayerSettings extends ShapeDataLayerSettings {
polylineKey: DataKey; polylineKey: DataKey;
} }
@ -699,31 +696,7 @@ export const defaultBasePolylinesDataLayerSettings = (mapType: MapType): Partial
type: DataLayerColorType.constant, type: DataLayerColorType.constant,
color: '#3388ff', color: '#3388ff',
}, },
strokeWeight: 3, 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
},
} as Partial<PolylinesDataLayerSettings>, defaultBaseDataLayerSettings(mapType), } as Partial<PolylinesDataLayerSettings>, defaultBaseDataLayerSettings(mapType),
{ {
label: {show: false}, label: {show: false},

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

@ -8643,7 +8643,9 @@
"draw-polyline": "Draw polyline", "draw-polyline": "Draw polyline",
"polyline-place-first-point-hint-with-entity": "Polyline for '{{entityName}}': click to place first point", "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", "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": "Select entity",
"select-entity-hint": "Hint: after selection click at the map to set position" "select-entity-hint": "Hint: after selection click at the map to set position"

Loading…
Cancel
Save