TB-36: Map widgets: Marker color and icon based on attributes/telemetry values (#40)
This commit is contained in:
parent
be34dfa1e9
commit
d3ffde5dee
File diff suppressed because one or more lines are too long
@ -53,6 +53,7 @@
|
|||||||
"js-beautify": "^1.6.4",
|
"js-beautify": "^1.6.4",
|
||||||
"json-schema-defaults": "^0.2.0",
|
"json-schema-defaults": "^0.2.0",
|
||||||
"justgage": "^1.2.2",
|
"justgage": "^1.2.2",
|
||||||
|
"leaflet": "^1.0.3",
|
||||||
"material-ui": "^0.16.1",
|
"material-ui": "^0.16.1",
|
||||||
"material-ui-number-input": "^5.0.16",
|
"material-ui-number-input": "^5.0.16",
|
||||||
"md-color-picker": "^0.2.6",
|
"md-color-picker": "^0.2.6",
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import thinsboardLedLight from '../components/led-light.directive';
|
|||||||
import TbAnalogueLinearGauge from '../widget/lib/analogue-linear-gauge';
|
import TbAnalogueLinearGauge from '../widget/lib/analogue-linear-gauge';
|
||||||
import TbAnalogueRadialGauge from '../widget/lib/analogue-radial-gauge';
|
import TbAnalogueRadialGauge from '../widget/lib/analogue-radial-gauge';
|
||||||
import TbDigitalGauge from '../widget/lib/digital-gauge';
|
import TbDigitalGauge from '../widget/lib/digital-gauge';
|
||||||
|
import TbMapWidget from '../widget/lib/map-widget';
|
||||||
|
|
||||||
import 'oclazyload';
|
import 'oclazyload';
|
||||||
import cssjs from '../../vendor/css.js/css';
|
import cssjs from '../../vendor/css.js/css';
|
||||||
@ -44,6 +45,7 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, typ
|
|||||||
$window.TbAnalogueLinearGauge = TbAnalogueLinearGauge;
|
$window.TbAnalogueLinearGauge = TbAnalogueLinearGauge;
|
||||||
$window.TbAnalogueRadialGauge = TbAnalogueRadialGauge;
|
$window.TbAnalogueRadialGauge = TbAnalogueRadialGauge;
|
||||||
$window.TbDigitalGauge = TbDigitalGauge;
|
$window.TbDigitalGauge = TbDigitalGauge;
|
||||||
|
$window.TbMapWidget = TbMapWidget;
|
||||||
|
|
||||||
var cssParser = new cssjs();
|
var cssParser = new cssjs();
|
||||||
cssParser.testMode = false;
|
cssParser.testMode = false;
|
||||||
|
|||||||
@ -58,7 +58,7 @@ class ThingsboardImage extends React.Component {
|
|||||||
if (event) {
|
if (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
this.onValueChanged(null);
|
this.onValueChanged("");
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@ -64,8 +64,11 @@ class ThingsboardNumber extends React.Component {
|
|||||||
fieldClass += " tb-focused";
|
fieldClass += " tb-focused";
|
||||||
}
|
}
|
||||||
var value = this.state.lastSuccessfulValue;
|
var value = this.state.lastSuccessfulValue;
|
||||||
|
if (typeof value !== 'undefined') {
|
||||||
value = Number(value);
|
value = Number(value);
|
||||||
|
} else {
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<NumberInput
|
<NumberInput
|
||||||
className={fieldClass}
|
className={fieldClass}
|
||||||
|
|||||||
304
ui/src/app/widget/lib/google-map.js
Normal file
304
ui/src/app/widget/lib/google-map.js
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2016-2017 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
var gmGlobals = {
|
||||||
|
loadingGmId: null,
|
||||||
|
gmApiKeys: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class TbGoogleMap {
|
||||||
|
constructor(containerElement, defaultZoomLevel, dontFitMapBounds, minZoomLevel, gmApiKey) {
|
||||||
|
|
||||||
|
var tbMap = this;
|
||||||
|
this.defaultZoomLevel = defaultZoomLevel;
|
||||||
|
this.dontFitMapBounds = dontFitMapBounds;
|
||||||
|
this.minZoomLevel = minZoomLevel;
|
||||||
|
this.tooltips = [];
|
||||||
|
|
||||||
|
function clearGlobalId() {
|
||||||
|
if (gmGlobals.loadingGmId && gmGlobals.loadingGmId === tbMap.mapId) {
|
||||||
|
gmGlobals.loadingGmId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayError(message) {
|
||||||
|
$(containerElement).html( // eslint-disable-line angular/angularelement
|
||||||
|
"<div class='error'>"+ message + "</div>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initGoogleMap() {
|
||||||
|
|
||||||
|
tbMap.map = new google.maps.Map(containerElement, { // eslint-disable-line no-undef
|
||||||
|
scrollwheel: false,
|
||||||
|
zoom: tbMap.defaultZoomLevel || 8
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mapId = '' + Math.random().toString(36).substr(2, 9);
|
||||||
|
this.apiKey = gmApiKey || '';
|
||||||
|
|
||||||
|
window.gm_authFailure = function() { // eslint-disable-line no-undef, angular/window-service
|
||||||
|
if (gmGlobals.loadingGmId && gmGlobals.loadingGmId === tbMap.mapId) {
|
||||||
|
gmGlobals.loadingGmId = null;
|
||||||
|
gmGlobals.gmApiKeys[tbMap.apiKey].error = 'Unable to authentificate for Google Map API.</br>Please check your API key.';
|
||||||
|
displayError(gmGlobals.gmApiKeys[tbMap.apiKey].error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.initMapFunctionName = 'initGoogleMap_' + this.mapId;
|
||||||
|
|
||||||
|
window[this.initMapFunctionName] = function() { // eslint-disable-line no-undef, angular/window-service
|
||||||
|
lazyLoad.load({ type: 'js', path: 'https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerwithlabel/src/markerwithlabel.js' }).then( // eslint-disable-line no-undef
|
||||||
|
function success() {
|
||||||
|
gmGlobals.gmApiKeys[tbMap.apiKey].loaded = true;
|
||||||
|
initGoogleMap();
|
||||||
|
for (var p in gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits) {
|
||||||
|
var pendingInit = gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits[p];
|
||||||
|
pendingInit();
|
||||||
|
}
|
||||||
|
gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits = [];
|
||||||
|
},
|
||||||
|
function fail(e) {
|
||||||
|
clearGlobalId();
|
||||||
|
gmGlobals.gmApiKeys[tbMap.apiKey].error = 'Google map api load failed!</br>'+e;
|
||||||
|
displayError(gmGlobals.gmApiKeys[tbMap.apiKey].error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.apiKey && this.apiKey.length > 0) {
|
||||||
|
if (gmGlobals.gmApiKeys[this.apiKey]) {
|
||||||
|
if (gmGlobals.gmApiKeys[this.apiKey].error) {
|
||||||
|
displayError(gmGlobals.gmApiKeys[this.apiKey].error);
|
||||||
|
} else if (gmGlobals.gmApiKeys[this.apiKey].loaded) {
|
||||||
|
initGoogleMap();
|
||||||
|
} else {
|
||||||
|
gmGlobals.gmApiKeys[this.apiKey].pendingInits.push(initGoogleMap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gmGlobals.gmApiKeys[this.apiKey] = {
|
||||||
|
loaded: false,
|
||||||
|
pendingInits: []
|
||||||
|
};
|
||||||
|
var googleMapScriptRes = 'https://maps.googleapis.com/maps/api/js?key='+this.apiKey+'&callback='+this.initMapFunctionName;
|
||||||
|
|
||||||
|
gmGlobals.loadingGmId = this.mapId;
|
||||||
|
lazyLoad.load({ type: 'js', path: googleMapScriptRes }).then( // eslint-disable-line no-undef
|
||||||
|
function success() {
|
||||||
|
setTimeout(clearGlobalId, 2000); // eslint-disable-line no-undef, angular/timeout-service
|
||||||
|
},
|
||||||
|
function fail(e) {
|
||||||
|
clearGlobalId();
|
||||||
|
gmGlobals.gmApiKeys[tbMap.apiKey].error = 'Google map api load failed!</br>'+e;
|
||||||
|
displayError(gmGlobals.gmApiKeys[tbMap.apiKey].error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
displayError('No Google Map Api Key provided!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inited() {
|
||||||
|
return angular.isDefined(this.map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
updateMarkerColor(marker, color) {
|
||||||
|
var pinColor = color.substr(1);
|
||||||
|
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColor,
|
||||||
|
new google.maps.Size(21, 34),
|
||||||
|
new google.maps.Point(0,0),
|
||||||
|
new google.maps.Point(10, 34));
|
||||||
|
marker.setIcon(pinImage);
|
||||||
|
}
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
updateMarkerImage(marker, settings, image, maxSize) {
|
||||||
|
var testImage = new Image();
|
||||||
|
testImage.onload = function() {
|
||||||
|
var width;
|
||||||
|
var height;
|
||||||
|
var aspect = testImage.width / testImage.height;
|
||||||
|
if (aspect > 1) {
|
||||||
|
width = maxSize;
|
||||||
|
height = maxSize / aspect;
|
||||||
|
} else {
|
||||||
|
width = maxSize * aspect;
|
||||||
|
height = maxSize;
|
||||||
|
}
|
||||||
|
var pinImage = {
|
||||||
|
url: image,
|
||||||
|
scaledSize : new google.maps.Size(width, height)
|
||||||
|
}
|
||||||
|
marker.setIcon(pinImage);
|
||||||
|
if (settings.showLabel) {
|
||||||
|
marker.set('labelAnchor', new google.maps.Point(50, height + 20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testImage.src = image;
|
||||||
|
}
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
createMarker(location, settings) {
|
||||||
|
var height = 34;
|
||||||
|
var pinColor = settings.color.substr(1);
|
||||||
|
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColor,
|
||||||
|
new google.maps.Size(21, 34),
|
||||||
|
new google.maps.Point(0,0),
|
||||||
|
new google.maps.Point(10, 34));
|
||||||
|
var pinShadow = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_shadow",
|
||||||
|
new google.maps.Size(40, 37),
|
||||||
|
new google.maps.Point(0, 0),
|
||||||
|
new google.maps.Point(12, 35));
|
||||||
|
var marker;
|
||||||
|
if (settings.showLabel) {
|
||||||
|
marker = new MarkerWithLabel({
|
||||||
|
position: location,
|
||||||
|
map: this.map,
|
||||||
|
icon: pinImage,
|
||||||
|
shadow: pinShadow,
|
||||||
|
labelContent: '<b>'+settings.label+'</b>',
|
||||||
|
labelClass: "tb-labels",
|
||||||
|
labelAnchor: new google.maps.Point(50, height + 20)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
marker = new google.maps.Marker({
|
||||||
|
position: location,
|
||||||
|
map: this.map,
|
||||||
|
icon: pinImage,
|
||||||
|
shadow: pinShadow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.useMarkerImage) {
|
||||||
|
this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo);
|
||||||
|
|
||||||
|
return marker;
|
||||||
|
}
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
createTooltip(marker, pattern, replaceInfo) {
|
||||||
|
var popup = new google.maps.InfoWindow({
|
||||||
|
content: ''
|
||||||
|
});
|
||||||
|
marker.addListener('click', function() {
|
||||||
|
popup.open(this.map, marker);
|
||||||
|
});
|
||||||
|
this.tooltips.push( {
|
||||||
|
popup: popup,
|
||||||
|
pattern: pattern,
|
||||||
|
replaceInfo: replaceInfo
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
updatePolylineColor(polyline, settings, color) {
|
||||||
|
var options = {
|
||||||
|
path: polyline.getPath(),
|
||||||
|
strokeColor: color,
|
||||||
|
strokeOpacity: settings.strokeOpacity,
|
||||||
|
strokeWeight: settings.strokeWeight,
|
||||||
|
map: this.map
|
||||||
|
};
|
||||||
|
polyline.setOptions(options);
|
||||||
|
}
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
createPolyline(locations, settings) {
|
||||||
|
var polyline = new google.maps.Polyline({
|
||||||
|
path: locations,
|
||||||
|
strokeColor: settings.color,
|
||||||
|
strokeOpacity: settings.strokeOpacity,
|
||||||
|
strokeWeight: settings.strokeWeight,
|
||||||
|
map: this.map
|
||||||
|
});
|
||||||
|
|
||||||
|
return polyline;
|
||||||
|
}
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
fitBounds(bounds) {
|
||||||
|
var tbMap = this;
|
||||||
|
google.maps.event.addListenerOnce(this.map, 'bounds_changed', function() { // eslint-disable-line no-undef
|
||||||
|
var newZoomLevel = tbMap.map.getZoom();
|
||||||
|
if (tbMap.dontFitMapBounds && tbMap.defaultZoomLevel) {
|
||||||
|
newZoomLevel = tbMap.defaultZoomLevel;
|
||||||
|
}
|
||||||
|
tbMap.map.setZoom(newZoomLevel);
|
||||||
|
|
||||||
|
if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
|
||||||
|
tbMap.map.setZoom(tbMap.minZoomLevel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.map.fitBounds(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
createLatLng(lat, lng) {
|
||||||
|
return new google.maps.LatLng(lat, lng); // eslint-disable-line no-undef
|
||||||
|
}
|
||||||
|
|
||||||
|
getMarkerPosition(marker) {
|
||||||
|
return marker.getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
setMarkerPosition(marker, latLng) {
|
||||||
|
marker.setPosition(latLng);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPolylineLatLngs(polyline) {
|
||||||
|
return polyline.getPath().getArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
setPolylineLatLngs(polyline, latLngs) {
|
||||||
|
polyline.setPath(latLngs);
|
||||||
|
}
|
||||||
|
|
||||||
|
createBounds() {
|
||||||
|
return new google.maps.LatLngBounds(); // eslint-disable-line no-undef
|
||||||
|
}
|
||||||
|
|
||||||
|
extendBounds(bounds, polyline) {
|
||||||
|
if (polyline && polyline.getPath()) {
|
||||||
|
var locations = polyline.getPath();
|
||||||
|
for (var i = 0; i < locations.getLength(); i++) {
|
||||||
|
bounds.extend(locations.getAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidateSize() {
|
||||||
|
google.maps.event.trigger(this.map, "resize"); // eslint-disable-line no-undef
|
||||||
|
}
|
||||||
|
|
||||||
|
getTooltips() {
|
||||||
|
return this.tooltips;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
458
ui/src/app/widget/lib/map-widget.js
Normal file
458
ui/src/app/widget/lib/map-widget.js
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2016-2017 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import tinycolor from 'tinycolor2';
|
||||||
|
|
||||||
|
import TbGoogleMap from './google-map';
|
||||||
|
import TbOpenStreetMap from './openstreet-map';
|
||||||
|
|
||||||
|
export default class TbMapWidget {
|
||||||
|
constructor(mapProvider, drawRoutes, containerElement, settings, datasources) {
|
||||||
|
|
||||||
|
var tbMap = this;
|
||||||
|
|
||||||
|
this.drawRoutes = drawRoutes;
|
||||||
|
this.markers = [];
|
||||||
|
if (this.drawRoutes) {
|
||||||
|
this.polylines = [];
|
||||||
|
}
|
||||||
|
this.locationsSettings = [];
|
||||||
|
this.varsRegex = /\$\{([^\}]*)\}/g;
|
||||||
|
|
||||||
|
if (settings.defaultZoomLevel) {
|
||||||
|
if (settings.defaultZoomLevel > 0 && settings.defaultZoomLevel < 21) {
|
||||||
|
this.defaultZoomLevel = Math.floor(settings.defaultZoomLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dontFitMapBounds = settings.fitMapBounds === false;
|
||||||
|
|
||||||
|
function procesTooltipPattern(pattern) {
|
||||||
|
var match = tbMap.varsRegex.exec(pattern);
|
||||||
|
var replaceInfo = {};
|
||||||
|
replaceInfo.variables = [];
|
||||||
|
while (match !== null) {
|
||||||
|
var variableInfo = {};
|
||||||
|
variableInfo.dataKeyIndex = -1;
|
||||||
|
var variable = match[0];
|
||||||
|
var label = match[1];
|
||||||
|
var valDec = 2;
|
||||||
|
var splitVals = label.split(':');
|
||||||
|
if (splitVals.length > 1) {
|
||||||
|
label = splitVals[0];
|
||||||
|
valDec = parseFloat(splitVals[1]);
|
||||||
|
}
|
||||||
|
variableInfo.variable = variable;
|
||||||
|
variableInfo.valDec = valDec;
|
||||||
|
|
||||||
|
if (label.startsWith('#')) {
|
||||||
|
var keyIndexStr = label.substring(1);
|
||||||
|
var n = Math.floor(Number(keyIndexStr));
|
||||||
|
if (String(n) === keyIndexStr && n >= 0) {
|
||||||
|
variableInfo.dataKeyIndex = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (variableInfo.dataKeyIndex === -1) {
|
||||||
|
var offset = 0;
|
||||||
|
for (var i=0;i<datasources.length;i++) {
|
||||||
|
var datasource = datasources[i];
|
||||||
|
for (var k = 0; k < datasource.dataKeys.length; k++) {
|
||||||
|
var dataKey = datasource.dataKeys[k];
|
||||||
|
if (dataKey.label === label) {
|
||||||
|
variableInfo.dataKeyIndex = offset + k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += datasource.dataKeys.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
replaceInfo.variables.push(variableInfo);
|
||||||
|
match = tbMap.varsRegex.exec(pattern);
|
||||||
|
}
|
||||||
|
return replaceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
var configuredLocationsSettings = drawRoutes ? settings.routesSettings : settings.markersSettings;
|
||||||
|
if (!configuredLocationsSettings) {
|
||||||
|
configuredLocationsSettings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0;i<configuredLocationsSettings.length;i++) {
|
||||||
|
this.locationsSettings[i] = {
|
||||||
|
latKeyName: "lat",
|
||||||
|
lngKeyName: "lng",
|
||||||
|
showLabel: true,
|
||||||
|
label: "",
|
||||||
|
color: "#FE7569",
|
||||||
|
useColorFunction: false,
|
||||||
|
colorFunction: null,
|
||||||
|
markerImage: null,
|
||||||
|
markerImageSize: 34,
|
||||||
|
useMarkerImage: false,
|
||||||
|
useMarkerImageFunction: false,
|
||||||
|
markerImageFunction: null,
|
||||||
|
markerImages: [],
|
||||||
|
tooltipPattern: "<b>Latitude:</b> ${lat:7}<br/><b>Longitude:</b> ${lng:7}"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (drawRoutes) {
|
||||||
|
this.locationsSettings[i].strokeWeight = 2;
|
||||||
|
this.locationsSettings[i].strokeOpacity = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuredLocationsSettings[i]) {
|
||||||
|
this.locationsSettings[i].latKeyName = configuredLocationsSettings[i].latKeyName || this.locationsSettings[i].latKeyName;
|
||||||
|
this.locationsSettings[i].lngKeyName = configuredLocationsSettings[i].lngKeyName || this.locationsSettings[i].lngKeyName;
|
||||||
|
|
||||||
|
this.locationsSettings[i].tooltipPattern = configuredLocationsSettings[i].tooltipPattern || "<b>Latitude:</b> ${"+this.locationsSettings[i].latKeyName+":7}<br/><b>Longitude:</b> ${"+this.locationsSettings[i].lngKeyName+":7}";
|
||||||
|
|
||||||
|
this.locationsSettings[i].tooltipReplaceInfo = procesTooltipPattern(this.locationsSettings[i].tooltipPattern);
|
||||||
|
|
||||||
|
this.locationsSettings[i].showLabel = configuredLocationsSettings[i].showLabel !== false;
|
||||||
|
this.locationsSettings[i].label = configuredLocationsSettings[i].label || this.locationsSettings[i].label;
|
||||||
|
this.locationsSettings[i].color = configuredLocationsSettings[i].color ? tinycolor(configuredLocationsSettings[i].color).toHexString() : this.locationsSettings[i].color;
|
||||||
|
|
||||||
|
this.locationsSettings[i].useColorFunction = configuredLocationsSettings[i].useColorFunction === true;
|
||||||
|
if (angular.isDefined(configuredLocationsSettings[i].colorFunction) && configuredLocationsSettings[i].colorFunction.length > 0) {
|
||||||
|
try {
|
||||||
|
this.locationsSettings[i].colorFunction = new Function('data', configuredLocationsSettings[i].colorFunction);
|
||||||
|
} catch (e) {
|
||||||
|
this.locationsSettings[i].colorFunction = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.locationsSettings[i].useMarkerImageFunction = configuredLocationsSettings[i].useMarkerImageFunction === true;
|
||||||
|
if (angular.isDefined(configuredLocationsSettings[i].markerImageFunction) && configuredLocationsSettings[i].markerImageFunction.length > 0) {
|
||||||
|
try {
|
||||||
|
this.locationsSettings[i].markerImageFunction = new Function('data, images', configuredLocationsSettings[i].markerImageFunction);
|
||||||
|
} catch (e) {
|
||||||
|
this.locationsSettings[i].markerImageFunction = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.locationsSettings[i].markerImages = configuredLocationsSettings[i].markerImages || [];
|
||||||
|
|
||||||
|
if (!this.locationsSettings[i].useMarkerImageFunction &&
|
||||||
|
angular.isDefined(configuredLocationsSettings[i].markerImage) &&
|
||||||
|
configuredLocationsSettings[i].markerImage.length > 0) {
|
||||||
|
this.locationsSettings[i].markerImage = configuredLocationsSettings[i].markerImage;
|
||||||
|
this.locationsSettings[i].useMarkerImage = true;
|
||||||
|
this.locationsSettings[i].markerImageSize = configuredLocationsSettings[i].markerImageSize || 34;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawRoutes) {
|
||||||
|
this.locationsSettings[i].strokeWeight = configuredLocationsSettings[i].strokeWeight || this.locationsSettings[i].strokeWeight;
|
||||||
|
this.locationsSettings[i].strokeOpacity = angular.isDefined(configuredLocationsSettings[i].strokeOpacity) ? configuredLocationsSettings[i].strokeOpacity : this.locationsSettings[i].strokeOpacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var minZoomLevel = this.drawRoutes ? 18 : 15;
|
||||||
|
if (mapProvider === 'google-map') {
|
||||||
|
this.map = new TbGoogleMap(containerElement, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.gmApiKey);
|
||||||
|
} else if (mapProvider === 'openstreet-map') {
|
||||||
|
this.map = new TbOpenStreetMap(containerElement, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw(data, sizeChanged) {
|
||||||
|
|
||||||
|
var tbMap = this;
|
||||||
|
|
||||||
|
function isNumber(n) {
|
||||||
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
function padValue(val, dec, int) {
|
||||||
|
var i = 0;
|
||||||
|
var s, strVal, n;
|
||||||
|
|
||||||
|
val = parseFloat(val);
|
||||||
|
n = (val < 0);
|
||||||
|
val = Math.abs(val);
|
||||||
|
|
||||||
|
if (dec > 0) {
|
||||||
|
strVal = val.toFixed(dec).toString().split('.');
|
||||||
|
s = int - strVal[0].length;
|
||||||
|
|
||||||
|
for (; i < s; ++i) {
|
||||||
|
strVal[0] = '0' + strVal[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
strVal = (n ? '-' : '') + strVal[0] + '.' + strVal[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
strVal = Math.round(val).toString();
|
||||||
|
s = int - strVal.length;
|
||||||
|
|
||||||
|
for (; i < s; ++i) {
|
||||||
|
strVal = '0' + strVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
strVal = (n ? '-' : '') + strVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
function arraysEqual(a, b) {
|
||||||
|
if (a === b) return true;
|
||||||
|
if (a === null || b === null) return false;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < a.length; ++i) {
|
||||||
|
if (!a[i].equals(b[i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateLocationColor(settings, dataMap) {
|
||||||
|
if (settings.useColorFunction && settings.colorFunction) {
|
||||||
|
var color = '#FE7569';
|
||||||
|
try {
|
||||||
|
color = settings.colorFunction(dataMap);
|
||||||
|
} catch (e) {
|
||||||
|
color = '#FE7569';
|
||||||
|
}
|
||||||
|
return tinycolor(color).toHexString();
|
||||||
|
} else {
|
||||||
|
return settings.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLocationColor(location, dataMap) {
|
||||||
|
var color = calculateLocationColor(location.settings, dataMap);
|
||||||
|
if (!location.settings.calculatedColor || location.settings.calculatedColor !== color) {
|
||||||
|
if (!location.settings.useMarkerImage && !location.settings.useMarkerImageFunction) {
|
||||||
|
tbMap.map.updateMarkerColor(location.marker, color);
|
||||||
|
}
|
||||||
|
if (location.polyline) {
|
||||||
|
tbMap.map.updatePolylineColor(location.polyline, location.settings, color);
|
||||||
|
}
|
||||||
|
location.settings.calculatedColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateLocationMarkerImage(settings, dataMap) {
|
||||||
|
if (settings.useMarkerImageFunction && settings.markerImageFunction) {
|
||||||
|
var image = null;
|
||||||
|
try {
|
||||||
|
image = settings.markerImageFunction(dataMap, settings.markerImages);
|
||||||
|
} catch (e) {
|
||||||
|
image = null;
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLocationMarkerImage(location, dataMap) {
|
||||||
|
var image = calculateLocationMarkerImage(location.settings, dataMap);
|
||||||
|
if (image != null && (!location.settings.calculatedImage || !angular.equals(location.settings.calculatedImage, image))) {
|
||||||
|
tbMap.map.updateMarkerImage(location.marker, location.settings, image.url, image.size);
|
||||||
|
location.settings.calculatedImage = image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLocationStyle(location, dataMap) {
|
||||||
|
updateLocationColor(location, dataMap);
|
||||||
|
updateLocationMarkerImage(location, dataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLocation(location, data, dataMap) {
|
||||||
|
var locationChanged = false;
|
||||||
|
if (location.latIndex > -1 && location.lngIndex > -1) {
|
||||||
|
var latData = data[location.latIndex].data;
|
||||||
|
var lngData = data[location.lngIndex].data;
|
||||||
|
var lat, lng, latLng;
|
||||||
|
if (latData.length > 0 && lngData.length > 0) {
|
||||||
|
if (tbMap.drawRoutes) {
|
||||||
|
// Create or update route
|
||||||
|
var latLngs = [];
|
||||||
|
for (var i = 0; i < latData.length; i++) {
|
||||||
|
lat = latData[i][1];
|
||||||
|
lng = lngData[i][1];
|
||||||
|
latLng = tbMap.map.createLatLng(lat, lng);
|
||||||
|
if (i == 0 || !latLngs[latLngs.length-1].equals(latLng)) {
|
||||||
|
latLngs.push(latLng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latLngs.length > 0) {
|
||||||
|
var markerLocation = latLngs[latLngs.length-1];
|
||||||
|
if (!location.marker) {
|
||||||
|
location.marker = tbMap.map.createMarker(markerLocation, location.settings);
|
||||||
|
} else {
|
||||||
|
tbMap.map.setMarkerPosition(location.marker, markerLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!location.polyline) {
|
||||||
|
location.polyline = tbMap.map.createPolyline(latLngs, location.settings);
|
||||||
|
tbMap.polylines.push(location.polyline);
|
||||||
|
locationChanged = true;
|
||||||
|
} else {
|
||||||
|
var prevPath = tbMap.map.getPolylineLatLngs(location.polyline);
|
||||||
|
if (!prevPath || !arraysEqual(prevPath, latLngs)) {
|
||||||
|
tbMap.map.setPolylineLatLngs(location.polyline, latLngs);
|
||||||
|
locationChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create or update marker
|
||||||
|
lat = latData[latData.length-1][1];
|
||||||
|
lng = lngData[lngData.length-1][1];
|
||||||
|
latLng = tbMap.map.createLatLng(lat, lng);
|
||||||
|
if (!location.marker) {
|
||||||
|
location.marker = tbMap.map.createMarker(latLng, location.settings);
|
||||||
|
tbMap.markers.push(location.marker);
|
||||||
|
locationChanged = true;
|
||||||
|
} else {
|
||||||
|
var prevPosition = tbMap.map.getMarkerPosition(location.marker);
|
||||||
|
if (!prevPosition.equals(latLng)) {
|
||||||
|
tbMap.map.setMarkerPosition(location.marker, latLng);
|
||||||
|
locationChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateLocationStyle(location, dataMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toLabelValueMap(data) {
|
||||||
|
var dataMap = {};
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
var dataKey = data[i].dataKey;
|
||||||
|
var label = dataKey.label;
|
||||||
|
var keyData = data[i].data;
|
||||||
|
var val = null;
|
||||||
|
if (keyData.length > 0) {
|
||||||
|
val = keyData[keyData.length-1][1];
|
||||||
|
}
|
||||||
|
dataMap[label] = val;
|
||||||
|
}
|
||||||
|
return dataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadLocations(data) {
|
||||||
|
var bounds = tbMap.map.createBounds();
|
||||||
|
tbMap.locations = [];
|
||||||
|
var dataMap = toLabelValueMap(data);
|
||||||
|
for (var l in tbMap.locationsSettings) {
|
||||||
|
var locationSettings = tbMap.locationsSettings[l];
|
||||||
|
var latIndex = -1;
|
||||||
|
var lngIndex = -1;
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
var dataKey = data[i].dataKey;
|
||||||
|
if (dataKey.label === locationSettings.latKeyName) {
|
||||||
|
latIndex = i;
|
||||||
|
} else if (dataKey.label === locationSettings.lngKeyName) {
|
||||||
|
lngIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latIndex > -1 && lngIndex > -1) {
|
||||||
|
var location = {
|
||||||
|
latIndex: latIndex,
|
||||||
|
lngIndex: lngIndex,
|
||||||
|
settings: locationSettings
|
||||||
|
};
|
||||||
|
tbMap.locations.push(location);
|
||||||
|
updateLocation(location, data, dataMap);
|
||||||
|
if (location.polyline) {
|
||||||
|
tbMap.map.extendBounds(bounds, location.polyline);
|
||||||
|
} else if (location.marker) {
|
||||||
|
bounds.extend(tbMap.map.getMarkerPosition(location.marker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tbMap.map.fitBounds(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLocations(data) {
|
||||||
|
var locationsChanged = false;
|
||||||
|
var bounds = tbMap.map.createBounds();
|
||||||
|
var dataMap = toLabelValueMap(data);
|
||||||
|
for (var p in tbMap.locations) {
|
||||||
|
var location = tbMap.locations[p];
|
||||||
|
locationsChanged |= updateLocation(location, data, dataMap);
|
||||||
|
if (location.polyline) {
|
||||||
|
tbMap.map.extendBounds(bounds, location.polyline);
|
||||||
|
} else if (location.marker) {
|
||||||
|
bounds.extend(tbMap.map.getMarkerPosition(location.marker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tbMap.dontFitMapBounds && locationsChanged) {
|
||||||
|
tbMap.map.fitBounds(bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.map && this.map.inited()) {
|
||||||
|
if (data) {
|
||||||
|
if (!this.locations) {
|
||||||
|
loadLocations(data);
|
||||||
|
} else {
|
||||||
|
updateLocations(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sizeChanged) {
|
||||||
|
this.map.invalidateSize();
|
||||||
|
if (!this.dontFitMapBounds) {
|
||||||
|
var bounds = this.map.createBounds();
|
||||||
|
for (var m in this.markers) {
|
||||||
|
bounds.extend(this.map.getMarkerPosition(this.markers[m]));
|
||||||
|
}
|
||||||
|
if (this.polylines) {
|
||||||
|
for (var p in this.polylines) {
|
||||||
|
this.map.extendBounds(bounds, this.polylines[p]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.map.fitBounds(bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tooltips = this.map.getTooltips();
|
||||||
|
|
||||||
|
for (var t in tooltips) {
|
||||||
|
var tooltip = tooltips[t];
|
||||||
|
var text = tooltip.pattern;
|
||||||
|
var replaceInfo = tooltip.replaceInfo;
|
||||||
|
for (var v in replaceInfo.variables) {
|
||||||
|
var variableInfo = replaceInfo.variables[v];
|
||||||
|
var txtVal = '';
|
||||||
|
if (variableInfo.dataKeyIndex > -1) {
|
||||||
|
var varData = data[variableInfo.dataKeyIndex].data;
|
||||||
|
if (varData.length > 0) {
|
||||||
|
var val = varData[varData.length-1][1];
|
||||||
|
if (isNumber(val)) {
|
||||||
|
txtVal = padValue(val, variableInfo.valDec, 0);
|
||||||
|
} else {
|
||||||
|
txtVal = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text = text.split(variableInfo.variable).join(txtVal);
|
||||||
|
}
|
||||||
|
tooltip.popup.setContent(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
198
ui/src/app/widget/lib/openstreet-map.js
Normal file
198
ui/src/app/widget/lib/openstreet-map.js
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2016-2017 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'leaflet/dist/leaflet.css';
|
||||||
|
import L from 'leaflet/dist/leaflet';
|
||||||
|
|
||||||
|
export default class TbOpenStreetMap {
|
||||||
|
|
||||||
|
constructor(containerElement, defaultZoomLevel, dontFitMapBounds, minZoomLevel) {
|
||||||
|
|
||||||
|
this.defaultZoomLevel = defaultZoomLevel;
|
||||||
|
this.dontFitMapBounds = dontFitMapBounds;
|
||||||
|
this.minZoomLevel = minZoomLevel;
|
||||||
|
this.tooltips = [];
|
||||||
|
|
||||||
|
this.map = L.map(containerElement).setView([0, 0], this.defaultZoomLevel || 8);
|
||||||
|
|
||||||
|
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||||
|
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||||
|
}).addTo(this.map);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inited() {
|
||||||
|
return angular.isDefined(this.map);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMarkerColor(marker, color) {
|
||||||
|
var pinColor = color.substr(1);
|
||||||
|
var icon = L.icon({
|
||||||
|
iconUrl: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,
|
||||||
|
iconSize: [21, 34],
|
||||||
|
iconAnchor: [10, 34],
|
||||||
|
popupAnchor: [0, -34],
|
||||||
|
shadowUrl: 'http://chart.apis.google.com/chart?chst=d_map_pin_shadow',
|
||||||
|
shadowSize: [40, 37],
|
||||||
|
shadowAnchor: [12, 35]
|
||||||
|
});
|
||||||
|
marker.setIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMarkerImage(marker, settings, image, maxSize) {
|
||||||
|
var testImage = new Image(); // eslint-disable-line no-undef
|
||||||
|
testImage.onload = function() {
|
||||||
|
var width;
|
||||||
|
var height;
|
||||||
|
var aspect = testImage.width / testImage.height;
|
||||||
|
if (aspect > 1) {
|
||||||
|
width = maxSize;
|
||||||
|
height = maxSize / aspect;
|
||||||
|
} else {
|
||||||
|
width = maxSize * aspect;
|
||||||
|
height = maxSize;
|
||||||
|
}
|
||||||
|
var icon = L.icon({
|
||||||
|
iconUrl: image,
|
||||||
|
iconSize: [width, height],
|
||||||
|
iconAnchor: [width/2, height],
|
||||||
|
popupAnchor: [0, -height]
|
||||||
|
});
|
||||||
|
marker.setIcon(icon);
|
||||||
|
if (settings.showLabel) {
|
||||||
|
marker.unbindTooltip();
|
||||||
|
marker.bindTooltip('<b>' + settings.label + '</b>',
|
||||||
|
{ className: 'tb-marker-label', permanent: true, direction: 'top', offset: [0, -height + 10] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testImage.src = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
createMarker(location, settings) {
|
||||||
|
var height = 34;
|
||||||
|
var pinColor = settings.color.substr(1);
|
||||||
|
var icon = L.icon({
|
||||||
|
iconUrl: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,
|
||||||
|
iconSize: [21, 34],
|
||||||
|
iconAnchor: [10, 34],
|
||||||
|
popupAnchor: [0, -34],
|
||||||
|
shadowUrl: 'http://chart.apis.google.com/chart?chst=d_map_pin_shadow',
|
||||||
|
shadowSize: [40, 37],
|
||||||
|
shadowAnchor: [12, 35]
|
||||||
|
});
|
||||||
|
|
||||||
|
var marker = L.marker(location, {icon: icon}).addTo(this.map);
|
||||||
|
|
||||||
|
if (settings.showLabel) {
|
||||||
|
marker.bindTooltip('<b>' + settings.label + '</b>',
|
||||||
|
{ className: 'tb-marker-label', permanent: true, direction: 'top', offset: [0, -height + 10] });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.useMarkerImage) {
|
||||||
|
this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo);
|
||||||
|
|
||||||
|
return marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
createTooltip(marker, pattern, replaceInfo) {
|
||||||
|
var popup = L.popup();
|
||||||
|
popup.setContent('');
|
||||||
|
marker.bindPopup(popup, {autoClose: false, closeOnClick: false});
|
||||||
|
this.tooltips.push( {
|
||||||
|
popup: popup,
|
||||||
|
pattern: pattern,
|
||||||
|
replaceInfo: replaceInfo
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePolylineColor(polyline, settings, color) {
|
||||||
|
var style = {
|
||||||
|
color: color,
|
||||||
|
opacity: settings.strokeOpacity,
|
||||||
|
weight: settings.strokeWeight
|
||||||
|
};
|
||||||
|
polyline.setStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
createPolyline(locations, settings) {
|
||||||
|
var polyline = L.polyline(locations,
|
||||||
|
{
|
||||||
|
color: settings.color,
|
||||||
|
opacity: settings.strokeOpacity,
|
||||||
|
weight: settings.strokeWeight
|
||||||
|
}
|
||||||
|
).addTo(this.map);
|
||||||
|
return polyline;
|
||||||
|
}
|
||||||
|
|
||||||
|
fitBounds(bounds) {
|
||||||
|
var tbMap = this;
|
||||||
|
this.map.once('zoomend', function() {
|
||||||
|
var newZoomLevel = tbMap.map.getZoom();
|
||||||
|
if (tbMap.dontFitMapBounds && tbMap.defaultZoomLevel) {
|
||||||
|
newZoomLevel = tbMap.defaultZoomLevel;
|
||||||
|
}
|
||||||
|
tbMap.map.setZoom(newZoomLevel, {animate: false});
|
||||||
|
|
||||||
|
if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
|
||||||
|
tbMap.map.setZoom(tbMap.minZoomLevel, {animate: false});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.map.fitBounds(bounds, {padding: [50, 50], animate: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
createLatLng(lat, lng) {
|
||||||
|
return L.latLng(lat, lng);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMarkerPosition(marker) {
|
||||||
|
return marker.getLatLng();
|
||||||
|
}
|
||||||
|
|
||||||
|
setMarkerPosition(marker, latLng) {
|
||||||
|
marker.setLatLng(latLng);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPolylineLatLngs(polyline) {
|
||||||
|
return polyline.getLatLngs();
|
||||||
|
}
|
||||||
|
|
||||||
|
setPolylineLatLngs(polyline, latLngs) {
|
||||||
|
polyline.setLatLngs(latLngs);
|
||||||
|
}
|
||||||
|
|
||||||
|
createBounds() {
|
||||||
|
return L.latLngBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
extendBounds(bounds, polyline) {
|
||||||
|
if (polyline && polyline.getLatLngs()) {
|
||||||
|
bounds.extend(polyline.getBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidateSize() {
|
||||||
|
this.map.invalidateSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTooltips() {
|
||||||
|
return this.tooltips;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user