diff --git a/dist/ol/include-ol.js b/dist/ol/include-ol.js index 6297011130..a9f814ebf1 100644 --- a/dist/ol/include-ol.js +++ b/dist/ol/include-ol.js @@ -89,7 +89,7 @@ inputScript(libsurl + '/openlayers/ol3-echarts/1.3.6/ol3Echarts.min.js'); } if (inArray(includes, 'ol-mapbox-style')) { - inputScript(libsurl + '/openlayers/plugins/ol-mapbox-style/2.11.2-5/olms.js'); + inputScript(libsurl + '/openlayers/plugins/ol-mapbox-style/2.11.2-6/olms.js'); } if (inArray(includes, 'deck')) { inputScript(libsurl + '/deck.gl/5.1.3/deck.gl.min.js'); diff --git a/dist/openlayers/include-openlayers.js b/dist/openlayers/include-openlayers.js index d8066b5c9a..9b955ec0b8 100644 --- a/dist/openlayers/include-openlayers.js +++ b/dist/openlayers/include-openlayers.js @@ -89,7 +89,7 @@ inputScript(libsurl + '/openlayers/ol3-echarts/1.3.6/ol3Echarts.min.js'); } if (inArray(includes, 'ol-mapbox-style')) { - inputScript(libsurl + '/openlayers/plugins/ol-mapbox-style/2.11.2-5/olms.js'); + inputScript(libsurl + '/openlayers/plugins/ol-mapbox-style/2.11.2-6/olms.js'); } if (inArray(includes, 'deck')) { inputScript(libsurl + '/deck.gl/5.1.3/deck.gl.min.js'); diff --git a/src/common/commontypes/Util.js b/src/common/commontypes/Util.js index 58da5c0093..877b1a414d 100644 --- a/src/common/commontypes/Util.js +++ b/src/common/commontypes/Util.js @@ -1086,6 +1086,34 @@ const Util = { } return encodeURIComponent(value); }); + }, + /** + * @description 是否是绝对地址。 + * @private + * @param {string} url - 验证地址。 + * @returns {boolean} 是否是绝对地址。 + */ + isAbsoluteURL(url) { + try { + const res = new URL(url); + return !!res; + } catch (_) { + return false; + } + }, + /** + * @description 相对地址转绝对地址。 + * @private + * @param {string} url - 相对地址。 + * @param {string} base - 基础地址。 + * @returns {string} 完整地址。 + */ + relative2absolute(url, base) { + let newUrl = new URL(url, base); + if (newUrl && newUrl.href) { + return decodeURIComponent(newUrl.href); + } + return; } }; diff --git a/src/common/iServer/InitMapServiceBase.js b/src/common/iServer/InitMapServiceBase.js index dd03f8b0b8..851a75a88e 100644 --- a/src/common/iServer/InitMapServiceBase.js +++ b/src/common/iServer/InitMapServiceBase.js @@ -1,7 +1,7 @@ /* 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 { scaleToResolution, getZoomByResolution } from '../util/MapCalculateUtil'; +import { scaleToResolution, getZoomByResolution } from '../util/MapCalculateUtil'; /** * @private @@ -113,9 +113,15 @@ export function getEpsgCode(prjCoordSys) { * @description mapboxgl maplibregl 获取地图resolutions。 * @returns {Array} resolutions */ - export function scalesToResolutions(bounds, maxZoom = 22, tileSize = 512) { +export function extentToResolutions(bounds, maxZoom = 22, tileSize = 512) { var resolutions = []; - const maxReolution = Math.abs(bounds.left - bounds.right) / tileSize; + var left = bounds.left; + var right = bounds.right; + if (Array.isArray(bounds)) { + left = bounds[0]; + right = bounds[2]; + } + const maxReolution = Math.abs(left - right) / tileSize; for (let i = 0; i < maxZoom; i++) { resolutions.push(maxReolution / Math.pow(2, i)); } @@ -135,7 +141,7 @@ export function getEpsgCode(prjCoordSys) { * @param {Object} extent - extent。 * @returns {number} zoom */ - export function getZoom({ scale, dpi, coordUnit }, extent) { - const resolutions = scalesToResolutions(extent); +export function getZoom({ scale, dpi, coordUnit }, extent) { + const resolutions = extentToResolutions(extent); return getZoomByResolution(scaleToResolution(scale, dpi, coordUnit), resolutions); } \ No newline at end of file diff --git a/src/mapboxgl/core/Util.js b/src/mapboxgl/core/Util.js index 3ad5f0b623..5188fb9a10 100644 --- a/src/mapboxgl/core/Util.js +++ b/src/mapboxgl/core/Util.js @@ -45,7 +45,7 @@ export const Util = { if (geoJSON && geoJSON.type) { var format = new GeoJSONFormat(); var result = format.read(geoJSON, "FeatureCollection"); - return result[0].geometry; + return result && result[0].geometry; } }, diff --git a/src/maplibregl/core/Util.js b/src/maplibregl/core/Util.js index 2cde5f2248..6cf2f18e88 100644 --- a/src/maplibregl/core/Util.js +++ b/src/maplibregl/core/Util.js @@ -45,7 +45,7 @@ export const Util = { if (geoJSON && geoJSON.type) { var format = new GeoJSONFormat(); var result = format.read(geoJSON, "FeatureCollection"); - return result[0].geometry; + return result && result[0].geometry; } }, diff --git a/src/openlayers/core/Util.js b/src/openlayers/core/Util.js index 07522a88c0..ffb0e41a22 100644 --- a/src/openlayers/core/Util.js +++ b/src/openlayers/core/Util.js @@ -72,7 +72,7 @@ return null; } const result = new GeoJSONFormat().read(geoJSON, 'FeatureCollection'); - return result[0].geometry; + return result && result[0].geometry; }, /** diff --git a/src/openlayers/mapping/WebMap.js b/src/openlayers/mapping/WebMap.js index 31323b4687..193736f0cd 100644 --- a/src/openlayers/mapping/WebMap.js +++ b/src/openlayers/mapping/WebMap.js @@ -88,8 +88,8 @@ const dpiConfig = { * @param {function} [options.errorCallback] - 加载地图失败调用的函数 * @param {string} [options.credentialKey] - 凭证密钥。例如为"key"、"token",或者用户自定义的密钥。用户申请了密钥,此参数必填 * @param {string} [options.credentialValue] - 凭证密钥对应的值,credentialKey和credentialValue必须一起使用 - * @param {boolean} [options.withCredentials=false] - 请求是否携带 cookie - * @param {boolean} [options.excludePortalProxyUrl] - server传递过来的url是否带有代理 + * @deprecated {boolean} [options.withCredentials=false] - 请求是否携带 cookie。 + * @deprecated {boolean} [options.excludePortalProxyUrl] - server 传递过来的 URL 是否带有代理。 * @param {Object} [options.serviceProxy] - iportal内置代理信息, 仅矢量瓦片图层上图才会使用 * @param {string} [options.tiandituKey] - 天地图的key * @param {string} [options.bingMapsKey] - 必应地图的 key。 @@ -121,9 +121,7 @@ export class WebMap extends Observable { this.errorCallback = options.errorCallback; this.credentialKey = options.credentialKey; this.credentialValue = options.credentialValue; - this.withCredentials = options.withCredentials || false; this.target = options.target || "map"; - this.excludePortalProxyUrl = options.excludePortalProxyUrl || false; this.serviceProxy = options.serviceProxy || null; this.tiandituKey = options.tiandituKey; this.bingMapsKey = options.bingMapsKey || ''; @@ -270,7 +268,7 @@ export class WebMap extends Observable { } mapUrl = this.server + 'web/maps/' + this.mapId + '/map'; let filter = 'getUrlResource.json?url='; - if (this.excludePortalProxyUrl && this.server.indexOf(filter) > -1) { + if (this.server.indexOf(filter) > -1) { //大屏需求,或者有加上代理的 let urlArray = this.server.split(filter); if (urlArray.length > 1) { @@ -296,7 +294,7 @@ export class WebMap extends Observable { mapUrl = url; } FetchRequest.get(that.getRequestUrl(mapUrl), null, { - withCredentials: this.withCredentials + withCredentials: that.isCredentail(mapUrl) }).then(function (response) { return response.json(); }).then(function (mapInfo) { @@ -381,7 +379,7 @@ export class WebMap extends Observable { if (this.isCustomProjection(crs)) { // 去iServer请求wkt 否则只能预览出图 await FetchRequest.get(that.getRequestUrl(`${baseLayerUrl}/prjCoordSys.wkt`), null, { - withCredentials: that.withCredentials, + withCredentials: that.isCredentail(baseLayerUrl), withoutFormatSuffix: true }).then(function (response) { return response.text(); @@ -550,7 +548,7 @@ export class WebMap extends Observable { if (baseLayerType === "TILE") { url = this.handleJSONSuffix(url); FetchRequest.get(me.getRequestUrl(url), null, { - withCredentials: this.withCredentials + withCredentials: me.isCredentail(url) }).then(function (response) { return response.json(); }).then(function (result) { @@ -569,7 +567,7 @@ export class WebMap extends Observable { url, tileGrid: TileSuperMapRest.optionsFromMapJSON(url, result).tileGrid } - if (url && !CommonUtil.isInTheSameDomain(url) && !this.isIportalProxyServiceUrl(url)) { + if (url && me.isAddProxy(url)) { options.tileProxy = me.server + 'apps/viewer/getUrlResource.png?url='; } source = new TileSuperMapRest(options); @@ -582,7 +580,7 @@ export class WebMap extends Observable { me.addSpecToMap(source); } else if (baseLayerType === "WMTS") { FetchRequest.get(me.getRequestUrl(url, true), null, { - withCredentials: this.withCredentials + withCredentials: me.isCredentail(url) }).then(function (response) { return response.text(); }).then(function (capabilitiesText) { @@ -1196,7 +1194,7 @@ export class WebMap extends Observable { options.tileGrid = tileGrid; } //主机名相同时不添加代理,iportal geturlResource不支持webp代理 - if (layerInfo.url && !CommonUtil.isInTheSameDomain(layerInfo.url) && !this.isIportalProxyServiceUrl(layerInfo.url) && layerInfo.format !== 'webp') { + if (layerInfo.url && layerInfo.format !== 'webp' && this.isAddProxy(layerInfo.url, layerInfo.proxy)) { options.tileProxy = this.server + 'apps/viewer/getUrlResource.png?url='; } let source = new TileSuperMapRest(options); @@ -1301,8 +1299,9 @@ export class WebMap extends Observable { }, projection: layerInfo.projection || that.baseProjection, tileLoadFunction: function (imageTile, src) { - imageTile.getImage().src = src + imageTile.getImage().src = that.isAddProxy(src, layerInfo.proxy) ? `${that.getProxy('png')}${encodeURIComponent(src)}`: src; } + }) } @@ -1350,7 +1349,7 @@ export class WebMap extends Observable { url = layerInfo.url.trim(), credential = layerInfo.credential, options = { - withCredentials: this.withCredentials, + withCredentials: that.isCredentail(url, layerInfo.proxy), withoutFormatSuffix: true }; if (isDynamic) { @@ -1367,7 +1366,7 @@ export class WebMap extends Observable { token = credential.token; } url = this.handleJSONSuffix(url); - return FetchRequest.get(that.getRequestUrl(url), null, options).then(function (response) { + return FetchRequest.get(that.getRequestUrl(url, layerInfo.proxy), null, options).then(function (response) { return response.json(); }).then(async (result) => { if (result.succeed === false) { @@ -1375,7 +1374,7 @@ export class WebMap extends Observable { } let format = 'png'; if(that.tileFormat === 'webp') { - const isSupportWebp = await that.isSupportWebp(layerInfo.url, token); + const isSupportWebp = await that.isSupportWebp(layerInfo.url, token, layerInfo.proxy); format = isSupportWebp ? 'webp' : 'png'; } return { @@ -1404,7 +1403,7 @@ export class WebMap extends Observable { getTileInfo(layerInfo, callback, mapInfo) { let that = this; let options = { - withCredentials: this.withCredentials, + withCredentials: that.isCredentail(layerInfo.url, layerInfo.proxy), withoutFormatSuffix: true }; let tempUrl = layerInfo.url; @@ -1413,7 +1412,7 @@ export class WebMap extends Observable { layerInfo.url = layerInfo.url.split("?token=")[0]; } let url = this.handleJSONSuffix(tempUrl); - return FetchRequest.get(that.getRequestUrl(url), null, options).then(function (response) { + return FetchRequest.get(that.getRequestUrl(url, layerInfo.proxy), null, options).then(function (response) { return response.json(); }).then(async function (result) { // layerInfo.projection = mapInfo.projection; @@ -1432,7 +1431,7 @@ export class WebMap extends Observable { layerInfo.format = 'png'; // china_dark为默认底图,还是用png出图 if(that.tileFormat === 'webp' && layerInfo.url !== 'https://maptiles.supermapol.com/iserver/services/map_China/rest/maps/China_Dark') { - const isSupprtWebp = await that.isSupportWebp(layerInfo.url, token); + const isSupprtWebp = await that.isSupportWebp(layerInfo.url, token, layerInfo.proxy); layerInfo.format = isSupprtWebp ? 'webp' : 'png'; } // 请求结果完成 继续添加图层 @@ -1454,7 +1453,7 @@ export class WebMap extends Observable { * @param {string} url - 图层信息。 * @param {boolean} isKvp - 是否为kvp模式 */ - getWMTSUrl(url, isKvp) { + getWMTSUrl(url, isKvp, proxy) { let splitStr = '?'; if (url.indexOf('?') > -1) { splitStr = '&' @@ -1464,7 +1463,7 @@ export class WebMap extends Observable { } else { url += splitStr + '/1.0.0/WMTSCapabilities.xml'; } - return this.getRequestUrl(url, true); + return this.getRequestUrl(url, proxy); } /** @@ -1477,18 +1476,18 @@ export class WebMap extends Observable { getWmtsInfo(layerInfo, callback) { let that = this; let options = { - withCredentials: that.withCredentials, + withCredentials: that.isCredentail(layerInfo.url, layerInfo.proxy), withoutFormatSuffix: true }; const isKvp = !layerInfo.requestEncoding || layerInfo.requestEncoding === 'KVP'; - return FetchRequest.get(that.getWMTSUrl(layerInfo.url, isKvp), null, options).then(function (response) { + return FetchRequest.get(that.getWMTSUrl(layerInfo.url, isKvp, layerInfo.proxy), null, options).then(function (response) { return response.text(); }).then(function (capabilitiesText) { const format = new WMTSCapabilities(); let capabilities = format.read(capabilitiesText); if (that.isValidResponse(capabilities)) { let content = capabilities.Contents; - let tileMatrixSet = content.TileMatrixSet, + let tileMatrixSet = content.TileMatrixSet, layers = content.Layer, layer, idx, layerFormat, style = 'default'; @@ -1568,12 +1567,12 @@ export class WebMap extends Observable { let url = layerInfo.url.trim(); url += (url.indexOf('?') > -1 ? '&SERVICE=WMS&REQUEST=GetCapabilities' : '?SERVICE=WMS&REQUEST=GetCapabilities'); let options = { - withCredentials: that.withCredentials, + withCredentials: that.isCredentail(url, layerInfo.proxy), withoutFormatSuffix: true }; let promise = new Promise(function (resolve) { - return FetchRequest.get(that.getRequestUrl(url, true), null, options).then(function (response) { + return FetchRequest.get(that.getRequestUrl(url, layerInfo.proxy), null, options).then(function (response) { return response.text(); }).then(async function (capabilitiesText) { const format = new WMSCapabilities(); @@ -1648,7 +1647,7 @@ export class WebMap extends Observable { // 单位通过坐标系获取 (PS: 以前代码非4326 都默认是米) let unit = olProj.get(this.baseProjection).getUnits(); - + const that = this; return new WMTS({ url: layerInfo.tileUrl || layerInfo.url, layer: layerInfo.layer, @@ -1662,6 +1661,10 @@ export class WebMap extends Observable { imageTile.getImage().src = `${src}&tk=${CommonUtil.getParameters(layerInfo.url)['tk']}`; return; } + if(that.isAddProxy(src, layerInfo.proxy)) { + imageTile.getImage().src = `${that.getProxy('png')}${encodeURIComponent(src)}`; + return; + } imageTile.getImage().src = src } }) @@ -1805,14 +1808,14 @@ export class WebMap extends Observable { await that.addLayer(layer, null, layerIndex); that.layerAdded++; that.sendMapToUser(len); - return; + continue; } if ((layer.layerType === "MARKER") || (dataSource && (!dataSource.accessType || dataSource.accessType === 'DIRECT')) || isSampleData) { //原来二进制文件 let url = isSampleData ? `${that.server}apps/dataviz/libs/sample-datas/${dataSource.name}.json` : `${that.server}web/datas/${serverId}/content.json?pageSize=9999999¤tPage=1`; - url = that.getRequestUrl(url); + url = that.getRequestUrl(url, layer.proxy); FetchRequest.get(url, null, { - withCredentials: this.withCredentials + withCredentials: that.isCredentail(url, layer.proxy) }).then(function (response) { return response.json() }).then(async function (data) { @@ -1870,7 +1873,7 @@ export class WebMap extends Observable { if (isMapService) { //需要判断是使用tile还是mvt服务 let dataService = that.getService(dataItemServices, 'RESTDATA'); - that.isMvt(dataService.address, datasetName).then(async info => { + that.isMvt(dataService.address, datasetName, layer.proxy).then(async info => { await that.getServiceInfoFromLayer(layerIndex, len, layer, dataItemServices, datasetName, featureType, info); }).catch(async () => { //判断失败就走之前逻辑,>数据量用tile @@ -1892,7 +1895,7 @@ export class WebMap extends Observable { }) } } else if (dataSource && dataSource.type === "USER_DATA") { - that.addGeojsonFromUrl(layer, len, layerIndex, false); + that.addGeojsonFromUrl(layer, len, layerIndex); } else if (layer.layerType === "TILE"){ that.getTileLayerExtent(layer, function (layerInfo) { that.map.addLayer(that.createBaseLayer(layerInfo, layerIndex)); @@ -1979,11 +1982,11 @@ export class WebMap extends Observable { * @param {number} layerIndex - 当前图层index * @param {boolean} withCredentials - 是否携带cookie */ - addGeojsonFromUrl(layerInfo, len, layerIndex, withCredentials = this.withCredentials) { + addGeojsonFromUrl(layerInfo, len, layerIndex) { // 通过web添加geojson不需要携带cookie let {dataSource} = layerInfo, {url} = dataSource, that = this; FetchRequest.get(url, null, { - withCredentials, + withCredentials: that.isCredentail(url), withoutFormatSuffix: true }).then(function (response) { return response.json() @@ -2056,7 +2059,7 @@ export class WebMap extends Observable { if (service && isMapService && service.serviceType === 'RESTMAP') { isAdded = true; //地图服务,判断使用mvt还是tile - that.getTileLayerInfo(service.address).then(function (restMaps) { + that.getTileLayerInfo(service.address, layer.proxy).then(function (restMaps) { restMaps.forEach(function (restMapInfo) { let bounds = restMapInfo.bounds; layer.layerType = 'TILE'; @@ -2123,13 +2126,13 @@ export class WebMap extends Observable { let that = this; let url = layerInfo.url, token; url = this.handleJSONSuffix(url); - let requestUrl = that.getRequestUrl(url, false); + let requestUrl = that.getRequestUrl(url, layerInfo.proxy); if (layerInfo.credential && layerInfo.credential.token) { token = layerInfo.credential.token; requestUrl += `?token=${token}`; } FetchRequest.get(requestUrl, null, { - withCredentials: this.withCredentials + withCredentials: that.isCredentail(url, layerInfo.proxy) }).then(function (response) { return response.json() }).then(function (result) { @@ -2157,8 +2160,8 @@ export class WebMap extends Observable { url = layer.dataSource.url, dataSourceName = dataSource.dataSourceName || layer.name; let requestUrl = that.formatUrlWithCredential(url), serviceOptions = {}; - serviceOptions.withCredentials = this.withCredentials; - if (!this.excludePortalProxyUrl && !CommonUtil.isInTheSameDomain(requestUrl) && !this.isIportalProxyServiceUrl(requestUrl)) { + serviceOptions.withCredentials = this.isCredentail(url, layer.proxy); + if (that.isAddProxy(requestUrl, layer.proxy)) { serviceOptions.proxy = this.getProxy(); } if(['EPSG:0'].includes(layer.projection)) { @@ -2260,8 +2263,9 @@ export class WebMap extends Observable { if (layerInfo.layerType === 'MIGRATION') { try { if (dataSource.type === 'PORTAL_DATA') { - const {dataMetaInfo} = await FetchRequest.get(`${this.server}web/datas/${dataSource.serverId}.json`, null, { - withCredentials: this.withCredentials + const requestUrl = `${this.server}web/datas/${dataSource.serverId}.json`; + const {dataMetaInfo} = await FetchRequest.get(requestUrl, null, { + withCredentials: this.isCredentail(requestUrl) }).then(res => res.json()); // eslint-disable-next-line require-atomic-updates layerInfo.xyField = { @@ -2649,8 +2653,8 @@ export class WebMap extends Observable { that.addGeojsonFromUrl(layerInfo, null, layerIndex) } else { let requestUrl = that.formatUrlWithCredential(url), serviceOptions = {}; - serviceOptions.withCredentials = this.withCredentials; - if (!this.excludePortalProxyUrl && !CommonUtil.isInTheSameDomain(requestUrl) && !this.isIportalProxyServiceUrl(requestUrl)) { + serviceOptions.withCredentials = that.isCredentail(requestUrl); + if (that.isAddProxy(requestUrl)) { serviceOptions.proxy = this.getProxy(); } //因为itest上使用的https,iserver是http,所以要加上代理 @@ -3934,7 +3938,7 @@ export class WebMap extends Observable { checkUploadToRelationship(fileId) { let url = this.getRequestUrl(`${this.server}web/datas/${fileId}/datasets.json`); return FetchRequest.get(url, null, { - withCredentials: this.withCredentials + withCredentials: this.isCredentail(url) }).then(function (response) { return response.json() }).then(function (result) { @@ -3951,7 +3955,7 @@ export class WebMap extends Observable { getDatasources(url) { let requestUrl = this.getRequestUrl(`${url}/data/datasources.json`); return FetchRequest.get(requestUrl, null, { - withCredentials: this.withCredentials + withCredentials: this.isCredentail(requestUrl) }).then(function (response) { return response.json() }).then(function (datasource) { @@ -3971,7 +3975,7 @@ export class WebMap extends Observable { getDataService(fileId, datasetName) { let url = this.getRequestUrl(`${this.server}web/datas/${fileId}.json`); return FetchRequest.get(url, null, { - withCredentials: this.withCredentials + withCredentials: this.isCredentail(url) }).then(function (response) { return response.json() }).then(function (result) { @@ -3981,21 +3985,40 @@ export class WebMap extends Observable { }); } + /** + * 请求是否带上cookie + * @param {string} url 请求地址,必选参数。 + * @param {boolean} proxy 是否需要加上代理,可选参数。 + * @returns + */ + isCredentail(url, proxy) { + if(proxy || this.isIportalProxyServiceUrl(url) || CommonUtil.isInTheSameDomain(url)) { + return true + } + return; + } + /** + * url是否要带上代理 + * @param {*} url 请求地址,必选参数。 + * @param {*} proxy 是否需要加上代理,可选参数。 + * @returns + */ + isAddProxy(url, proxy) { + return !CommonUtil.isInTheSameDomain(url) && !this.isIportalProxyServiceUrl(url) && proxy !== false; + } /** * @private * @function WebMap.prototype.getRootUrl * @description 获取请求地址 * @param {string} url 请求的地址 - * @param {boolean} 请求是否带上Credential. + * @param {boolean | undefined} proxy 是否带上代理。 * @returns {Promise} 请求地址 */ - getRequestUrl(url, excludeCreditial) { - url = excludeCreditial ? url : this.formatUrlWithCredential(url); - //如果传入进来的url带了代理则不需要处理 - if (this.excludePortalProxyUrl) { - return; - } - return CommonUtil.isInTheSameDomain(url) || this.isIportalProxyServiceUrl(url) ? url : `${this.getProxy()}${encodeURIComponent(url)}`; + getRequestUrl(url, proxy) { + url = this.formatUrlWithCredential(url); + return this.isAddProxy(url, proxy) ? + `${this.getProxy()}${encodeURIComponent(url)}`: + url; } /** @@ -4031,20 +4054,20 @@ export class WebMap extends Observable { * @param {string} url 地图服务的url(没有地图名字) * @returns {Promise} 地图服务信息 */ - getTileLayerInfo(url) { + getTileLayerInfo(url, proxy) { let that = this, epsgCode = that.baseProjection.split('EPSG:')[1]; - let requestUrl = that.getRequestUrl(`${url}/maps.json`); + let requestUrl = that.getRequestUrl(`${url}/maps.json`, proxy); return FetchRequest.get(requestUrl, null, { - withCredentials: this.withCredentials + withCredentials: that.isCredentail(url, proxy) }).then(function (response) { return response.json() }).then(function (mapInfo) { let promises = []; if (mapInfo) { mapInfo.forEach(function (info) { - let mapUrl = that.getRequestUrl(`${info.path}.json?prjCoordSys=${encodeURI(JSON.stringify({epsgCode: epsgCode}))}`) + let mapUrl = that.getRequestUrl(`${info.path}.json?prjCoordSys=${encodeURI(JSON.stringify({epsgCode: epsgCode}))}`, proxy) let promise = FetchRequest.get(mapUrl, null, { - withCredentials: that.withCredentials + withCredentials: that.isCredentail(mapUrl, proxy) }).then(function (response) { return response.json() }).then(function (restMapInfo) { @@ -4426,13 +4449,13 @@ export class WebMap extends Observable { * @param {string} datasetName 数据服务的数据集名称 * @returns {Object} 数据服务的信息 */ - isMvt(serviceUrl, datasetName) { + isMvt(serviceUrl, datasetName, proxy) { let that = this; return this.getDatasetsInfo(serviceUrl, datasetName).then((info) => { //判断是否和底图坐标系一直 if (info.epsgCode == that.baseProjection.split('EPSG:')[1]) { - return FetchRequest.get(that.getRequestUrl(`${info.url}/tilefeature.mvt`), null, { - withCredentials: that.withCredentials + return FetchRequest.get(that.getRequestUrl(`${info.url}/tilefeature.mvt`, proxy), null, { + withCredentials: that.isCredentail(info.url, proxy) }).then(function (response) { return response.json() }).then(function (result) { @@ -4460,7 +4483,7 @@ export class WebMap extends Observable { //判断mvt服务是否可用 let url = `${serviceUrl}/data/datasources/${datasourceName}/datasets/${datasetName}.json`; return FetchRequest.get(that.getRequestUrl(url), null, { - withCredentials: that.withCredentials + withCredentials: that.isCredentail(url) }).then(function (response) { return response.json() }).then(function (datasetsInfo) { @@ -4525,10 +4548,14 @@ export class WebMap extends Observable { let dataSource = layerInfo.dataSource; let url = dataSource.url; if (this.isRestMapMapboxStyle(layerInfo)) { - url = url.replace(restMapMVTStr, '') + url = url.replace(restMapMVTStr, ''); + url = this.getRequestUrl(url + '.json'); + } + if (url.indexOf('/restjsr/') > -1 && !/\.json$/.test(url)) { + url = this.getRequestUrl(url + '.json', layerInfo.proxy); + } else { + url = this.getRequestUrl(url, layerInfo.proxy); } - url = this.getRequestUrl(url + '.json') - let credential = layerInfo.credential; let credentialValue,keyfix; //携带令牌(restmap用的首字母大写,但是这里要用小写) @@ -4539,7 +4566,7 @@ export class WebMap extends Observable { } return FetchRequest.get(url, null, { - withCredentials: this.withCredentials, + withCredentials: this.isCredentail(url, layerInfo.proxy), withoutFormatSuffix: true, headers: { 'Content-Type': 'application/json;chartset=uft-8' @@ -4548,10 +4575,23 @@ export class WebMap extends Observable { return response.json(); }).then((result) => { layerInfo.visibleScales = result.visibleScales; - layerInfo.coordUnit = result.coordUnit; + layerInfo.coordUnit = result.coordUnit || 'METER'; layerInfo.scale = result.scale; - layerInfo.epsgCode = result.prjCoordSys.epsgCode; - layerInfo.bounds = result.bounds; + layerInfo.epsgCode = (result.prjCoordSys && result.prjCoordSys.epsgCode) || '3857'; + layerInfo.bounds = result.bounds || { + top: 20037508.342789244, + left: -20037508.342789244, + bottom: -20037508.342789244, + leftBottom: { + x: -20037508.342789244, + y: -20037508.342789244 + }, + right: 20037508.342789244, + rightTop: { + x: 20037508.342789244, + y: 20037508.342789244 + } + }; return layerInfo; }).catch(error => { throw error; @@ -4571,10 +4611,10 @@ export class WebMap extends Observable { let _this = this; let url = layerInfo.url || layerInfo.dataSource.url; let styleUrl = url; - if (styleUrl.indexOf('/restjsr/') > -1) { + if (styleUrl.indexOf('/restjsr/') > -1 && !/\/style\.json$/.test(url)) { styleUrl = `${styleUrl}/style.json`; } - styleUrl = this.getRequestUrl(styleUrl) + styleUrl = this.getRequestUrl(styleUrl, layerInfo.proxy) let credential = layerInfo.credential; //携带令牌(restmap用的首字母大写,但是这里要用小写) let credentialValue, keyfix; @@ -4585,7 +4625,7 @@ export class WebMap extends Observable { } return FetchRequest.get(styleUrl, null, { - withCredentials: this.withCredentials, + withCredentials: this.isCredentail(styleUrl, layerInfo.proxy), withoutFormatSuffix: true, headers: { 'Content-Type': 'application/json;chartset=uft-8' @@ -4602,7 +4642,8 @@ export class WebMap extends Observable { let sourcesNames = Object.keys(sources); sourcesNames.forEach(function (sourceName) { styles.sources[sourceName].tiles.forEach(function (tiles, i) { - styles.sources[sourceName].tiles[i] = `${tiles}?${keyfix}=${credentialValue}` + const splicing = tiles.includes('?') ? '&' : '?'; + styles.sources[sourceName].tiles[i] = `${tiles}${splicing}${keyfix}=${credentialValue}`; }) }) } @@ -4801,9 +4842,29 @@ export class WebMap extends Observable { const envelope = this.getEnvelope(indexbounds, layerInfo.bounds); const styleResolutions = this.getStyleResolutions(envelope); // const origin = [envelope.left, envelope.top]; - let withCredentials = this.isIportalProxyServiceUrl(styles.sprite); + let baseUrl = layerInfo.url; + let paramUrl = baseUrl.split('?')[1]; + if (layerInfo.dataSource.type === 'ARCGIS_VECTORTILE') { + Object.keys(styles.sources).forEach(function (key) { + Object.keys(styles.sources[key]).forEach(function(fieldName) { + if (fieldName === 'url') { + if (typeof styles.sources[key][fieldName] === 'string' && !CommonUtil.isAbsoluteURL(styles.sources[key][fieldName])) { + styles.sources[key][fieldName] = CommonUtil.relative2absolute(styles.sources[key][fieldName], baseUrl); + } + styles.sources[key][fieldName] = styles.sources[key][fieldName] + (paramUrl ? '?' + paramUrl + '&f=json' : '?f=json'); + } + }); + }); + } + let sourceName = Object.keys(styles.sources)[0]; + let checkUrl = styles.sources[sourceName].url || styles.sources[sourceName].tiles[0]; + if (checkUrl && !CommonUtil.isAbsoluteURL(checkUrl)) { + checkUrl = CommonUtil.relative2absolute(checkUrl, baseUrl); + } + let withCredentials = CommonUtil.isInTheSameDomain(checkUrl) || this.isIportalProxyServiceUrl(checkUrl); // 创建MapBoxStyle样式 let mapboxStyles = new MapboxStyles({ + baseUrl, style: styles, source: styles.name, resolutions: styleResolutions, @@ -4818,6 +4879,7 @@ export class WebMap extends Observable { //设置避让参数 declutter: true, source: new VectorTileSuperMapRest({ + baseUrl, style: styles, withCredentials, projection: layerInfo.projection, @@ -4847,7 +4909,7 @@ export class WebMap extends Observable { * @param {*} token 服务token * @returns {boolean} */ - isSupportWebp(url, token) { + isSupportWebp(url, token, proxy) { // 还需要判断浏览器 let isIE = this.isIE(); if (isIE || (this.isFirefox() && this.getFirefoxVersion() < 65) || @@ -4855,16 +4917,9 @@ export class WebMap extends Observable { return false; } url = token ? `${url}/tileImage.webp?token=${token}` : `${url}/tileImage.webp`; - let isSameDomain = CommonUtil.isInTheSameDomain(url), excledeCreditial; - if (isSameDomain && !token) { - // online上服务域名一直,要用token值 - excledeCreditial = false; - } else { - excledeCreditial = true; - } - url = this.getRequestUrl(url, excledeCreditial); + url = this.getRequestUrl(url, proxy); return FetchRequest.get(url, null, { - withCredentials: this.withCredentials, + withCredentials: this.isCredentail(url, proxy), withoutFormatSuffix: true }).then(function (response) { if (response.status !== 200) { diff --git a/src/openlayers/overlay/VectorTileSuperMapRest.js b/src/openlayers/overlay/VectorTileSuperMapRest.js index aa2913aaad..3068ebc45b 100644 --- a/src/openlayers/overlay/VectorTileSuperMapRest.js +++ b/src/openlayers/overlay/VectorTileSuperMapRest.js @@ -25,6 +25,7 @@ import TileGrid from 'ol/tilegrid/TileGrid'; * @modulecategory Overlay * @param {Object} options - 参数。 * @param {(string|undefined)} options.url - 服务地址。 + * @param {string} [options.baseUrl] - 当传入 style 对象且 style 中包含了相对路径时,需要传入 baseUrl 来拼接资源路径。 * @param {(string|Object|undefined)} options.style - Mapbox Style JSON 对象或获取 Mapbox Style JSON 对象的 URL。当 `options.format` 为 {@link ol.format.MVT} 且 `options.source` 不为空时有效,优先级高于 `options.url`。 * @param {(string|undefined)} options.source - Mapbox Style JSON 对象中的source名称。当 `options.style` 设置时有效。当不配置时,默认为 Mapbox Style JSON 的 `sources` 对象中的第一个。 * @param {(string|Object)} [options.attributions='Tile Data © SuperMap iServer with © SuperMap iClient'] - 版权信息。 @@ -58,8 +59,7 @@ export class VectorTileSuperMapRest extends VectorTile { projection: options.projection, state: options.format instanceof MVT && - options.style && - Object.prototype.toString.call(options.style) == '[object String]' + options.style ? 'loading' : options.state, tileClass: options.tileClass, @@ -74,22 +74,9 @@ export class VectorTileSuperMapRest extends VectorTile { var me = this; me.withCredentials = options.withCredentials; me._tileType = options.tileType || 'ScaleXY'; + me.baseUrl = options.baseUrl; this.vectorTileStyles = new VectorTileStyles(); - if (options.format instanceof MVT && options.style) { - if (Object.prototype.toString.call(options.style) == '[object String]') { - var url = SecurityManager.appendCredential(options.style); - FetchRequest.get(url, null, { withCredentials: options.withCredentials }) - .then((response) => response.json()) - .then((mbStyle) => { - this._fillByStyleJSON(mbStyle, options.source); - this.setState('ready'); - }); - } else { - this._fillByStyleJSON(options.style, options.source); - } - } else { - this._fillByRestMapOptions(options.url, options); - } + this._initialized(options); function tileUrlFunction(tileCoord, pixelRatio, projection) { if (!me.tileGrid) { @@ -313,13 +300,56 @@ export class VectorTileSuperMapRest extends VectorTile { }); } } - _fillByStyleJSON(style, source) { + + async _initialized(options) { + if (options.format instanceof MVT && options.style) { + let style = options.style; + if (Object.prototype.toString.call(options.style) == '[object String]') { + var url = SecurityManager.appendCredential(options.style); + const response = await FetchRequest.get(url, null, { + withCredentials: options.withCredentials + }); + this.baseUrl = url; + style = await response.json(); + } + await this._fillByStyleJSON(style, options.source); + } else { + this._fillByRestMapOptions(options.url, options); + } + this.setState('ready'); + } + async _fillByStyleJSON(style, source) { if (!source) { source = Object.keys(style.sources)[0]; } if (style.sources && style.sources[source]) { - //ToDo 支持多个tiles地址 - this._tileUrl = SecurityManager.appendCredential(style.sources[source].tiles[0]); + let newUrl; + let paramUrl = this.baseUrl && this.baseUrl.split('?')[1]; + if (style.sources[source].tiles) { + newUrl = style.sources[source].tiles[0]; + if (!CommonUtil.isAbsoluteURL(newUrl)) { + newUrl = CommonUtil.relative2absolute(newUrl, this.baseUrl); + } + if (paramUrl) { + newUrl = CommonUtil.urlAppend(newUrl, paramUrl); + } + } else if (style.sources[source].url) { + let tiles = style.sources[source].url; + if (!CommonUtil.isAbsoluteURL(tiles)) { + tiles = CommonUtil.relative2absolute(tiles, this.baseUrl); + } + const response = await FetchRequest.get(tiles, {}, { withoutFormatSuffix: true }); + const sourceInfo = await response.json(); + let tileUrl = sourceInfo.tiles[0]; + if (!CommonUtil.isAbsoluteURL(tileUrl)) { + tileUrl = CommonUtil.relative2absolute(tileUrl, tiles); + } + newUrl = SecurityManager.appendCredential(tileUrl); + if (paramUrl) { + newUrl = CommonUtil.urlAppend(newUrl, paramUrl); + } + } + this._tileUrl = SecurityManager.appendCredential(newUrl); } if (style.metadata && style.metadata.indexbounds) { const indexbounds = style.metadata.indexbounds; diff --git a/src/openlayers/overlay/vectortile/MapboxStyles.js b/src/openlayers/overlay/vectortile/MapboxStyles.js index 9350bb003f..9651155b0c 100644 --- a/src/openlayers/overlay/vectortile/MapboxStyles.js +++ b/src/openlayers/overlay/vectortile/MapboxStyles.js @@ -25,6 +25,7 @@ import Text from 'ol/style/Text'; * @param {Object} options - 参数。 * @param {(string|undefined)} [options.url] - SuperMap iServer 地图服务地址,例如'http://localhost:8090/iserver/services/map-mvt-test/rest/maps/test',与options.style互斥,优先级低于options.style。 * @param {(Object|string|undefined)} [options.style] - Mapbox Style JSON 对象或获取 Mapbox Style JSON 对象的 URL。与 options.url 互斥,优先级高于 options.url。 + * @param {string} [options.baseUrl] - 当传入 style 对象且 style 中包含了相对路径时,需要传入 baseUrl 来拼接资源路径。 * @param {Array.} [options.resolutions] - 地图分辨率数组,用于映射 zoom 值。通常情況与地图的 {@link ol.View} 的分辨率一致。
* 默认值为:[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]。 * @param {(string|Array.|undefined)} [options.source] - Mapbox Style 'source'的 key 值或者 'layer' 的 ID 数组。 @@ -101,6 +102,7 @@ export class MapboxStyles extends Observable { }); }; this.layersBySourceLayer = {}; + this.baseUrl = options.baseUrl; olExtends(this.map); this._loadStyle(this.styleTarget); } @@ -246,6 +248,7 @@ export class MapboxStyles extends Observable { } _loadStyle(style) { if (Object.prototype.toString.call(style) == '[object Object]') { + this._handleRelativeUrl(style, this.baseUrl); this._mbStyle = style; this._resolve(); } else { @@ -253,6 +256,7 @@ export class MapboxStyles extends Observable { FetchRequest.get(url, null, { withCredentials: this.withCredentials }) .then(response => response.json()) .then(mbStyle => { + this._handleRelativeUrl(mbStyle, url); this._mbStyle = mbStyle; this._resolve(); }); @@ -372,4 +376,37 @@ export class MapboxStyles extends Observable { const parts = url.match(this.spriteRegEx); return parts ? parts[1] + extension + (parts.length > 2 ? parts[2] : '') : url + extension; } + + _handleRelativeUrl(styles, url) { + if (!url) { + return styles; + } + const baseUrl = url.split('?')[0]; + const paramUrl = url.split('?')[1] || ''; + Object.keys(styles).forEach((fieldName) => { + if (fieldName === 'sources') { + Object.keys(styles[fieldName]).forEach((sourceName) => { + this._handleRelativeUrl(styles[fieldName][sourceName], url); + }) + } + if (fieldName === 'sprite' || fieldName === 'glyphs' || fieldName === 'url') { + if (styles[fieldName] && typeof styles[fieldName] === 'string' && !CommonUtil.isAbsoluteURL(styles[fieldName])) { + styles[fieldName] = CommonUtil.relative2absolute(styles[fieldName], baseUrl); + } + if (paramUrl && !styles[fieldName].includes(paramUrl)) { + styles[fieldName] = styles[fieldName] + (paramUrl ? (styles[fieldName].includes('?') ? '&' + paramUrl : '?' + paramUrl) : ''); + } + } + if (fieldName === 'tiles' && Array.isArray(styles[fieldName])) { + styles[fieldName].forEach((tile) => { + if (!CommonUtil.isAbsoluteURL(tile)) { + tile = CommonUtil.relative2absolute(tile, baseUrl); + } + if (paramUrl && !tile.includes(paramUrl)) { + tile = tile + (paramUrl ? (styles[fieldName].includes('?') ? '&' + paramUrl : '?' + paramUrl) : ''); + } + }) + } + }) + } } diff --git a/test/common/iServer/InitMapServiceBaseSpec.js b/test/common/iServer/InitMapServiceBaseSpec.js new file mode 100644 index 0000000000..e695c8c3b7 --- /dev/null +++ b/test/common/iServer/InitMapServiceBaseSpec.js @@ -0,0 +1,42 @@ +import { extentToResolutions } from '../../../src/common/iServer/InitMapServiceBase'; + +describe('extentToResolutions', () => { + it('should calculate resolutions for a given bounding box', () => { + const bounds = { left: -180, right: 180 }; + const resolutions = extentToResolutions(bounds); + expect(resolutions.length).toBe(22); + expect(resolutions[0]).toBeCloseTo(0.703125); + expect(resolutions[21]).toBeCloseTo(0.00000686328125); + }); + + it('should handle array bounds input', () => { + const bounds = [-180, -90, 180, 90]; + const resolutions = extentToResolutions(bounds); + expect(resolutions.length).toBe(22); + expect(resolutions[0]).toBeCloseTo(0.703125); + expect(resolutions[21]).toBeCloseTo(0.00000686328125); + }); + + it('should handle custom maxZoom and tileSize', () => { + const bounds = { left: -180, right: 180 }; + const resolutions = extentToResolutions(bounds, 10, 256); + expect(resolutions.length).toBe(10); + expect(resolutions[0]).toBeCloseTo(1.40625); + expect(resolutions[9]).toBeCloseTo(0.00146484375); + }); + + it('should handle zero width bounds', () => { + const bounds = { left: 0, right: 0 }; + const resolutions = extentToResolutions(bounds); + expect(resolutions.length).toBe(22); + expect(resolutions[0]).toBe(0); + }); + + it('should handle negative width bounds', () => { + const bounds = { left: 180, right: -180 }; + const resolutions = extentToResolutions(bounds); + expect(resolutions.length).toBe(22); + expect(resolutions[0]).toBeCloseTo(0.703125); + expect(resolutions[21]).toBeCloseTo(0.00000686328125); + }); +}); \ No newline at end of file diff --git a/test/mapboxgl/core/UtilSpec.js b/test/mapboxgl/core/UtilSpec.js new file mode 100644 index 0000000000..23b6d4714b --- /dev/null +++ b/test/mapboxgl/core/UtilSpec.js @@ -0,0 +1,65 @@ +import { Util } from '../../../src/mapboxgl/core/Util'; + +describe('Util', () => { + it('toSuperMapGeometry', () => { + var geoJSON = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + attributes: { + SmArea: '1.6060069623493825E15', + SmGeoPosition: '65536', + SmID: '1', + SmPerimeter: '1.6030006674231339E8' + }, + id: 1, + layerName: 'World@China', + searchValues: '', + type: 'REGION' + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [-2, 258], + [258, 258], + [-2, 258], + [-2, 258] + ] + ] + ] + } + } + ] + }; + var result = Util.toSuperMapGeometry(geoJSON); + expect(result).not.toBeNull(); + + var geoJSON2 = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + attributes: { + SmArea: '1.6060069623493825E15', + SmGeoPosition: '65536', + SmID: '1', + SmPerimeter: '1.6030006674231339E8' + }, + id: 1, + layerName: 'World@China', + searchValues: '', + type: 'REGION' + }, + geometry: null + } + ] + }; + var result2 = Util.toSuperMapGeometry(geoJSON2); + expect(result2).toBeNull(); + }); +}); diff --git a/test/maplibregl/core/UtilSpec.js b/test/maplibregl/core/UtilSpec.js new file mode 100644 index 0000000000..a5f7cc5fc8 --- /dev/null +++ b/test/maplibregl/core/UtilSpec.js @@ -0,0 +1,65 @@ +import { Util } from '../../../src/maplibregl/core/Util'; + +describe('Util', () => { + it('toSuperMapGeometry', () => { + var geoJSON = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + attributes: { + SmArea: '1.6060069623493825E15', + SmGeoPosition: '65536', + SmID: '1', + SmPerimeter: '1.6030006674231339E8' + }, + id: 1, + layerName: 'World@China', + searchValues: '', + type: 'REGION' + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [-2, 258], + [258, 258], + [-2, 258], + [-2, 258] + ] + ] + ] + } + } + ] + }; + var result = Util.toSuperMapGeometry(geoJSON); + expect(result).not.toBeNull(); + + var geoJSON2 = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + attributes: { + SmArea: '1.6060069623493825E15', + SmGeoPosition: '65536', + SmID: '1', + SmPerimeter: '1.6030006674231339E8' + }, + id: 1, + layerName: 'World@China', + searchValues: '', + type: 'REGION' + }, + geometry: null + } + ] + }; + var result2 = Util.toSuperMapGeometry(geoJSON2); + expect(result2).toBeNull(); + }); +}); diff --git a/test/openlayers/core/UtilSpec.js b/test/openlayers/core/UtilSpec.js index f86aa51803..cb5cfc859d 100644 --- a/test/openlayers/core/UtilSpec.js +++ b/test/openlayers/core/UtilSpec.js @@ -121,6 +121,29 @@ describe('openlayers_Util', () => { expect(point instanceof Point).toBeTruthy(); expect(point.x).toBe(-2); expect(point.y).toBe(258); + var geoJSON2 = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + attributes: { + SmArea: '1.6060069623493825E15', + SmGeoPosition: '65536', + SmID: '1', + SmPerimeter: '1.6030006674231339E8' + }, + id: 1, + layerName: 'World@China', + searchValues: '', + type: 'REGION' + }, + geometry: null + } + ] + }; + var result2 = Util.toSuperMapGeometry(geoJSON2); + expect(result2).toBeNull(); }); it('resolutionToScale', () => { diff --git a/test/openlayers/mapping/WebMapSpec.js b/test/openlayers/mapping/WebMapSpec.js index f7a822e791..168da53c39 100644 --- a/test/openlayers/mapping/WebMapSpec.js +++ b/test/openlayers/mapping/WebMapSpec.js @@ -1343,4 +1343,48 @@ describe('openlayers_WebMap', () => { console.log(error); } }); + + it('datavizWebMap_noServerIdMarker', (done) => { + let options = { + server: server, + webMap: defaultServeRequest, + successCallback, + errorCallback: function () { } + }; + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('map.json') > -1) { + var mapJson = datavizWebMap_noServerIdMarker; + return Promise.resolve(new Response(mapJson)); + } + return Promise.resolve(); + }); + var datavizWebmap = new WebMap(options); + function successCallback() { + expect(datavizWebmap.server).toBe(server); + done(); + } + }); + it('datavizWebMap_isCredentail_isAddProxy', (done) => { + const serviceProxy = { + "httpConnPoolInfo": null, + "enableAccessStatistics": true, + "scheme": null, + "enableBuiltinProxy": true, + "port": 8195, + "proxyServerRootUrl": "http://127.0.0.1:8195/portalproxy", + "rootUrlPostfix": "portalproxy", + "enable": true, + "httpsSetting": null, + "cacheConfig": null + }; + var datavizWebmap = new WebMap(id, { webMap: JSON.parse(datavizWebMap_BAIDU), successCallback, serviceProxy: serviceProxy }); + function successCallback() { + const url = 'http://127.0.0.1:8195/portalproxy/11111/iserver/services/map-Population/rest/maps/PopulationDistribution/tileImage' + const withCredential = datavizWebmap.isCredentail(url, false); + const isProxy = datavizWebmap.isAddProxy(url, false); + expect(withCredential).toBeTruthy(); + expect(isProxy).toBeFalse(); + done(); + } + }); }); diff --git a/test/openlayers/overlay/VectorTileSuperMapRestSpec.js b/test/openlayers/overlay/VectorTileSuperMapRestSpec.js index aa66eedf41..8f5ecf8bb0 100644 --- a/test/openlayers/overlay/VectorTileSuperMapRestSpec.js +++ b/test/openlayers/overlay/VectorTileSuperMapRestSpec.js @@ -1,149 +1,221 @@ import { VectorTileSuperMapRest } from '../../../src/openlayers/overlay/VectorTileSuperMapRest'; import { - FetchRequest + FetchRequest } from '@supermapgis/iclient-common/util/FetchRequest'; import { MapService } from '../../../src/openlayers/services/MapService'; import Map from 'ol/Map'; +import MVT from 'ol/format/MVT'; import View from 'ol/View'; import VectorTileLayer from 'ol/layer/VectorTile'; var url = GlobeParameter.ChinaURL; const mapObject = { - "viewBounds": { - "top": 1.0018754171380693E7, - "left": -1.0018754171380727E7, - "bottom": -1.0018754171380745E7, - "leftBottom": { - "x": -1.0018754171380727E7, - "y": -1.0018754171380745E7 - }, - "right": 1.0018754171380712E7, - "rightTop": { - "x": 1.0018754171380712E7, - "y": 1.0018754171380693E7 - } - }, "bounds": { - "top": 2.0037508342789087E7, - "left": -2.0037508342789248E7, - "bottom": -2.003750834278914E7, - "leftBottom": { - "x": -2.0037508342789248E7, - "y": -2.003750834278914E7 - }, - "right": 2.0037508342789244E7, - "rightTop": { - "x": 2.0037508342789244E7, - "y": 2.0037508342789087E7 - } - }, "viewer": { - "leftTop": { - "x": 0, - "y": 0 - }, - "top": 0, - "left": 0, - "bottom": 256, - "rightBottom": { - "x": 256, - "y": 256 - }, - "width": 256, - "right": 256, - "height": 256 - }, "coordUnit": "METER", visibleScales: [], + "viewBounds": { + "top": 1.0018754171380693E7, + "left": -1.0018754171380727E7, + "bottom": -1.0018754171380745E7, + "leftBottom": { + "x": -1.0018754171380727E7, + "y": -1.0018754171380745E7 + }, + "right": 1.0018754171380712E7, + "rightTop": { + "x": 1.0018754171380712E7, + "y": 1.0018754171380693E7 + } + }, "bounds": { + "top": 2.0037508342789087E7, + "left": -2.0037508342789248E7, + "bottom": -2.003750834278914E7, + "leftBottom": { + "x": -2.0037508342789248E7, + "y": -2.003750834278914E7 + }, + "right": 2.0037508342789244E7, + "rightTop": { + "x": 2.0037508342789244E7, + "y": 2.0037508342789087E7 + } + }, "viewer": { + "leftTop": { + "x": 0, + "y": 0 + }, + "top": 0, + "left": 0, + "bottom": 256, + "rightBottom": { + "x": 256, + "y": 256 + }, + "width": 256, + "right": 256, + "height": 256 + }, "coordUnit": "METER", visibleScales: [], } describe('openlayers_VectorTileSuperMapRest', () => { - var testDiv, map, vectorTileOptions, vectorTileSource, originalTimeout, vectorLayer; - beforeAll(() => { - testDiv = window.document.createElement("div"); - testDiv.setAttribute("id", "map"); - testDiv.style.styleFloat = "left"; - testDiv.style.marginLeft = "8px"; - testDiv.style.marginTop = "50px"; - testDiv.style.width = "500px"; - testDiv.style.height = "500px"; - window.document.body.appendChild(testDiv); - spyOn(FetchRequest, 'get').and.callFake((testUrl, params, options) => { - return Promise.resolve(new Response(JSON.stringify(mapObject))); - }); + var testDiv, map, vectorTileOptions, vectorTileSource, originalTimeout, vectorLayer; + beforeAll(() => { + testDiv = window.document.createElement("div"); + testDiv.setAttribute("id", "map"); + testDiv.style.styleFloat = "left"; + testDiv.style.marginLeft = "8px"; + testDiv.style.marginTop = "50px"; + testDiv.style.width = "500px"; + testDiv.style.height = "500px"; + window.document.body.appendChild(testDiv); + }); + beforeEach(() => { + originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + }); + afterEach(() => { + if (vectorLayer) { + map.removeLayer(vectorLayer); + } + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + }); + afterAll(() => { + window.document.body.removeChild(testDiv); + }); + it('initialize', (done) => { + spyOn(FetchRequest, 'get').and.callFake((testUrl, params, options) => { + return Promise.resolve(new Response(JSON.stringify(mapObject))); }); - beforeEach(() => { - originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; - jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - }); - afterEach(() => { - if (vectorLayer) { - map.removeLayer(vectorLayer); - } - jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; - }); - afterAll(() => { - window.document.body.removeChild(testDiv); - }); + new MapService(url).getMapInfo((serviceResult) => { + map = new Map({ + target: 'map', + view: new View({ + center: [12957388, 4853991], + zoom: 11 + }) + }); + vectorTileOptions = VectorTileSuperMapRest.optionsFromMapJSON(url, serviceResult.result); + vectorTileOptions.tileLoadFunction = (tile) => { + tile.setLoader(() => { + tile.setFeatures([]) + }) + }; + vectorTileSource = new VectorTileSuperMapRest(vectorTileOptions); + vectorTileSource.once('tileloadend', () => { + expect(vectorTileOptions).not.toBeNull(); + expect(vectorTileOptions.crossOrigin).toBe("anonymous"); + expect(vectorTileSource).not.toBeNull(); + done(); + }) + vectorLayer = new VectorTileLayer({ + source: vectorTileSource + }); + map.addLayer(vectorLayer); - it('initialize', (done) => { - new MapService(url).getMapInfo((serviceResult) => { - map = new Map({ - target: 'map', - view: new View({ - center: [12957388, 4853991], - zoom: 11 - }) - }); - vectorTileOptions = VectorTileSuperMapRest.optionsFromMapJSON(url, serviceResult.result); - vectorTileOptions.tileLoadFunction = (tile) => { - tile.setLoader(() => { - tile.setFeatures([]) - }) - }; - vectorTileSource = new VectorTileSuperMapRest(vectorTileOptions); - vectorTileSource.once('tileloadend', () => { - expect(vectorTileOptions).not.toBeNull(); - expect(vectorTileOptions.crossOrigin).toBe("anonymous"); - expect(vectorTileSource).not.toBeNull(); - done(); - }) - vectorLayer = new VectorTileLayer({ - source: vectorTileSource - }); - map.addLayer(vectorLayer); + }); - }); + }); + it('handle relative url', (done) => { + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('fake') > -1) { + return Promise.resolve(new Response(JSON.stringify({ + tiles: ['tile/{z}/{y}/{x}.pbf'] + }))); + } + if (url.indexOf('http://localhost:9876/iserver/services/map-china400/rest/maps/China') > -1) { + return Promise.resolve(new Response(JSON.stringify(mapObject))); + } + return Promise.resolve(); }); - it('custom_tileLoadFunction', (done) => { - var spy = jasmine.createSpy('test') - var tileLoadFunction = (tile) => { - tile.setLoader(() => { - spy(); - tile.setFeatures([]) - }) - }; - new MapService(url).getMapInfo((serviceResult) => { - map = new Map({ - target: 'map', - view: new View({ - center: [12957388, 4853991], - zoom: 11 - }) - }); - vectorTileOptions = VectorTileSuperMapRest.optionsFromMapJSON(url, serviceResult.result); - vectorTileOptions.tileLoadFunction = tileLoadFunction; - vectorTileSource = new VectorTileSuperMapRest(vectorTileOptions); - vectorLayer = new VectorTileLayer({ - source: vectorTileSource - }); - map.addLayer(vectorLayer); - vectorLayer.getSource().once('tileloadend', () => { - expect(vectorTileOptions).not.toBeNull(); - expect(spy).toHaveBeenCalled(); - done(); - - }) + new MapService(url).getMapInfo((serviceResult) => { + map = new Map({ + target: 'map', + view: new View({ + center: [12957388, 4853991], + zoom: 11 + }) + }); + vectorTileOptions = VectorTileSuperMapRest.optionsFromMapJSON(url, serviceResult.result); + vectorTileOptions.tileLoadFunction = (tile) => { + tile.setLoader(() => { + tile.setFeatures([]); }); + }; + vectorTileOptions.format = new MVT(); + vectorTileOptions.baseUrl = 'http://fake/iportal/services'; + vectorTileOptions.style = { + "version": 8, + "sprite": "../sprites/sprite", + "glyphs": "../fonts/{fontstack}/{range}.pbf", + "sources": { + "esri": { + "type": "vector", + "url": "../../" + } + }, + "layers": [{ + "id": "Contour_11_main/0", + "type": "line", + "source": "esri", + "source-layer": "Contour", + "filter": ["all", ["==", "Index3", 1], ["==", "Index5", 1]], + "minzoom": 11, + "maxzoom": 12, + "paint": { + "line-color": "#61674a", + "line-opacity": 0.5, + "line-width": { + "base": 1.2, + "stops": [[11, 0.7], [16, 1.1]] + } + } + }] + } + vectorTileSource = new VectorTileSuperMapRest(vectorTileOptions); + vectorTileSource.once('tileloadend', () => { + expect(vectorTileOptions).not.toBeNull(); + expect(vectorTileOptions.crossOrigin).toBe('anonymous'); + expect(vectorTileSource).not.toBeNull(); + done(); + }); + vectorLayer = new VectorTileLayer({ + source: vectorTileSource + }); + map.addLayer(vectorLayer); + }); + }); + it('custom_tileLoadFunction', (done) => { + spyOn(FetchRequest, 'get').and.callFake((testUrl, params, options) => { + return Promise.resolve(new Response(JSON.stringify(mapObject))); + }); + var spy = jasmine.createSpy('test') + var tileLoadFunction = (tile) => { + tile.setLoader(() => { + spy(); + tile.setFeatures([]) + }) + }; + new MapService(url).getMapInfo((serviceResult) => { + map = new Map({ + target: 'map', + view: new View({ + center: [12957388, 4853991], + zoom: 11 + }) + }); + vectorTileOptions = VectorTileSuperMapRest.optionsFromMapJSON(url, serviceResult.result); + vectorTileOptions.tileLoadFunction = tileLoadFunction; + vectorTileSource = new VectorTileSuperMapRest(vectorTileOptions); + vectorLayer = new VectorTileLayer({ + source: vectorTileSource + }); + map.addLayer(vectorLayer); + vectorLayer.getSource().once('tileloadend', () => { + expect(vectorTileOptions).not.toBeNull(); + expect(spy).toHaveBeenCalled(); + done(); + }) }); + }); }); \ No newline at end of file diff --git a/test/openlayers/overlay/vectortile/MapboxStylesSpec.js b/test/openlayers/overlay/vectortile/MapboxStylesSpec.js index a71e2571af..220ca3f176 100644 --- a/test/openlayers/overlay/vectortile/MapboxStylesSpec.js +++ b/test/openlayers/overlay/vectortile/MapboxStylesSpec.js @@ -254,4 +254,113 @@ describe("openlayers_MapboxStyles", () => { } }); }); + + it("handle relative url", done => { + spyOn(XMLHttpRequest.prototype, 'send').and.callThrough(); + spyOn(XMLHttpRequest.prototype, 'setRequestHeader').and.callThrough(); + var style = { + "version" : 8, + "sprite" : "../sprites/sprite", + "glyphs" : "../fonts/{fontstack}/{range}.pbf", + "sources": { + "esri": { + "type": "vector", + "url": "../../" + } + }, + "layers" : [{ + "id" : "Contour_11_main/0", + "type" : "line", + "source" : "esri", + "source-layer" : "Contour", + "filter" : ["all", ["==", "Index3", 1], ["==", "Index5", 1]], + "minzoom" : 11, + "maxzoom" : 12, + "paint" : { + "line-color" : "#61674a", + "line-opacity" : 0.5, + "line-width" : { + "base" : 1.2, + "stops" : [[11, 0.7], [16, 1.1]] + } + } + }] + } + mapboxStyles = new MapboxStyles({ + style: style, + baseUrl: 'http://localhost:9876', + map: map, + source: "California", + headers:{'appToken':'test'} + }); + mapboxStyles.on("styleloaded", () => { + try { + style = mapboxStyles.getStyleFunction(); + expect(style).not.toBeNull(); + console.log('mapboxStyles', mapboxStyles); + expect(mapboxStyles._mbStyle.glyphs).toBe('http://localhost:9876/fonts/{fontstack}/{range}.pbf'); + expect(mapboxStyles._mbStyle.sprite).toBe('http://localhost:9876/sprites/sprite'); + expect(mapboxStyles._mbStyle.sources['esri']['url']).toBe('http://localhost:9876/'); + done(); + } catch (e) { + console.log("'init_Style_headers'案例失败" + e.name + ":" + e.message); + expect(false).toBeTruthy(); + done(); + } + }); + }); + + it("handle relative url with param", done => { + spyOn(XMLHttpRequest.prototype, 'send').and.callThrough(); + spyOn(XMLHttpRequest.prototype, 'setRequestHeader').and.callThrough(); + var style = { + "version" : 8, + "sprite" : "../sprites/sprite", + "glyphs" : "../fonts/{fontstack}/{range}.pbf", + "sources": { + "esri": { + "type": "vector", + "url": "../../" + } + }, + "layers" : [{ + "id" : "Contour_11_main/0", + "type" : "line", + "source" : "esri", + "source-layer" : "Contour", + "filter" : ["all", ["==", "Index3", 1], ["==", "Index5", 1]], + "minzoom" : 11, + "maxzoom" : 12, + "paint" : { + "line-color" : "#61674a", + "line-opacity" : 0.5, + "line-width" : { + "base" : 1.2, + "stops" : [[11, 0.7], [16, 1.1]] + } + } + }] + } + mapboxStyles = new MapboxStyles({ + style: style, + baseUrl: 'http://localhost:9876?tkk=ddddssss', + map: map, + source: "California", + headers:{'appToken':'test'} + }); + mapboxStyles.on("styleloaded", () => { + try { + style = mapboxStyles.getStyleFunction(); + expect(style).not.toBeNull(); + expect(mapboxStyles._mbStyle.glyphs).toBe('http://localhost:9876/fonts/{fontstack}/{range}.pbf?tkk=ddddssss'); + expect(mapboxStyles._mbStyle.sprite).toBe('http://localhost:9876/sprites/sprite?tkk=ddddssss'); + expect(mapboxStyles._mbStyle.sources['esri']['url']).toBe('http://localhost:9876/?tkk=ddddssss'); + done(); + } catch (e) { + console.log("'init_Style_headers'案例失败" + e.name + ":" + e.message); + expect(false).toBeTruthy(); + done(); + } + }); +}); }); diff --git a/test/resources/MapboxStyles.js b/test/resources/MapboxStyles.js index 1d2f7fbe65..9d1a2e7f4f 100644 --- a/test/resources/MapboxStyles.js +++ b/test/resources/MapboxStyles.js @@ -8,7 +8,7 @@ var vectorstylesEscapedJson={ } }, "name": "California", - "sprite": "../../base/resources/img/sprite@2x", + "sprite": "http://localhost:9876/base/resources/img/sprite@2x", "layers": [ { "paint": { diff --git a/test/resources/WebMapV5.js b/test/resources/WebMapV5.js index 5ad34cfb54..95b6c109a3 100644 --- a/test/resources/WebMapV5.js +++ b/test/resources/WebMapV5.js @@ -54,6 +54,7 @@ var datavizWebMap_WMTS = '{"version":"6.0","title":"wmts","description":"","proj var datavizWebMap_WMTS1 = '{ "extent": { "leftBottom": { "x": -20037508.3427892, "y": -20037508.3427892 }, "rightTop": { "x": 20037508.3427892, "y": 20037508.3427892 } }, "level": 1, "center": { "x": 8548489.791091159, "y": -2939180.84386342 }, "baseLayer": { "layerType": "TIANDITU_VEC_3857", "visible": true, "labelLayerVisible": true, "name": "天地图" }, "layers": [ { "layerType": "WMTS", "tileMatrixSet": "GoogleMapsCompatible_China_4326", "name": "China_4326", "url": "http://localhost:9876/iserver/services/map-china400/wmts100?", "layer": "China_4326" } ], "description": "", "projection": "EPSG:3857", "title": "3857", "version": "1.0" }' var datavizWebMap_WMTS2 = '{ "extent": { "leftBottom": { "x": -20037508.3427892, "y": -20037508.3427892 }, "rightTop": { "x": 20037508.3427892, "y": 20037508.3427892 } }, "level": 1, "center": { "x": 8548489.791091159, "y": -2939180.84386342 }, "baseLayer": { "layerType": "TIANDITU_VEC_3857", "visible": true, "labelLayerVisible": false, "name": "天地图" }, "layers": [ { "layerType": "WMTS", "tileMatrixSet": "Custom_China_4326", "name": "China_4326", "url": "http://localhost:9876/iserver/services/map-china400/wmts100?", "layer": "China_4326" } ], "description": "", "projection": "EPSG:3857", "title": "3857", "version": "1.0" }' var datavizWebMap_fiter = '{ "extent": { "leftBottom": { "x": -2.00375083427892E7, "y": -2.00375083427892E7 }, "rightTop": { "x": 2.00375083427892E7, "y": 2.00375083427892E7 } }, "level": 11, "center": { "x": 1.2980839382783111E7, "y": 4850526.359611664 }, "baseLayer": { "layerType": "TIANDITU_VEC_3857", "visible": true, "labelLayerVisible": true, "name": "天地图" }, "layers": [ { "layerType": "VECTOR", "visible": true, "filterCondition": "SmID>20", "name": "北京市轨道交通站点", "featureType": "LINE", "style": { "fillColor": "#ff0000", "strokeWidth": 1, "fillOpacity": 0.9, "type": "BASIC_POINT", "radius": 6, "strokeColor": "#ffffff", "strokeOpacity": 1 }, "projection": "EPSG:4326", "dataSource": { "type": "PORTAL_DATA", "serverId": "1276193546" } } ], "description": "", "projection": "EPSG:3857", "title": "filter", "version": "1.0" }' +var datavizWebMap_noServerIdMarker = '{"extent":{"leftBottom":{"x":-20037508.3427892,"y":-20037508.3427892},"rightTop":{"x":20037508.3427892,"y":20037508.3427892}},"maxScale":"1:144447.92746805","level":1,"center":{"x":0,"y":-7.081154551613622E-10},"baseLayer":{"layerType":"TILE","visible":true,"name":"中国暗色地图","url":"https://maptiles.supermapol.com/iserver/services/map_China/rest/maps/China_Dark"},"layers":[{"layerType":"MARKER","visible":true,"name":"未命名标注图层1"},{"layerType":"MARKER","visible":true,"name":"未命名标注图层2"}],"description":"","projection":"EPSG:3857","minScale":"1:591658710.909131","title":"无标题","version":"2.4.1","rootUrl":"http://127.0.0.1:8082/iportal/"}'; var xlsData = '{"fileName":"671个气象站观测数据(1).xlsx","type":"EXCEL","lineNumber":1,"content":{"colTitles":["区站号","站台","省份","X","Y","海拔","平均最低气温","最热七天气温","最高气温","最低气温","年均降雨"],"rows":[["50136","漠河","黑龙江","122.37","53.47","296","-47","29","33","-53","366.1"]]}}'; var csvData = '{"fileName":"北京市幼儿园_1.csv","type":"CSV","lineNumber":1,"content":{"colTitles":["名称","学校类别","电话","地址","学校类别_Num","X","Y","城市"],"rows":[["北京市顺义区汇佳东方幼儿园","61幼儿园","89431740","北京市顺义区东方太阳城万晴园54号","61","116.718806","40.086966","北京"]]}}'; diff --git a/test/test-main-common.js b/test/test-main-common.js index 48b353831a..e5f91c87ca 100644 --- a/test/test-main-common.js +++ b/test/test-main-common.js @@ -46,6 +46,7 @@ import './common/iServer/GetLayersInfoServiceSpec.js'; import './common/iServer/GetLayersLegendInfoServiceSpec.js'; import './common/iServer/GridSpec.js'; import './common/iServer/ImageSpec.js'; +import './common/iServer/InitMapServiceBaseSpec.js'; import './common/iServer/InterpolationAnalystServiceSpec.js'; import './common/iServer/LabelImageCellSpec.js'; import './common/iServer/LabelMixedStyleSpec.js';