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,6 +30,7 @@ import { Datasource, DatasourceData } from '@shared/models/widget.models'; | ||
30 | import _ from 'lodash'; | 30 | import _ from 'lodash'; |
31 | import { mapProviderSchema, providerSets } from '@home/components/widget/lib/maps/schemes'; | 31 | import { mapProviderSchema, providerSets } from '@home/components/widget/lib/maps/schemes'; |
32 | import { addCondition, mergeSchemes } from '@core/schema-utils'; | 32 | import { addCondition, mergeSchemes } from '@core/schema-utils'; |
33 | +import L, {Projection} from "leaflet"; | ||
33 | 34 | ||
34 | export function getProviderSchema(mapProvider: MapProviders, ignoreImageMap = false) { | 35 | export function getProviderSchema(mapProvider: MapProviders, ignoreImageMap = false) { |
35 | const providerSchema = _.cloneDeep(mapProviderSchema); | 36 | const providerSchema = _.cloneDeep(mapProviderSchema); |
@@ -443,3 +444,21 @@ export function createLoadingDiv(loadingText: string): JQuery<HTMLElement> { | @@ -443,3 +444,21 @@ export function createLoadingDiv(loadingText: string): JQuery<HTMLElement> { | ||
443 | </div> | 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,12 +16,12 @@ | ||
16 | 16 | ||
17 | import L, { | 17 | import L, { |
18 | FeatureGroup, | 18 | FeatureGroup, |
19 | - Icon, | 19 | + Icon, LatLng, |
20 | LatLngBounds, | 20 | LatLngBounds, |
21 | LatLngTuple, | 21 | LatLngTuple, |
22 | markerClusterGroup, | 22 | markerClusterGroup, |
23 | MarkerClusterGroup, | 23 | MarkerClusterGroup, |
24 | - MarkerClusterGroupOptions | 24 | + MarkerClusterGroupOptions, Projection |
25 | } from 'leaflet'; | 25 | } from 'leaflet'; |
26 | import tinycolor from 'tinycolor2'; | 26 | import tinycolor from 'tinycolor2'; |
27 | import 'leaflet-providers'; | 27 | import 'leaflet-providers'; |
@@ -46,6 +46,7 @@ import { | @@ -46,6 +46,7 @@ import { | ||
46 | createTooltip, | 46 | createTooltip, |
47 | } from '@home/components/widget/lib/maps/maps-utils'; | 47 | } from '@home/components/widget/lib/maps/maps-utils'; |
48 | import { | 48 | import { |
49 | + checkLngLat, | ||
49 | createLoadingDiv, | 50 | createLoadingDiv, |
50 | parseArray, | 51 | parseArray, |
51 | parseData, | 52 | parseData, |
@@ -79,6 +80,8 @@ export default abstract class LeafletMap { | @@ -79,6 +80,8 @@ export default abstract class LeafletMap { | ||
79 | updatePending = false; | 80 | updatePending = false; |
80 | addMarkers: L.Marker[] = []; | 81 | addMarkers: L.Marker[] = []; |
81 | addPolygons: L.Polygon[] = []; | 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 | protected constructor(public ctx: WidgetContext, | 86 | protected constructor(public ctx: WidgetContext, |
84 | public $container: HTMLElement, | 87 | public $container: HTMLElement, |
@@ -206,21 +209,30 @@ export default abstract class LeafletMap { | @@ -206,21 +209,30 @@ export default abstract class LeafletMap { | ||
206 | 209 | ||
207 | addPolygonControl() { | 210 | addPolygonControl() { |
208 | if (this.options.showPolygon && this.options.editablePolygon) { | 211 | if (this.options.showPolygon && this.options.editablePolygon) { |
209 | - let mousePositionOnMap: L.LatLng[]; | 212 | + let polygonPoints: L.LatLng[]; |
210 | let addPolygon: L.Control; | 213 | let addPolygon: L.Control; |
214 | + let mousePositionOnMap: LatLng; | ||
211 | this.map.on('mousemove', (e: L.LeafletMouseEvent) => { | 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 | const dragListener = (e: L.DragEndEvent) => { | 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 | this.addPolygons.push(newPolygon); | 233 | this.addPolygons.push(newPolygon); |
222 | const datasourcesList = document.createElement('div'); | 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 | const header = document.createElement('p'); | 236 | const header = document.createElement('p'); |
225 | header.appendChild(document.createTextNode('Select entity:')); | 237 | header.appendChild(document.createTextNode('Select entity:')); |
226 | header.setAttribute('style', 'font-size: 14px; margin: 8px 0'); | 238 | header.setAttribute('style', 'font-size: 14px; margin: 8px 0'); |
@@ -414,12 +426,9 @@ export default abstract class LeafletMap { | @@ -414,12 +426,9 @@ export default abstract class LeafletMap { | ||
414 | }).filter(el => !!el); | 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 | return { | 432 | return { |
424 | [this.options.latKeyName]: position.lat, | 433 | [this.options.latKeyName]: position.lat, |
425 | [this.options.lngKeyName]: position.lng | 434 | [this.options.lngKeyName]: position.lng |
@@ -728,6 +737,11 @@ export default abstract class LeafletMap { | @@ -728,6 +737,11 @@ export default abstract class LeafletMap { | ||
728 | if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) { | 737 | if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) { |
729 | return; | 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 | this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe(); | 745 | this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe(); |
732 | } | 746 | } |
733 | 747 |
@@ -19,7 +19,12 @@ import LeafletMap from '../leaflet-map'; | @@ -19,7 +19,12 @@ import LeafletMap from '../leaflet-map'; | ||
19 | import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models'; | 19 | import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models'; |
20 | import { Observable, ReplaySubject } from 'rxjs'; | 20 | import { Observable, ReplaySubject } from 'rxjs'; |
21 | import { filter, map, mergeMap } from 'rxjs/operators'; | 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 | import { WidgetContext } from '@home/models/widget-component.models'; | 28 | import { WidgetContext } from '@home/models/widget-component.models'; |
24 | import { DataSet, DatasourceType, widgetType } from '@shared/models/widget.models'; | 29 | import { DataSet, DatasourceType, widgetType } from '@shared/models/widget.models'; |
25 | import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; | 30 | import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; |
@@ -132,9 +137,9 @@ export class ImageMap extends LeafletMap { | @@ -132,9 +137,9 @@ export class ImageMap extends LeafletMap { | ||
132 | updateBounds(updateImage?: boolean, lastCenterPos?) { | 137 | updateBounds(updateImage?: boolean, lastCenterPos?) { |
133 | const w = this.width; | 138 | const w = this.width; |
134 | const h = this.height; | 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 | if (updateImage && this.imageOverlay) { | 144 | if (updateImage && this.imageOverlay) { |
140 | this.imageOverlay.remove(); | 145 | this.imageOverlay.remove(); |
@@ -147,8 +152,8 @@ export class ImageMap extends LeafletMap { | @@ -147,8 +152,8 @@ export class ImageMap extends LeafletMap { | ||
147 | this.imageOverlay = L.imageOverlay(this.imageUrl, bounds).addTo(this.map); | 152 | this.imageOverlay = L.imageOverlay(this.imageUrl, bounds).addTo(this.map); |
148 | } | 153 | } |
149 | const padding = 200 * maxZoom; | 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 | const maxBounds = new L.LatLngBounds(southWest, northEast); | 157 | const maxBounds = new L.LatLngBounds(southWest, northEast); |
153 | this.map.setMaxBounds(maxBounds); | 158 | this.map.setMaxBounds(maxBounds); |
154 | if (lastCenterPos) { | 159 | if (lastCenterPos) { |
@@ -187,7 +192,7 @@ export class ImageMap extends LeafletMap { | @@ -187,7 +192,7 @@ export class ImageMap extends LeafletMap { | ||
187 | this.updateMarkers(this.markersData); | 192 | this.updateMarkers(this.markersData); |
188 | if (this.options.draggableMarker && this.addMarkers.length) { | 193 | if (this.options.draggableMarker && this.addMarkers.length) { |
189 | this.addMarkers.forEach((marker) => { | 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 | marker.setLatLng(this.convertPosition(prevPoint)); | 196 | marker.setLatLng(this.convertPosition(prevPoint)); |
192 | }); | 197 | }); |
193 | } | 198 | } |
@@ -257,11 +262,10 @@ export class ImageMap extends LeafletMap { | @@ -257,11 +262,10 @@ export class ImageMap extends LeafletMap { | ||
257 | return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1); | 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 | const point = this.latLngToPoint(position); | 266 | const point = this.latLngToPoint(position); |
262 | const customX = calculateNewPointCoordinate(point.x, width); | 267 | const customX = calculateNewPointCoordinate(point.x, width); |
263 | const customY = calculateNewPointCoordinate(point.y, height); | 268 | const customY = calculateNewPointCoordinate(point.y, height); |
264 | - | ||
265 | if (customX === 0) { | 269 | if (customX === 0) { |
266 | point.x = 0; | 270 | point.x = 0; |
267 | } else if (customX === 1) { | 271 | } else if (customX === 1) { |
@@ -273,7 +277,8 @@ export class ImageMap extends LeafletMap { | @@ -273,7 +277,8 @@ export class ImageMap extends LeafletMap { | ||
273 | } else if (customY === 1) { | 277 | } else if (customY === 1) { |
274 | point.y = height; | 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 | return { | 283 | return { |
279 | [this.options.xPosKeyName]: customX, | 284 | [this.options.xPosKeyName]: customX, |