From 327d0c5c8c62a4926f3f450a67bec80a6177b69d Mon Sep 17 00:00:00 2001 From: qiwei Date: Mon, 29 Sep 2025 16:20:24 +0800 Subject: [PATCH 1/5] =?UTF-8?q?update=20=E5=A4=84=E7=90=86=E5=AF=B9webmap?= =?UTF-8?q?=20crs=20=E7=9A=843857=204326=20=E6=8A=95=E5=BD=B1=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mapboxgl/mapping/webmap/CRSManager.js | 10 +++++++++- test/mapboxgl/mapping/WebMapV3Spec.js | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mapboxgl/mapping/webmap/CRSManager.js b/src/mapboxgl/mapping/webmap/CRSManager.js index f5e4bde861..6029596c8d 100644 --- a/src/mapboxgl/mapping/webmap/CRSManager.js +++ b/src/mapboxgl/mapping/webmap/CRSManager.js @@ -1,5 +1,11 @@ import mapboxgl from 'mapbox-gl'; +const equivalenceMap = { + 'EPSG:4490': 'EPSG:4326', + 'EPSG:4326': 'EPSG:4490', + 'EPSG:3857': 'EPSG:900913', + 'EPSG:900913': 'EPSG:3857' +}; export class CRSManager { constructor(proj4) { this.proj4 = proj4; @@ -7,7 +13,9 @@ export class CRSManager { } isSameProjection(map, epsgCode) { - return map.getCRS().epsgCode === epsgCode; + const mapEpsgCode = map.getCRS().epsgCode; + return mapEpsgCode === epsgCode || + (equivalenceMap[mapEpsgCode] === epsgCode && equivalenceMap[epsgCode] === mapEpsgCode); } getProj4() { diff --git a/test/mapboxgl/mapping/WebMapV3Spec.js b/test/mapboxgl/mapping/WebMapV3Spec.js index 84bb818fe6..48397fc36b 100644 --- a/test/mapboxgl/mapping/WebMapV3Spec.js +++ b/test/mapboxgl/mapping/WebMapV3Spec.js @@ -318,6 +318,8 @@ describe('mapboxgl-webmap3.0', () => { existedMap.on('load', function () { mapstudioWebmap.initializeMap(nextMapInfo, existedMap); }); + const isSameCrs = extendOptions.crsManager.isSameProjection(existedMap, 'EPSG:4326'); + expect(isSameCrs).toBe(true); mapstudioWebmap.on('mapcreatesucceeded', ({ map }) => { expect(mapstudioWebmap._appendLayers).toBe(true); expect(map).toEqual(existedMap); From cfdacf6e4c6b60fdea1ee634f57309763912f9b4 Mon Sep 17 00:00:00 2001 From: chenxianhui Date: Sat, 11 Oct 2025 11:16:19 +0800 Subject: [PATCH 2/5] =?UTF-8?q?ISVJ-10976=20=E6=94=AF=E6=8C=81dv=E9=9D=9E?= =?UTF-8?q?=E4=B8=93=E9=A2=98=E5=9B=BE=E5=B1=82=E7=9A=84=E5=9B=BE=E4=BE=8B?= =?UTF-8?q?=20review=20by=20xiongjj?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/mapping/WebMapV2.js | 12 +++++++++++- src/common/mapping/WebMapV2Base.js | 10 ++++++++++ test/mapboxgl/mapping/WebMapV2Spec.js | 23 +++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/common/mapping/WebMapV2.js b/src/common/mapping/WebMapV2.js index 79d69c4611..5557e79009 100644 --- a/src/common/mapping/WebMapV2.js +++ b/src/common/mapping/WebMapV2.js @@ -575,6 +575,8 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa features = this.handleLayerFeatures(features, layerInfo); if (layerType === 'VECTOR') { + const styleGroups = this.getVectorStyleGroup(layerInfo); + this._initLegendConfigInfo(layerInfo, styleGroups); if (featureType === 'POINT') { if (style.type === 'SYMBOL_POINT') { this._createSymbolLayer(layerInfo, features); @@ -2633,11 +2635,18 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa this._addOverlayToMap({ type: 'LINE', source, layerID, parentLayerId, layerStyle: lineStyle, minzoom, maxzoom }); } + _getThemeField(layerInfo) { + if (layerInfo.layerType === 'VECTOR') { + return '' + } + return layerInfo.layerType === 'HEAT' ? layerInfo.themeSetting.weight : layerInfo.themeSetting.themeField + } + _initLegendConfigInfo(layerInfo, style) { const legendItem = { layerId: layerInfo.layerID, layerTitle: layerInfo.layerID, - themeField: layerInfo.layerType === 'HEAT' ? layerInfo.themeSetting.weight : layerInfo.themeSetting.themeField, + themeField: this._getThemeField(layerInfo), styleGroup: style }; @@ -2654,6 +2663,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa switch (layerInfo.layerType) { case 'UNIQUE': + case 'VECTOR': legendItem.styleGroup = legendItem.styleGroup.map((styleGroup) => { return { fieldValue: styleGroup.value, diff --git a/src/common/mapping/WebMapV2Base.js b/src/common/mapping/WebMapV2Base.js index bc227cbd41..7ffe806283 100644 --- a/src/common/mapping/WebMapV2Base.js +++ b/src/common/mapping/WebMapV2Base.js @@ -722,6 +722,16 @@ export function createWebMapV2BaseExtending(SuperClass = Events, fireField = 'tr return styleGroup; } + + getVectorStyleGroup(layerInfo) { + const color = layerInfo.style.fillColor || layerInfo.style.strokeColor; + const styleGroup = [{ + color: color, + style: layerInfo.style, + value: layerInfo.name + }] + return styleGroup; + } transformFeatures(features) { features && diff --git a/test/mapboxgl/mapping/WebMapV2Spec.js b/test/mapboxgl/mapping/WebMapV2Spec.js index fbc64ede6c..4fc86bd904 100644 --- a/test/mapboxgl/mapping/WebMapV2Spec.js +++ b/test/mapboxgl/mapping/WebMapV2Spec.js @@ -490,6 +490,29 @@ describe('mapboxgl_WebMapV2', () => { datavizWebmap.on('mapcreatesucceeded', callback); }); + it('vectorlayer should have legends', (done) => { + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('map.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(vectorLayer_line))); + } else if (url.indexOf('1788054202/content.json?') > -1) { + return Promise.resolve(new Response(JSON.stringify(chart_content))); + } else if (url.indexOf('13136933/content.json?') > -1) { + return Promise.resolve(new Response(JSON.stringify(layerData_geojson['POINT_GEOJSON']))); + } else if (url.indexOf('portal.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy))); + } else if (url.indexOf('web/datas/1920557079/content.json') > -1) { + return Promise.resolve(new Response(layerData_CSV)); + } + return Promise.resolve(new Response(JSON.stringify({}))); + }); + datavizWebmap = new WebMap(id, { ...commonOption, map: commonMap }, { ...commonMapOptions }); + const callback = function (data) { + expect(datavizWebmap.getLegends().length).toBe(1); + done(); + }; + datavizWebmap.on('mapcreatesucceeded', callback); + }); + it('add heatLayer', (done) => { spyOn(FetchRequest, 'get').and.callFake((url) => { if (url.indexOf('web/datas/1920557079/content.json') > -1) { From 0238f4441ae8863565bdb10af60058af4410bba5 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Wed, 15 Oct 2025 14:00:03 +0800 Subject: [PATCH 3/5] [fix]ISVJ-10807 preferServer featureService webmap --- src/common/commontypes/Util.js | 12 + src/common/iServer/CommonServiceBase.js | 1 + src/common/iServer/FeatureService.js | 27 +- .../iServer/GetFeaturesByBoundsService.js | 1 + .../iServer/GetFeaturesByBufferService.js | 1 + .../iServer/GetFeaturesByGeometryService.js | 1 + src/common/iServer/GetFeaturesByIDsService.js | 1 + src/common/iServer/GetFeaturesBySQLService.js | 1 + src/common/iServer/GetFeaturesServiceBase.js | 257 +++++++++--------- src/common/mapping/WebMapBase.js | 1 + src/common/mapping/WebMapService.js | 2 + src/common/util/FetchRequest.js | 9 +- src/mapboxgl/mapping/WebMap.js | 1 + src/mapboxgl/services/FeatureService.js | 1 + test/mapboxgl/mapping/WebMapSpec.js | 34 +++ .../services/GetFeaturesByBoundsSpec.js | 54 ++-- .../services/GetFeaturesByBufferSpec.js | 45 +++ .../services/GetFeaturesByGeometrySpec.js | 46 ++++ .../mapboxgl/services/GetFeaturesByIDsSpec.js | 68 +++-- .../mapboxgl/services/GetFeaturesBySQLSpec.js | 82 +++++- 20 files changed, 464 insertions(+), 181 deletions(-) diff --git a/src/common/commontypes/Util.js b/src/common/commontypes/Util.js index 59803646a6..f5a37e021b 100644 --- a/src/common/commontypes/Util.js +++ b/src/common/commontypes/Util.js @@ -435,6 +435,18 @@ const Util = { return paramsArray.join('&'); }, + handleUrlSuffix(url, suffix = '.json') { + if (url.indexOf('?') < 0) { + url += suffix; + } else { + var urlArrays = url.split('?'); + if (urlArrays.length === 2) { + url = urlArrays[0] + suffix + '?' + urlArrays[1]; + } + } + return url + }, + /** * @memberOf CommonUtil * @description 给 URL 追加查询参数。 diff --git a/src/common/iServer/CommonServiceBase.js b/src/common/iServer/CommonServiceBase.js index d4407251da..6f778ac364 100644 --- a/src/common/iServer/CommonServiceBase.js +++ b/src/common/iServer/CommonServiceBase.js @@ -150,6 +150,7 @@ export class CommonServiceBase { options.headers = options.headers || me.headers; options.isInTheSameDomain = me.isInTheSameDomain; options.withoutFormatSuffix = options.scope.withoutFormatSuffix || false; + options.preferServer = options.preferServer || me.preferServer; //为url添加安全认证信息片段 options.url = SecurityManager.appendCredential(options.url); diff --git a/src/common/iServer/FeatureService.js b/src/common/iServer/FeatureService.js index 6f180b3519..9541acb7a6 100644 --- a/src/common/iServer/FeatureService.js +++ b/src/common/iServer/FeatureService.js @@ -17,7 +17,7 @@ const FEATURE_SERVICE_MAP = { bounds: GetFeaturesByBoundsService, buffer: GetFeaturesByBufferService, geometry: GetFeaturesByGeometryService -} +}; /** * @class FeatureService @@ -34,11 +34,11 @@ const FEATURE_SERVICE_MAP = { * @param {boolean} [options.withCredentials=false] - 请求是否携带 cookie。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当resultFormat=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @extends {ServiceBase} * @usage */ export class FeatureService { - constructor(url, options) { this.url = url; this.options = options || {}; @@ -59,7 +59,8 @@ export class FeatureService { withCredentials: me.options.withCredentials, crossOrigin: me.options.crossOrigin, headers: me.options.headers, - format: resultFormat + format: resultFormat, + preferServer: me.options.preferServer }); return getFeaturesByIDsService.processAsync(params, callback); } @@ -79,7 +80,8 @@ export class FeatureService { withCredentials: me.options.withCredentials, crossOrigin: me.options.crossOrigin, headers: me.options.headers, - format: me._processFormat(resultFormat) + format: me._processFormat(resultFormat), + preferServer: me.options.preferServer }); return getFeaturesByBoundsService.processAsync(params, callback); } @@ -99,7 +101,8 @@ export class FeatureService { withCredentials: me.options.withCredentials, crossOrigin: me.options.crossOrigin, headers: me.options.headers, - format: me._processFormat(resultFormat) + format: me._processFormat(resultFormat), + preferServer: me.options.preferServer }); return getFeatureService.processAsync(params, callback); } @@ -119,7 +122,8 @@ export class FeatureService { withCredentials: me.options.withCredentials, crossOrigin: me.options.crossOrigin, headers: me.options.headers, - format: me._processFormat(resultFormat) + format: me._processFormat(resultFormat), + preferServer: me.options.preferServer }); return getFeatureBySQLService.processAsync(params, callback); } @@ -139,7 +143,8 @@ export class FeatureService { withCredentials: me.options.withCredentials, crossOrigin: me.options.crossOrigin, headers: me.options.headers, - format: me._processFormat(resultFormat) + format: me._processFormat(resultFormat), + preferServer: me.options.preferServer }); return getFeaturesByGeometryService.processAsync(params, callback); } @@ -159,7 +164,7 @@ export class FeatureService { url = me.url, dataSourceName = params.dataSourceName, dataSetName = params.dataSetName; - url = CommonUtil.urlPathAppend(url, "datasources/" + dataSourceName + "/datasets/" + dataSetName); + url = CommonUtil.urlPathAppend(url, 'datasources/' + dataSourceName + '/datasets/' + dataSetName); var editFeatureService = new EditFeaturesService(url, { proxy: me.options.proxy, @@ -182,7 +187,7 @@ export class FeatureService { url = me.url, dataSourceName = params.dataSourceName, dataSetName = params.dataSetName; - url = CommonUtil.urlPathAppend(url, "datasources/" + dataSourceName + "/datasets/" + dataSetName); + url = CommonUtil.urlPathAppend(url, 'datasources/' + dataSourceName + '/datasets/' + dataSetName); var editFeatureService = new EditFeaturesService(url, { proxy: me.options.proxy, withCredentials: me.options.withCredentials, @@ -207,7 +212,7 @@ export class FeatureService { url = me.url, dataSourceName = params.dataSourceName, dataSetName = params.dataSetName; - url = CommonUtil.urlPathAppend(url, "datasources/" + dataSourceName + "/datasets/" + dataSetName); + url = CommonUtil.urlPathAppend(url, 'datasources/' + dataSourceName + '/datasets/' + dataSetName); var featureAttachmentsService = new FeatureAttachmentsService(url, { proxy: me.options.proxy, withCredentials: me.options.withCredentials, @@ -233,7 +238,7 @@ export class FeatureService { url = me.url, dataSourceName = params.dataSourceName, dataSetName = params.dataSetName; - url = CommonUtil.urlPathAppend(url, "datasources/" + dataSourceName + "/datasets/" + dataSetName); + url = CommonUtil.urlPathAppend(url, 'datasources/' + dataSourceName + '/datasets/' + dataSetName); var featureAttachmentsService = new FeatureAttachmentsService(url, { proxy: me.options.proxy, withCredentials: me.options.withCredentials, diff --git a/src/common/iServer/GetFeaturesByBoundsService.js b/src/common/iServer/GetFeaturesByBoundsService.js index 39953436ae..e2e7ec15bf 100644 --- a/src/common/iServer/GetFeaturesByBoundsService.js +++ b/src/common/iServer/GetFeaturesByBoundsService.js @@ -17,6 +17,7 @@ import {GetFeaturesByBoundsParameters} from './GetFeaturesByBoundsParameters'; * @param {DataFormat} [options.format=DataFormat.GEOJSON] - 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。参数格式为 "ISERVER","GEOJSON","FGB"。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当options.format=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @example * var myGetFeaturesByBoundsService = new SuperMa.GetFeaturesByBoundsService(url); * @usage diff --git a/src/common/iServer/GetFeaturesByBufferService.js b/src/common/iServer/GetFeaturesByBufferService.js index e96000e35b..9906ec99fa 100644 --- a/src/common/iServer/GetFeaturesByBufferService.js +++ b/src/common/iServer/GetFeaturesByBufferService.js @@ -16,6 +16,7 @@ import {GetFeaturesByBufferParameters} from './GetFeaturesByBufferParameters'; * @param {DataFormat} [options.format=DataFormat.GEOJSON] - 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。参数格式为 "ISERVER","GEOJSON","FGB"。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当options.format=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @extends {GetFeaturesServiceBase} * @example * var myGetFeaturesByBufferService = new GetFeaturesByBufferService(url); diff --git a/src/common/iServer/GetFeaturesByGeometryService.js b/src/common/iServer/GetFeaturesByGeometryService.js index 7c1e46c6ea..cc42770789 100644 --- a/src/common/iServer/GetFeaturesByGeometryService.js +++ b/src/common/iServer/GetFeaturesByGeometryService.js @@ -16,6 +16,7 @@ import {GetFeaturesByGeometryParameters} from './GetFeaturesByGeometryParameters * @param {DataFormat} [options.format=DataFormat.GEOJSON] - 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。参数格式为 "ISERVER","GEOJSON","FGB"。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当options.format=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @extends {GetFeaturesServiceBase} * @example * var myService = new GetFeaturesByGeometryService(url); diff --git a/src/common/iServer/GetFeaturesByIDsService.js b/src/common/iServer/GetFeaturesByIDsService.js index 9ac2cd86a1..bb2ffc1b13 100644 --- a/src/common/iServer/GetFeaturesByIDsService.js +++ b/src/common/iServer/GetFeaturesByIDsService.js @@ -16,6 +16,7 @@ import {GetFeaturesByIDsParameters} from './GetFeaturesByIDsParameters'; * @param {DataFormat} [options.format=DataFormat.GEOJSON] - 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。参数格式为 "ISERVER","GEOJSON","FGB"。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当options.format=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @extends {GetFeaturesServiceBase} * @example * var myGetFeaturesByIDsService = new GetFeaturesByIDsService(url); diff --git a/src/common/iServer/GetFeaturesBySQLService.js b/src/common/iServer/GetFeaturesBySQLService.js index d4216034d2..d04327e138 100644 --- a/src/common/iServer/GetFeaturesBySQLService.js +++ b/src/common/iServer/GetFeaturesBySQLService.js @@ -17,6 +17,7 @@ import {GetFeaturesBySQLParameters} from './GetFeaturesBySQLParameters'; * @param {DataFormat} [options.format=DataFormat.GEOJSON] - 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。参数格式为 "ISERVER","GEOJSON","FGB"。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当options.format=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @extends {GetFeaturesServiceBase} * @example * var myGetFeaturesBySQLService = new GetFeaturesBySQLService(url); diff --git a/src/common/iServer/GetFeaturesServiceBase.js b/src/common/iServer/GetFeaturesServiceBase.js index d3c3db5021..dc09bb0f1d 100644 --- a/src/common/iServer/GetFeaturesServiceBase.js +++ b/src/common/iServer/GetFeaturesServiceBase.js @@ -1,10 +1,10 @@ /* Copyright© 2000 - 2025 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 {Util} from '../commontypes/Util'; -import {DataFormat} from '../REST'; -import {CommonServiceBase} from './CommonServiceBase'; -import {GeoJSON} from '../format/GeoJSON'; +import { Util } from '../commontypes/Util'; +import { DataFormat } from '../REST'; +import { CommonServiceBase } from './CommonServiceBase'; +import { GeoJSON } from '../format/GeoJSON'; /** * @class GetFeaturesServiceBase @@ -19,65 +19,65 @@ import {GeoJSON} from '../format/GeoJSON'; * @param {DataFormat} [options.format=DataFormat.GEOJSON] - 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。参数格式为 "ISERVER","GEOJSON","FGB"。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer=false] - 当options.format=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @example * var myService = new GetFeaturesServiceBase(url); * @usage */ export class GetFeaturesServiceBase extends CommonServiceBase { - constructor(url, options) { - super(url, options); - options = options || {}; - - /** - * @member {boolean} [GetFeaturesServiceBase.prototype.returnContent=true] - * @description 是否立即返回新创建资源的表述还是返回新资源的 URI。 - * 如果为 true,则直接返回新创建资源,即查询结果的表述。 - * 如果为 false,则返回的是查询结果资源的 URI。 - */ - this.returnContent = true; - - /** - * @member {boolean} [GetFeaturesServiceBase.prototype.returnFeaturesOnly=false] - * @description 是否仅返回要素信息。 - */ - this.returnFeaturesOnly = false; - - /** - * @member {number} [GetFeaturesServiceBase.prototype.fromIndex=0] - * @description 查询结果的最小索引号。如果该值大于查询结果的最大索引号,则查询结果为空。 - */ - this.fromIndex = 0; - - /** - * @member {number} [GetFeaturesServiceBase.prototype.toIndex=19] - * @description 查询结果的最大索引号。 - * 如果该值大于查询结果的最大索引号,则以查询结果的最大索引号为终止索引号。 - */ - this.toIndex = 19; - - /** - * @member {number} [GetFeaturesServiceBase.prototype.hasGeometry=true] - * @description 返回结果是否包含 Geometry。 - */ - this.hasGeometry = true; - - /** - * @member {number} [GetFeaturesServiceBase.prototype.maxFeatures=1000] - * @description 进行 SQL 查询时,用于设置服务端返回查询结果条目数量。 - */ - this.maxFeatures = null; - - /** - * @member {string} [GetFeaturesServiceBase.prototype.format=DataFormat.GEOJSON] - * @description 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。 - * 参数格式为 "ISERVER","GEOJSON","FGB"。 - */ - this.format = DataFormat.GEOJSON; - - Util.extend(this, options); - this.url = Util.urlPathAppend(this.url, 'featureResults'); - this.CLASS_NAME = "SuperMap.GetFeaturesServiceBase"; + super(url, options); + options = options || {}; + + /** + * @member {boolean} [GetFeaturesServiceBase.prototype.returnContent=true] + * @description 是否立即返回新创建资源的表述还是返回新资源的 URI。 + * 如果为 true,则直接返回新创建资源,即查询结果的表述。 + * 如果为 false,则返回的是查询结果资源的 URI。 + */ + this.returnContent = true; + + /** + * @member {boolean} [GetFeaturesServiceBase.prototype.returnFeaturesOnly=false] + * @description 是否仅返回要素信息。 + */ + this.returnFeaturesOnly = false; + + /** + * @member {number} [GetFeaturesServiceBase.prototype.fromIndex=0] + * @description 查询结果的最小索引号。如果该值大于查询结果的最大索引号,则查询结果为空。 + */ + this.fromIndex = 0; + + /** + * @member {number} [GetFeaturesServiceBase.prototype.toIndex=19] + * @description 查询结果的最大索引号。 + * 如果该值大于查询结果的最大索引号,则以查询结果的最大索引号为终止索引号。 + */ + this.toIndex = 19; + + /** + * @member {number} [GetFeaturesServiceBase.prototype.hasGeometry=true] + * @description 返回结果是否包含 Geometry。 + */ + this.hasGeometry = true; + + /** + * @member {number} [GetFeaturesServiceBase.prototype.maxFeatures=1000] + * @description 进行 SQL 查询时,用于设置服务端返回查询结果条目数量。 + */ + this.maxFeatures = null; + + /** + * @member {string} [GetFeaturesServiceBase.prototype.format=DataFormat.GEOJSON] + * @description 查询结果返回格式,目前支持 iServerJSON、GeoJSON、FGB 三种格式。 + * 参数格式为 "ISERVER","GEOJSON","FGB"。 + */ + this.format = DataFormat.GEOJSON; + + Util.extend(this, options); + this.url = Util.urlPathAppend(this.url, 'featureResults'); + this.CLASS_NAME = 'SuperMap.GetFeaturesServiceBase'; } /** @@ -85,14 +85,14 @@ export class GetFeaturesServiceBase extends CommonServiceBase { * @description 释放资源,将引用资源的属性置空。 */ destroy() { - super.destroy(); - var me = this; - me.returnContent = null; - me.fromIndex = null; - me.toIndex = null; - me.maxFeatures = null; - me.format = null; - me.hasGeometry = null; + super.destroy(); + var me = this; + me.returnContent = null; + me.fromIndex = null; + me.toIndex = null; + me.maxFeatures = null; + me.format = null; + me.hasGeometry = null; } /** @@ -103,52 +103,57 @@ export class GetFeaturesServiceBase extends CommonServiceBase { * @returns {Promise} Promise 对象。 */ processAsync(params, callback) { - if (!params) { - return; - } - var me = this, - jsonParameters = null, - firstPara = true; - - me.returnContent = params.returnContent; - me.returnFeaturesOnly = params.returnFeaturesOnly; - me.fromIndex = params.fromIndex; - me.toIndex = params.toIndex; - me.maxFeatures = params.maxFeatures; - me.hasGeometry = params.hasGeometry; - if (me.returnContent) { - firstPara = false; + if (!params) { + return; + } + var me = this, + jsonParameters = null, + firstPara = true; + me.returnContent = params.returnContent; + me.returnFeaturesOnly = params.returnFeaturesOnly; + me.fromIndex = params.fromIndex; + me.toIndex = params.toIndex; + me.maxFeatures = params.maxFeatures; + me.hasGeometry = params.hasGeometry; + if (me.returnContent) { + firstPara = false; + } + var isValidNumber = me.fromIndex != null && me.toIndex != null && !isNaN(me.fromIndex) && !isNaN(me.toIndex); + if (isValidNumber && me.fromIndex >= 0 && me.toIndex >= 0 && !firstPara) { + me.url = Util.urlAppend(me.url, `fromIndex=${me.fromIndex}&toIndex=${me.toIndex}`); + } + + if (me.returnContent) { + if (!params.returnCountOnly && !params.returnDatasetInfoOnly && !params.returnFeaturesOnly) { + console.warn( + 'recommend set returnFeaturesOnly config to true to imporve performance. if need get Total amount and Dataset information. FeatureService provide getFeaturesCount and getFeaturesDatasetInfo method' + ); } - var isValidNumber = me.fromIndex != null && me.toIndex != null && !isNaN(me.fromIndex) && !isNaN(me.toIndex); - if (isValidNumber && me.fromIndex >= 0 && me.toIndex >= 0 && !firstPara) { - me.url = Util.urlAppend(me.url, `fromIndex=${me.fromIndex}&toIndex=${me.toIndex}`); + if (params.returnCountOnly) { + me.url = Util.urlAppend(me.url, 'returnCountOnly=' + params.returnCountOnly); } - if (me.returnContent) { - if (!params.returnCountOnly && !params.returnDatasetInfoOnly && !params.returnFeaturesOnly) { - console.warn('recommend set returnFeaturesOnly config to true to imporve performance. if need get Total amount and Dataset information. FeatureService provide getFeaturesCount and getFeaturesDatasetInfo method'); - } - if (params.returnCountOnly) { - me.url = Util.urlAppend(me.url, "returnCountOnly=" + params.returnCountOnly) - } - - if (params.returnDatasetInfoOnly) { - me.url = Util.urlAppend(me.url, "returnDatasetInfoOnly=" + params.returnDatasetInfoOnly) - } - - if (params.returnFeaturesOnly) { - me.url = Util.urlAppend(me.url, "returnFeaturesOnly=" + params.returnFeaturesOnly) - } - } - - jsonParameters = me.getJsonParameters(params); - return me.request({ - method: "POST", - data: jsonParameters, - scope: me, - success: callback, - failure: callback - }); + if (params.returnDatasetInfoOnly) { + me.url = Util.urlAppend(me.url, 'returnDatasetInfoOnly=' + params.returnDatasetInfoOnly); + } + if (params.returnFeaturesOnly) { + me.url = Util.urlAppend(me.url, 'returnFeaturesOnly=' + params.returnFeaturesOnly); + } + } + + if (me.preferServer && me.format === DataFormat.GEOJSON) { + me.url = Util.handleUrlSuffix(me.url, '.geojson'); + me.withoutFormatSuffix = true; + } + + jsonParameters = me.getJsonParameters(params); + return me.request({ + method: 'POST', + data: jsonParameters, + scope: me, + success: callback, + failure: callback + }); } /** @@ -159,25 +164,29 @@ export class GetFeaturesServiceBase extends CommonServiceBase { * @return {Object} 转换结果。 */ transformResult(result, options) { - var me = this; - result = Util.transformResult(result); - var geoJSONFormat = new GeoJSON(); - if (me.format === DataFormat.GEOJSON && result.features) { - result.features = geoJSONFormat.toGeoJSON(result.features); - } - if (me.returnFeaturesOnly && Array.isArray(result)) { - let succeed = result.succeed; - let features = geoJSONFormat.toGeoJSON(result); - result = { - succeed, - features - }; - } - return { result, options }; + var me = this; + result = Util.transformResult(result); + var geoJSONFormat = new GeoJSON(); + if (me.preferServer && me.format === DataFormat.GEOJSON) { + const succeed = result.succeed; + delete result.succeed; + return { result: { succeed, features: result }, options }; + } + if (me.format === DataFormat.GEOJSON && result.features) { + result.features = geoJSONFormat.toGeoJSON(result.features); + } + if (me.returnFeaturesOnly && Array.isArray(result)) { + let succeed = result.succeed; + let features = geoJSONFormat.toGeoJSON(result); + result = { + succeed, + features + }; + } + return { result, options }; } dataFormat() { return [DataFormat.GEOJSON, DataFormat.ISERVER, DataFormat.FGB]; } - } diff --git a/src/common/mapping/WebMapBase.js b/src/common/mapping/WebMapBase.js index 5912e536a3..081fe8b69f 100644 --- a/src/common/mapping/WebMapBase.js +++ b/src/common/mapping/WebMapBase.js @@ -28,6 +28,7 @@ const WORLD_WIDTH = 360; * @param {boolean} [options.isSuperMapOnline] - 是否是 SuperMap Online 地图。 * @param {string} [options.iportalServiceProxyUrlPrefix] - iportal的代理服务地址前缀。 * @param {string|boolean} [options.proxy] - HTTP 请求代理地址 。布尔值表示使用 iPortal 默认代理地址。 + * @param {boolean} [options.preferServer=false] - iServer rest/data服务, 使用服务器直接返回geojson。 * @param {Object} mapOptions - 地图参数。 * @param {Array} [mapOptions.center] - 中心点。 * @param {number} [mapOptions.zoom] - 缩放级别。 diff --git a/src/common/mapping/WebMapService.js b/src/common/mapping/WebMapService.js index 229ca1f60b..d98b9def11 100644 --- a/src/common/mapping/WebMapService.js +++ b/src/common/mapping/WebMapService.js @@ -42,6 +42,7 @@ export class WebMapService { this.excludePortalProxyUrl = options.excludePortalProxyUrl; this.iportalServiceProxyUrl = options.iportalServiceProxyUrlPrefix; this.proxy = options.proxy; + this.preferServer = options.preferServer || false; this.proxyOptions = { data: 'apps/viewer/getUrlResource.json?url=', image: 'apps/viewer/getUrlResource.png?url=' @@ -1224,6 +1225,7 @@ export class WebMapService { let options = { proxy, withCredentials: this.handleWithCredentials(proxy, url, false), + preferServer: this.preferServer, eventListeners: { processCompleted: getFeaturesEventArgs => { let result = getFeaturesEventArgs.result; diff --git a/src/common/util/FetchRequest.js b/src/common/util/FetchRequest.js index ef4c3db091..703d11eeb4 100644 --- a/src/common/util/FetchRequest.js +++ b/src/common/util/FetchRequest.js @@ -514,14 +514,7 @@ export var FetchRequest = { } if (url.indexOf('.json') === -1 && !options.withoutFormatSuffix) { - if (url.indexOf('?') < 0) { - url += '.json'; - } else { - var urlArrays = url.split('?'); - if (urlArrays.length === 2) { - url = urlArrays[0] + '.json?' + urlArrays[1]; - } - } + url = Util.handleUrlSuffix(url); } if (options && options.proxy) { if (typeof options.proxy === 'function') { diff --git a/src/mapboxgl/mapping/WebMap.js b/src/mapboxgl/mapping/WebMap.js index 3595948d4b..9859762232 100644 --- a/src/mapboxgl/mapping/WebMap.js +++ b/src/mapboxgl/mapping/WebMap.js @@ -49,6 +49,7 @@ import { GraticuleLayer } from '../overlay/GraticuleLayer'; * @param {boolean} [options.isSuperMapOnline] - 是否是 SuperMap Online 地图。 * @param {string} [options.iportalServiceProxyUrlPrefix] - iportal的代理服务地址前缀。 * @param {string|boolean} [options.proxy] - HTTP 请求代理地址 。布尔值表示使用 iPortal 默认代理地址。 + * @param {boolean} [options.preferServer=false] - 当图层数据来源为SuperMap iServer RestData服务, 使用服务器直接返回geojson。 * @param {Object} mapOptions - 地图参数。 * @param {Array} [mapOptions.center] - 中心点。 * @param {number} [mapOptions.zoom] - 缩放级别。 diff --git a/src/mapboxgl/services/FeatureService.js b/src/mapboxgl/services/FeatureService.js index 6b957d5ac7..d2f9461ffe 100644 --- a/src/mapboxgl/services/FeatureService.js +++ b/src/mapboxgl/services/FeatureService.js @@ -27,6 +27,7 @@ import { FeatureService as CommonFeatureService } from '@supermapgis/iclient-com * @param {boolean} [options.withCredentials=false] - 请求是否携带 cookie。 * @param {boolean} [options.crossOrigin] - 是否允许跨域请求。 * @param {Object} [options.headers] - 请求头。 + * @param {boolean} [options.preferServer] - 当resultFormat=DataFormat.GEOJSON时,使用服务器直接返回geojson。 * @usage */ export class FeatureService extends ServiceBase { diff --git a/test/mapboxgl/mapping/WebMapSpec.js b/test/mapboxgl/mapping/WebMapSpec.js index 32a74957ca..1d38969303 100644 --- a/test/mapboxgl/mapping/WebMapSpec.js +++ b/test/mapboxgl/mapping/WebMapSpec.js @@ -732,6 +732,40 @@ describe('mapboxgl_WebMap', () => { }); }); + it('createThemeLayer_SUPERMAPREST_DATA preferServer', (done) => { + let options = { + server: server, + preferServer: true + }; + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('web/config/portal.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy))); + } + if (url.indexOf('map.json') > -1) { + var mapJson = datavizWebMap_RestData; + return Promise.resolve(new Response(mapJson)); + } + return Promise.resolve(); + }); + spyOn(FetchRequest, 'post').and.callFake((url) => { + expect(url).toBe('http://fakeiserver/iserver/services/data-jingjin/rest/data/featureResults.geojson?returnFeaturesOnly=true&returnContent=true'); + return Promise.resolve(new Response(JSON.stringify(JSON.parse(markerData2.content)))); + }); + var datavizWebmap = new WebMap(id, options); + + datavizWebmap.on('mapcreatesucceeded', function () { + expect(datavizWebmap.credentialKey).toBeUndefined(); + expect(datavizWebmap.credentialValue).toBeUndefined(); + + var map = datavizWebmap.map; + expect(map.getZoom()).toBeCloseTo(9, 0.001); + expect(map.getCenter()).toEqual(new mapboxgl.LngLat(116.8995771532053, 39.700527641334965)); + expect(datavizWebmap.mapParams.title).toBe('RestData'); + expect(datavizWebmap.mapParams.description).toBe(''); + done(); + }); + }); + it('WMS', (done) => { let options = { server: server diff --git a/test/mapboxgl/services/GetFeaturesByBoundsSpec.js b/test/mapboxgl/services/GetFeaturesByBoundsSpec.js index c88acc9bab..d8e7ae708a 100644 --- a/test/mapboxgl/services/GetFeaturesByBoundsSpec.js +++ b/test/mapboxgl/services/GetFeaturesByBoundsSpec.js @@ -63,26 +63,40 @@ describe('mapboxgl_FeatureService_getFeaturesByBounds', () => { done(); }); }); - it('GetFeaturesByBoundsParameters:targetEpsgCode', done => { - var sw = new mapboxgl.LngLat(-20, -20); - var ne = new mapboxgl.LngLat(20, 20); - var lngLatBounds = new mapboxgl.LngLatBounds(sw, ne); - var boundsParam = new GetFeaturesByBoundsParameters({ - datasetNames: ['World:Capitals'], - bounds: lngLatBounds, - targetEpsgCode: 4326 - }); - var service = new FeatureService(url); - spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { - var paramsObj = JSON.parse(params.replace(/'/g, '"')); - expect(paramsObj.targetEpsgCode).toEqual(4326); - return Promise.resolve(new Response(JSON.stringify(getFeaturesResultJson))); - }); - service.getFeaturesByBounds(boundsParam, result => { - serviceResult = result; - boundsParam.destroy(); - done(); - }); + it('getFeaturesByBounds preferServer', done => { + var sw = new mapboxgl.LngLat(-20, -20); + var ne = new mapboxgl.LngLat(20, 20); + var lngLatBounds = new mapboxgl.LngLatBounds(sw, ne); + var boundsParam = new GetFeaturesByBoundsParameters({ + datasetNames: ['World:Capitals'], + bounds: lngLatBounds, + fromIndex: 1, + toIndex: 3 + }); + var service = new FeatureService(url, { preferServer: true }); + spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { + expect(method).toBe('POST'); + expect(testUrl).toBe(url + '/featureResults.geojson?fromIndex=1&toIndex=3&returnContent=true'); + var paramsObj = JSON.parse(params.replace(/'/g, '"')); + expect(paramsObj.datasetNames[0]).toBe('World:Capitals'); + expect(paramsObj.getFeatureMode).toBe('BOUNDS'); + expect(paramsObj.spatialQueryMode).toBe('CONTAIN'); + expect(options).not.toBeNull(); + expect(options.withoutFormatSuffix).toBe(true); + return Promise.resolve(new Response(JSON.stringify(getFeaturesBySQLService.result.features))); + }); + service.getFeaturesByBounds(boundsParam, testResult => { + serviceResult = testResult; + expect(service).not.toBeNull(); + expect(serviceResult.type).toBe('processCompleted'); + expect(serviceResult.object.format).toBe('GEOJSON'); + var result = serviceResult.result; + expect(result.succeed).toBe(true); + expect(result.features.type).toEqual('FeatureCollection'); + expect(serviceResult.object.preferServer).toBe(true); + boundsParam.destroy(); + done(); + }); }); it('GetFeaturesByBoundsParameters:targetPrj', done => { var sw = new mapboxgl.LngLat(-20, -20); diff --git a/test/mapboxgl/services/GetFeaturesByBufferSpec.js b/test/mapboxgl/services/GetFeaturesByBufferSpec.js index 8dce24e577..5965e44ccd 100644 --- a/test/mapboxgl/services/GetFeaturesByBufferSpec.js +++ b/test/mapboxgl/services/GetFeaturesByBufferSpec.js @@ -72,6 +72,51 @@ describe('mapboxgl_FeatureService_getFeaturesByBuffer', () => { done(); }); }); + it('getFeaturesByBuffer_geometry preferServer', done => { + var queryBufferGeometry = { + type: 'Polygon', + coordinates: [ + [ + [-20, 20], + [-20, -20], + [20, -20], + [20, 20], + [-20, 20] + ] + ] + }; + var bufferParam = new GetFeaturesByBufferParameters({ + datasetNames: ['World:Capitals'], + bufferDistance: 10, + geometry: queryBufferGeometry, + fromIndex: 1, + toIndex: 3 + }); + var service = new FeatureService(url, { preferServer: true }); + spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { + expect(method).toBe('POST'); + expect(testUrl).toBe(url + '/featureResults.geojson?fromIndex=1&toIndex=3&returnContent=true'); + var paramsObj = JSON.parse(params.replace(/'/g, '"')); + expect(paramsObj.datasetNames[0]).toBe('World:Capitals'); + expect(paramsObj.bufferDistance).toEqual(10); + expect(paramsObj.getFeatureMode).toBe('BUFFER'); + expect(options.withoutFormatSuffix).toBe(true); + expect(options).not.toBeNull(); + return Promise.resolve(new Response(JSON.stringify(getFeaturesBySQLService.result.features))); + }); + service.getFeaturesByBuffer(bufferParam, testResult => { + serviceResult = testResult; + expect(service).not.toBeNull(); + expect(serviceResult.type).toBe('processCompleted'); + expect(serviceResult.object.format).toBe('GEOJSON'); + var result = serviceResult.result; + expect(result.succeed).toBe(true); + expect(serviceResult.result.features.type).toEqual('FeatureCollection'); + expect(serviceResult.object.preferServer).toBe(true); + bufferParam.destroy(); + done(); + }); + }); it('GetFeaturesByBufferParameters:targetEpsgCode', done => { var queryBufferGeometry = { type: 'Polygon', diff --git a/test/mapboxgl/services/GetFeaturesByGeometrySpec.js b/test/mapboxgl/services/GetFeaturesByGeometrySpec.js index d052d64bfb..755b73f37c 100644 --- a/test/mapboxgl/services/GetFeaturesByGeometrySpec.js +++ b/test/mapboxgl/services/GetFeaturesByGeometrySpec.js @@ -73,6 +73,52 @@ describe('mapboxgl_FeatureService_getFeaturesByGeometry', () => { } }); }); + it('getFeaturesByGeometry preferServer', done => { + var queryPolygonGeometry = { + type: 'Polygon', + coordinates: [ + [ + [0, 0], + [-10, 30], + [-30, 0], + [0, 0] + ] + ] + }; + var geometryParam = new GetFeaturesByGeometryParameters({ + datasetNames: ['World:Countries'], + geometry: queryPolygonGeometry, + spatialQueryMode: 'INTERSECT' + }); + var service = new FeatureService(url, { preferServer: true }); + spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { + expect(method).toBe('POST'); + expect(testUrl).toBe(url + '/featureResults.geojson?fromIndex=0&toIndex=19&returnContent=true'); + var paramsObj = JSON.parse(params.replace(/'/g, '"')); + expect(paramsObj.datasetNames[0]).toBe('World:Countries'); + expect(paramsObj.spatialQueryMode).toBe('INTERSECT'); + expect(options.withoutFormatSuffix).toBe(true); + expect(options).not.toBeNull(); + return Promise.resolve(new Response(JSON.stringify(getFeaturesBySQLService.result.features))); + }); + service.getFeaturesByGeometry(geometryParam, result => { + serviceResult = result; + try { + expect(service).not.toBeNull(); + expect(serviceResult).not.toBeNull(); + expect(serviceResult.type).toBe('processCompleted'); + expect(serviceResult.result.succeed).toBe(true); + expect(serviceResult.options.data).toContain('World:Countries'); + expect(serviceResult.object.preferServer).toBe(true); + expect(serviceResult.result.features.type).toBe('FeatureCollection'); + done(); + } catch (e) { + console.log("'getFeaturesByGeometry preferServer'案例失败" + e.name + ':' + e.message); + expect(false).toBeTruthy(); + done(); + } + }); + }); it('GetFeaturesByGeometryParameters:targetEpsgCode', done => { var queryPolygonGeometry = { type: 'Polygon', diff --git a/test/mapboxgl/services/GetFeaturesByIDsSpec.js b/test/mapboxgl/services/GetFeaturesByIDsSpec.js index 34e691e884..7d3eeeb2dc 100644 --- a/test/mapboxgl/services/GetFeaturesByIDsSpec.js +++ b/test/mapboxgl/services/GetFeaturesByIDsSpec.js @@ -20,19 +20,65 @@ describe('mapboxgl_FeatureService_getFeaturesByIDs', () => { //数据集ID查询服务 it('getFeaturesByIDs', done => { + var idsParam = new GetFeaturesByIDsParameters({ + IDs: [247], + datasetNames: ['World:Countries'] + }); + var service = new FeatureService(url); + spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { + expect(method).toBe('POST'); + expect(testUrl).toBe(url + '/featureResults?fromIndex=0&toIndex=19&returnContent=true'); + var paramsObj = JSON.parse(params.replace(/'/g, '"')); + expect(paramsObj.datasetNames[0]).toBe('World:Countries'); + expect(paramsObj.getFeatureMode).toBe('ID'); + expect(options).not.toBeNull(); + return Promise.resolve(new Response(JSON.stringify(getFeaturesResultJson))); + }); + service.getFeaturesByIDs(idsParam, result => { + serviceResult = result; + try { + expect(service).not.toBeNull(); + expect(serviceResult).not.toBeNull(); + expect(serviceResult.type).toBe('processCompleted'); + expect(serviceResult.result.succeed).toBe(true); + expect(serviceResult.options.data).toContain('World:Countries'); + expect(serviceResult.result.featureCount).toEqual(1); + expect(serviceResult.result.totalCount).toEqual(serviceResult.result.featureCount); + expect(serviceResult.result.features.type).toEqual('FeatureCollection'); + expect(serviceResult.result.features.features[0].id).toEqual(127); + expect(serviceResult.result.features.features[0].type).toEqual('Feature'); + expect(serviceResult.result.features.features[0].geometry.type).toEqual('MultiPolygon'); + var coordinates = serviceResult.result.features.features[0].geometry.coordinates; + expect(coordinates.length).toBeGreaterThan(0); + for (var i = 0; i < coordinates.length; i++) { + expect(coordinates[i][0].length).toBeGreaterThan(0); + for (var j = 0; j < coordinates[i][0].length; j++) { + expect(coordinates[i][0][j].length).toEqual(2); + } + } + done(); + } catch (e) { + console.log("'getFeaturesByIDs'案例失败" + e.name + ':' + e.message); + expect(false).toBeTruthy(); + done(); + } + }); + }); + it('getFeaturesByIDs preferServer', done => { var idsParam = new GetFeaturesByIDsParameters({ IDs: [247], datasetNames: ['World:Countries'] }); - var service = new FeatureService(url); + var service = new FeatureService(url, { preferServer: true }); spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { expect(method).toBe('POST'); - expect(testUrl).toBe(url + '/featureResults?fromIndex=0&toIndex=19&returnContent=true'); + expect(testUrl).toBe(url + '/featureResults.geojson?fromIndex=0&toIndex=19&returnContent=true'); var paramsObj = JSON.parse(params.replace(/'/g, '"')); expect(paramsObj.datasetNames[0]).toBe('World:Countries'); expect(paramsObj.getFeatureMode).toBe('ID'); expect(options).not.toBeNull(); - return Promise.resolve(new Response(JSON.stringify(getFeaturesResultJson))); + expect(options.withoutFormatSuffix).toBe(true); + return Promise.resolve(new Response(JSON.stringify(getFeaturesBySQLService.result.features))); }); service.getFeaturesByIDs(idsParam, result => { serviceResult = result; @@ -41,24 +87,12 @@ describe('mapboxgl_FeatureService_getFeaturesByIDs', () => { expect(serviceResult).not.toBeNull(); expect(serviceResult.type).toBe('processCompleted'); expect(serviceResult.result.succeed).toBe(true); + expect(serviceResult.object.preferServer).toBe(true); expect(serviceResult.options.data).toContain('World:Countries'); - expect(serviceResult.result.featureCount).toEqual(1); - expect(serviceResult.result.totalCount).toEqual(serviceResult.result.featureCount); expect(serviceResult.result.features.type).toEqual('FeatureCollection'); - expect(serviceResult.result.features.features[0].id).toEqual(127); - expect(serviceResult.result.features.features[0].type).toEqual('Feature'); - expect(serviceResult.result.features.features[0].geometry.type).toEqual('MultiPolygon'); - var coordinates = serviceResult.result.features.features[0].geometry.coordinates; - expect(coordinates.length).toBeGreaterThan(0); - for (var i = 0; i < coordinates.length; i++) { - expect(coordinates[i][0].length).toBeGreaterThan(0); - for (var j = 0; j < coordinates[i][0].length; j++) { - expect(coordinates[i][0][j].length).toEqual(2); - } - } done(); } catch (e) { - console.log("'getFeaturesByIDs'案例失败" + e.name + ':' + e.message); + console.log("'getFeaturesByIDs preferServer'案例失败" + e.name + ':' + e.message); expect(false).toBeTruthy(); done(); } diff --git a/test/mapboxgl/services/GetFeaturesBySQLSpec.js b/test/mapboxgl/services/GetFeaturesBySQLSpec.js index 048320f797..0531fbc8bc 100644 --- a/test/mapboxgl/services/GetFeaturesBySQLSpec.js +++ b/test/mapboxgl/services/GetFeaturesBySQLSpec.js @@ -26,7 +26,87 @@ describe('mapboxgl_FeatureService_getFeaturesBySQL', () => { expect(getFeaturesBySQLService.options.headers).not.toBeNull(); }); - //数据集SQL查询服务 + it('getFeaturesBySQL geojson preferServer true', done => { + var sqlParam = new GetFeaturesBySQLParameters({ + queryParameter: { + name: 'Countries@World', + attributeFilter: 'SMID = 247' + }, + datasetNames: ['World:Countries'] + }); + var service = new FeatureService(url, { preferServer: true }); + spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { + expect(method).toBe('POST'); + expect(testUrl).toBe(url + '/featureResults.geojson?fromIndex=0&toIndex=19&returnContent=true'); + var paramsObj = JSON.parse(params.replace(/'/g, '"')); + expect(paramsObj.datasetNames[0]).toBe('World:Countries'); + expect(paramsObj.getFeatureMode).toBe('SQL'); + expect(options).not.toBeNull(); + expect(options.withoutFormatSuffix).toBe(true); + return Promise.resolve(new Response(JSON.stringify(getFeaturesBySQLService.result.features))); + }); + service.getFeaturesBySQL(sqlParam, result => { + serviceResult = result; + + try { + expect(service).not.toBeNull(); + expect(serviceResult).not.toBeNull(); + expect(serviceResult.type).toBe('processCompleted'); + expect(serviceResult.result.succeed).toBe(true); + expect(serviceResult.object.preferServer).toBe(true); + expect(serviceResult.result.features.type).toBe('FeatureCollection'); + expect(serviceResult.options.data).toContain('Countries@World'); + expect(serviceResult.options.data).toContain('SMID = 247'); + done(); + } catch (e) { + console.log("'getFeaturesBySQL prefreServer'案例失败" + e.name + ':' + e.message); + expect(false).toBeTruthy(); + done(); + } + }); + }); + + it('getFeaturesBySQL iserver preferServer true', done => { + var sqlParam = new GetFeaturesBySQLParameters({ + queryParameter: { + name: 'Countries@World', + attributeFilter: 'SMID = 247' + }, + datasetNames: ['World:Countries'] + }); + var service = new FeatureService(url, { preferServer: true }); + spyOn(FetchRequest, 'commit').and.callFake((method, testUrl, params, options) => { + expect(method).toBe('POST'); + expect(testUrl).toBe(url + '/featureResults?fromIndex=0&toIndex=19&returnContent=true'); + var paramsObj = JSON.parse(params.replace(/'/g, '"')); + expect(paramsObj.datasetNames[0]).toBe('World:Countries'); + expect(paramsObj.getFeatureMode).toBe('SQL'); + expect(options).not.toBeNull(); + expect(options.withoutFormatSuffix).toBe(false); + return Promise.resolve(new Response(JSON.stringify(getFeaturesResultJson))); + }); + service.getFeaturesBySQL(sqlParam, result => { + serviceResult = result; + try { + expect(service).not.toBeNull(); + expect(serviceResult).not.toBeNull(); + expect(serviceResult.type).toBe('processCompleted'); + expect(serviceResult.result.succeed).toBe(true); + expect(serviceResult.object.preferServer).toBe(true); + expect(serviceResult.result.features).not.toBeNull(); + expect(serviceResult.options.data).toContain('Countries@World'); + expect(serviceResult.options.data).toContain('SMID = 247'); + expect(serviceResult.result.featureCount).toEqual(1); + expect(serviceResult.result.totalCount).toEqual(1); + done(); + } catch (e) { + console.log("'getFeaturesBySQL prefreServer'案例失败" + e.name + ':' + e.message); + expect(false).toBeTruthy(); + done(); + } + }, 'ISERVER'); + }); + it('getFeaturesBySQL', done => { var sqlParam = new GetFeaturesBySQLParameters({ queryParameter: { From 694f0d7ad8866c27a656e88180c8882aaee7d20e Mon Sep 17 00:00:00 2001 From: chenxianhui Date: Thu, 4 Dec 2025 10:49:33 +0800 Subject: [PATCH 4/5] =?UTF-8?q?[update]=20=E6=9B=B4=E6=96=B0http=E4=B8=BAh?= =?UTF-8?q?ttps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clientcomputation/ClientComputationView.js | 2 +- .../dataservicequery/DataServiceQueryView.js | 2 +- .../distributedanalysis/DistributedAnalysisView.js | 2 +- src/openlayers/mapping/Tianditu.js | 10 +++++----- src/openlayers/mapping/WebMap.js | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/leaflet/components/clientcomputation/ClientComputationView.js b/src/leaflet/components/clientcomputation/ClientComputationView.js index c3c0008d3f..9d919c3701 100644 --- a/src/leaflet/components/clientcomputation/ClientComputationView.js +++ b/src/leaflet/components/clientcomputation/ClientComputationView.js @@ -308,7 +308,7 @@ export var ClientComputationView = ComponentsViewBase.extend({ let analysisingBtn = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysising', analysingContainer); let svgContainer = L.DomUtil.create('div', 'component-analysis__svg-container', analysisingBtn); svgContainer.id = 'analyse_background'; - svgContainer.innerHTML = ` + svgContainer.innerHTML = ` diff --git a/src/leaflet/components/dataservicequery/DataServiceQueryView.js b/src/leaflet/components/dataservicequery/DataServiceQueryView.js index 0b8fa53736..d9bbc681e5 100644 --- a/src/leaflet/components/dataservicequery/DataServiceQueryView.js +++ b/src/leaflet/components/dataservicequery/DataServiceQueryView.js @@ -231,7 +231,7 @@ export var DataServiceQueryView = ComponentsViewBase.extend({ let analysingContainer = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysing-container hidden', runBtn); let analysisingBtn = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysising component-servicequery__querybtn--querying', analysingContainer); let svgContainer = L.DomUtil.create('div', 'component-analysis__svg-container', analysisingBtn); - svgContainer.innerHTML = ` + svgContainer.innerHTML = ` diff --git a/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js b/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js index 81767b0799..43b40f05b8 100644 --- a/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js +++ b/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js @@ -274,7 +274,7 @@ export var DistributedAnalysisView = ComponentsViewBase.extend({ let analysisingBtn = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysising', analysingContainer); analysisingBtn.style.width = '200px'; let svgContainer = L.DomUtil.create('div', 'component-analysis__svg-container', analysisingBtn); - svgContainer.innerHTML = ` + svgContainer.innerHTML = ` diff --git a/src/openlayers/mapping/Tianditu.js b/src/openlayers/mapping/Tianditu.js index 5584e216dc..08e88dcfb0 100644 --- a/src/openlayers/mapping/Tianditu.js +++ b/src/openlayers/mapping/Tianditu.js @@ -12,8 +12,8 @@ import WMTSTileGrid from 'ol/tilegrid/WMTS'; * @classdesc 天地图图层源。 * @modulecategory Mapping * @param {Object} opt_options - 参数。 - * @param {string} [opt_options.url='http://t{0-7}.tianditu.gov.cn/{layer}_{proj}/wmts?'] - 服务地址。 - * @param {string} opt_options.key - 天地图服务密钥。详见{@link http://lbs.tianditu.gov.cn/server/MapService.html} + * @param {string} [opt_options.url='https://t{0-7}.tianditu.gov.cn/{layer}_{proj}/wmts?'] - 服务地址。 + * @param {string} opt_options.key - 天地图服务密钥。详见{@link https://lbs.tianditu.gov.cn/server/MapService.html} * @param {string} [opt_options.layerType='vec'] - 图层类型。(vec:矢量图层,img:影像图层,ter:地形图层) * @param {string} [opt_options.attributions] - 版权描述信息。 * @param {number} [opt_options.cacheSize = 2048] - 缓冲大小。 @@ -39,14 +39,14 @@ export class Tianditu extends WMTS { "img": 18 } var options = opt_options || {}; - var attributions = options.attributions || "Map Data with " + + var attributions = options.attributions || "Map Data with " + "© SuperMap iClient" options.layerType = options.layerType || "vec"; options.layerType = options.isLabel ? layerLabelMap[options.layerType] : options.layerType; options.matrixSet = (options.projection === 'EPSG:4326' || options.projection === 'EPSG:4490') ? "c" : "w"; if (!options.url && !options.urls) { - options.url = "http://t{0-7}.tianditu.gov.cn/{layer}_{proj}/wmts?" + options.url = "https://t{0-7}.tianditu.gov.cn/{layer}_{proj}/wmts?" } if (options.key) { options.url = `${options.url}tk=${options.key}`; diff --git a/src/openlayers/mapping/WebMap.js b/src/openlayers/mapping/WebMap.js index 0fc4bcf2ca..1cbf9143dc 100644 --- a/src/openlayers/mapping/WebMap.js +++ b/src/openlayers/mapping/WebMap.js @@ -1138,7 +1138,7 @@ export class WebMap extends Observable { } break; case 'OSM': - baseLayerInfo.url = 'http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'; + baseLayerInfo.url = 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'; baseLayerInfo.epsgCode = 'EPSG:3857'; baseLayerInfo.minZoom = 1; baseLayerInfo.maxZoom = 19; From 3607ec92f01e8fddc4591cb04d78cc33dca89c3b Mon Sep 17 00:00:00 2001 From: chenxianhui Date: Thu, 11 Dec 2025 15:29:08 +0800 Subject: [PATCH 5/5] =?UTF-8?q?[fix]=E8=BF=98=E5=8E=9F=E9=83=A8=E5=88=86ht?= =?UTF-8?q?tp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/clientcomputation/ClientComputationView.js | 2 +- src/leaflet/components/dataservicequery/DataServiceQueryView.js | 2 +- .../components/distributedanalysis/DistributedAnalysisView.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/leaflet/components/clientcomputation/ClientComputationView.js b/src/leaflet/components/clientcomputation/ClientComputationView.js index 9d919c3701..c3c0008d3f 100644 --- a/src/leaflet/components/clientcomputation/ClientComputationView.js +++ b/src/leaflet/components/clientcomputation/ClientComputationView.js @@ -308,7 +308,7 @@ export var ClientComputationView = ComponentsViewBase.extend({ let analysisingBtn = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysising', analysingContainer); let svgContainer = L.DomUtil.create('div', 'component-analysis__svg-container', analysisingBtn); svgContainer.id = 'analyse_background'; - svgContainer.innerHTML = ` + svgContainer.innerHTML = ` diff --git a/src/leaflet/components/dataservicequery/DataServiceQueryView.js b/src/leaflet/components/dataservicequery/DataServiceQueryView.js index d9bbc681e5..0b8fa53736 100644 --- a/src/leaflet/components/dataservicequery/DataServiceQueryView.js +++ b/src/leaflet/components/dataservicequery/DataServiceQueryView.js @@ -231,7 +231,7 @@ export var DataServiceQueryView = ComponentsViewBase.extend({ let analysingContainer = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysing-container hidden', runBtn); let analysisingBtn = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysising component-servicequery__querybtn--querying', analysingContainer); let svgContainer = L.DomUtil.create('div', 'component-analysis__svg-container', analysisingBtn); - svgContainer.innerHTML = ` + svgContainer.innerHTML = ` diff --git a/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js b/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js index 43b40f05b8..81767b0799 100644 --- a/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js +++ b/src/leaflet/components/distributedanalysis/DistributedAnalysisView.js @@ -274,7 +274,7 @@ export var DistributedAnalysisView = ComponentsViewBase.extend({ let analysisingBtn = L.DomUtil.create('div', 'component-analysis__analysisbtn--analysising', analysingContainer); analysisingBtn.style.width = '200px'; let svgContainer = L.DomUtil.create('div', 'component-analysis__svg-container', analysisingBtn); - svgContainer.innerHTML = ` + svgContainer.innerHTML = `