Commit cff36668ed73b3f0b5b9eab23576c373373c49ee
Committed by
GitHub
Merge pull request #3940 from kalutkaz/fixMapPolygon
[3.2.1] Fix map polygon
Showing
3 changed files
with
65 additions
and
27 deletions
... | ... | @@ -30,6 +30,7 @@ import { Datasource, DatasourceData } from '@shared/models/widget.models'; |
30 | 30 | import _ from 'lodash'; |
31 | 31 | import { mapProviderSchema, providerSets } from '@home/components/widget/lib/maps/schemes'; |
32 | 32 | import { addCondition, mergeSchemes } from '@core/schema-utils'; |
33 | +import L, {Projection} from "leaflet"; | |
33 | 34 | |
34 | 35 | export function getProviderSchema(mapProvider: MapProviders, ignoreImageMap = false) { |
35 | 36 | const providerSchema = _.cloneDeep(mapProviderSchema); |
... | ... | @@ -443,3 +444,21 @@ export function createLoadingDiv(loadingText: string): JQuery<HTMLElement> { |
443 | 444 | </div> |
444 | 445 | `); |
445 | 446 | } |
447 | + | |
448 | +export function checkLngLat(point: L.LatLng, southWest: L.LatLng, northEast: L.LatLng, offset = 0): L.LatLng { | |
449 | + const maxLngMap = northEast.lng - offset; | |
450 | + const minLngMap = southWest.lng + offset; | |
451 | + const maxLatMap = northEast.lat - offset; | |
452 | + const minLatMap = southWest.lat + offset; | |
453 | + if (point.lng > maxLngMap) { | |
454 | + point.lng = maxLngMap; | |
455 | + } else if (point.lng < minLngMap) { | |
456 | + point.lng = minLngMap; | |
457 | + } | |
458 | + if (point.lat > maxLatMap) { | |
459 | + point.lat = maxLatMap; | |
460 | + } else if (point.lat < minLatMap) { | |
461 | + point.lat = minLatMap; | |
462 | + } | |
463 | + return point; | |
464 | +} | ... | ... |
... | ... | @@ -16,12 +16,12 @@ |
16 | 16 | |
17 | 17 | import L, { |
18 | 18 | FeatureGroup, |
19 | - Icon, | |
19 | + Icon, LatLng, | |
20 | 20 | LatLngBounds, |
21 | 21 | LatLngTuple, |
22 | 22 | markerClusterGroup, |
23 | 23 | MarkerClusterGroup, |
24 | - MarkerClusterGroupOptions | |
24 | + MarkerClusterGroupOptions, Projection | |
25 | 25 | } from 'leaflet'; |
26 | 26 | import tinycolor from 'tinycolor2'; |
27 | 27 | import 'leaflet-providers'; |
... | ... | @@ -46,6 +46,7 @@ import { |
46 | 46 | createTooltip, |
47 | 47 | } from '@home/components/widget/lib/maps/maps-utils'; |
48 | 48 | import { |
49 | + checkLngLat, | |
49 | 50 | createLoadingDiv, |
50 | 51 | parseArray, |
51 | 52 | parseData, |
... | ... | @@ -79,6 +80,8 @@ export default abstract class LeafletMap { |
79 | 80 | updatePending = false; |
80 | 81 | addMarkers: L.Marker[] = []; |
81 | 82 | addPolygons: L.Polygon[] = []; |
83 | + southWest = new L.LatLng(-Projection.SphericalMercator['MAX_LATITUDE'], -180); | |
84 | + northEast = new L.LatLng(Projection.SphericalMercator['MAX_LATITUDE'], 180); | |
82 | 85 | |
83 | 86 | protected constructor(public ctx: WidgetContext, |
84 | 87 | public $container: HTMLElement, |
... | ... | @@ -206,21 +209,30 @@ export default abstract class LeafletMap { |
206 | 209 | |
207 | 210 | addPolygonControl() { |
208 | 211 | if (this.options.showPolygon && this.options.editablePolygon) { |
209 | - let mousePositionOnMap: L.LatLng[]; | |
212 | + let polygonPoints: L.LatLng[]; | |
210 | 213 | let addPolygon: L.Control; |
214 | + let mousePositionOnMap: LatLng; | |
211 | 215 | this.map.on('mousemove', (e: L.LeafletMouseEvent) => { |
212 | - const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01; | |
213 | - const latlng1 = e.latlng; | |
214 | - const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset); | |
215 | - const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng); | |
216 | - mousePositionOnMap = [latlng1, latlng2, latlng3]; | |
216 | + mousePositionOnMap = e.latlng; | |
217 | 217 | }); |
218 | + | |
218 | 219 | const dragListener = (e: L.DragEndEvent) => { |
219 | - if (e.type === 'dragend' && mousePositionOnMap) { | |
220 | - const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map); | |
220 | + if (e.type === 'dragend') { | |
221 | + const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01; | |
222 | + | |
223 | + let convert = this.convertToCustomFormat(mousePositionOnMap,polygonOffset); | |
224 | + mousePositionOnMap.lat = convert[this.options.latKeyName]; | |
225 | + mousePositionOnMap.lng = convert[this.options.lngKeyName]; | |
226 | + | |
227 | + const latlng1 = mousePositionOnMap; | |
228 | + const latlng2 = L.latLng(mousePositionOnMap.lat, mousePositionOnMap.lng + polygonOffset); | |
229 | + const latlng3 = L.latLng(mousePositionOnMap.lat - polygonOffset, mousePositionOnMap.lng); | |
230 | + polygonPoints = [latlng1, latlng2, latlng3]; | |
231 | + | |
232 | + const newPolygon = L.polygon(polygonPoints).addTo(this.map); | |
221 | 233 | this.addPolygons.push(newPolygon); |
222 | 234 | const datasourcesList = document.createElement('div'); |
223 | - const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)}; | |
235 | + const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(polygonPoints)}; | |
224 | 236 | const header = document.createElement('p'); |
225 | 237 | header.appendChild(document.createTextNode('Select entity:')); |
226 | 238 | header.setAttribute('style', 'font-size: 14px; margin: 8px 0'); |
... | ... | @@ -414,12 +426,9 @@ export default abstract class LeafletMap { |
414 | 426 | }).filter(el => !!el); |
415 | 427 | } |
416 | 428 | |
417 | - convertToCustomFormat(position: L.LatLng): object { | |
418 | - if (position.lng > 180) { | |
419 | - position.lng = 180; | |
420 | - } else if (position.lng < -180) { | |
421 | - position.lng = -180; | |
422 | - } | |
429 | + convertToCustomFormat(position: L.LatLng, offset = 0): object { | |
430 | + position = checkLngLat(position, this.southWest, this.northEast, offset); | |
431 | + | |
423 | 432 | return { |
424 | 433 | [this.options.latKeyName]: position.lat, |
425 | 434 | [this.options.lngKeyName]: position.lng |
... | ... | @@ -728,6 +737,11 @@ export default abstract class LeafletMap { |
728 | 737 | if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) { |
729 | 738 | return; |
730 | 739 | } |
740 | + if(this.options.provider !== MapProviders.image) { | |
741 | + for (let key in e.layer._latlngs[0]) { | |
742 | + e.layer._latlngs[0][key] = checkLngLat(e.layer._latlngs[0][key], this.southWest, this.northEast); | |
743 | + } | |
744 | + } | |
731 | 745 | this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe(); |
732 | 746 | } |
733 | 747 | ... | ... |
... | ... | @@ -19,7 +19,12 @@ import LeafletMap from '../leaflet-map'; |
19 | 19 | import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models'; |
20 | 20 | import { Observable, ReplaySubject } from 'rxjs'; |
21 | 21 | import { filter, map, mergeMap } from 'rxjs/operators'; |
22 | -import { aspectCache, calculateNewPointCoordinate, parseFunction } from '@home/components/widget/lib/maps/common-maps-utils'; | |
22 | +import { | |
23 | + aspectCache, | |
24 | + calculateNewPointCoordinate, | |
25 | + checkLngLat, | |
26 | + parseFunction | |
27 | +} from '@home/components/widget/lib/maps/common-maps-utils'; | |
23 | 28 | import { WidgetContext } from '@home/models/widget-component.models'; |
24 | 29 | import { DataSet, DatasourceType, widgetType } from '@shared/models/widget.models'; |
25 | 30 | import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; |
... | ... | @@ -132,9 +137,9 @@ export class ImageMap extends LeafletMap { |
132 | 137 | updateBounds(updateImage?: boolean, lastCenterPos?) { |
133 | 138 | const w = this.width; |
134 | 139 | const h = this.height; |
135 | - let southWest = this.pointToLatLng(0, h); | |
136 | - let northEast = this.pointToLatLng(w, 0); | |
137 | - const bounds = new L.LatLngBounds(southWest, northEast); | |
140 | + this.southWest = this.pointToLatLng(0, h); | |
141 | + this.northEast = this.pointToLatLng(w, 0); | |
142 | + const bounds = new L.LatLngBounds(this.southWest, this.northEast); | |
138 | 143 | |
139 | 144 | if (updateImage && this.imageOverlay) { |
140 | 145 | this.imageOverlay.remove(); |
... | ... | @@ -147,8 +152,8 @@ export class ImageMap extends LeafletMap { |
147 | 152 | this.imageOverlay = L.imageOverlay(this.imageUrl, bounds).addTo(this.map); |
148 | 153 | } |
149 | 154 | const padding = 200 * maxZoom; |
150 | - southWest = this.pointToLatLng(-padding, h + padding); | |
151 | - northEast = this.pointToLatLng(w + padding, -padding); | |
155 | + const southWest = this.pointToLatLng(-padding, h + padding); | |
156 | + const northEast = this.pointToLatLng(w + padding, -padding); | |
152 | 157 | const maxBounds = new L.LatLngBounds(southWest, northEast); |
153 | 158 | this.map.setMaxBounds(maxBounds); |
154 | 159 | if (lastCenterPos) { |
... | ... | @@ -187,7 +192,7 @@ export class ImageMap extends LeafletMap { |
187 | 192 | this.updateMarkers(this.markersData); |
188 | 193 | if (this.options.draggableMarker && this.addMarkers.length) { |
189 | 194 | this.addMarkers.forEach((marker) => { |
190 | - const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight); | |
195 | + const prevPoint = this.convertToCustomFormat(marker.getLatLng(), null, prevWidth, prevHeight); | |
191 | 196 | marker.setLatLng(this.convertPosition(prevPoint)); |
192 | 197 | }); |
193 | 198 | } |
... | ... | @@ -257,11 +262,10 @@ export class ImageMap extends LeafletMap { |
257 | 262 | return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1); |
258 | 263 | } |
259 | 264 | |
260 | - convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object { | |
265 | + convertToCustomFormat(position: L.LatLng, offset = 0, width = this.width, height = this.height): object { | |
261 | 266 | const point = this.latLngToPoint(position); |
262 | 267 | const customX = calculateNewPointCoordinate(point.x, width); |
263 | 268 | const customY = calculateNewPointCoordinate(point.y, height); |
264 | - | |
265 | 269 | if (customX === 0) { |
266 | 270 | point.x = 0; |
267 | 271 | } else if (customX === 1) { |
... | ... | @@ -273,7 +277,8 @@ export class ImageMap extends LeafletMap { |
273 | 277 | } else if (customY === 1) { |
274 | 278 | point.y = height; |
275 | 279 | } |
276 | - const customLatLng = this.pointToLatLng(point.x, point.y); | |
280 | + | |
281 | + const customLatLng = checkLngLat(this.pointToLatLng(point.x, point.y), this.southWest, this.northEast, offset); | |
277 | 282 | |
278 | 283 | return { |
279 | 284 | [this.options.xPosKeyName]: customX, | ... | ... |