Browse Source

Merge pull request #3940 from kalutkaz/fixMapPolygon

[3.2.1] Fix map polygon
pull/3963/head
Igor Kulikov 6 years ago
committed by GitHub
parent
commit
cff36668ed
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      ui-ngx/src/app/modules/home/components/widget/lib/maps/common-maps-utils.ts
  2. 48
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  3. 25
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts

19
ui-ngx/src/app/modules/home/components/widget/lib/maps/common-maps-utils.ts

@ -30,6 +30,7 @@ import { Datasource, DatasourceData } from '@shared/models/widget.models';
import _ from 'lodash'; import _ from 'lodash';
import { mapProviderSchema, providerSets } from '@home/components/widget/lib/maps/schemes'; import { mapProviderSchema, providerSets } from '@home/components/widget/lib/maps/schemes';
import { addCondition, mergeSchemes } from '@core/schema-utils'; import { addCondition, mergeSchemes } from '@core/schema-utils';
import L, {Projection} from "leaflet";
export function getProviderSchema(mapProvider: MapProviders, ignoreImageMap = false) { export function getProviderSchema(mapProvider: MapProviders, ignoreImageMap = false) {
const providerSchema = _.cloneDeep(mapProviderSchema); const providerSchema = _.cloneDeep(mapProviderSchema);
@ -443,3 +444,21 @@ export function createLoadingDiv(loadingText: string): JQuery<HTMLElement> {
</div> </div>
`); `);
} }
export function checkLngLat(point: L.LatLng, southWest: L.LatLng, northEast: L.LatLng, offset = 0): L.LatLng {
const maxLngMap = northEast.lng - offset;
const minLngMap = southWest.lng + offset;
const maxLatMap = northEast.lat - offset;
const minLatMap = southWest.lat + offset;
if (point.lng > maxLngMap) {
point.lng = maxLngMap;
} else if (point.lng < minLngMap) {
point.lng = minLngMap;
}
if (point.lat > maxLatMap) {
point.lat = maxLatMap;
} else if (point.lat < minLatMap) {
point.lat = minLatMap;
}
return point;
}

48
ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts

