Skip to content

Commit 64b67d8

Browse files
【update】处理ol 矢量瓦片支持相对地址服务加载 review by luox
1 parent 1c36f7d commit 64b67d8

File tree

5 files changed

+94
-9
lines changed

5 files changed

+94
-9
lines changed

src/common/commontypes/Util.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,34 @@ const Util = {
11101110
}
11111111
rgba.push(opacity);
11121112
return "rgba(" + rgba.join(",") + ")";
1113+
},
1114+
/**
1115+
* @description 是否是绝对地址。
1116+
* @private
1117+
* @param {string} url - 验证地址。
1118+
* @returns {boolean} 是否是绝对地址。
1119+
*/
1120+
isAbsoluteURL(url) {
1121+
try {
1122+
const res = new URL(url);
1123+
return !!res;
1124+
} catch (_) {
1125+
return false;
1126+
}
1127+
},
1128+
/**
1129+
* @description 相对地址转绝对地址。
1130+
* @private
1131+
* @param {string} url - 相对地址。
1132+
* @param {string} base - 基础地址。
1133+
* @returns {string} 完整地址。
1134+
*/
1135+
relative2absolute(url, base) {
1136+
let newUrl = new URL(url, base);
1137+
if (newUrl && newUrl.href) {
1138+
return decodeURIComponent(newUrl.href);
1139+
}
1140+
return;
11131141
}
11141142
};
11151143

