Commit 1e1d3a8257a5aa824e3a8cbe15f44b22201ea6b8

Authored by Vladyslav_Prykhodko
1 parent d547ba40

Fixed update position new marker/polygon on resize in image-map

@@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster'; @@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster';
30 import { 30 import {
31 defaultSettings, 31 defaultSettings,
32 FormattedData, 32 FormattedData,
  33 + MapProviders,
33 MapSettings, 34 MapSettings,
34 MarkerSettings, 35 MarkerSettings,
35 PolygonSettings, 36 PolygonSettings,
@@ -74,6 +75,8 @@ export default abstract class LeafletMap { @@ -74,6 +75,8 @@ export default abstract class LeafletMap {
74 drawRoutes: boolean; 75 drawRoutes: boolean;
75 showPolygon: boolean; 76 showPolygon: boolean;
76 updatePending = false; 77 updatePending = false;
  78 + addMarkers: L.Marker[] = [];
  79 + addPolygons: L.Polygon[] = [];
77 80
78 protected constructor(public ctx: WidgetContext, 81 protected constructor(public ctx: WidgetContext,
79 public $container: HTMLElement, 82 public $container: HTMLElement,
@@ -133,6 +136,7 @@ export default abstract class LeafletMap { @@ -133,6 +136,7 @@ export default abstract class LeafletMap {
133 shadowSize: [41, 41] 136 shadowSize: [41, 41]
134 }); 137 });
135 const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map); 138 const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
  139 + this.addMarkers.push(newMarker);
136 const datasourcesList = document.createElement('div'); 140 const datasourcesList = document.createElement('div');
137 const customLatLng = this.convertToCustomFormat(mousePositionOnMap); 141 const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
138 const header = document.createElement('p'); 142 const header = document.createElement('p');
@@ -147,6 +151,10 @@ export default abstract class LeafletMap { @@ -147,6 +151,10 @@ export default abstract class LeafletMap {
147 const updatedEnttity = { ...ds, ...customLatLng }; 151 const updatedEnttity = { ...ds, ...customLatLng };
148 this.saveMarkerLocation(updatedEnttity).subscribe(() => { 152 this.saveMarkerLocation(updatedEnttity).subscribe(() => {
149 this.map.removeLayer(newMarker); 153 this.map.removeLayer(newMarker);
  154 + const markerIndex = this.addMarkers.indexOf(newMarker);
  155 + if (markerIndex > -1) {
  156 + this.addMarkers.splice(markerIndex, 1);
  157 + }
150 this.deleteMarker(ds.entityName); 158 this.deleteMarker(ds.entityName);
151 this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options); 159 this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
152 }); 160 });
@@ -158,6 +166,10 @@ export default abstract class LeafletMap { @@ -158,6 +166,10 @@ export default abstract class LeafletMap {
158 deleteBtn.appendChild(document.createTextNode('Discard changes')); 166 deleteBtn.appendChild(document.createTextNode('Discard changes'));
159 deleteBtn.onclick = () => { 167 deleteBtn.onclick = () => {
160 this.map.removeLayer(newMarker); 168 this.map.removeLayer(newMarker);
  169 + const markerIndex = this.addMarkers.indexOf(newMarker);
  170 + if (markerIndex > -1) {
  171 + this.addMarkers.splice(markerIndex, 1);
  172 + }
161 }; 173 };
162 datasourcesList.append(deleteBtn); 174 datasourcesList.append(deleteBtn);
163 const popup = L.popup(); 175 const popup = L.popup();
@@ -196,14 +208,16 @@ export default abstract class LeafletMap { @@ -196,14 +208,16 @@ export default abstract class LeafletMap {
196 let mousePositionOnMap: L.LatLng[]; 208 let mousePositionOnMap: L.LatLng[];
197 let addPolygon: L.Control; 209 let addPolygon: L.Control;
198 this.map.on('mousemove', (e: L.LeafletMouseEvent) => { 210 this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
  211 + const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01;
199 const latlng1 = e.latlng; 212 const latlng1 = e.latlng;
200 - const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + 10);  
201 - const latlng3 = L.latLng(e.latlng.lat - 10, e.latlng.lng); 213 + const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset);
  214 + const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng);
202 mousePositionOnMap = [latlng1, latlng2, latlng3]; 215 mousePositionOnMap = [latlng1, latlng2, latlng3];
203 }); 216 });
204 const dragListener = (e: L.DragEndEvent) => { 217 const dragListener = (e: L.DragEndEvent) => {
205 if (e.type === 'dragend' && mousePositionOnMap) { 218 if (e.type === 'dragend' && mousePositionOnMap) {
206 const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map); 219 const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
  220 + this.addPolygons.push(newPolygon);
207 const datasourcesList = document.createElement('div'); 221 const datasourcesList = document.createElement('div');
208 const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)}; 222 const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
209 const header = document.createElement('p'); 223 const header = document.createElement('p');
@@ -218,6 +232,10 @@ export default abstract class LeafletMap { @@ -218,6 +232,10 @@ export default abstract class LeafletMap {
218 const updatedEnttity = { ...ds, ...customLatLng }; 232 const updatedEnttity = { ...ds, ...customLatLng };
219 this.savePolygonLocation(updatedEnttity).subscribe(() => { 233 this.savePolygonLocation(updatedEnttity).subscribe(() => {
220 this.map.removeLayer(newPolygon); 234 this.map.removeLayer(newPolygon);
  235 + const polygonIndex = this.addPolygons.indexOf(newPolygon);
  236 + if (polygonIndex > -1) {
  237 + this.addPolygons.splice(polygonIndex, 1);
  238 + }
221 this.deletePolygon(ds.entityName); 239 this.deletePolygon(ds.entityName);
222 }); 240 });
223 }; 241 };
@@ -228,6 +246,10 @@ export default abstract class LeafletMap { @@ -228,6 +246,10 @@ export default abstract class LeafletMap {
228 deleteBtn.appendChild(document.createTextNode('Discard changes')); 246 deleteBtn.appendChild(document.createTextNode('Discard changes'));
229 deleteBtn.onclick = () => { 247 deleteBtn.onclick = () => {
230 this.map.removeLayer(newPolygon); 248 this.map.removeLayer(newPolygon);
  249 + const polygonIndex = this.addPolygons.indexOf(newPolygon);
  250 + if (polygonIndex > -1) {
  251 + this.addPolygons.splice(polygonIndex, 1);
  252 + }
231 }; 253 };
232 datasourcesList.append(deleteBtn); 254 datasourcesList.append(deleteBtn);
233 const popup = L.popup(); 255 const popup = L.popup();
@@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; @@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
26 import { WidgetSubscriptionOptions } from '@core/api/widget-api.models'; 26 import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
27 import { isDefinedAndNotNull, isEmptyStr } from '@core/utils'; 27 import { isDefinedAndNotNull, isEmptyStr } from '@core/utils';
28 28
29 -const maxZoom = 4;// ? 29 +const maxZoom = 4; // ?
30 30
31 export class ImageMap extends LeafletMap { 31 export class ImageMap extends LeafletMap {
32 32
@@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap { @@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap {
162 } 162 }
163 163
164 onResize(updateImage?: boolean) { 164 onResize(updateImage?: boolean) {
165 - let width = this.$container.clientWidth;  
166 - if (width > 0 && this.aspect) {  
167 - let height = width / this.aspect;  
168 - const imageMapHeight = this.$container.clientHeight;  
169 - if (imageMapHeight > 0 && height > imageMapHeight) {  
170 - height = imageMapHeight;  
171 - width = height * this.aspect; 165 + let width = this.$container.clientWidth;
  166 + if (width > 0 && this.aspect) {
  167 + let height = width / this.aspect;
  168 + const imageMapHeight = this.$container.clientHeight;
  169 + if (imageMapHeight > 0 && height > imageMapHeight) {
  170 + height = imageMapHeight;
  171 + width = height * this.aspect;
  172 + }
  173 + width *= maxZoom;
  174 + const prevWidth = this.width;
  175 + const prevHeight = this.height;
  176 + if (this.width !== width || updateImage) {
  177 + this.width = width;
  178 + this.height = width / this.aspect;
  179 + if (!this.map) {
  180 + this.initMap(updateImage);
  181 + } else {
  182 + const lastCenterPos = this.latLngToPoint(this.map.getCenter());
  183 + lastCenterPos.x /= prevWidth;
  184 + lastCenterPos.y /= prevHeight;
  185 + this.updateBounds(updateImage, lastCenterPos);
  186 + this.map.invalidateSize(true);
  187 + this.updateMarkers(this.markersData);
  188 + if (this.options.draggableMarker && this.addMarkers.length) {
  189 + this.addMarkers.forEach((marker) => {
  190 + const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight);
  191 + marker.setLatLng(this.convertPosition(prevPoint));
  192 + });
172 } 193 }
173 - width *= maxZoom;  
174 - const prevWidth = this.width;  
175 - const prevHeight = this.height;  
176 - if (this.width !== width || updateImage) {  
177 - this.width = width;  
178 - this.height = width / this.aspect;  
179 - if (!this.map) {  
180 - this.initMap(updateImage);  
181 - } else {  
182 - const lastCenterPos = this.latLngToPoint(this.map.getCenter());  
183 - lastCenterPos.x /= prevWidth;  
184 - lastCenterPos.y /= prevHeight;  
185 - this.updateBounds(updateImage, lastCenterPos);  
186 - this.map.invalidateSize(true);  
187 - this.updateMarkers(this.markersData);  
188 - this.updatePolygons(this.polygonsData);  
189 - } 194 + this.updatePolygons(this.polygonsData);
  195 + if (this.options.showPolygon && this.options.editablePolygon && this.addPolygons.length) {
  196 + this.addPolygons.forEach((polygon) => {
  197 + const prevPolygonPoint = this.convertToPolygonFormat(polygon.getLatLngs(), prevWidth, prevHeight);
  198 + polygon.setLatLngs(this.convertPositionPolygon(prevPolygonPoint));
  199 + });
190 } 200 }
  201 + }
191 } 202 }
  203 + }
192 } 204 }
193 205
194 fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { } 206 fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { }
195 207
196 initMap(updateImage?: boolean) { 208 initMap(updateImage?: boolean) {
197 - if (!this.map && this.aspect > 0) {  
198 - const center = this.pointToLatLng(this.width / 2, this.height / 2);  
199 - this.map = L.map(this.$container, {  
200 - minZoom: 1,  
201 - maxZoom,  
202 - scrollWheelZoom: !this.options.disableScrollZooming,  
203 - center,  
204 - zoom: 1,  
205 - crs: L.CRS.Simple,  
206 - attributionControl: false,  
207 - editable: !!this.options.editablePolygon  
208 - });  
209 - this.updateBounds(updateImage);  
210 - } 209 + if (!this.map && this.aspect > 0) {
  210 + const center = this.pointToLatLng(this.width / 2, this.height / 2);
  211 + this.map = L.map(this.$container, {
  212 + minZoom: 1,
  213 + maxZoom,
  214 + scrollWheelZoom: !this.options.disableScrollZooming,
  215 + center,
  216 + zoom: 1,
  217 + crs: L.CRS.Simple,
  218 + attributionControl: false,
  219 + editable: !!this.options.editablePolygon
  220 + });
  221 + this.updateBounds(updateImage);
  222 + }
211 } 223 }
212 224
213 convertPosition(expression): L.LatLng { 225 convertPosition(expression): L.LatLng {
@@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap { @@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap {
227 if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) { 239 if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
228 return this.pointToLatLng( 240 return this.pointToLatLng(
229 el[0] * this.width, 241 el[0] * this.width,
230 - el[1] * this.height) 242 + el[1] * this.height
  243 + );
231 } else if (Array.isArray(el) && el.length) { 244 } else if (Array.isArray(el) && el.length) {
232 return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]); 245 return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
233 } else { 246 } else {
234 return null; 247 return null;
235 } 248 }
236 - }).filter(el => !!el) 249 + }).filter(el => !!el);
237 } 250 }
238 251
239 pointToLatLng(x, y): L.LatLng { 252 pointToLatLng(x, y): L.LatLng {
@@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap { @@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap {
244 return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1); 257 return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
245 } 258 }
246 259
247 - convertToCustomFormat(position: L.LatLng): object {  
248 - const point = this.latLngToPoint(position);  
249 - return {  
250 - [this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, this.width),  
251 - [this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, this.height)  
252 - } 260 + convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object {
  261 + const point = this.latLngToPoint(position);
  262 + return {
  263 + [this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, width),
  264 + [this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, height)
  265 + };
253 } 266 }
254 267
255 - convertToPolygonFormat(points: Array<any>): Array<any> { 268 + convertToPolygonFormat(points: Array<any>, width = this.width, height = this.height): Array<any> {
256 if (points.length) { 269 if (points.length) {
257 - return points.map(point=> { 270 + return points.map(point => {
258 if (point.length) { 271 if (point.length) {
259 - return this.convertToPolygonFormat(point); 272 + return this.convertToPolygonFormat(point, width, height);
260 } else { 273 } else {
261 const pos = this.latLngToPoint(point); 274 const pos = this.latLngToPoint(point);
262 - return [calculateNewPointCoordinate(pos.x, this.width), calculateNewPointCoordinate(pos.y, this.height)]; 275 + return [calculateNewPointCoordinate(pos.x, width), calculateNewPointCoordinate(pos.y, height)];
263 } 276 }
264 - }) 277 + });
265 } else { 278 } else {
266 - return [] 279 + return [];
267 } 280 }
268 } 281 }
269 282
270 convertPolygonToCustomFormat(expression: any[][]): object { 283 convertPolygonToCustomFormat(expression: any[][]): object {
271 return { 284 return {
272 [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) 285 [this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
273 - } 286 + };
274 } 287 }
275 } 288 }