Commit 489ea63f8820b79c4fd73cd71d8249d860e009fb

Authored by stormwrym
1 parent ca7ffd99

tencent map implementation

... ... @@ -18,6 +18,7 @@ import tinycolor from 'tinycolor2';
18 18 import TbGoogleMap from './google-map';
19 19 import TbOpenStreetMap from './openstreet-map';
20 20 import TbImageMap from './image-map';
  21 +import TbTencentMap from './tencent-map';
21 22
22 23 import {processPattern, arraysEqual, toLabelValueMap, fillPattern, fillPatternWithActions} from './widget-utils';
23 24
... ... @@ -83,6 +84,8 @@ export default class TbMapWidgetV2 {
83 84 settings.posFunction,
84 85 settings.imageEntityAlias,
85 86 settings.imageUrlAttribute);
  87 + } else if (mapProvider === 'tencent-map') {
  88 + this.map = new TbTencentMap($element,this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.tmApiKey, settings.tmDefaultMapType);
86 89 }
87 90 }
88 91
... ... @@ -466,6 +469,8 @@ export default class TbMapWidgetV2 {
466 469 schema = angular.copy(openstreetMapSettingsSchema);
467 470 } else if (mapProvider === 'image-map') {
468 471 return imageMapSettingsSchema;
  472 + } else if (mapProvider === 'tencent-map') {
  473 + schema = angular.copy(tencentMapSettingsSchema);
469 474 }
470 475 angular.merge(schema.schema.properties, commonMapSettingsSchema.schema.properties);
471 476 schema.schema.required = schema.schema.required.concat(commonMapSettingsSchema.schema.required);
... ... @@ -544,7 +549,51 @@ const googleMapSettingsSchema =
544 549 }
545 550 ]
546 551 };
547   -
  552 +
  553 +const tencentMapSettingsSchema =
  554 + {
  555 + "schema":{
  556 + "title":"Tencent Map Configuration",
  557 + "type":"object",
  558 + "properties":{
  559 + "tmApiKey":{
  560 + "title":"Tencent Maps API Key",
  561 + "type":"string"
  562 + },
  563 + "tmDefaultMapType":{
  564 + "title":"Default map type",
  565 + "type":"string",
  566 + "default":"roadmap"
  567 + }
  568 + },
  569 + "required":[
  570 + "tmApiKey"
  571 + ]
  572 + },
  573 + "form":[
  574 + "tmApiKey",
  575 + {
  576 + "key":"tmDefaultMapType",
  577 + "type":"rc-select",
  578 + "multiple":false,
  579 + "items":[
  580 + {
  581 + "value":"roadmap",
  582 + "label":"Roadmap"
  583 + },
  584 + {
  585 + "value":"satellite",
  586 + "label":"Satellite"
  587 + },
  588 + {
  589 + "value":"hybrid",
  590 + "label":"Hybrid"
  591 + },
  592 + ]
  593 + }
  594 + ]
  595 + };
  596 +
