@@ -59,50 +76,120 @@
import Theme from 'vue-iclient/src/common/_mixin/Theme';
import SmCollapse from 'vue-iclient/src/common/collapse/Collapse.vue';
import SmCollapsePanel from 'vue-iclient/src/common/collapse/Panel.vue';
+import SmTree from 'vue-iclient/src/common/tree/Tree.vue';
+import SmSlider from 'vue-iclient/src/common/slider/Slider.vue';
export default {
name: 'LayerGroup',
mixins: [Theme],
components: {
SmCollapse,
- SmCollapsePanel
+ SmCollapsePanel,
+ SmTree,
+ SmSlider
},
props: {
+ currentOpacity: {
+ type: Number,
+ default: 0
+ },
layerCatalog: {
type: Array,
default() {
return [];
}
},
+ operations: {
+ type: Object,
+ default() {
+ return {
+ fitBounds: true,
+ draggable: false,
+ opacity: false
+ };
+ }
+ },
attributes: {
type: Object,
default() {
return {};
}
- }
+ },
+ dropHandler: Function
},
computed: {
+ formatOpacity() {
+ return +(this.currentOpacity * 100).toFixed(0);
+ },
attributesIconClass() {
- return (this.attributes && this.attributes.iconClass) || 'sm-components-icon-attribute';
+ return (this.attributes && this.attributes.iconClass) || 'sm-components-icon-attribute-table';
},
attributesEnabled() {
- return (item) => {
- const isGeojson = item.renderSource.type === 'geojson';
- const isStructureData = item.dataSource.type === 'STRUCTURE_DATA';
- return this.attributes.enabled && (isGeojson || isStructureData);
+ return item => {
+ const isGeojson = item.renderSource && item.renderSource.type === 'geojson';
+ const isStructureData = item.dataSource && item.dataSource.type === 'STRUCTURE_DATA';
+ return this.attributes.enabled && (isGeojson || isStructureData) && (item && item.type) !== 'group';
};
}
},
+ watch: {
+ layerCatalog: {
+ handler: function (newVal, oldVal) {
+ this.treeData = this.getTreeData(this.layerCatalog);
+ },
+ deep: true,
+ immediate: true
+ }
+ },
+ data() {
+ return {
+ treeData: [],
+ showIconsItem: '',
+ showOpacityItem: ''
+ };
+ },
methods: {
+ getTreeData(data) {
+ const treeData = [];
+ data.map(item => {
+ const data = { ...item, key: item.id, scopedSlots: { title: 'custom' } };
+ if (data.children) {
+ const children = this.getTreeData(data.children);
+ data.children = children;
+ } else if(item.layerOrder !== 'auto') {
+ data.disabled = true;
+ }
+ treeData.push(data);
+ });
+ return treeData;
+ },
+ changeOpacity(val) {
+ if (this.showOpacityItem) {
+ val = val / 100;
+ this.$emit('changeOpacity', this.showOpacityItem, val);
+ this.$emit('getLayerOpacityById', this.showOpacityItem);
+ }
+ },
toggleItemVisibility(item) {
this.$emit('toggleItemVisibility', item, !item.visible);
},
toggleAttributesVisibility(e, item) {
this.$emit('toggleAttributesVisibility', e, item);
+ },
+ changeItemOpacity(item) {
+ if (this.showOpacityItem === item.id) {
+ this.showOpacityItem = '';
+ } else {
+ this.showOpacityItem = item.id;
+ this.$emit('getLayerOpacityById', this.showOpacityItem);
+ }
+ },
+ changeIconsStatus(val) {
+ this.showIconsItem = val;
+ },
+ zoomToBounds(item) {
+ this.$emit('zoomToBounds', item);
}
}
};
-
-
diff --git a/src/mapboxgl/web-map/MapStyle.ts b/src/mapboxgl/web-map/MapStyle.ts
deleted file mode 100644
index 0c91bf0c..00000000
--- a/src/mapboxgl/web-map/MapStyle.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-import { Events } from 'vue-iclient/src/common/_types/event/Events';
-import mapboxgl from 'vue-iclient/static/libs/mapboxgl/mapbox-gl-enhance';
-import 'vue-iclient/static/libs/iclient-mapboxgl/iclient-mapboxgl.min';
-import SourceListModel from 'vue-iclient/src/mapboxgl/web-map/SourceListModel';
-import WebMapService from '../../common/_utils/WebMapService';
-import cloneDeep from 'lodash.clonedeep';
-
-interface webMapOptions {
- target?: string;
- serverUrl?: string;
- accessToken?: string;
- accessKey?: string;
- tiandituKey?: string;
- googleMapsAPIKey?: string;
- googleMapsLanguage?: string;
- withCredentials?: boolean;
- excludePortalProxyUrl?: boolean;
- isSuperMapOnline?: boolean;
- center?: number[];
- zoom?: number;
- proxy?: boolean | string;
- iportalServiceProxyUrlPrefix?: string;
- checkSameLayer?: boolean;
-}
-
-interface mapOptions {
- name?: string;
- center?: [number, number] | mapboxglTypes.LngLatLike | { lon: number; lat: number } | number[];
- zoom?: number;
- bounds?: mapboxglTypes.LngLatBoundsLike;
- maxBounds?: [[number, number], [number, number]] | mapboxglTypes.LngLatBoundsLike;
- minZoom?: number;
- maxZoom?: number;
- renderWorldCopies?: boolean;
- bearing?: number;
- pitch?: number;
- style?: any;
- rasterTileSize?: number;
- container?: string;
- crs?: string | { epsgCode: string; WKT: string; extent: any; unit: string };
- transformRequest?: (url: string, resourceType: string) => void;
- fadeDuration?: number;
-}
-
-export default class MapStyle extends Events {
- options: webMapOptions;
- mapOptions: mapOptions;
- target: string;
- proxy: string | boolean;
- map: mapboxglTypes.Map;
- layerFilter: Function;
- withCredentials: boolean;
- eventTypes: string[];
- private _sourceListModel: InstanceType
;
- protected webMapService: InstanceType;
- _layerIdRenameMapList: any[] = [];
- _appendLayers = false;
-
- triggerEvent: (name: string, ...rest: any) => any;
-
- on: (data: Record) => void;
-
- constructor(
- id: string | number | Object,
- options: webMapOptions,
- mapOptions: mapOptions,
- layerFilter: Function
- ) {
- super();
- this.target = options.target || 'map';
- this.options = options;
- this.proxy = options.proxy;
- this.withCredentials = options.withCredentials || false;
- this.mapOptions = cloneDeep(mapOptions);
- this.webMapService = new WebMapService(id, options);
- this.layerFilter = layerFilter;
- this.eventTypes = ['addlayerssucceeded', 'mapinitialized'];
- }
-
- initializeMap(_: Record, map?: mapboxglTypes.Map) {
- if (map) {
- this._appendLayers = true;
- this.map = map;
- this._addLayersToMap();
- return;
- }
- this.mapOptions.container = this.target;
- if (typeof this.mapOptions.crs === 'object' && this.mapOptions.crs.epsgCode) {
- this.mapOptions.crs = new mapboxgl.CRS(
- this.mapOptions.crs.epsgCode,
- this.mapOptions.crs.WKT,
- this.mapOptions.crs.extent,
- this.mapOptions.crs.unit
- );
- }
- if (!this.mapOptions.transformRequest) {
- this.mapOptions.transformRequest = (url: string, resourceType: string) => {
- let proxy = '';
- if (typeof this.proxy === 'string') {
- let proxyType = 'data';
- if (resourceType === 'Tile') {
- proxyType = 'image';
- }
- proxy = this.webMapService.handleProxy(proxyType);
- }
- return {
- url: proxy ? `${proxy}${encodeURIComponent(url)}` : url,
- credentials: this.webMapService.handleWithCredentials(proxy, url, this.withCredentials || false)
- ? 'include'
- : undefined
- };
- };
- }
- this.mapOptions.center = this.mapOptions.center ?? [0, 0];
- this.mapOptions.zoom = this.mapOptions.zoom ?? 0;
- let fadeDuration = 0;
- if (Object.prototype.hasOwnProperty.call(this.mapOptions, 'fadeDuration')) {
- fadeDuration = this.mapOptions.fadeDuration;
- }
- this.map = new mapboxgl.Map({ ...this.mapOptions, fadeDuration });
- this.triggerEvent('mapinitialized', { map: this.map });
- this.map.on('load', () => {
- this._sendMapToUser();
- });
- }
-
- _addLayersToMap() {
- const { sources, layers, layerIdMapList } = this._setUniqueId(this.mapOptions.style);
- layers.forEach(layer => {
- layer.source && !this.map.getSource(layer.source) && this.map.addSource(layer.source, sources[layer.source]);
- this.map.addLayer(layer);
- });
- this._layerIdRenameMapList = layerIdMapList;
- this._sendMapToUser();
- }
-
- _setUniqueId(style: Record) {
- const layersToMap = JSON.parse(JSON.stringify(style.layers));
- const nextSources = {};
- const layerIdToChange = [];
- const timestamp = `_${+new Date()}`;
- for (const sourceId in style.sources) {
- let nextSourceId = sourceId;
- if (this.map.getSource(sourceId)) {
- nextSourceId = sourceId + timestamp;
- }
- nextSources[nextSourceId] = style.sources[sourceId];
- for (const layer of layersToMap) {
- if (layer.source === sourceId) {
- layer.source = nextSourceId;
- }
- }
- }
- for (const layer of layersToMap) {
- const originId = layer.id;
- if (this.map.getLayer(layer.id)) {
- const layerId = layer.id + timestamp;
- layer.id = layerId;
- }
- layerIdToChange.push({ originId: originId, renderId: layer.id });
- }
- return {
- sources: nextSources,
- layers: layersToMap,
- layerIdMapList: layerIdToChange
- };
- }
-
- _generateAppreciableLayers() {
- const layers = this.mapOptions.style.layers.map((layer: Record) => {
- const matchLayer = this._layerIdRenameMapList.find(item => item.originId === layer.id) || { renderId: layer.id };
- const overlayLayers = {
- id: matchLayer.renderId,
- name: layer.id
- };
- return overlayLayers;
- });
- return layers;
- }
-
- _sendMapToUser() {
- const appreciableLayers = this._generateAppreciableLayers();
- this._sourceListModel = new SourceListModel({
- map: this.map,
- layers: appreciableLayers,
- appendLayers: this._appendLayers
- });
- const matchLayers = this.getAppreciableLayers().filter((item: Record) =>
- appreciableLayers.some((layer: Record) => layer.id === item.id)
- );
- this.triggerEvent('addlayerssucceeded', {
- map: this.map,
- mapparams: { title: this.mapOptions.name, description: '' },
- layers: matchLayers
- });
- }
-
- clean() {
- if (this.map) {
- this.map.remove();
- this.map = null;
- this._sourceListModel = null;
- }
- }
-
- getLayerCatalog() {
- return this._sourceListModel?.getSourceList() ?? [];
- }
-
- getLegendInfo() {
- return [];
- }
-
- getAppreciableLayers() {
- return this._sourceListModel?.getLayers() ?? [];
- }
-}
diff --git a/src/mapboxgl/web-map/SourceListModel.js b/src/mapboxgl/web-map/SourceListModel.js
deleted file mode 100644
index 9fb927b0..00000000
--- a/src/mapboxgl/web-map/SourceListModel.js
+++ /dev/null
@@ -1,139 +0,0 @@
-import SourceModel from 'vue-iclient/src/mapboxgl/web-map/SourceModel';
-
-class SourceListModel {
- constructor(options) {
- this.map = options.map;
- this.layers = options.layers || [];
- this.appendLayers = options.appendLayers || false;
- this.excludeSourceNames = ['tdt-search-', 'tdt-route-', 'smmeasure', 'mapbox-gl-draw', /tracklayer-\d+-line/];
- }
-
- getLayers() {
- const detailLayers = this._initLayers();
- return this._initAppreciableLayers(detailLayers);
- }
-
- getSourceList() {
- const appreciableLayers = this.getLayers();
- return this._initSource(appreciableLayers);
- }
-
- excludeSource(key) {
- for (let i = 0; i < this.excludeSourceNames.length; i++) {
- if (key && key.match(this.excludeSourceNames[i])) {
- return false;
- }
- }
- return true;
- }
-
- _initLayers() {
- const layersOnMap = this.map.getStyle().layers.map(layer => this.map.getLayer(layer.id));
- const overlayLayers = Object.values(this.map.overlayLayersManager).reduce((layers, overlayLayer) => {
- if (overlayLayer.id && !layers.some(item => item.id === overlayLayer.id)) {
- const visibility =
- overlayLayer.visibility === 'visible' ||
- overlayLayer.visibility ||
- overlayLayer.visible ||
- (!('visible' in overlayLayer) && !('visibility' in overlayLayer))
- ? 'visible'
- : 'none';
- let source = overlayLayer.source || overlayLayer.sourceId;
- if (typeof source === 'object') {
- source = overlayLayer.id;
- }
- layers.push({
- id: overlayLayer.id,
- visibility,
- source,
- type: overlayLayer.type
- });
- }
- return layers;
- }, []);
- const renderLayers = layersOnMap
- .concat(overlayLayers)
- .filter(layer => !this.appendLayers || this.layers.some(item => layer.id === item.id));
- const nextLayers = renderLayers
- .filter(layer => this.excludeSource(layer.source))
- .filter(layer => !layer.id.includes('-SM-'));
- const selfLayers = [];
- const selfLayerIds = [];
- // 排序
- this.layers.forEach(item => {
- const matchLayer = nextLayers.find(layer => layer.id === item.id);
- if (matchLayer) {
- selfLayers.push(matchLayer);
- selfLayerIds.push(matchLayer.id);
- }
- });
- const otherLayers = nextLayers.filter(item => !selfLayerIds.includes(item.id));
- return selfLayers.concat(otherLayers);
- }
-
- _initSource(detailLayers) {
- const datas = detailLayers.reduce((sourceList, layer) => {
- let matchItem = sourceList.find(item => {
- const sourceId = layer.renderSource.id || layer.id;
- return item.id === sourceId;
- });
- if (!matchItem) {
- const sourceListItem = new SourceModel(layer);
- sourceList.push(sourceListItem);
- matchItem = sourceListItem;
- }
- matchItem.addLayer(layer);
- return sourceList;
- }, []);
- datas.reverse();
- return datas;
- }
-
- _initAppreciableLayers(detailLayers) {
- // dv 没有关联一个可感知图层对应对个渲染图层的关系,默认相同source的layer就是渲染图层
- return detailLayers.reduce((layers, layer) => {
- let matchLayer = layers.find(item => {
- const layerId = layer.sourceLayer || layer.source || layer.id;
- return item.id === layerId;
- });
- if (!matchLayer) {
- matchLayer = this._createCommonFields(layer);
- layers.push(matchLayer);
- }
- matchLayer.renderLayers.push(layer.id);
- return layers;
- }, []);
- }
-
- _createCommonFields(layer) {
- const layerInfo = this.layers.find(layerItem => layer.id === layerItem.id) || {};
- // type: background overlaymanager layers 只有 id
- const layerId = layer.sourceLayer || layer.source || layer.id;
- const {
- dataSource,
- themeSetting = {},
- name = layerId,
- visible = layer.visibility ? layer.visibility === 'visible' : true,
- serverId
- } = layerInfo;
- const sourceOnMap = this.map.getSource(layer.source);
- const fields = {
- id: layerId,
- title: name,
- type: layer.type,
- visible,
- renderSource: {
- id: layer.source,
- type: sourceOnMap && sourceOnMap.type
- },
- renderLayers: [],
- dataSource: dataSource || (serverId ? { serverId } : {}),
- themeSetting
- };
- if (layer.sourceLayer) {
- fields.renderSource.sourceLayer = layer.sourceLayer;
- }
- return fields;
- }
-}
-export default SourceListModel;
diff --git a/src/mapboxgl/web-map/SourceModel.js b/src/mapboxgl/web-map/SourceModel.js
deleted file mode 100644
index 8ef93ca4..00000000
--- a/src/mapboxgl/web-map/SourceModel.js
+++ /dev/null
@@ -1,31 +0,0 @@
-class SourceModel {
- constructor(options) {
- this.dataSource = options.dataSource;
- this.id = options.renderSource.id || options.id;
- this.title = options.title;
- this.renderSource = options.renderSource;
- this.renderLayers = [];
- this.type = options.type;
- this.themeSetting = options.themeSetting;
- this.visible = options.visible;
- }
-
- addLayer(layer) {
- if (layer.renderSource.sourceLayer) {
- if (!this.children) {
- this.children = [];
- this.type = 'group';
- this.renderSource = {};
- this.dataSource = {};
- this.themeSetting = {};
- this.visible = true;
- this.title = this.id;
- }
- this.children.push(layer);
- return;
- }
- this.renderLayers.push(...layer.renderLayers);
- }
-}
-
-export default SourceModel;
diff --git a/src/mapboxgl/web-map/WebMap.vue b/src/mapboxgl/web-map/WebMap.vue
index 57d67508..7dd9cb2c 100644
--- a/src/mapboxgl/web-map/WebMap.vue
+++ b/src/mapboxgl/web-map/WebMap.vue
@@ -390,18 +390,17 @@ class SmWebMap extends Mixins(VmUpdater, MapEvents) {
*/
this.load({ map: e.map });
},
- getmapinfofailed: e => {
+ mapcreatefailed: e => {
/**
* @event getMapFailed
* @desc 获取 WebMap 地图信息失败。
* @property {Object} error - 失败原因。
*/
this.getMapFailed({ error: e.error });
- // @ts-ignore
- Message.error(e.error.message);
+ this.notifyErrorTip({ e, defaultTip: 'mapCreatedFailed' });
this.spinning = false;
},
- getlayerdatasourcefailed: e => {
+ layercreatefailed: e => {
/**
* @event getLayerDatasourceFailed
* @desc 获取图层数据失败。
@@ -411,34 +410,38 @@ class SmWebMap extends Mixins(VmUpdater, MapEvents) {
*/
this.getLayerDatasourceFailed({ error: e.error, layer: e.layer, map: e.map });
if (e.error === 'SAMPLE DATA is not supported') {
- // @ts-ignore
- Message.error(this.$t('webmap.sampleDataNotSupport'));
+ this.notifyErrorTip({ defaultTip: 'sampleDataNotSupport', showErrorMsg: false });
+ } else if (e.error_code === 'DRILL_LAYERS_NOT_SUPPORTED') {
+ this.notifyErrorTip({ defaultTip: 'drillLayersNotSupport', showErrorMsg: false });
} else {
- // @ts-ignore
- Message.error(this.$t('webmap.getLayerInfoFailed'));
+ this.notifyErrorTip({ e, defaultTip: 'getLayerInfoFailed' });
}
},
- getlayersfailed: e => {
- /**
- * @event getlayersfailed
- * @desc 获取图层失败。
- * @property {Object} error - 失败原因。
- */
- const errorMsg = Object.prototype.toString.call(e.error) === '[object Error]' ? this.$t('webmap.getLayerInfoFailed') : e.error;
- // @ts-ignore
- Message.error(errorMsg);
+ baidumapnotsupport: () => {
+ this.notifyErrorTip({ defaultTip: 'baiduMapNotSupport', showErrorMsg: false });
},
- notsupportbaidumap: () => {
- // @ts-ignore
- Message.error(this.$t('webmap.baiduMapNotSupport'));
+ layerorsourcenameduplicated: () => {
+ this.notifyErrorTip({ defaultTip: 'layerorsourcenameduplicated', showErrorMsg: false });
},
- beforeremovemap: () => {
+ mapbeforeremove: () => {
mapEvent.$options.deleteMap(this.target);
mapEvent.$options.deleteWebMap(this.target);
}
});
}
+ notifyErrorTip({ e, defaultTip, showErrorMsg = true }: { e?: any; defaultTip: string; showErrorMsg?: boolean; }) {
+ let msg = '';
+ if (showErrorMsg) {
+ if (e.error && e.error.message) {
+ msg = e.error.message;
+ } else if (typeof e.error === 'string') {
+ msg = e.error;
+ }
+ }
+ Message.error(this.$t(`webmap.${defaultTip}`) + msg);
+ }
+
destory(): void {
if (this.autoresize) {
// @ts-ignore
diff --git a/src/mapboxgl/web-map/WebMapV2.ts b/src/mapboxgl/web-map/WebMapV2.ts
deleted file mode 100644
index fa0fc316..00000000
--- a/src/mapboxgl/web-map/WebMapV2.ts
+++ /dev/null
@@ -1,2957 +0,0 @@
-/* Copyright© 2000 - 2024 SuperMap Software Co.Ltd. All rights reserved.
- * This program are made available under the terms of the Apache License, Version 2.0
- * which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html. */
-import mapboxgl from 'vue-iclient/static/libs/mapboxgl/mapbox-gl-enhance';
-import SourceListModel from 'vue-iclient/src/mapboxgl/web-map/SourceListModel';
-import { handleMultyPolygon } from 'vue-iclient/src/mapboxgl/_utils/geometry-util';
-import 'vue-iclient/static/libs/iclient-mapboxgl/iclient-mapboxgl.min';
-import 'vue-iclient/static/libs/geostats/geostats';
-import 'vue-iclient/static/libs/json-sql/jsonsql';
-import echarts from 'echarts';
-import EchartsLayer from 'vue-iclient/static/libs/echarts-layer/EchartsLayer';
-import cloneDeep from 'lodash.clonedeep';
-import { geti18n } from 'vue-iclient/src/common/_lang/index';
-import WebMapBase from 'vue-iclient/src/common/web-map/WebMapBase';
-import { getColorWithOpacity } from 'vue-iclient/src/common/_utils/util';
-import { getProjection, registerProjection, toEpsgCode } from 'vue-iclient/src/common/_utils/epsg-define';
-import proj4 from 'proj4';
-
-/**
- * @class WebMapViewModel
- * @category ViewModel
- * @classdesc 对接 iPortal/Online 地图类。目前支持地图坐标系包括:'EPSG:3857','EPSG:4326','EPSG:4490','EPSG:4214','EPSG:4610'。
- * @param {number} id - iPortal|Online 地图 ID。
- * @param {Object} options - 参数。
- * @param {string} [options.target='map'] - 地图容器 ID。
- * @param {string} [options.serverUrl="https://www.supermapol.com"] - SuperMap iPortal/Online 服务器地址。当设置 `id` 时有效。
- * @param {string} [options.accessToken] - 用于访问 SuperMap iPortal 、SuperMap Online 中受保护的服务。当设置 `id` 时有效。
- * @param {string} [options.accessKey] - SuperMap iServer 提供的一种基于 Token(令牌)的用户身份验证机制。当设置 `id` 时有效。
- * @param {String} [options.tiandituKey] - 用于访问天地图的服务。当设置 `id` 时有效。
- * @param {String} [options.bingMapsKey] - 用于访问必应地图的服务。当设置 `id` 时有效。
- * @param {String} [options.googleMapsAPIKey] - 用于访问谷歌地图。当设置 `id` 时有效。
- * @param {String} [options.googleMapsLanguage] - 用于定义在谷歌地图图块上显示标签的语言。当设置 `id` 且底图为谷歌地图时有效。
- * @param {boolean} [options.withCredentials=false] - 请求是否携带 cookie。当设置 `id` 时有效。
- * @param {boolean} [options.excludePortalProxyUrl] - server 传递过来的 URL 是否带有代理。当设置 `id` 时有效。
- * @param {boolean} [options.ignoreBaseProjection = 'false'] - 是否忽略底图坐标系和叠加图层坐标系不一致。
- * @param {String} [options.iportalServiceProxyUrlPrefix] - iportal的代理服务地址前缀。
- * @fires WebMapViewModel#mapinitialized
- * @fires WebMapViewModel#getmapinfofailed
- * @fires WebMapViewModel#getlayerdatasourcefailed
- * @fires WebMapViewModel#addlayerssucceeded
- */
-interface webMapOptions {
- target?: string;
- serverUrl?: string;
- accessToken?: string;
- accessKey?: string;
- tiandituKey?: string;
- bingMapsKey?: string;
- googleMapsAPIKey?: string;
- googleMapsLanguage?: string;
- withCredentials?: boolean;
- excludePortalProxyUrl?: boolean;
- isSuperMapOnline?: boolean;
- center?: number[];
- zoom?: number;
- proxy?: boolean | string;
- iportalServiceProxyUrlPrefix?: string;
- checkSameLayer?: boolean;
- parentEvents?: Record;
-}
-interface mapOptions {
- center?: [number, number] | mapboxglTypes.LngLatLike | { lon: number; lat: number } | number[];
- zoom?: number;
- bounds?: mapboxglTypes.LngLatBoundsLike;
- maxBounds?: [[number, number], [number, number]] | mapboxglTypes.LngLatBoundsLike;
- minZoom?: number;
- maxZoom?: number;
- renderWorldCopies?: boolean;
- bearing?: number;
- pitch?: number;
- style?: any;
- rasterTileSize?: number;
- container?: string;
- crs: string;
-}
-
-type layerType = 'POINT' | 'LINE' | 'POLYGON';
-
-export default class WebMap extends WebMapBase {
- map: mapboxglTypes.Map;
-
- center: [number, number] | mapboxglTypes.LngLatLike | { lon: number; lat: number } | number[];
-
- bounds: mapboxglTypes.LngLatBoundsLike;
-
- renderWorldCopies: boolean;
-
- bearing: number;
-
- pitch: number;
-
- rasterTileSize: number;
-
- layerFilter: Function;
-
- baseLayerProxy: string | boolean;
-
- private _sourceListModel: SourceListModel;
-
- private _legendList: any;
-
- private _handleDataflowFeaturesCallback: Function;
-
- private _initDataflowLayerCallback: Function;
-
- private _dataflowService: any;
-
- private _unprojectProjection: string;
-
- private _layerTimerList: Array = [];
-
- private checkSameLayer: boolean;
-
- private _mapInfo: Record;
-
- private _parentEvents: Record;
-
- private _cacheLayerId: Map> = new Map();
-
- private _appendLayers = false;
-
- constructor(
- id: string | number | Object,
- options: webMapOptions = {},
- mapOptions: mapOptions,
- layerFilter: Function = function () {
- return true;
- }
- ) {
- super(id, options, mapOptions);
- if (typeof id === 'string' || typeof id === 'number') {
- this.mapId = id;
- }
- if (this.centerValid(mapOptions.center)) {
- this.center = mapOptions.center;
- }
- this.zoom = mapOptions.zoom;
- this.renderWorldCopies = mapOptions.renderWorldCopies;
- this.bounds = mapOptions.bounds;
- this.bearing = mapOptions.bearing;
- this.pitch = mapOptions.pitch;
- this.rasterTileSize = mapOptions.rasterTileSize || 256;
- this.layerFilter = layerFilter;
- this.checkSameLayer = options.checkSameLayer;
- this._legendList = [];
- this._parentEvents = options.parentEvents ?? {};
- this._taskID = new Date();
- }
-
- initializeMap(mapInfo: Record, map?: mapboxglTypes.Map) {
- if (map) {
- this._appendLayers = true;
- this.map = map;
- }
- this._getMapInfo(mapInfo, this._taskID);
- }
-
- getLegendInfo() {
- return this._legendList;
- }
-
- getLayerCatalog() {
- return this._sourceListModel?.getSourceList() || [];
- }
-
- getAppreciableLayers() {
- return this._sourceListModel?.getLayers() || [];
- }
-
- _initWebMap(): void {}
-
- _loadLayers(mapInfo, _taskID): void {
- if (this.map) {
- // @ts-ignore
- if (this.map.getCRS().epsgCode !== this.baseProjection && !this.ignoreBaseProjection) {
- this._triggerEvent('projectionisnotmatch', {});
- return;
- }
- this._handleLayerInfo(mapInfo, _taskID);
- } else {
- setTimeout(() => {
- this._createMap(mapInfo);
- this.map.on('load', () => {
- this._handleLayerInfo(mapInfo, _taskID);
- });
- }, 0);
- }
- }
-
- _setCRS(baseProjection, wkt, bounds): void {
- const crs = new mapboxgl.CRS(baseProjection, wkt, bounds, bounds[2] > 180 ? 'meter' : 'degree');
- mapboxgl.CRS.set(crs);
- }
-
- _getMapInfo(mapInfo: Record, _taskID: Date): void {
- this._mapInfo = mapInfo;
- const { projection } = mapInfo;
- let bounds, wkt;
- this.baseProjection = toEpsgCode(projection);
- let defaultWktValue = getProjection(this.baseProjection);
-
- if (defaultWktValue) {
- wkt = defaultWktValue;
- }
- if (!mapboxgl.CRS.get(this.baseProjection)) {
- if (mapInfo.baseLayer && mapInfo.baseLayer.layerType === 'MAPBOXSTYLE') {
- let url = mapInfo.baseLayer.dataSource.url;
- if (url.indexOf('/restjsr/') > -1 && !/\/style\.json$/.test(url)) {
- url += '/style.json';
- }
- this.webMapService.getMapBoxStyle(url).then((res: any) => {
- if (res && res.metadata && res.metadata.indexbounds) {
- bounds = res.metadata.indexbounds;
- } else {
- bounds = [
- mapInfo.extent.leftBottom.x,
- mapInfo.extent.leftBottom.y,
- mapInfo.extent.rightTop.x,
- mapInfo.extent.rightTop.y
- ];
- }
- this._defineProj4(projection);
- this._setCRS(this.baseProjection, wkt, bounds);
- this._loadLayers(mapInfo, _taskID);
- });
- } else if (mapInfo.baseLayer && mapInfo.baseLayer.layerType === 'TILE') {
- // 获取地图的wkt
- this.getEpsgCodeWKT(`${mapInfo.baseLayer.url}/prjCoordSys.wkt`, {
- withoutFormatSuffix: true,
- withCredentials: this.webMapService.handleWithCredentials('', mapInfo.baseLayer.url, false)
- }).then(res => {
- if (!wkt) {
- wkt = res;
- }
- this.getBounds(`${mapInfo.baseLayer.url}.json`, {
- withoutFormatSuffix: true,
- withCredentials: this.webMapService.handleWithCredentials('', mapInfo.baseLayer.url, false)
- }).then(res => {
- if (res && res.bounds) {
- bounds = [res.bounds.leftBottom.x, res.bounds.leftBottom.y, res.bounds.rightTop.x, res.bounds.rightTop.y];
- } else {
- bounds = [
- mapInfo.extent.leftBottom.x,
- mapInfo.extent.leftBottom.y,
- mapInfo.extent.rightTop.x,
- mapInfo.extent.rightTop.y
- ];
- }
- this._defineProj4(wkt, projection);
- this._setCRS(this.baseProjection, wkt, bounds);
- this._loadLayers(mapInfo, _taskID);
- });
- });
- } else {
- // this._defineProj4(projection);
- // this._loadLayers(mapInfo, _taskID);
- throw Error(geti18n().t('webmap.crsNotSupport'));
- }
- } else {
- this._defineProj4(projection);
- bounds = [
- mapInfo.extent.leftBottom.x,
- mapInfo.extent.leftBottom.y,
- mapInfo.extent.rightTop.x,
- mapInfo.extent.rightTop.y
- ];
- this._setCRS(this.baseProjection, wkt, bounds);
- this._loadLayers(mapInfo, _taskID);
- }
- }
-
- _handleLayerInfo(mapInfo, _taskID): void {
- mapInfo = this._setLayerID(mapInfo);
- this._mapInfo = mapInfo;
- this.layerAdded = 0;
- this.expectLayerLen = 0;
- const { layers, grid } = mapInfo;
- this._setExpectLayerLen(mapInfo);
- if (this.expectLayerLen === 0) {
- this._sendMapToUser(0, 0);
- }
- if (this._shouldLoadBaseLayer(mapInfo, this.layerFilter)) {
- this._initBaseLayer(mapInfo, () => {
- this._addLayerSucceeded();
- });
- }
- if (layers && layers.length !== 0) {
- let filterLayers = layers;
- if (typeof this.layerFilter === 'function') {
- filterLayers = layers.filter(this.layerFilter);
- }
- this._initOverlayLayers(filterLayers, _taskID);
- }
- if (grid && grid.graticule) {
- this._initGraticuleLayer(grid.graticule);
- }
- }
-
- _setExpectLayerLen(mapInfo) {
- if (this._shouldLoadBaseLayer(mapInfo, this.layerFilter)) {
- this.expectLayerLen++;
- }
- let overLayers = mapInfo.layers;
- if (overLayers && overLayers.length > 0) {
- if (typeof this.layerFilter === 'function') {
- overLayers = overLayers.filter(this.layerFilter);
- }
- this.expectLayerLen += overLayers.length;
- }
- }
-
- _shouldLoadBaseLayer(mapInfo, layerFilter) {
- const baseLayer = mapInfo.baseLayer;
- if (!baseLayer) {
- return false;
- }
- if (typeof layerFilter === 'function') {
- return layerFilter(baseLayer);
- }
- return true;
- }
-
- _createMap(mapInfo?): void {
- // 获取字体样式
- const fontFamilys: string = this._getLabelFontFamily(mapInfo);
- const center = this._getMapCenter(mapInfo);
- // zoom
- let zoom = mapInfo.level || 0;
- let zoomBase = 0;
- let { bounds, minZoom, maxZoom } = this.mapOptions;
- const interactive = this.mapOptions.interactive;
- if (isNaN(minZoom)) {
- minZoom = mapInfo.minScale
- ? this._transformScaleToZoom(mapInfo.minScale, mapboxgl.CRS.get(this.baseProjection))
- : 0;
- }
- if (isNaN(maxZoom)) {
- maxZoom = mapInfo.maxScale
- ? this._transformScaleToZoom(mapInfo.maxScale, mapboxgl.CRS.get(this.baseProjection))
- : 22;
- }
- if (mapInfo.visibleExtent && mapInfo.visibleExtent.length === 4 && !bounds) {
- bounds = [
- this._unproject([mapInfo.visibleExtent[0], mapInfo.visibleExtent[1]]),
- this._unproject([mapInfo.visibleExtent[2], mapInfo.visibleExtent[3]])
- ];
- }
- if (minZoom > maxZoom) {
- [minZoom, maxZoom] = [maxZoom, minZoom];
- }
- if (!bounds) {
- if (mapInfo.minScale && mapInfo.maxScale) {
- zoomBase = Math.min(
- this._transformScaleToZoom(mapInfo.minScale, mapboxgl.CRS.get(this.baseProjection)),
- this._transformScaleToZoom(mapInfo.maxScale, mapboxgl.CRS.get(this.baseProjection))
- );
- } else {
- zoomBase = +Math.log2(
- this._getResolution(mapboxgl.CRS.get(this.baseProjection).getExtent()) / this._getResolution(mapInfo.extent)
- ).toFixed(2);
- }
- zoom += zoomBase;
- }
-
- // 初始化 map
- this.map = new mapboxgl.Map({
- ...this.mapOptions,
- container: this.target,
- center: this.center || center,
- zoom: this.zoom || zoom,
- minZoom,
- maxZoom,
- bearing: this.bearing || 0,
- pitch: this.pitch || 0,
- bounds,
- interactive: interactive === void 0 ? true : interactive,
- style: {
- version: 8,
- sources: {},
- layers: []
- },
- // @ts-ignore fix-crs
- crs: this.baseProjection,
- localIdeographFontFamily: fontFamilys || '',
- renderWorldCopies: this.renderWorldCopies || false,
- transformRequest: (url, resourceType) => {
- if (resourceType === 'Tile') {
- if (this.isSuperMapOnline && url.indexOf('http://') === 0) {
- url = `https://www.supermapol.com/apps/viewer/getUrlResource.png?url=${encodeURIComponent(url)}`;
- }
- if (this.webMapService.isIportalResourceUrl(url)) {
- url = this.webMapService.handleParentRes(url);
- }
- const proxy = this.webMapService.handleProxy('image');
- return {
- url: url,
- credentials: this.webMapService.handleWithCredentials(proxy, url, false) ? 'include' : undefined
- };
- }
- return { url };
- },
- fadeDuration: 0
- });
- /**
- * @description Map 初始化成功。
- */
- this._triggerEvent('mapinitialized', { map: this.map });
- }
-
- private _createMVTBaseLayer(layerInfo, addedCallback?: Function) {
- let url = layerInfo.dataSource.url;
- if (url.indexOf('/restjsr/') > -1 && !/\/style\.json$/.test(url)) {
- url += '/style.json';
- }
- this.webMapService
- // @ts-ignore
- .getMapBoxStyle(url)
- .then(
- (style: any) => {
- const sourceIds = Object.keys(style.sources);
- if (sourceIds.some(id => this.map.getSource(id))) {
- addedCallback && addedCallback();
- return;
- }
- // @ts-ignore
- this.map.addStyle(style);
- const layerIds = [];
- style.layers.forEach((item: Record) => {
- if (item.type !== 'background') {
- layerIds.push(item.id);
- }
- });
- this._cacheLayerId.set(layerInfo.layerID || layerInfo.name, layerIds.map((layerId: string) => ({ layerId, name: layerId })));
- addedCallback && addedCallback();
- },
- error => {
- addedCallback && addedCallback();
- throw new Error(error);
- }
- )
- .catch(error => {
- /**
- * @event WebMapViewModel#getmapinfofailed
- * @description 获取地图信息失败。
- * @property {Object} error - 失败原因。
- */
- this._triggerEvent('getmapinfofailed', { error });
- });
- }
-
- _initBaseLayer(mapInfo: any, addedCallback?: Function): void {
- const layerInfo = mapInfo.baseLayer || mapInfo;
- const layerType = this.getBaseLayerType(layerInfo);
- const mapUrls = this.getMapurls();
- let url: string;
- this.baseLayerProxy = this.webMapService.handleProxy('image');
- switch (layerType) {
- case 'TIANDITU':
- this.baseLayerProxy = null;
- this._createTiandituLayer(mapInfo, addedCallback);
- break;
- case 'BING':
- this.baseLayerProxy = null;
- this._createBingLayer(layerInfo.layerID || layerInfo.name, layerInfo, addedCallback);
- break;
- case 'WMS':
- this._createWMSLayer(layerInfo, addedCallback);
- break;
- case 'WMTS':
- this._createWMTSLayer(layerInfo, addedCallback);
- break;
- case 'TILE':
- this._createDynamicTiledLayer(layerInfo, addedCallback);
- break;
- case 'CLOUD':
- case 'XYZ':
- url = mapUrls[layerInfo.layerType]
- .replace('{googleMapsLanguage}', this.googleMapsLanguage)
- .replace('{googleMapsAPIKey}', this.googleMapsAPIKey);
- this._createXYZLayer(layerInfo, url, addedCallback);
- break;
- case 'BAIDU':
- this._triggerEvent('notsupportbaidumap', {});
- addedCallback && addedCallback();
- break;
- case 'MAPBOXSTYLE':
- this._createMVTBaseLayer(layerInfo, addedCallback); // 添加矢量瓦片服务作为底图
- break;
- }
- }
-
- _initOverlayLayers(layers: any, _taskID: any): void {
- // 存储地图上所有的图层对象
- if (this.expectLayerLen > 0) {
- layers.forEach(layer => {
- const type = this.webMapService.getDatasourceType(layer);
- // TODO --- 暂不支持 SAMPLE_DATA
- if (type === 'SAMPLE_DATA') {
- this._addLayerSucceeded();
- this._triggerEvent('getlayerdatasourcefailed', {
- error: 'SAMPLE DATA is not supported',
- layer,
- map: this.map
- });
- return;
- }
-
- if (layer.visibleScale) {
- const { minScale, maxScale } = layer.visibleScale;
- layer.minzoom = Math.max(this._transformScaleToZoom(minScale), 0);
- layer.maxzoom = Math.min(24, this._transformScaleToZoom(maxScale) + 0.0000001);
- }
-
- if (type === 'tile') {
- this._initBaseLayer(layer, () => {
- this._addLayerSucceeded();
- });
- if (layer.autoUpdateTime) {
- this._layerTimerList.push(
- setInterval(() => {
- this._initBaseLayer(layer);
- }, layer.autoUpdateTime)
- );
- }
- } else {
- this.getLayerFeatures(layer, _taskID, type);
- if (layer.autoUpdateTime) {
- this._layerTimerList.push(
- setInterval(() => {
- this.getLayerFeatures(layer, _taskID, type);
- }, layer.autoUpdateTime)
- );
- }
- }
- }, this);
- }
- }
-
- _initOverlayLayer(layerInfo: any, features: any = [], mergeByField?: string) {
- const { layerID, layerType, visible, style, featureType, projection } = layerInfo;
- layerInfo.visible = visible ? 'visible' : 'none';
- features = this.mergeFeatures(layerID, features, mergeByField);
- if (layerType === 'restMap') {
- this._createRestMapLayer(features, layerInfo);
- return;
- }
- if (layerType === 'mvt') {
- this._createMvtLayer(features.info, layerInfo, features.featureType);
- return;
- }
-
- // mbgl 目前不能处理 geojson 复杂面情况
- // mbgl isssue https://github.com/mapbox/mapbox-gl-js/issues/7023
- if (features && features[0] && features[0].geometry && features[0].geometry.type === 'Polygon') {
- features = handleMultyPolygon(features);
- }
-
- if (
- features &&
- projection &&
- (projection !== this.baseProjection || projection === 'EPSG:3857' || projection === 'EPSG:-1000') &&
- layerInfo.dataSource &&
- layerInfo.dataSource.type !== 'REST_DATA'
- ) {
- this._unprojectProjection = this._defineProj4(projection);
- features = this.transformFeatures(features);
- }
-
- features = this.handleLayerFeatures(features, layerInfo);
-
- if (layerType === 'VECTOR') {
- if (featureType === 'POINT') {
- if (style.type === 'SYMBOL_POINT') {
- this._createSymbolLayer(layerInfo, features);
- } else {
- this._createGraphicLayer(layerInfo, features);
- }
- } else {
- // 线和面
- this._createVectorLayer(layerInfo, features);
- // 不在 _createVectorLayer 里面处理 layerAdded++ 的原因:_createDataflowLayer 也调用了_createVectorLayer ,会导致layerAdded > expectLayerLen
- this._addLayerSucceeded({ layerInfo, features });
- }
- } else if (layerType === 'UNIQUE') {
- this._createUniqueLayer(layerInfo, features);
- } else if (layerType === 'RANGE') {
- this._createRangeLayer(layerInfo, features);
- } else if (layerType === 'HEAT') {
- this._createHeatLayer(layerInfo, features);
- } else if (layerType === 'MARKER') {
- this._createMarkerLayer(layerInfo, features);
- } else if (layerType === 'MIGRATION') {
- this._createMigrationLayer(layerInfo, features);
- } else if (layerType === 'RANK_SYMBOL') {
- this._createRankSymbolLayer(layerInfo, features);
- } else if (layerType === 'DATAFLOW_POINT_TRACK' || layerType === 'DATAFLOW_HEAT') {
- this._createDataflowLayer(layerInfo);
- }
- }
-
- _initGraticuleLayer(graticuleInfo: any) {
- const options = this._createGraticuleOptions(graticuleInfo);
- const graticuleLayers = new mapboxgl.supermap.GraticuleLayer(options);
- this.map.addLayer(graticuleLayers);
- this._setGraticuleDash(graticuleInfo.lineDash, graticuleLayers);
- }
-
- private _createGraticuleOptions(graticuleInfo) {
- let { extent, lonLabelStyle, latLabelStyle } = graticuleInfo;
- const { strokeColor, lineDash, strokeWidth, interval } = graticuleInfo;
- const strokeStyle = {
- lineColor: strokeColor,
- lindDasharray: lineDash,
- lineWidth: strokeWidth
- };
- lonLabelStyle = {
- textFont: lonLabelStyle.fontFamily.split(','),
- textSize: lonLabelStyle.fontSize,
- textAnchor: latLabelStyle.textBaseline,
- textColor: lonLabelStyle.fill,
- textHaloColor: lonLabelStyle.outlineColor,
- textHaloWidth: lonLabelStyle.outlineWidth
- };
- latLabelStyle = {
- textFont: latLabelStyle.fontFamily.split(','),
- textSize: latLabelStyle.fontSize,
- textAnchor: latLabelStyle.textBaseline,
- textColor: latLabelStyle.fill,
- textHaloColor: latLabelStyle.outlineColor,
- textHaloWidth: latLabelStyle.outlineWidth
- };
- // @ts-ignore
- extent = extent || this.map.getCRS().extent;
- extent = [this._unproject([extent[0], extent[1]]), this._unproject([extent[2], extent[3]])];
- return {
- minZoom: 1,
- strokeStyle,
- extent,
- interval: interval && interval[0],
- lngLabelStyle: lonLabelStyle,
- latLabelStyle
- };
- }
-
- private _setGraticuleDash(lindDasharray, graticuleLayers) {
- this.map.on('zoomend', () => {
- if (this.map.getZoom() < 3) {
- graticuleLayers.setStrokeStyle({ lindDasharray: [0.1, 3] });
- } else {
- graticuleLayers.setStrokeStyle({ lindDasharray });
- }
- });
- }
-
- private _createTiandituLayer(mapInfo: any, addedCallback?: Function): void {
- const tiandituUrls = this._getTiandituUrl(mapInfo);
- const { labelLayerVisible, name, visible } = mapInfo.baseLayer;
- const isLabel = Boolean(labelLayerVisible);
- const labelUrl = tiandituUrls.labelUrl;
- const tiandituUrl = tiandituUrls.tiandituUrl;
- this._addBaselayer(tiandituUrl, name, visible);
- isLabel && this._addBaselayer(labelUrl, `${name}-label`, visible);
- addedCallback && addedCallback();
- }
-
- private _createWMTSLayer(layerInfo, addedCallback?: Function): void {
- this.webMapService
- // @ts-ignore
- .getWmtsInfo(layerInfo, this.map.getCRS().epsgCode)
- .then(
- (result: any) => {
- const layerId = layerInfo.layerID || layerInfo.name;
- if (result.isMatched) {
- const wmtsUrl = this._getWMTSUrl(Object.assign({}, layerInfo, result));
- this._addBaselayer(
- [wmtsUrl],
- layerId,
- layerInfo.visible,
- result.matchMinZoom,
- result.matchMaxZoom,
- false,
- result.bounds
- );
- addedCallback && addedCallback();
- }
- },
- error => {
- addedCallback && addedCallback();
- throw new Error(error);
- }
- )
- .catch(error => {
- /**
- * @event WebMapViewModel#getmapinfofailed
- * @description 获取地图信息失败。
- * @property {Object} error - 失败原因。
- */
- this._triggerEvent('getmapinfofailed', { error });
- });
- }
-
- private async _createBingLayer(layerName: string, layerInfo: any, addedCallback?: Function): Promise {
- let metaInfoUrl =
- `https://dev.virtualearth.net/REST/v1/Imagery/Metadata/RoadOnDemand?uriScheme=https&include=ImageryProviders&key=${this.bingMapsKey}&c=zh-cn`;
- const metaInfo = await this._fetchRequest(metaInfoUrl, 'json', {
- withoutFormatSuffix: true
- });
- if (
- metaInfo.statusCode !== 200 ||
- metaInfo.resourceSets.length !== 1 ||
- metaInfo.resourceSets[0].resources.length !== 1
- ) {
- return;
- }
- const resource = metaInfo.resourceSets[0].resources[0];
- const urls = [];
- resource.imageUrlSubdomains.map(function (subdomain) {
- const imageUrl = resource.imageUrl
- .replace('{subdomain}', subdomain);
- urls.push(imageUrl);
- });
-
- // @ts-ignore
- this._addBaselayer(urls, layerName, layerInfo.visible);
- addedCallback && addedCallback();
- }
-
- private _createXYZLayer(layerInfo: any, url: string, addedCallback?: Function): void {
- let urlArr: string[] = [];
-
- if (layerInfo.layerType === 'OSM') {
- const res = url.match(/\w\-\w/g)[0];
- const start = res[0];
- const end = res[2];
- let alphabet = '';
- for (let i = 97; i < 123; i++) {
- alphabet += String.fromCharCode(i);
- }
- const alphabetArr = alphabet.split('');
-
- const startIndex = alphabetArr.indexOf(start);
- const endIndex = alphabetArr.indexOf(end);
-
- const res3 = alphabetArr.slice(startIndex, endIndex + 1);
-
- for (let i = 0; i < res3.length; i++) {
- const replaceRes = url.replace(/{\w\-\w}/g, res3[i]);
- urlArr.push(replaceRes);
- }
- } else if (layerInfo.layerType === 'GOOGLE_CN') {
- const res = url.match(/\d\-\d/g)[0];
- const start = parseInt(res[0]);
- const end = parseInt(res[2]);
-
- for (let i = start; i <= end; i++) {
- const replaceRes = url.replace(/{\d\-\d}/g, i.toString());
- urlArr.push(replaceRes);
- }
- } else {
- urlArr = [url];
- }
- const layerId = layerInfo.layerID || layerInfo.name;
- this._addBaselayer(urlArr, layerId, layerInfo.visible);
- addedCallback && addedCallback();
- }
-
- private _createDynamicTiledLayer(layerInfo: any, addedCallback?: Function): void {
- const url = layerInfo.url;
- const layerId = layerInfo.layerID || layerInfo.name;
- const { minzoom, maxzoom } = layerInfo;
- this._addBaselayer([url], layerId, layerInfo.visible, minzoom, maxzoom, true);
- addedCallback && addedCallback();
- }
-
- private _createWMSLayer(layerInfo: any, addedCallback?: Function): void {
- this.webMapService
- // @ts-ignore
- .getWmsInfo(layerInfo)
- .then(
- (result: any) => {
- const layerId = layerInfo.layerID || layerInfo.name;
- if (result) {
- const wmsUrl = this._getWMSUrl(layerInfo, result.version);
- this._addBaselayer([wmsUrl], layerId, layerInfo.visible);
- addedCallback && addedCallback();
- }
- },
- error => {
- addedCallback && addedCallback();
- throw new Error(error);
- }
- )
- .catch(error => {
- /**
- * @event WebMapViewModel#getmapinfofailed
- * @description 获取地图信息失败。
- * @property {Object} error - 失败原因。
- */
- this._triggerEvent('getmapinfofailed', { error });
- });
- }
-
- private _createVectorLayer(layerInfo: any, features: any): void {
- const type = layerInfo.featureType;
- const { layerID, minzoom, maxzoom, style, visible } = layerInfo;
- const layerSource = this.map.getSource(layerID);
- const sourceData: GeoJSON.FeatureCollection = {
- type: 'FeatureCollection',
- features: features
- };
- if (!layerSource) {
- const source: mapboxglTypes.GeoJSONSourceRaw = {
- type: 'geojson',
- data: sourceData
- };
- this.map.addSource(layerID, source);
- } else {
- // @ts-ignore
- layerSource.setData(sourceData);
- }
- const styleArr = Array.isArray(style) ? style : [style];
- if (styleArr.length === 2) {
- // 道路
- if (styleArr[0].lineDash === 'solid' && styleArr[1].lineDash === 'solid') {
- styleArr[0].strokeWidth = styleArr[1].strokeWidth;
- styleArr[1].strokeWidth = styleArr[1].strokeWidth - 2;
- }
- // 铁路
- if (styleArr[0].lineDash === 'solid' && styleArr[1].lineDash === 'dash') {
- styleArr[0].strokeWidth = styleArr[1].strokeWidth;
- styleArr[1].strokeWidth = styleArr[1].strokeWidth * 0.5;
- styleArr[1].lineDash = 'dashrailway';
- }
- }
- styleArr.forEach((element, index) => {
- const layerStyle = {
- style: this._transformStyleToMapBoxGl(element, type),
- layout: {
- visibility: visible
- }
- };
- const newLayerID = index === 0 ? layerID : `${layerID}-additional-${index}`;
- this._addOverlayToMap(type, layerID, newLayerID, layerStyle, minzoom, maxzoom);
- });
- // 如果面有边框
- type === 'POLYGON' &&
- style.strokeColor &&
- this._addStrokeLineForPoly(style, layerID, layerID + '-strokeLine', visible, minzoom, maxzoom);
- }
-
- private _getWMSUrl(mapInfo: any, version = '1.1.1'): string {
- let url = mapInfo.url;
- const options: any = {
- service: 'WMS',
- request: 'GetMap',
- layers:
- mapInfo.layers !== null && typeof mapInfo.layers === 'object'
- ? mapInfo.layers.join(',')
- : mapInfo.layers || '0', // 如果是多个图层,用逗号分隔
- styles: '',
- format: 'image/png',
- transparent: 'true',
- version,
- width: 256,
- height: 256
- };
- if (version === '1.3.0') {
- options.bbox = this.baseProjection === 'EPSG:4326' ? '{bbox-wms-1.3.0}' : '{bbox-epsg-3857}';
- options.crs = this.baseProjection;
- } else {
- options.bbox = '{bbox-epsg-3857}';
- options.srs = this.baseProjection;
- }
- return SuperMap.Util.urlAppend(url, this._getParamString(options, url));
- }
-
- private _setLayerID(mapInfo): Array