Fixed update position new marker/polygon on resize in image-map
This commit is contained in:
parent
d547ba407a
commit
1e1d3a8257
@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster';
|
|||||||
import {
|
import {
|
||||||
defaultSettings,
|
defaultSettings,
|
||||||
FormattedData,
|
FormattedData,
|
||||||
|
MapProviders,
|
||||||
MapSettings,
|
MapSettings,
|
||||||
MarkerSettings,
|
MarkerSettings,
|
||||||
PolygonSettings,
|
PolygonSettings,
|
||||||
@ -74,6 +75,8 @@ export default abstract class LeafletMap {
|
|||||||
drawRoutes: boolean;
|
drawRoutes: boolean;
|
||||||
showPolygon: boolean;
|
showPolygon: boolean;
|
||||||
updatePending = false;
|
updatePending = false;
|
||||||
|
addMarkers: L.Marker[] = [];
|
||||||
|
addPolygons: L.Polygon[] = [];
|
||||||
|
|
||||||
protected constructor(public ctx: WidgetContext,
|
protected constructor(public ctx: WidgetContext,
|
||||||
public $container: HTMLElement,
|
public $container: HTMLElement,
|
||||||
@ -133,6 +136,7 @@ export default abstract class LeafletMap {
|
|||||||
shadowSize: [41, 41]
|
shadowSize: [41, 41]
|
||||||
});
|
});
|
||||||
const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
|
const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
|
||||||
|
this.addMarkers.push(newMarker);
|
||||||
const datasourcesList = document.createElement('div');
|
const datasourcesList = document.createElement('div');
|
||||||
const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
|
const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
|
||||||
const header = document.createElement('p');
|
const header = document.createElement('p');
|
||||||
@ -147,6 +151,10 @@ export default abstract class LeafletMap {
|
|||||||
const updatedEnttity = { ...ds, ...customLatLng };
|
const updatedEnttity = { ...ds, ...customLatLng };
|
||||||
this.saveMarkerLocation(updatedEnttity).subscribe(() => {
|
this.saveMarkerLocation(updatedEnttity).subscribe(() => {
|
||||||
this.map.removeLayer(newMarker);
|
this.map.removeLayer(newMarker);
|
||||||
|
const markerIndex = this.addMarkers.indexOf(newMarker);
|
||||||
|
if (markerIndex > -1) {
|
||||||
|
this.addMarkers.splice(markerIndex, 1);
|
||||||
|
}
|
||||||
this.deleteMarker(ds.entityName);
|
this.deleteMarker(ds.entityName);
|
||||||
this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
|
this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
|
||||||
});
|
});
|
||||||
@ -158,6 +166,10 @@ export default abstract class LeafletMap {
|
|||||||
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
||||||
deleteBtn.onclick = () => {
|
deleteBtn.onclick = () => {
|
||||||
this.map.removeLayer(newMarker);
|
this.map.removeLayer(newMarker);
|
||||||
|
const markerIndex = this.addMarkers.indexOf(newMarker);
|
||||||
|
if (markerIndex > -1) {
|
||||||
|
this.addMarkers.splice(markerIndex, 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
datasourcesList.append(deleteBtn);
|
datasourcesList.append(deleteBtn);
|
||||||
const popup = L.popup();
|
const popup = L.popup();
|
||||||
@ -196,14 +208,16 @@ export default abstract class LeafletMap {
|
|||||||
let mousePositionOnMap: L.LatLng[];
|
let mousePositionOnMap: L.LatLng[];
|
||||||
let addPolygon: L.Control;
|
let addPolygon: L.Control;
|
||||||
this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
|
this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
|
||||||
|
const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01;
|
||||||
const latlng1 = e.latlng;
|
const latlng1 = e.latlng;
|
||||||
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + 10);
|
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset);
|
||||||
const latlng3 = L.latLng(e.latlng.lat - 10, e.latlng.lng);
|
const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng);
|
||||||
mousePositionOnMap = [latlng1, latlng2, latlng3];
|
mousePositionOnMap = [latlng1, latlng2, latlng3];
|
||||||
});
|
});
|
||||||
const dragListener = (e: L.DragEndEvent) => {
|
const dragListener = (e: L.DragEndEvent) => {
|
||||||
if (e.type === 'dragend' && mousePositionOnMap) {
|
if (e.type === 'dragend' && mousePositionOnMap) {
|
||||||
const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
|
const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
|
||||||
|
this.addPolygons.push(newPolygon);
|
||||||
const datasourcesList = document.createElement('div');
|
const datasourcesList = document.createElement('div');
|
||||||
const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
|
const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
|
||||||
const header = document.createElement('p');
|
const header = document.createElement('p');
|
||||||
@ -218,6 +232,10 @@ export default abstract class LeafletMap {
|
|||||||
const updatedEnttity = { ...ds, ...customLatLng };
|
const updatedEnttity = { ...ds, ...customLatLng };
|
||||||
this.savePolygonLocation(updatedEnttity).subscribe(() => {
|
this.savePolygonLocation(updatedEnttity).subscribe(() => {
|
||||||
this.map.removeLayer(newPolygon);
|
this.map.removeLayer(newPolygon);
|
||||||
|
const polygonIndex = this.addPolygons.indexOf(newPolygon);
|
||||||
|
if (polygonIndex > -1) {
|
||||||
|
this.addPolygons.splice(polygonIndex, 1);
|
||||||
|
}
|
||||||
this.deletePolygon(ds.entityName);
|
this.deletePolygon(ds.entityName);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -228,6 +246,10 @@ export default abstract class LeafletMap {
|
|||||||
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
||||||
deleteBtn.onclick = () => {
|
deleteBtn.onclick = () => {
|
||||||
this.map.removeLayer(newPolygon);
|
this.map.removeLayer(newPolygon);
|
||||||
|
const polygonIndex = this.addPolygons.indexOf(newPolygon);
|
||||||
|
if (polygonIndex > -1) {
|
||||||
|
this.addPolygons.splice(polygonIndex, 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
datasourcesList.append(deleteBtn);
|
datasourcesList.append(deleteBtn);
|
||||||
const popup = L.popup();
|
const popup = L.popup();
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
|||||||
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
||||||
import { isDefinedAndNotNull, isEmptyStr } from '@core/utils';
|
import { isDefinedAndNotNull, isEmptyStr } from '@core/utils';
|
||||||
|
|
||||||
const maxZoom = 4;// ?
|
const maxZoom = 4; // ?
|
||||||
|
|
||||||
export class ImageMap extends LeafletMap {
|
export class ImageMap extends LeafletMap {
|
||||||
|
|
||||||
@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onResize(updateImage?: boolean) {
|
onResize(updateImage?: boolean) {
|
||||||
let width = this.$container.clientWidth;
|
let width = this.$container.clientWidth;
|
||||||
if (width > 0 && this.aspect) {
|
if (width > 0 && this.aspect) {
|
||||||
let height = width / this.aspect;
|
let height = width / this.aspect;
|
||||||
const imageMapHeight = this.$container.clientHeight;
|
const imageMapHeight = this.$container.clientHeight;
|
||||||
if (imageMapHeight > 0 && height > imageMapHeight) {
|
if (imageMapHeight > 0 && height > imageMapHeight) {
|
||||||
height = imageMapHeight;
|
height = imageMapHeight;
|
||||||
width = height * this.aspect;
|
width = height * this.aspect;
|
||||||
}
|
|
||||||
width *= maxZoom;
|
|
||||||
const prevWidth = this.width;
|
|
||||||
const prevHeight = this.height;
|
|
||||||
if (this.width !== width || updateImage) {
|
|
||||||
this.width = width;
|
|
||||||
this.height = width / this.aspect;
|
|
||||||
if (!this.map) {
|
|
||||||
this.initMap(updateImage);
|
|
||||||
} else {
|
|
||||||
const lastCenterPos = this.latLngToPoint(this.map.getCenter());
|
|
||||||
lastCenterPos.x /= prevWidth;
|
|
||||||
lastCenterPos.y /= prevHeight;
|
|
||||||
this.updateBounds(updateImage, lastCenterPos);
|
|
||||||
this.map.invalidateSize(true);
|
|
||||||
this.updateMarkers(this.markersData);
|
|
||||||
this.updatePolygons(this.polygonsData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
width *= maxZoom;
|
||||||
|
const prevWidth = this.width;
|
||||||
|
const prevHeight = this.height;
|
||||||
|
if (this.width !== width || updateImage) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = width / this.aspect;
|
||||||
|
if (!this.map) {
|
||||||
|
this.initMap(updateImage);
|
||||||
|
} else {
|
||||||
|
const lastCenterPos = this.latLngToPoint(this.map.getCenter());
|
||||||
|
lastCenterPos.x /= prevWidth;
|
||||||
|
lastCenterPos.y /= prevHeight;
|
||||||
|
this.updateBounds(updateImage, lastCenterPos);
|
||||||
|
this.map.invalidateSize(true);
|
||||||
|
this.updateMarkers(this.markersData);
|
||||||
|
if (this.options.draggableMarker && this.addMarkers.length) {
|
||||||
|
this.addMarkers.forEach((marker) => {
|
||||||
|
const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight);
|
||||||
|
marker.setLatLng(this.convertPosition(prevPoint));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.updatePolygons(this.polygonsData);
|
||||||
|
if (this.options.showPolygon && this.options.editablePolygon && this.addPolygons.length) {
|
||||||
|
this.addPolygons.forEach((polygon) => {
|
||||||
|
const prevPolygonPoint = this.convertToPolygonFormat(polygon.getLatLngs(), prevWidth, prevHeight);
|
||||||
|
polygon.setLatLngs(this.convertPositionPolygon(prevPolygonPoint));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { }
|
fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { }
|
||||||
|
|
||||||
initMap(updateImage?: boolean) {
|
initMap(updateImage?: boolean) {
|
||||||
if (!this.map && this.aspect > 0) {
|
if (!this.map && this.aspect > 0) {
|
||||||
const center = this.pointToLatLng(this.width / 2, this.height / 2);
|
const center = this.pointToLatLng(this.width / 2, this.height / 2);
|
||||||
this.map = L.map(this.$container, {
|
this.map = L.map(this.$container, {
|
||||||
minZoom: 1,
|
minZoom: 1,
|
||||||
maxZoom,
|
maxZoom,
|
||||||
scrollWheelZoom: !this.options.disableScrollZooming,
|
scrollWheelZoom: !this.options.disableScrollZooming,
|
||||||
center,
|
center,
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
crs: L.CRS.Simple,
|
crs: L.CRS.Simple,
|
||||||
attributionControl: false,
|
attributionControl: false,
|
||||||
editable: !!this.options.editablePolygon
|
editable: !!this.options.editablePolygon
|
||||||
});
|
});
|
||||||
this.updateBounds(updateImage);
|
this.updateBounds(updateImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convertPosition(expression): L.LatLng {
|
convertPosition(expression): L.LatLng {
|
||||||
@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap {
|
|||||||
if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
|
if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
|
||||||
return this.pointToLatLng(
|
return this.pointToLatLng(
|
||||||
el[0] * this.width,
|
el[0] * this.width,
|
||||||
el[1] * this.height)
|
el[1] * this.height
|
||||||
|
);
|
||||||
} else if (Array.isArray(el) && el.length) {
|
} else if (Array.isArray(el) && el.length) {
|
||||||
return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
|
return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).filter(el => !!el)
|
}).filter(el => !!el);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointToLatLng(x, y): L.LatLng {
|
pointToLatLng(x, y): L.LatLng {
|
||||||
@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap {
|
|||||||
return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
|
return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToCustomFormat(position: L.LatLng): object {
|
convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object {
|
||||||
const point = this.latLngToPoint(position);
|
const point = this.latLngToPoint(position);
|
||||||
return {
|
return {
|
||||||
[this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, this.width),
|
[this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, width),
|
||||||
[this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, this.height)
|
[this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, height)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToPolygonFormat(points: Array<any>): Array<any> {
|
convertToPolygonFormat(points: Array<any>, width = this.width, height = this.height): Array<any> {
|
||||||
if (points.length) {
|
if (points.length) {
|
||||||
return points.map(point=> {
|
return points.map(point => {
|
||||||
if (point.length) {
|
if (point.length) {
|
||||||
return this.convertToPolygonFormat(point);
|
return this.convertToPolygonFormat(point, width, height);
|
||||||
} else {
|
} else {
|
||||||
const pos = this.latLngToPoint(point);
|
const pos = this.latLngToPoint(point);
|
||||||
return [calculateNewPointCoordinate(pos.x, this.width), calculateNewPointCoordinate(pos.y, this.height)];
|
return [calculateNewPointCoordinate(pos.x, width), calculateNewPointCoordinate(pos.y, height)];
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convertPolygonToCustomFormat(expression: any[][]): object {
|
convertPolygonToCustomFormat(expression: any[][]): object {
|
||||||
return {
|
return {
|
||||||
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
|
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user