Skip to content

Commit

Permalink
【feature】crs 逻辑重构, 优先取map的crs定义; review by sogym
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongjiaojiao committed Dec 9, 2024
1 parent bf07589 commit af11251
Show file tree
Hide file tree
Showing 17 changed files with 1,373 additions and 448 deletions.
29 changes: 19 additions & 10 deletions src/common/mapping/MapStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { WebMapService } from './WebMapService';
import { SourceListModelV2 } from './utils/SourceListModelV2';
import { createAppreciableLayerId, isSameRasterLayer } from './utils/util';

export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
export function createMapStyleExtending(SuperClass, { MapManager, crsManager }) {
return class MapStyle extends SuperClass {
constructor(id, options = {}, mapOptions = {}) {
super();
Expand All @@ -11,24 +11,22 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
this.webMapService = new WebMapService(id, options);
this._layerIdRenameMapList = [];
this._appendLayers = false;
this._baseProjection = '';
}

initializeMap(_, map) {
this._baseProjection = this._registerMapCRS(this.mapOptions);
if (map) {
if (!crsManager.isSameProjection(map, this._baseProjection)) {
this.fire('projectionnotmatch');
return;
}
this._appendLayers = true;
this.map = map;
this._addLayersToMap();
return;
}
this.mapOptions.container = this.options.target;
if (typeof this.mapOptions.crs === 'object' && this.mapOptions.crs.epsgCode) {
this.mapOptions.crs = new mapRepo.CRS(
this.mapOptions.crs.epsgCode,
this.mapOptions.crs.WKT,
this.mapOptions.crs.extent,
this.mapOptions.crs.unit
);
}
if (!this.mapOptions.transformRequest) {
this.mapOptions.transformRequest = (url, resourceType) => {
let proxy = '';
Expand All @@ -53,7 +51,7 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
if (Object.prototype.hasOwnProperty.call(this.mapOptions, 'fadeDuration')) {
fadeDuration = this.mapOptions.fadeDuration;
}
this.map = new MapManager({ ...this.mapOptions, fadeDuration });
this.map = new MapManager({ ...this.mapOptions, fadeDuration, crs: this._baseProjection });
this.fire('mapinitialized', { map: this.map });
this.map.on('load', () => {
this._sendMapToUser();
Expand All @@ -71,6 +69,17 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
}
}

_registerMapCRS(mapOptions) {
const { crs } = mapOptions;
let epsgCode = crs;
if (typeof crs === 'object' && crs.epsgCode) {
const { epsgCode: name, WKT: wkt, extent, unit } = crs;
crsManager.registerCRS({ name, wkt, extent, unit });
epsgCode = name;
}
return epsgCode;
}

_addLayersToMap() {
const { sources, layers, layerIdMapList } = this._setUniqueId(this.mapOptions.style);
layers.forEach((layer) => {
Expand Down
33 changes: 5 additions & 28 deletions src/common/mapping/WebMapBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
this._mapInitializedHandler = this._mapInitializedHandler.bind(this);
this._mapCreateSucceededHandler = this._mapCreateSucceededHandler.bind(this);
this._addLayerChangedHandler = this._addLayerChangedHandler.bind(this);
this._initWebMap(!this.map);
}

/**
Expand All @@ -193,33 +192,6 @@ export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
}
}

/**
* @function WebMapBase.prototype.setCRS
* @description 更新地图投影。
* @param {string|Object} crs - 地图 crs。
*/
setCRS(crs) {
if (this.map) {
this.mapOptions.crs = crs;
if (this.mapOptions.crs) {
if (this.map.getCRS(typeof crs === 'string' ? crs : crs.epsgCode)) {
return;
}
if (crs.epsgCode) {
this.mapOptions.crs = new mapRepo.CRS(
this.mapOptions.crs.epsgCode,
this.mapOptions.crs.WKT,
this.mapOptions.crs.extent,
this.mapOptions.crs.unit
);
this.map.setCRS(this.mapOptions.crs);
} else {
this.map.setCRS(mapRepo.CRS.get(crs));
}
}
}
}

/**
* @function WebMapBase.prototype.setCenter
* @description 更新地图中心点。
Expand Down Expand Up @@ -500,6 +472,10 @@ export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
this.clean(false);
}

_readyForInitializingWebMap() {
this._initWebMap(!this.map);
}

_initWebMap(clean = true) {
clean && this.clean();
if (this.webMapInfo) {
Expand Down Expand Up @@ -660,6 +636,7 @@ export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
};
}
this.type = type;
// initializeMap 完成3个步骤:1. 注册投影 2. 判断投影与存在的map是否一致 3. 创建地图
this._handler.initializeMap(_mapInfo, this.map);
}

Expand Down
172 changes: 70 additions & 102 deletions src/common/mapping/WebMapV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* 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 cloneDeep from 'lodash.clonedeep';
import { getProjection, registerProjection, toEpsgCode, transformCoodinates } from './utils/epsg-define';
import { getProjection, toEpsgCode, transformCoodinates } from './utils/epsg-define';
import { ColorsPickerUtil } from '../util/ColorsPickerUtil';
import { Util } from '../commontypes/Util';
import { ArrayStatistic } from '../util/ArrayStatistic';
Expand All @@ -17,7 +17,7 @@ const INTERNET_MAP_BOUNDS = {
BING: [-180, -90, 180, 90]
}

export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataFlowService, GraticuleLayer }) {
export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsManager, DataFlowService, GraticuleLayer }) {
return class WebMapV2 extends SuperClass {
constructor(
id,
Expand Down Expand Up @@ -49,12 +49,23 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF
this._appendLayers = false;
}

initializeMap(mapInfo, map) {
if (map) {
this._appendLayers = true;
this.map = map;
async initializeMap(mapInfo, map) {
try {
this.baseProjection = await this._registerMapCRS(mapInfo);
if (map) {
if (!crsManager.isSameProjection(map, this.baseProjection) && !this.ignoreBaseProjection) {
this.fire('projectionnotmatch');
return;
}
this._appendLayers = true;
this.map = map;
}
this._mapInfo = mapInfo;
this._loadLayers(mapInfo, this._taskID);
} catch (error) {
console.error(error);
this.fire('mapcreatefailed', { error });
}
this._getMapInfo(mapInfo, this._taskID);
}

cleanLayers(layers) {
Expand Down Expand Up @@ -95,12 +106,10 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF

_initWebMap() {}

_getMapInfo() {}

_loadLayers(mapInfo, _taskID) {
if (this.map) {
if (this.map.getCRS().epsgCode !== this.baseProjection && !this.ignoreBaseProjection) {
this.fire('projectionnotmatch', {});
return;
}
this._handleLayerInfo(mapInfo, _taskID);
} else {
setTimeout(() => {
Expand All @@ -112,95 +121,59 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF
}
}

_setCRS(baseProjection, wkt, bounds) {
if (mapRepo.CRS.get(baseProjection)) {
return;
}
const crs = new mapRepo.CRS(baseProjection, wkt, bounds, bounds[2] > 180 ? 'meter' : 'degree');
mapRepo.CRS.set(crs);
}

_getMapInfo(mapInfo, _taskID) {
this._mapInfo = mapInfo;
const { projection } = mapInfo;
let bounds, wkt;
this.baseProjection = toEpsgCode(projection);
let defaultWktValue = getProjection(this.baseProjection, this.specifiedProj4);

if (defaultWktValue) {
wkt = defaultWktValue;
}
if (!mapRepo.CRS.get(this.baseProjection)) {
if (mapInfo.baseLayer && mapInfo.baseLayer.layerType === 'MAPBOXSTYLE') {
let url = mapInfo.baseLayer.dataSource.url;
if (url.indexOf('/restjsr/') > -1 && !/\/style\.json$/.test(url)) {
url += '/style.json';
}
this.webMapService.getMapBoxStyle(url).then((res) => {
async _registerMapCRS(mapInfo) {
const { projection, extent, baseLayer = {} } = mapInfo;
const epsgCode = toEpsgCode(projection);
let crs = {
name: epsgCode,
extent: [extent.leftBottom.x, extent.leftBottom.y, extent.rightTop.x, extent.rightTop.y],
wkt: this._getProjectionWKT(projection)
};
if (!crsManager.getCRS(epsgCode)) {
switch (baseLayer.layerType) {
case 'MAPBOXSTYLE': {
let url = baseLayer.dataSource.url;
if (url.indexOf('/restjsr/') > -1 && !/\/style\.json$/.test(url)) {
url += '/style.json';
}
const res = await this.webMapService.getMapBoxStyle(url);
if (res && res.metadata && res.metadata.indexbounds) {
bounds = res.metadata.indexbounds;
} else {
bounds = [
mapInfo.extent.leftBottom.x,
mapInfo.extent.leftBottom.y,
mapInfo.extent.rightTop.x,
mapInfo.extent.rightTop.y
];
crs.extent = res.metadata.indexbounds;
}
this._defineProj4(projection);
this._setCRS(this.baseProjection, wkt, bounds);
this._loadLayers(mapInfo, _taskID);
});
} else if (mapInfo.baseLayer && mapInfo.baseLayer.layerType === 'TILE') {
// 获取地图的wkt
this.getEpsgCodeWKT(`${mapInfo.baseLayer.url}/prjCoordSys.wkt`, {
withoutFormatSuffix: true,
withCredentials: this.webMapService.handleWithCredentials('', mapInfo.baseLayer.url, false)
}).then((res) => {
if (!wkt) {
wkt = res;
break;
}
case 'TILE': {
// 获取地图的wkt
if (!crs.wkt) {
crs.wkt = await this.getEpsgCodeWKT(`${baseLayer.url}/prjCoordSys.wkt`, {
withoutFormatSuffix: true,
withCredentials: this.webMapService.handleWithCredentials('', baseLayer.url, false)
});
}
this.getBounds(`${mapInfo.baseLayer.url}.json`, {
const boundsRes = await this.getBounds(`${baseLayer.url}.json`, {
withoutFormatSuffix: true,
withCredentials: this.webMapService.handleWithCredentials('', mapInfo.baseLayer.url, false)
}).then((res) => {
if (res && res.bounds) {
bounds = [
res.bounds.leftBottom.x,
res.bounds.leftBottom.y,
res.bounds.rightTop.x,
res.bounds.rightTop.y
];
} else {
bounds = [
mapInfo.extent.leftBottom.x,
mapInfo.extent.leftBottom.y,
mapInfo.extent.rightTop.x,
mapInfo.extent.rightTop.y
];
}
this._defineProj4(wkt, projection);
this._setCRS(this.baseProjection, wkt, bounds);
this._loadLayers(mapInfo, _taskID);
withCredentials: this.webMapService.handleWithCredentials('', baseLayer.url, false)
});
});
} else {
const error = new Error('Unsupported coordinate system!');
console.log(error);
this.fire('mapcreatefailed', { error });
if (boundsRes && boundsRes.bounds) {
crs.extent = [
boundsRes.bounds.leftBottom.x,
boundsRes.bounds.leftBottom.y,
boundsRes.bounds.rightTop.x,
boundsRes.bounds.rightTop.y
];
}
break;
}
default:
crs = null;
break;
}
} else {
wkt = mapRepo.CRS.get(this.baseProjection).WKT
this._defineProj4(wkt || projection);
bounds = [
mapInfo.extent.leftBottom.x,
mapInfo.extent.leftBottom.y,
mapInfo.extent.rightTop.x,
mapInfo.extent.rightTop.y
];
this._setCRS(this.baseProjection, wkt, bounds);
this._loadLayers(mapInfo, _taskID);
}
if (!crs) {
throw new Error('Unsupported coordinate system!')
}
crsManager.registerCRS(crs);
return epsgCode;
}

_handleLayerInfo(mapInfo, _taskID) {
Expand Down Expand Up @@ -499,7 +472,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF
layerInfo.dataSource &&
layerInfo.dataSource.type !== 'REST_DATA'
) {
this._unprojectProjection = this._defineProj4(projection);
this._unprojectProjection = toEpsgCode(projection);
features = this.transformFeatures(features);
}

Expand Down Expand Up @@ -2772,15 +2745,10 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF
return tiandituUrls;
}

_defineProj4(projection, defaultEpsgCode) {
_getProjectionWKT(projection) {
let epsgCode = toEpsgCode(projection);
const reg = /^EPSG:/;
const defValue = epsgCode && projection.match(reg) ? getProjection(epsgCode, this.specifiedProj4) : projection;
if (!epsgCode && defaultEpsgCode && defaultEpsgCode.match(reg)) {
epsgCode = defaultEpsgCode;
}
registerProjection(epsgCode, defValue, this.specifiedProj4);
return epsgCode;
return epsgCode && projection.match(reg) ? getProjection(epsgCode, this.specifiedProj4) : projection;
}

_fetchRequest(url, type, options) {
Expand All @@ -2805,7 +2773,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF

getBounds(baseUrl, options) {
if (!baseUrl) {
return;
return Promise.resolve(null);
}
return this._fetchRequest(baseUrl, 'json', options);
}
Expand Down
Loading

0 comments on commit af11251

Please sign in to comment.