Skip to content

Commit b107e78

Browse files
committed
【feature】openlayers 对接矢量瓦片加密; review by songym
1 parent 41c1f0b commit b107e78

File tree

2 files changed

+309
-159
lines changed

2 files changed

+309
-159
lines changed

src/openlayers/overlay/VectorTileSuperMapRest.js

Lines changed: 76 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import { Util } from '../core/Util';
55
import { SecurityManager } from '@supermap/iclient-common/security/SecurityManager';
66
import { FetchRequest } from '@supermap/iclient-common/util/FetchRequest';
7+
import { EncryptRequest } from '@supermap/iclient-common/util/EncryptRequest';
78
import { Unit } from '@supermap/iclient-common/REST';
89
import { Util as CommonUtil } from '@supermap/iclient-common/commontypes/Util';
910
import { Bounds } from '@supermap/iclient-common/commontypes/Bounds';
@@ -16,6 +17,7 @@ import GeoJSON from 'ol/format/GeoJSON';
1617
import * as olSize from 'ol/size';
1718
import Projection from 'ol/proj/Projection';
1819
import TileGrid from 'ol/tilegrid/TileGrid';
20+
import decodeUtil from './bundle.esm';
1921

2022
/**
2123
* @class VectorTileSuperMapRest
@@ -32,6 +34,7 @@ import TileGrid from 'ol/tilegrid/TileGrid';
3234
* @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>'] - 版权描述信息。
3335
* @param {Object} [options.format] - 瓦片的要素格式化。
3436
* @param {boolean} [options.withCredentials] - 请求是否携带 cookie。
37+
* @param {boolean} [options.decrypt] - 瓦片是否需要解密。
3538
* @extends {ol.source.VectorTile}
3639
* @usage
3740
*/
@@ -59,9 +62,7 @@ export class VectorTileSuperMapRest extends VectorTile {
5962
overlaps: options.overlaps,
6063
projection: options.projection,
6164
state:
62-
options.format instanceof MVT &&
63-
options.style &&
64-
Object.prototype.toString.call(options.style) == '[object String]'
65+
options.format instanceof MVT
6566
? 'loading'
6667
: options.state,
6768
tileClass: options.tileClass,
@@ -77,21 +78,7 @@ export class VectorTileSuperMapRest extends VectorTile {
7778
me.withCredentials = options.withCredentials;
7879
me._tileType = options.tileType || 'ScaleXY';
7980
this.vectorTileStyles = new VectorTileStyles();
80-
if (options.format instanceof MVT && options.style) {
81-
if (Object.prototype.toString.call(options.style) == '[object String]') {
82-
var url = SecurityManager.appendCredential(options.style);
83-
FetchRequest.get(url, null, { withCredentials: options.withCredentials })
84-
.then((response) => response.json())
85-
.then((mbStyle) => {
86-
this._fillByStyleJSON(mbStyle, options.source);
87-
this.setState('ready');
88-
});
89-
} else {
90-
this._fillByStyleJSON(options.style, options.source);
91-
}
92-
} else {
93-
this._fillByRestMapOptions(options.url, options);
94-
}
81+
this._initialized(options);
9582

9683
function tileUrlFunction(tileCoord, pixelRatio, projection) {
9784
if (!me.tileGrid) {
@@ -156,10 +143,10 @@ export class VectorTileSuperMapRest extends VectorTile {
156143
if (!tileCoord) {
157144
return undefined;
158145
} else {
159-
return me._tileUrl
146+
return me._tileUrl
160147
.replace(zRegEx, tileCoord[0].toString())
161148
.replace(xRegEx, tileCoord[1].toString())
162-
.replace(yRegEx, function () {
149+
.replace(yRegEx, function () {
163150
var y = ['4', '5'].indexOf(Util.getOlVersion()) > -1 ? -tileCoord[2] - 1 : tileCoord[2];
164151
return y.toString();
165152
})
@@ -284,13 +271,17 @@ export class VectorTileSuperMapRest extends VectorTile {
284271
source = xhr.response;
285272
}
286273
if (source) {
274+
// console.time('瓦片解密完成');
275+
source = me._decryptMvt(source);
276+
// console.timeEnd('瓦片解密完成');
277+
// console.log('瓦片解密字节大小: ', source.byteLength);
287278
if (['4', '5'].indexOf(Util.getOlVersion()) > -1) {
288-
success.call(
289-
this,
290-
format.readFeatures(source, { featureProjection: projection }),
291-
format.readProjection(source),
292-
format.getLastExtent()
293-
);
279+
success.call(
280+
this,
281+
format.readFeatures(source, { featureProjection: projection }),
282+
format.readProjection(source),
283+
format.getLastExtent()
284+
);
294285
} else {
295286
success.call(
296287
this,
@@ -315,6 +306,27 @@ export class VectorTileSuperMapRest extends VectorTile {
315306
});
316307
}
317308
}
309+
310+
async _initialized(options) {
311+
if (options.format instanceof MVT && options.style) {
312+
let style = options.style;
313+
if (Object.prototype.toString.call(options.style) == '[object String]') {
314+
var url = SecurityManager.appendCredential(options.style);
315+
const response = await FetchRequest.get(url, null, { withCredentials: options.withCredentials })
316+
style = await response.json();
317+
}
318+
this._fillByStyleJSON(style, options.source);
319+
} else {
320+
this._fillByRestMapOptions(options.url, options);
321+
}
322+
if (options.format instanceof MVT) {
323+
if (options.decrypt) {
324+
await this._verifyVectorTileIsEncrypt(options);
325+
}
326+
this.setState('ready');
327+
}
328+
}
329+
318330
_fillByStyleJSON(style, source) {
319331
if (!source) {
320332
source = Object.keys(style.sources)[0];
@@ -375,6 +387,44 @@ export class VectorTileSuperMapRest extends VectorTile {
375387
this._tileUrl = CommonUtil.urlAppend(this._tileUrl, CommonUtil.getParameterString(params));
376388
}
377389

390+
async _verifyVectorTileIsEncrypt(options) {
391+
try {
392+
let serviceUrl = options.url || typeof options.style === 'string' && options.style;
393+
394+
if (!serviceUrl && Object.prototype.toString.call(options.style) == '[object Object]') {
395+
const firstSource = Object.keys(options.style.sources)[0];
396+
serviceUrl = options.style.sources[firstSource].tiles[0];
397+
}
398+
const workspaceServerUrl = (serviceUrl && serviceUrl.match(/.+(?=(\/restjsr\/v1\/vectortile\/|\/rest\/maps\/))/) || [])[0];
399+
if (!workspaceServerUrl) {
400+
return;
401+
}
402+
const servicesResponse = await FetchRequest.get(workspaceServerUrl);
403+
const servicesResult = await servicesResponse.json();
404+
const matchRestData = (servicesResult || []).find(item => serviceUrl.includes(item.name) && item.serviceEncryptInfo);
405+
if (!matchRestData) {
406+
return;
407+
}
408+
const iserverHost = workspaceServerUrl.split('/services/')[0];
409+
const encryptRequest = new EncryptRequest(iserverHost);
410+
const svckeyUrl = matchRestData && `${iserverHost}/services/security/svckeys/${matchRestData.serviceEncryptInfo.encrptKeyID}.json`
411+
const svcReponse = await encryptRequest.request({
412+
method: 'get',
413+
url: svckeyUrl
414+
})
415+
this.serviceKey = await svcReponse.json();
416+
} catch (error) {
417+
console.error(error);
418+
}
419+
}
420+
421+
_decryptMvt(mvtData) {
422+
if (this.serviceKey) {
423+
return decodeUtil(mvtData, this.serviceKey);
424+
}
425+
return mvtData;
426+
}
427+
378428
/**
379429
* @function VectorTileSuperMapRest.optionsFromMapJSON
380430
* @param {string} url - 地址。

0 commit comments

Comments
 (0)