Commit 1e1d3a8257a5aa824e3a8cbe15f44b22201ea6b8
1 parent
d547ba40
Fixed update position new marker/polygon on resize in image-map
Showing
2 changed files
with
91 additions
and
56 deletions
... | ... | @@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster'; |
30 | 30 | import { |
31 | 31 | defaultSettings, |
32 | 32 | FormattedData, |
33 | + MapProviders, | |
33 | 34 | MapSettings, |
34 | 35 | MarkerSettings, |
35 | 36 | PolygonSettings, |
... | ... | @@ -74,6 +75,8 @@ export default abstract class LeafletMap { |
74 | 75 | drawRoutes: boolean; |
75 | 76 | showPolygon: boolean; |
76 | 77 | updatePending = false; |
78 | + addMarkers: L.Marker[] = []; | |
79 | + addPolygons: L.Polygon[] = []; | |
77 | 80 | |
78 | 81 | protected constructor(public ctx: WidgetContext, |
79 | 82 | public $container: HTMLElement, |
... | ... | @@ -133,6 +136,7 @@ export default abstract class LeafletMap { |
133 | 136 | shadowSize: [41, 41] |
134 | 137 | }); |
135 | 138 | const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map); |
139 | + this.addMarkers.push(newMarker); | |
136 | 140 | const datasourcesList = document.createElement('div'); |
137 | 141 | const customLatLng = this.convertToCustomFormat(mousePositionOnMap); |
138 | 142 | const header = document.createElement('p'); |
... | ... | @@ -147,6 +151,10 @@ export default abstract class LeafletMap { |
147 | 151 | const updatedEnttity = { ...ds, ...customLatLng }; |
148 | 152 | this.saveMarkerLocation(updatedEnttity).subscribe(() => { |
149 | 153 | this.map.removeLayer(newMarker); |
154 | + const markerIndex = this.addMarkers.indexOf(newMarker); | |
155 | + if (markerIndex > -1) { | |
156 | + this.addMarkers.splice(markerIndex, 1); | |
157 | + } | |
150 | 158 | this.deleteMarker(ds.entityName); |
151 | 159 | this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options); |
152 | 160 | }); |
... | ... | @@ -158,6 +166,10 @@ export default abstract class LeafletMap { |
158 | 166 | deleteBtn.appendChild(document.createTextNode('Discard changes')); |
159 | 167 | deleteBtn.onclick = () => { |
160 | 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 | 174 | datasourcesList.append(deleteBtn); |
163 | 175 | const popup = L.popup(); |
... | ... | @@ -196,14 +208,16 @@ export default abstract class LeafletMap { |
196 | 208 | let mousePositionOnMap: L.LatLng[]; |
197 | 209 | let addPolygon: L.Control; |
198 | 210 | this.map.on('mousemove', (e: L.LeafletMouseEvent) => { |
211 | + const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01; | |
199 | 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 | 215 | mousePositionOnMap = [latlng1, latlng2, latlng3]; |
203 | 216 | }); |
204 | 217 | const dragListener = (e: L.DragEndEvent) => { |
205 | 218 | if (e.type === 'dragend' && mousePositionOnMap) { |
206 | 219 | const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map); |
220 | + this.addPolygons.push(newPolygon); | |
207 | 221 | const datasourcesList = document.createElement('div'); |
208 | 222 | const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)}; |
209 | 223 | const header = document.createElement('p'); |
... | ... | @@ -218,6 +232,10 @@ export default abstract class LeafletMap { |
218 | 232 | const updatedEnttity = { ...ds, ...customLatLng }; |
219 | 233 | this.savePolygonLocation(updatedEnttity).subscribe(() => { |
220 | 234 | this.map.removeLayer(newPolygon); |
235 | + const polygonIndex = this.addPolygons.indexOf(newPolygon); | |
236 | + if (polygonIndex > -1) { | |
237 | + this.addPolygons.splice(polygonIndex, 1); | |
238 | + } | |
221 | 239 | this.deletePolygon(ds.entityName); |
222 | 240 | }); |
223 | 241 | }; |
... | ... | @@ -228,6 +246,10 @@ export default abstract class LeafletMap { |
228 | 246 | deleteBtn.appendChild(document.createTextNode('Discard changes')); |
229 | 247 | deleteBtn.onclick = () => { |
230 | 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 | 254 | datasourcesList.append(deleteBtn); |
233 | 255 | const popup = L.popup(); | ... | ... |
... | ... | @@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; |
26 | 26 | import { WidgetSubscriptionOptions } from '@core/api/widget-api.models'; |
27 | 27 | import { isDefinedAndNotNull, isEmptyStr } from '@core/utils'; |
28 | 28 | |
29 | -const maxZoom = 4;// ? | |
29 | +const maxZoom = 4; // ? | |
30 | 30 | |
31 | 31 | export class ImageMap extends LeafletMap { |
32 | 32 | |
... | ... | @@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap { |
162 | 162 | } |
163 | 163 | |
164 | 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 | 206 | fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { } |
195 | 207 | |
196 | 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 | 225 | convertPosition(expression): L.LatLng { |
... | ... | @@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap { |
227 | 239 | if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) { |
228 | 240 | return this.pointToLatLng( |
229 | 241 | el[0] * this.width, |
230 | - el[1] * this.height) | |
242 | + el[1] * this.height | |
243 | + ); | |
231 | 244 | } else if (Array.isArray(el) && el.length) { |
232 | 245 | return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]); |
233 | 246 | } else { |
234 | 247 | return null; |
235 | 248 | } |
236 | - }).filter(el => !!el) | |
249 | + }).filter(el => !!el); | |
237 | 250 | } |
238 | 251 | |
239 | 252 | pointToLatLng(x, y): L.LatLng { |
... | ... | @@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap { |
244 | 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 | 269 | if (points.length) { |
257 | - return points.map(point=> { | |
270 | + return points.map(point => { | |
258 | 271 | if (point.length) { |
259 | - return this.convertToPolygonFormat(point); | |
272 | + return this.convertToPolygonFormat(point, width, height); | |
260 | 273 | } else { |
261 | 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 | 278 | } else { |
266 | - return [] | |
279 | + return []; | |
267 | 280 | } |
268 | 281 | } |
269 | 282 | |
270 | 283 | convertPolygonToCustomFormat(expression: any[][]): object { |
271 | 284 | return { |
272 | 285 | [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) |
273 | - } | |
286 | + }; | |
274 | 287 | } |
275 | 288 | } | ... | ... |