Skip to content

Commit 6312328

Browse files
committed
【feature/API】优化openlayers mapboxsty矢量瓦片的接口,支持填入style json对象或地址,以支持iServer的矢量瓦片服务。增加测试
1 parent 06902c7 commit 6312328

File tree

6 files changed

+311
-94
lines changed

6 files changed

+311
-94
lines changed

src/openlayers/overlay/VectorTileSuperMapRest.js

Lines changed: 132 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ ol.supermap = ol.supermap || {};
2525
* @category Visualization VectorTile
2626
* @classdesc 矢量瓦片图层源。
2727
* @param {Object} options - 参数。
28-
* @param {string} options.url - 服务地址。
28+
* @param {(string|undefined)} options.url - SuperMap iServer 地图服务地址。
29+
* @param {(string|Object|undefined)} options.style - Mapbox Style JSON 对象或获取 Mapbox Style JSON 对象的 URL。当 `options.format` 为 `ol.format.MVT ` 且 `options.source` 不为空时有效,优先级高于 `options.url`。
30+
* @param {(string|undefined)} options.source - Mapbox Style JSON 对象中的source名称。当 `options.style` 设置时必填。
2931
* @param {string} [options.crossOrigin = 'anonymous'] - 跨域模式。
3032
* @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='http://iclient.supermap.io' target='_blank'>SuperMap iClient</a></span>'] - 版权信息。
3133
* @param {Object} [options.format] - 瓦片的要素格式化。
@@ -35,98 +37,54 @@ ol.supermap = ol.supermap || {};
3537
export class VectorTileSuperMapRest extends ol.source.VectorTile {
3638

3739
constructor(options) {
38-
if (options.url === undefined) {
40+
if (options.url === undefined && options.style === undefined) {
3941
return;
4042
}
43+
var zRegEx = /\{z\}/g;
44+
var xRegEx = /\{x\}/g;
45+
var yRegEx = /\{y\}/g;
46+
var dashYRegEx = /\{-y\}/g;
4147
options.crossOrigin = 'anonymous';
4248
options.attributions = options.attributions ||
4349
new ol.Attribution({
4450
html: "Tile Data <span>© <a href='http://support.supermap.com.cn/product/iServer.aspx' target='_blank'>SuperMap iServer</a></span> with <span>© <a href='http://iclient.supermap.io' target='_blank'>SuperMap iClient</a></span>"
4551
})
46-
var layerUrl = options.url + '/tileFeature.json?';
47-
if (options.format instanceof ol.format.MVT) {
48-
layerUrl = options.url + '/tileFeature.mvt?';
49-
}
50-
//为url添加安全认证信息片段
51-
options.serverType = options.serverType || ServerType.ISERVER;
52-
layerUrl = appendCredential(layerUrl, options.serverType);
53-
54-
function appendCredential(url, serverType) {
55-
var newUrl = url,
56-
credential, value;
57-
switch (serverType) {
58-
case ServerType.IPORTAL:
59-
value = SecurityManager.getToken(url);
60-
credential = value ? new Credential(value, "token") : null;
61-
if (!credential) {
62-
value = SecurityManager.getKey(url);
63-
credential = value ? new Credential(value, "key") : null;
64-
}
65-
break;
66-
case ServerType.ONLINE:
67-
value = SecurityManager.getKey(url);
68-
credential = value ? new Credential(value, "key") : null;
69-
break;
70-
default:
71-
//iserver or others
72-
value = SecurityManager.getToken(url);
73-
credential = value ? new Credential(value, "token") : null;
74-
break;
75-
}
76-
if (credential) {
77-
newUrl += "&" + credential.getUrlParameters();
78-
}
79-
return newUrl;
80-
}
8152

82-
var returnAttributes = true;
83-
if (options.returnAttributes !== undefined) {
84-
returnAttributes = options.returnAttributes
85-
}
86-
var params = "";
87-
params += "&returnAttributes=" + returnAttributes;
88-
if (options._cache !== undefined) {
89-
params += "&_cache=" + options._cache;
90-
}
91-
if (options.layersID !== undefined) {
92-
params += "&layersID=" + options.layersID;
93-
}
94-
if (options.layerNames !== undefined) {
95-
params += "&layerNames=" + options.layerNames;
96-
}
97-
if (options.expands !== undefined) {
98-
params += "&expands=" + options.expands;
99-
}
100-
if (options.compressTolerance !== undefined) {
101-
params += "&compressTolerance=" + options.compressTolerance;
102-
}
103-
if (options.coordinateType !== undefined) {
104-
params += "&coordinateType=" + options.coordinateType;
105-
}
106-
if (options.returnCutEdges !== undefined) {
107-
params += "&returnCutEdges=" + options.returnCutEdges;
108-
}
109-
layerUrl += encodeURI(params);
11053
super({
11154
attributions: options.attributions,
11255
cacheSize: options.cacheSize,
11356
format: options.format || new ol.format.GeoJSON(),
11457
logo: options.logo,
11558
overlaps: options.overlaps,
11659
projection: options.projection,
117-
state: options.state,
60+
state: (options.format instanceof ol.format.MVT && options.style && options.source && Object.prototype.toString.call(options.style) == "[object String]") ? "loading" : options.state,
11861
tileClass: options.tileClass,
11962
tileGrid: options.tileGrid,
12063
tilePixelRatio: options.tilePixelRatio,
121-
tileUrlFunction: tileUrlFunction,
64+
tileUrlFunction: (options.format instanceof ol.format.MVT && options.style && options.source) ? zxyTileUrlFunction : tileUrlFunction,
12265
tileLoadFunction: (options.format instanceof ol.format.MVT) ? undefined : tileLoadFunction,
12366
url: options.url,
12467
urls: options.urls,
12568
wrapX: options.wrapX !== undefined ? options.wrapX : false
12669
});
12770

12871
var me = this;
129-
me.tileType = options.tileType || 'ScaleXY';
72+
me._tileType = options.tileType || 'ScaleXY';
73+
if (options.format instanceof ol.format.MVT && options.style && options.source) {
74+
if (Object.prototype.toString.call(options.style) == "[object String]") {
75+
FetchRequest.get(options.style).then(response =>
76+
response.json()).then(mbStyle => {
77+
this._fillByStyleJSON(mbStyle, options.source);
78+
this.setState("");
79+
});
80+
} else {
81+
this._fillByStyleJSON(options.style, options.source)
82+
}
83+
84+
} else {
85+
this._fillByRestMapOptions(options.url, options);
86+
}
87+
13088

13189
function tileUrlFunction(tileCoord, pixelRatio, projection) {
13290
if (!me.tileGrid) {
@@ -159,9 +117,27 @@ export class VectorTileSuperMapRest extends ol.source.VectorTile {
159117
var scale = Util.resolutionToScale(resolution, dpi, unit);
160118
params = "&x=" + x + "&y=" + y + "&width=" + tileSize[0] + "&height=" + tileSize[1] + "&scale=" + scale + "&origin={'x':" + origin[0] + ",'y':" + origin[1] + "}";
161119
}
162-
return layerUrl + encodeURI(params);
120+
return me._tileUrl + encodeURI(params);
163121
}
164122

123+
function zxyTileUrlFunction(tileCoord) {
124+
if (!tileCoord) {
125+
return undefined;
126+
} else {
127+
return me._tileUrl.replace(zRegEx, tileCoord[0].toString())
128+
.replace(xRegEx, tileCoord[1].toString())
129+
.replace(yRegEx, function () {
130+
var y = -tileCoord[2] - 1;
131+
return y.toString();
132+
})
133+
.replace(dashYRegEx, function () {
134+
var z = tileCoord[0];
135+
var range = me.tileGrid.getFullTileRange(z);
136+
var y = range.getHeight() + tileCoord[2];
137+
return y.toString();
138+
});
139+
}
140+
}
165141
/**
166142
* @private
167143
* @function ol.source.VectorTileSuperMapRest.prototype.tileLoadFunction
@@ -220,6 +196,93 @@ export class VectorTileSuperMapRest extends ol.source.VectorTile {
220196
});
221197
}
222198
}
199+
_fillByStyleJSON(style, source) {
200+
if (style.sources && style.sources[source]) {
201+
//ToDo 支持多个tiles地址
202+
this._tileUrl = style.sources[source].tiles[0]
203+
}
204+
if (style.metadata && style.metadata.indexbounds) {
205+
const indexbounds = style.metadata.indexbounds;
206+
var max = Math.max(indexbounds[2] - indexbounds[0], indexbounds[3] - indexbounds[1]);
207+
const defaultResolutions = [];
208+
for (let index = 0; index < 30; index++) {
209+
defaultResolutions.push(max / 512 / Math.pow(2, index));
210+
211+
}
212+
this.tileGrid = new ol.tilegrid.TileGrid({
213+
extent: style.metadata.indexbounds,
214+
resolutions: defaultResolutions,
215+
tileSize: [512, 512]
216+
});
217+
}
218+
}
219+
_fillByRestMapOptions(url, options) {
220+
this._tileUrl = options.url + '/tileFeature.json?';
221+
if (options.format instanceof ol.format.MVT) {
222+
this._tileUrl = options.url + '/tileFeature.mvt?';
223+
}
224+
//为url添加安全认证信息片段
225+
options.serverType = options.serverType || ServerType.ISERVER;
226+
this._tileUrl = appendCredential(this._tileUrl, options.serverType);
227+
228+
function appendCredential(url, serverType) {
229+
var newUrl = url,
230+
credential, value;
231+
switch (serverType) {
232+
case ServerType.IPORTAL:
233+
value = SecurityManager.getToken(url);
234+
credential = value ? new Credential(value, "token") : null;
235+
if (!credential) {
236+
value = SecurityManager.getKey(url);
237+
credential = value ? new Credential(value, "key") : null;
238+
}
239+
break;
240+
case ServerType.ONLINE:
241+
value = SecurityManager.getKey(url);
242+
credential = value ? new Credential(value, "key") : null;
243+
break;
244+
default:
245+
//iserver or others
246+
value = SecurityManager.getToken(url);
247+
credential = value ? new Credential(value, "token") : null;
248+
break;
249+
}
250+
if (credential) {
251+
newUrl += "&" + credential.getUrlParameters();
252+
}
253+
return newUrl;
254+
}
255+
256+
var returnAttributes = true;
257+
if (options.returnAttributes !== undefined) {
258+
returnAttributes = options.returnAttributes
259+
}
260+
var params = "";
261+
params += "&returnAttributes=" + returnAttributes;
262+
if (options._cache !== undefined) {
263+
params += "&_cache=" + options._cache;
264+
}
265+
if (options.layersID !== undefined) {
266+
params += "&layersID=" + options.layersID;
267+
}
268+
if (options.layerNames !== undefined) {
269+
params += "&layerNames=" + options.layerNames;
270+
}
271+
if (options.expands !== undefined) {
272+
params += "&expands=" + options.expands;
273+
}
274+
if (options.compressTolerance !== undefined) {
275+
params += "&compressTolerance=" + options.compressTolerance;
276+
}
277+
if (options.coordinateType !== undefined) {
278+
params += "&coordinateType=" + options.coordinateType;
279+
}
280+
if (options.returnCutEdges !== undefined) {
281+
params += "&returnCutEdges=" + options.returnCutEdges;
282+
}
283+
this._tileUrl += encodeURI(params);
284+
}
285+
223286

224287
/**
225288
* @function ol.source.VectorTileSuperMapRest.optionsFromMapJSON

src/openlayers/overlay/vectortile/MapboxStyles.js

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ import {
2121
* </div>
2222
* @category Visualization VectorTile
2323
* @param {Object} options - 初始化参数。
24-
* @param {(string|undefined)} [options.url] - iServer UGCV5(MVT) 地图服务地址,例如'http://localhost:8090/iserver/services/map-mvt-test/rest/maps/test',与options.style互斥,优先级低于options.style。
25-
* @param {(Object|undefined)} [options.style] - Mapbox style 对象。与 options.url 互斥,优先级高于 options.url。
24+
* @param {(string|undefined)} [options.url] - SuperMap iServer 地图服务地址,例如'http://localhost:8090/iserver/services/map-mvt-test/rest/maps/test',与options.style互斥,优先级低于options.style。
25+
* @param {(Object|string|undefined)} [options.style] - Mapbox Style JSON 对象或获取 Mapbox Style JSON 对象的 URL。与 options.url 互斥,优先级高于 options.url。
2626
* @param {Array.<number>} [options.resolutions] - 地图分辨率数组,用于映射 zoom 值。通常情況与地图的 {@link ol.View} 的分辨率一致。</br>
2727
* 默认值为:[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]。
2828
* @param {(string|Array.<string>)} [options.source] - Mapbox Style 'source'的 key 值或者 'layer' 的 ID 数组。
2929
* 当配置 'source' 的 key 值时,source 为该值的 layer 会被加载;
3030
* 当配置为 'layer' 的 ID 数组时,指定的 layer 会被加载,注意被指定的 layer 需要有相同的 source。
31-
* @param {ol.Map} [options.map] - Openlayers 地图对象,仅用于填充 Mapbox Style 中的 background,如没有配置 background 可不设置该参数
31+
* @param {ol.Map} [options.map] - Openlayers 地图对象,仅用于面填充样式,若没有面填充样式可不填
3232
* @param {ol.StyleFunction} [options.selectedStyle] -选中样式Function。
3333
* @example
3434
* var mbStyle = new ol.supermap.MapboxStyles({
@@ -62,9 +62,8 @@ export class MapboxStyles extends ol.Observable {
6262
];
6363
this.map = options.map;
6464
this.source = options.source;
65-
this.url = options.url ? options.url + '/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true' : "";
65+
this.styleTarget = options.style || options.url + '/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true';
6666
this.resolutions = options.resolutions;
67-
this.style = options.style;
6867
this.selectedStyle = options.selectedStyle || function () {
6968
return new ol.style.Style({
7069
fill: new ol.style.Fill({
@@ -91,16 +90,8 @@ export class MapboxStyles extends ol.Observable {
9190
}
9291
this.layersBySourceLayer = {};
9392
olExtends(this.map);
94-
if (this.style) {
95-
this._mbStyle = this.style;
96-
this._resolve();
97-
} else if (this.url) {
98-
FetchRequest.get(this.url).then(response =>
99-
response.json()).then(mbStyle => {
100-
this._mbStyle = mbStyle;
101-
this._resolve()
102-
});
103-
}
93+
this._loadStyle(this.styleTarget);
94+
10495
}
10596
/**
10697
* @function ol.supermap.MapboxStyles.prototype.getStyleFunction
@@ -143,7 +134,7 @@ export class MapboxStyles extends ol.Observable {
143134
sourceLayer: sourceLayer
144135
};
145136
}
146-
/**
137+
/**
147138
* @function ol.supermap.MapboxStyles.prototype.updateStyles
148139
* @description 更新图层样式。
149140
* @param {Object} layerStyles - 图层样式或图层样式数组。
@@ -179,9 +170,20 @@ export class MapboxStyles extends ol.Observable {
179170
* @param {Object} style - Mapbox style 对象。
180171
*/
181172
setStyle(style) {
182-
this.layersBySourceLayer={};
183-
this._mbStyle = style;
184-
this._resolve();
173+
this.layersBySourceLayer = {};
174+
this._loadStyle(style);
175+
}
176+
_loadStyle(style) {
177+
if (Object.prototype.toString.call(style) == "[object Object]") {
178+
this._mbStyle = style;
179+
this._resolve();
180+
} else {
181+
FetchRequest.get(style).then(response =>
182+
response.json()).then(mbStyle => {
183+
this._mbStyle = mbStyle;
184+
this._resolve()
185+
});
186+
}
185187
}
186188
_resolve() {
187189
if (this._mbStyle.sprite) {

0 commit comments

Comments
 (0)