@ -16,12 +16,12 @@
import L, { import L, {
FeatureGroup, FeatureGroup,
Icon, Icon, LatLng,
LatLngBounds, LatLngBounds,
LatLngTuple, LatLngTuple,
markerClusterGroup, markerClusterGroup,
MarkerClusterGroup, MarkerClusterGroup,
MarkerClusterGroupOptions MarkerClusterGroupOptions, Projection
} from 'leaflet'; } from 'leaflet';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import 'leaflet-providers'; import 'leaflet-providers';
@ -46,6 +46,7 @@ import {
createTooltip, createTooltip,
} from '@home/components/widget/lib/maps/maps-utils'; } from '@home/components/widget/lib/maps/maps-utils';
import { import {
checkLngLat,
createLoadingDiv, createLoadingDiv,
parseArray, parseArray,
parseData, parseData,
@ -79,6 +80,8 @@ export default abstract class LeafletMap {
updatePending = false; updatePending = false;
addMarkers: L.Marker[] = []; addMarkers: L.Marker[] = [];
addPolygons: L.Polygon[] = []; addPolygons: L.Polygon[] = [];
southWest = new L.LatLng(-Projection.SphericalMercator['MAX_LATITUDE'], -180);
northEast = new L.LatLng(Projection.SphericalMercator['MAX_LATITUDE'], 180);
protected constructor(public ctx: WidgetContext, protected constructor(public ctx: WidgetContext,
public $container: HTMLElement, public $container: HTMLElement,
@ -206,21 +209,30 @@ export default abstract class LeafletMap {
addPolygonControl() { addPolygonControl() {
if (this.options.showPolygon && this.options.editablePolygon) { if (this.options.showPolygon && this.options.editablePolygon) {
let mousePositionOnMap: L.LatLng[]; let polygonPoints: L.LatLng[];
let addPolygon: L.Control; let addPolygon: L.Control;
let mousePositionOnMap: LatLng;
this.map.on('mousemove', (e: L.LeafletMouseEvent) => { this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01; mousePositionOnMap = e.latlng;
const latlng1 = e.latlng;
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset);
const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng);
mousePositionOnMap = [latlng1, latlng2, latlng3];
}); });
const dragListener = (e: L.DragEndEvent) => { const dragListener = (e: L.DragEndEvent) => {
if (e.type === 'dragend' && mousePositionOnMap) { if (e.type === 'dragend') {
const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map); const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01;
let convert = this.convertToCustomFormat(mousePositionOnMap,polygonOffset);
mousePositionOnMap.lat = convert[this.options.latKeyName];
mousePositionOnMap.lng = convert[this.options.lngKeyName];
const latlng1 = mousePositionOnMap;
const latlng2 = L.latLng(mousePositionOnMap.lat, mousePositionOnMap.lng + polygonOffset);
const latlng3 = L.latLng(mousePositionOnMap.lat - polygonOffset, mousePositionOnMap.lng);
polygonPoints = [latlng1, latlng2, latlng3];
const newPolygon = L.polygon(polygonPoints).addTo(this.map);
this.addPolygons.push(newPolygon); 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(polygonPoints)};
const header = document.createElement('p'); const header = document.createElement('p');
header.appendChild(document.createTextNode('Select entity:')); header.appendChild(document.createTextNode('Select entity:'));
header.setAttribute('style', 'font-size: 14px; margin: 8px 0'); header.setAttribute('style', 'font-size: 14px; margin: 8px 0');
@ -414,12 +426,9 @@ export default abstract class LeafletMap {
}).filter(el => !!el); }).filter(el => !!el);
} }
convertToCustomFormat(position: L.LatLng): object { convertToCustomFormat(position: L.LatLng, offset = 0): object {
if (position.lng > 180) { position = checkLngLat(position, this.southWest, this.northEast, offset);
position.lng = 180;
} else if (position.lng < -180) {
position.lng = -180;
}
return { return {
[this.options.latKeyName]: position.lat, [this.options.latKeyName]: position.lat,
[this.options.lngKeyName]: position.lng [this.options.lngKeyName]: position.lng
@ -728,6 +737,11 @@ export default abstract class LeafletMap {
if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) { if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) {
return; return;
} }
if(this.options.provider !== MapProviders.image) {
for (let key in e.layer._latlngs[0]) {
e.layer._latlngs[0][key] = checkLngLat(e.layer._latlngs[0][key], this.southWest, this.northEast);
}
}
this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe(); this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe();
} }

25
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts

@ -19,7 +19,12 @@ import LeafletMap from '../leaflet-map';
import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models'; import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models';
import { Observable, ReplaySubject } from 'rxjs'; import { Observable, ReplaySubject } from 'rxjs';
import { filter, map, mergeMap } from 'rxjs/operators'; import { filter, map, mergeMap } from 'rxjs/operators';
import { aspectCache, calculateNewPointCoordinate, parseFunction } from '@home/components/widget/lib/maps/common-maps-utils'; import {
aspectCache,
calculateNewPointCoordinate,
checkLngLat,
parseFunction
} from '@home/components/widget/lib/maps/common-maps-utils';
import { WidgetContext } from '@home/models/widget-component.models'; import { WidgetContext } from '@home/models/widget-component.models';
import { DataSet, DatasourceType, widgetType } from '@shared/models/widget.models'; import { DataSet, DatasourceType, widgetType } from '@shared/models/widget.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
@ -132,9 +137,9 @@ export class ImageMap extends LeafletMap {
updateBounds(updateImage?: boolean, lastCenterPos?) { updateBounds(updateImage?: boolean, lastCenterPos?) {
const w = this.width; const w = this.width;
const h = this.height; const h = this.height;
let southWest = this.pointToLatLng(0, h); this.southWest = this.pointToLatLng(0, h);
let northEast = this.pointToLatLng(w, 0); this.northEast = this.pointToLatLng(w, 0);
const bounds = new L.LatLngBounds(southWest, northEast); const bounds = new L.LatLngBounds(this.southWest, this.northEast);
if (updateImage && this.imageOverlay) { if (updateImage && this.imageOverlay) {
this.imageOverlay.remove(); this.imageOverlay.remove();
@ -147,8 +152,8 @@ export class ImageMap extends LeafletMap {
this.imageOverlay = L.imageOverlay(this.imageUrl, bounds).addTo(this.map); this.imageOverlay = L.imageOverlay(this.imageUrl, bounds).addTo(this.map);
} }
const padding = 200 * maxZoom; const padding = 200 * maxZoom;
southWest = this.pointToLatLng(-padding, h + padding); const southWest = this.pointToLatLng(-padding, h + padding);
northEast = this.pointToLatLng(w + padding, -padding); const northEast = this.pointToLatLng(w + padding, -padding);
const maxBounds = new L.LatLngBounds(southWest, northEast); const maxBounds = new L.LatLngBounds(southWest, northEast);
this.map.setMaxBounds(maxBounds); this.map.setMaxBounds(maxBounds);
if (lastCenterPos) { if (lastCenterPos) {
@ -187,7 +192,7 @@ export class ImageMap extends LeafletMap {
this.updateMarkers(this.markersData); this.updateMarkers(this.markersData);
if (this.options.draggableMarker && this.addMarkers.length) { if (this.options.draggableMarker && this.addMarkers.length) {
this.addMarkers.forEach((marker) => { this.addMarkers.forEach((marker) => {
const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight); const prevPoint = this.convertToCustomFormat(marker.getLatLng(), null, prevWidth, prevHeight);
marker.setLatLng(this.convertPosition(prevPoint)); marker.setLatLng(this.convertPosition(prevPoint));
}); });
} }
@ -257,11 +262,10 @@ 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, width = this.width, height = this.height): object { convertToCustomFormat(position: L.LatLng, offset = 0, width = this.width, height = this.height): object {
const point = this.latLngToPoint(position); const point = this.latLngToPoint(position);
const customX = calculateNewPointCoordinate(point.x, width); const customX = calculateNewPointCoordinate(point.x, width);
const customY = calculateNewPointCoordinate(point.y, height); const customY = calculateNewPointCoordinate(point.y, height);
if (customX === 0) { if (customX === 0) {
point.x = 0; point.x = 0;
} else if (customX === 1) { } else if (customX === 1) {
@ -273,7 +277,8 @@ export class ImageMap extends LeafletMap {
} else if (customY === 1) { } else if (customY === 1) {
point.y = height; point.y = height;
} }
const customLatLng = this.pointToLatLng(point.x, point.y);
const customLatLng = checkLngLat(this.pointToLatLng(point.x, point.y), this.southWest, this.northEast, offset);
return { return {
[this.options.xPosKeyName]: customX, [this.options.xPosKeyName]: customX,

Loading…
Cancel
Save