src/common/mapping/WebMapV2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF
363363
style.layers.forEach(layer => {
364364
layer.layout && (layer.layout.visibility = this._getVisibility(layerInfo.visible));
365365
});
366-
this.map.addStyle(style);
366+
this.map.addStyle(style, undefined, undefined, undefined, url);
367367
const layerIds = [];
368368
style.layers.forEach((item) => {
369369
if (item.type !== 'background') {

src/openlayers/mapping/WebMap.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5126,10 +5126,16 @@ export class WebMap extends Observable {
51265126
const envelope = this.getEnvelope(indexbounds, layerInfo.bounds);
51275127
const styleResolutions = this.getStyleResolutions(envelope);
51285128
// const origin = [envelope.left, envelope.top];
5129-
let withCredentials = this.isIportalProxyServiceUrl(styles.sprite);
5130-
const requestParameters = this.tileRequestParameters && this.tileRequestParameters(styles.sprite);
5129+
let baseUrl = layerInfo.url && layerInfo.url.split('?')[0];
5130+
let spriteUrl = styles.sprite;
5131+
if (!CommonUtil.isAbsoluteURL(styles.sprite)) {
5132+
spriteUrl = CommonUtil.relative2absolute(styles.sprite, baseUrl);
5133+
}
5134+
let withCredentials = this.isIportalProxyServiceUrl(spriteUrl);
5135+
const requestParameters = this.tileRequestParameters && this.tileRequestParameters(spriteUrl);
51315136
// 创建MapBoxStyle样式
51325137
let mapboxStyles = new MapboxStyles({
5138+
baseUrl,
51335139
style: styles,
51345140
source: styles.name,
51355141
resolutions: styleResolutions,
@@ -5145,6 +5151,7 @@ export class WebMap extends Observable {
51455151
//设置避让参数
51465152
declutter: true,
51475153
source: new VectorTileSuperMapRest({
5154+
baseUrl,
51485155
style: styles,
51495156
withCredentials,
51505157
projection: layerInfo.projection,

src/openlayers/overlay/VectorTileSuperMapRest.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import decryptTileUtil from '@supermapgis/tile-decryptor';
2929
* @modulecategory Overlay
3030
* @param {Object} options - 参数。
3131
* @param {(string|undefined)} options.url - 服务地址。
32+
* @param {string} [options.baseUrl] - 当传入 style 对象且 style 中包含了相对路径时,需要传入 baseUrl 来拼接资源路径。
3233
* @param {(string|Object|undefined)} options.style - Mapbox Style JSON 对象或获取 Mapbox Style JSON 对象的 URL。当 `options.format` 为 {@link ol.format.MVT} 且 `options.source` 不为空时有效,优先级高于 `options.url`。
3334
* @param {(string|undefined)} options.source - Mapbox Style JSON 对象中的 source 名称。当 `options.style` 设置时有效。当不配置时,默认为 Mapbox Style JSON 的 `sources` 对象中的第一个。
3435
* @param {(string|Object)} [options.attributions='Tile Data <span>© <a href='http://support.supermap.com.cn/product/iServer.aspx' target='_blank'>SuperMap iServer</a></span> with <span>© <a href='https://iclient.supermap.io' target='_blank'>SuperMap iClient</a></span>'] - 版权描述信息。
@@ -80,6 +81,7 @@ export class VectorTileSuperMapRest extends VectorTile {
8081
me.withCredentials = options.withCredentials;
8182
me.headers = options.headers || {};
8283
me._tileType = options.tileType || 'ScaleXY';
84+
me.baseUrl = options.baseUrl;
8385
this.vectorTileStyles = new VectorTileStyles();
8486
this._initialized(options);
8587

@@ -317,7 +319,7 @@ export class VectorTileSuperMapRest extends VectorTile {
317319
});
318320
style = await response.json();
319321
}
320-
this._fillByStyleJSON(style, options.source);
322+
await this._fillByStyleJSON(style, options.source);
321323
} else {
322324
this._fillByRestMapOptions(options.url, options);
323325
}
@@ -329,13 +331,32 @@ export class VectorTileSuperMapRest extends VectorTile {
329331
}
330332
}
331333

332-
_fillByStyleJSON(style, source) {
334+
async _fillByStyleJSON(style, source) {
333335
if (!source) {
334336
source = Object.keys(style.sources)[0];
335337
}
338+
//ToDo 支持多个tiles地址
336339
if (style.sources && style.sources[source]) {
337-
//ToDo 支持多个tiles地址
338-
this._tileUrl = SecurityManager.appendCredential(style.sources[source].tiles[0]);
340+
let newUrl;
341+
if (style.sources[source].tiles) {
342+
newUrl = style.sources[source].tiles[0];
343+
if (!CommonUtil.isAbsoluteURL(newUrl)) {
344+
newUrl = CommonUtil.relative2absolute(newUrl, this.baseUrl);
345+
}
346+
} else if (style.sources[source].url) {
347+
let tiles = style.sources[source].url;
348+
if (!CommonUtil.isAbsoluteURL(tiles)) {
349+
tiles = CommonUtil.relative2absolute(tiles, this.baseUrl);
350+
}
351+
const response = await FetchRequest.get(tiles, {}, { withoutFormatSuffix: true });
352+
const sourceInfo = await response.json();
353+
let tileUrl = sourceInfo.tiles[0];
354+
if (!CommonUtil.isAbsoluteURL(tileUrl)) {
355+
tileUrl = CommonUtil.relative2absolute(tileUrl, style.sources[source].url);
356+
}
357+
newUrl = SecurityManager.appendCredential(tileUrl);
358+
}
359+
this._tileUrl = SecurityManager.appendCredential(newUrl);
339360
}
340361
if (style.metadata && style.metadata.indexbounds) {
341362
const indexbounds = style.metadata.indexbounds;

src/openlayers/overlay/vectortile/MapboxStyles.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
44
import { FetchRequest } from '@supermapgis/iclient-common/util/FetchRequest';
55
import { SecurityManager } from '@supermapgis/iclient-common/security/SecurityManager';
6-
import { Util as CommonUtil} from '@supermapgis/iclient-common/commontypes/Util';
6+
import { Util as CommonUtil } from '@supermapgis/iclient-common/commontypes/Util';
77
import { olExtends } from './olExtends';
88
import remove from 'lodash.remove';
99
import Observable from 'ol/Observable';
@@ -25,6 +25,7 @@ import Text from 'ol/style/Text';
2525
* @param {Object} options - 参数。
2626
* @param {(string|undefined)} [options.url] - SuperMap iServer 地图服务地址,例如'http://localhost:8090/iserver/services/map-mvt-test/rest/maps/test',与 options.style 互斥,优先级低于 options.style。
2727
* @param {(Object|string|undefined)} [options.style] - Mapbox Style JSON 对象或获取 Mapbox Style JSON 对象的 URL。与 options.url 互斥,优先级高于 options.url。
28+
* @param {string} [options.baseUrl] - 当传入 style 对象且 style 中包含了相对路径时,需要传入 baseUrl 来拼接资源路径。
2829
* @param {Array.<number>} [options.resolutions] - 地图分辨率数组,用于映射 zoom 值。通常情況与地图的 {@link ol.View} 的分辨率一致。</br>
2930
* 默认值为:[78271.51696402048,39135.75848201024, 19567.87924100512,9783.93962050256,4891.96981025128,2445.98490512564, 1222.99245256282,611.49622628141,305.748113140705,152.8740565703525, 76.43702828517625,38.21851414258813,19.109257071294063,9.554628535647032, 4.777314267823516,2.388657133911758,1.194328566955879,0.5971642834779395, 0.29858214173896974,0.14929107086948487,0.07464553543474244]。
3031
* @param {(string|Array.<string>|undefined)} [options.source] - Mapbox Style 'source'的 key 值或者 'layer' 的 ID 数组。
@@ -103,6 +104,7 @@ export class MapboxStyles extends Observable {
103104
});
104105
};
105106
this.layersBySourceLayer = {};
107+
this.baseUrl = options.baseUrl;
106108
olExtends(this.map);
107109
this._loadStyle(this.styleTarget);
108110
}
@@ -248,6 +250,7 @@ export class MapboxStyles extends Observable {
248250
}
249251
_loadStyle(style) {
250252
if (Object.prototype.toString.call(style) == '[object Object]') {
253+
this._handleRelativeUrl(style, this.baseUrl);
251254
this._mbStyle = style;
252255
setTimeout(() => {
253256
this._resolve();
@@ -257,6 +260,7 @@ export class MapboxStyles extends Observable {
257260
FetchRequest.get(url, null, { withCredentials: this.withCredentials, headers: this.headers })
258261
.then(response => response.json())
259262
.then(mbStyle => {
263+
this._handleRelativeUrl(mbStyle, url);
260264
this._mbStyle = mbStyle;
261265
this._resolve();
262266
});
@@ -288,7 +292,7 @@ export class MapboxStyles extends Observable {
288292
xhr.responseType = 'blob';
289293
xhr.addEventListener('loadend',(e) => {
290294
var data = e.target.response;
291-
if (data !== undefined) {
295+
if (data !== undefined && data !== null) {
292296
const img = new Image();
293297
img.src = URL.createObjectURL(data);
294298
this._spriteImage = img;
@@ -392,4 +396,29 @@ export class MapboxStyles extends Observable {
392396
const parts = url.match(this.spriteRegEx);
393397
return parts ? parts[1] + extension + (parts.length > 2 ? parts[2] : '') : url + extension;
394398
}
399+
400+
_handleRelativeUrl(styles, baseUrl) {
401+
if (!baseUrl) {
402+
return styles;
403+
}
404+
Object.keys(styles).forEach((fieldName) => {
405+
if (fieldName === 'sources') {
406+
Object.keys(styles[fieldName]).forEach((sourceName) => {
407+
this._handleRelativeUrl(styles[fieldName][sourceName], baseUrl);
408+
})
409+
}
410+
if (fieldName === 'sprite' || fieldName === 'glyphs' || fieldName === 'url') {
411+
if (typeof styles[fieldName] === 'string' && !CommonUtil.isAbsoluteURL(styles[fieldName])) {
412+
styles[fieldName] = CommonUtil.relative2absolute(styles[fieldName], baseUrl);
413+
}
414+
}
415+
if (fieldName === 'tiles' && Array.isArray(styles[fieldName])) {
416+
styles[fieldName].forEach((tile) => {
417+
if (!CommonUtil.isAbsoluteURL(tile)) {
418+
tile = CommonUtil.relative2absolute(tile, baseUrl);
419+
}
420+
})
421+
}
422+
})
423+
}
395424
}

0 commit comments

Comments
 (0)