548 597 const openstreetMapSettingsSchema =
549 598 {
550 599 "schema":{
... ...
  1 +/*
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +var tmGlobals = {
  18 + loadingTmId: null,
  19 + tmApiKeys: {}
  20 +}
  21 +
  22 +export default class TbTencentMap {
  23 + constructor($containerElement,utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, tmApiKey, tmDefaultMapType) {
  24 + var tbMap = this;
  25 + this.utils = utils;
  26 + this.defaultZoomLevel = defaultZoomLevel;
  27 + this.dontFitMapBounds = dontFitMapBounds;
  28 + this.minZoomLevel = minZoomLevel;
  29 + this.tooltips = [];
  30 + this.defaultMapType = tmDefaultMapType;
  31 +
  32 + function clearGlobalId() {
  33 + if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
  34 + tmGlobals.loadingTmId = null;
  35 + }
  36 + }
  37 +
  38 + function displayError(message) {
  39 + $containerElement.html( // eslint-disable-line angular/angularelement
  40 + "<div class='error'>"+ message + "</div>"
  41 + );
  42 + }
  43 +
  44 + function initTencentMap() {
  45 + tbMap.map = new qq.maps.Map($containerElement[0], { // eslint-disable-line no-undef
  46 + scrollwheel: true,
  47 + mapTypeId: getTencentMapTypeId(tbMap.defaultMapType),
  48 + zoom: tbMap.defaultZoomLevel || 8
  49 + });
  50 +
  51 + if (initCallback) {
  52 + initCallback();
  53 + }
  54 + }
  55 +
  56 + /* eslint-disable no-undef */
  57 +
  58 + function getTencentMapTypeId(mapType) {
  59 + var mapTypeId =qq.maps.MapTypeId.ROADMAP;
  60 + if (mapType) {
  61 + if (mapType === 'hybrid') {
  62 + mapTypeId = qq.maps.MapTypeId.HYBRID;
  63 + } else if (mapType === 'satellite') {
  64 + mapTypeId = qq.maps.MapTypeId.SATELLITE;
  65 + } else if (mapType === 'terrain') {
  66 + mapTypeId = qq.maps.MapTypeId.ROADMAP;
  67 + }
  68 + }
  69 + return mapTypeId;
  70 + }
  71 +
  72 + /* eslint-enable no-undef */
  73 +
  74 + this.mapId = '' + Math.random().toString(36).substr(2, 9);
  75 + this.apiKey = tmApiKey || '84d6d83e0e51e481e50454ccbe8986b';
  76 +
  77 + window.gm_authFailure = function() { // eslint-disable-line no-undef, angular/window-service
  78 + if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
  79 + tmGlobals.loadingTmId = null;
  80 + tmGlobals.tmApiKeys[tbMap.apiKey].error = 'Unable to authentificate for tencent Map API.</br>Please check your API key.';
  81 + displayError(tmGlobals.tmApiKeys[tbMap.apiKey].error);
  82 + }
  83 + };
  84 +
  85 + this.initMapFunctionName = 'initTencentMap_' + this.mapId;
  86 +
  87 + window[this.initMapFunctionName] = function() { // eslint-disable-line no-undef, angular/window-service
  88 + initTencentMap();
  89 + };
  90 + if (this.apiKey && this.apiKey.length > 0) {
  91 + if (tmGlobals.tmApiKeys[this.apiKey]) {
  92 + if (tmGlobals.tmApiKeys[this.apiKey].error) {
  93 + displayError(tmGlobals.tmApiKeys[this.apiKey].error);
  94 + } else if (tmGlobals.tmApiKeys[this.apiKey].loaded) {
  95 + initTencentMap();
  96 + } else {
  97 + tmGlobals.tmApiKeys[this.apiKey].pendingInits.push(initTencentMap);
  98 + }
  99 + } else {
  100 + tmGlobals.tmApiKeys[this.apiKey] = {
  101 + loaded: false,
  102 + pendingInits: []
  103 + };
  104 + var tencentMapScriptRes = 'http://map.qq.com/api/js?v=2.exp&key='+this.apiKey+'&callback='+this.initMapFunctionName;
  105 +
  106 + tmGlobals.loadingTmId = this.mapId;
  107 + lazyLoad.load({ type: 'js', path: tencentMapScriptRes }).then( // eslint-disable-line no-undef
  108 + function success() {
  109 + setTimeout(clearGlobalId, 2000); // eslint-disable-line no-undef, angular/timeout-service
  110 + },
  111 + function fail(e) {
  112 + clearGlobalId();
  113 + tmGlobals.tmApiKeys[tbMap.apiKey].error = 'tencent map api load failed!</br>'+e;
  114 + displayError(tmGlobals.tmApiKeys[tbMap.apiKey].error);
  115 + }
  116 + );
  117 + }
  118 + } else {
  119 + displayError('No tencent Map Api Key provided!');
  120 + }
  121 + }
  122 +
  123 + inited() {
  124 + return angular.isDefined(this.map);
  125 + }
  126 +
  127 + /* eslint-disable no-undef,no-unused-vars*/
  128 + updateMarkerLabel(marker, settings) {
  129 +
  130 + }
  131 + /* eslint-enable no-undef,no-unused-vars */
  132 +
  133 + /* eslint-disable no-undef,no-unused-vars */
  134 + updateMarkerColor(marker, color) {
  135 + this.createDefaultMarkerIcon(marker, color, (icon) => {
  136 + marker.setIcon(icon);
  137 + });
  138 + }
  139 + /* eslint-enable no-undef,,no-unused-vars */
  140 +
  141 + /* eslint-disable no-undef */
  142 + updateMarkerIcon(marker, settings) {
  143 + this.createMarkerIcon(marker, settings, (icon) => {
  144 + marker.setIcon(icon);
  145 + });
  146 + }
  147 + /* eslint-disable no-undef */
  148 +
  149 + /* eslint-disable no-undef */
  150 + createMarkerIcon(marker, settings, onMarkerIconReady) {
  151 + var currentImage = settings.currentImage;
  152 + var gMap = this;
  153 + if (currentImage && currentImage.url) {
  154 + this.utils.loadImageAspect(currentImage.url).then(
  155 + (aspect) => {
  156 + if (aspect) {
  157 + var width;
  158 + var height;
  159 + if (aspect > 1) {
  160 + width = currentImage.size;
  161 + height = currentImage.size / aspect;
  162 + } else {
  163 + width = currentImage.size * aspect;
  164 + height = currentImage.size;
  165 + }
  166 +
  167 + var icon = new qq.maps.MarkerImage(currentImage.url,
  168 + qq.maps.Size(width, height),
  169 + new qq.maps.Point(0,0),
  170 + new qq.maps.Point(10, 37));
  171 +
  172 + onMarkerIconReady(icon);
  173 + } else {
  174 + gMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
  175 + }
  176 + }
  177 + );
  178 + } else {
  179 + this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
  180 + }
  181 + }
  182 + /* eslint-enable no-undef */
  183 +
  184 + /* eslint-disable no-undef */
  185 + createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
  186 + /* var pinColor = color.substr(1);*/
  187 + var icon = new qq.maps.MarkerImage("http://api.map.qq.com/doc/img/nilt.png",
  188 + new qq.maps.Size(40, 37),
  189 + new qq.maps.Point(0,0),
  190 + new qq.maps.Point(10, 37));
  191 +
  192 + onMarkerIconReady(icon);
  193 + }
  194 + /* eslint-enable no-undef */
  195 +
  196 + /* eslint-disable no-undef */
  197 + createMarker(location, settings, onClickListener, markerArgs) {
  198 + var marker = new qq.maps.Marker({
  199 + map: this.map,
  200 + position:location
  201 + });
  202 +
  203 + var gMap = this;
  204 + this.createMarkerIcon(marker, settings, (icon) => {
  205 + marker.setIcon(icon);
  206 + marker.setMap(gMap.map)
  207 + });
  208 +
  209 + if (settings.displayTooltip) {
  210 + this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs);
  211 + }
  212 +
  213 + if (onClickListener) {
  214 + qq.maps.event.addListener(marker, 'click', onClickListener);
  215 + }
  216 +
  217 + return marker;
  218 + }
  219 +
  220 + /* eslint-disable no-undef */
  221 + removeMarker(marker) {
  222 + marker.setMap(null);
  223 + }
  224 +
  225 + /* eslint-enable no-undef */
  226 +
  227 + /* eslint-disable no-undef */
  228 + createTooltip(marker, pattern, replaceInfo, autoClose, markerArgs) {
  229 + var popup = new qq.maps.InfoWindow({
  230 + map :this.map
  231 + });
  232 + var map = this;
  233 + qq.maps.event.addListener(marker, 'click', function() {
  234 + if (autoClose) {
  235 + map.tooltips.forEach((tooltip) => {
  236 + tooltip.popup.close();
  237 + });
  238 + }
  239 + popup.open();
  240 + popup.setPosition(marker);
  241 + });
  242 + this.tooltips.push( {
  243 + markerArgs: markerArgs,
  244 + popup: popup,
  245 + pattern: pattern,
  246 + replaceInfo: replaceInfo
  247 + });
  248 + }
  249 + /* eslint-enable no-undef */
  250 +
  251 + /* eslint-disable no-undef */
  252 + updatePolylineColor(polyline, settings, color) {
  253 + var options = {
  254 + path: polyline.getPath(),
  255 + strokeColor: color,
  256 + strokeOpacity: settings.strokeOpacity,
  257 + strokeWeight: settings.strokeWeight,
  258 + map: this.map
  259 + };
  260 + polyline.setOptions(options);
  261 + }
  262 + /* eslint-enable no-undef */
  263 +
  264 + /* eslint-disable no-undef */
  265 + createPolyline(locations, settings) {
  266 + var polyline = new qq.maps.Polyline({
  267 + path: locations,
  268 + strokeColor: settings.color,
  269 + strokeOpacity: settings.strokeOpacity,
  270 + strokeWeight: settings.strokeWeight,
  271 + map: this.map
  272 + });
  273 +
  274 + return polyline;
  275 + }
  276 + /* eslint-enable no-undef */
  277 +
  278 + removePolyline(polyline) {
  279 + polyline.setMap(null);
  280 + }
  281 +
  282 + /* eslint-disable no-undef ,no-unused-vars*/
  283 + fitBounds(bounds) {
  284 + if (this.dontFitMapBounds && this.defaultZoomLevel) {
  285 + this.map.setZoom(this.defaultZoomLevel);
  286 + this.map.setCenter(bounds.getCenter());
  287 + } else {
  288 + var tbMap = this;
  289 + qq.maps.event.addListenerOnce(this.map, 'bounds_changed', function() { // eslint-disable-line no-undef
  290 + if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
  291 + tbMap.map.setZoom(tbMap.minZoomLevel);
  292 + }
  293 + });
  294 + this.map.fitBounds(bounds);
  295 + }
  296 + }
  297 + /* eslint-enable no-undef,no-unused-vars */
  298 +
  299 + createLatLng(lat, lng) {
  300 + return new qq.maps.LatLng(lat, lng); // eslint-disable-line no-undef
  301 + }
  302 +
  303 + extendBoundsWithMarker(bounds, marker) {
  304 + bounds.extend(marker.getPosition());
  305 + }
  306 +
  307 + getMarkerPosition(marker) {
  308 + return marker.getPosition();
  309 + }
  310 +
  311 + setMarkerPosition(marker, latLng) {
  312 + marker.setPosition(latLng);
  313 + }
  314 +
  315 + getPolylineLatLngs(polyline) {
  316 + return polyline.getPath().getArray();
  317 + }
  318 +
  319 + setPolylineLatLngs(polyline, latLngs) {
  320 + polyline.setPath(latLngs);
  321 + }
  322 +
  323 + createBounds() {
  324 + return new qq.maps.LatLngBounds(); // eslint-disable-line no-undef
  325 + }
  326 +
  327 + extendBounds(bounds, polyline) {
  328 + if (polyline && polyline.getPath()) {
  329 + var locations = polyline.getPath();
  330 + for (var i = 0; i < locations.getLength(); i++) {
  331 + bounds.extend(locations.getAt(i));
  332 + }
  333 + }
  334 + }
  335 +
  336 + invalidateSize() {
  337 + qq.maps.event.trigger(this.map, "resize"); // eslint-disable-line no-undef
  338 + }
  339 +
  340 + getTooltips() {
  341 + return this.tooltips;
  342 + }
  343 +
  344 +}
... ...