|
@@ -22078,18 +22078,17 @@
|
|
|
//移动过后使用移动后的坐标
|
|
|
model.position.copy(prop.position);
|
|
|
} else {
|
|
|
- if (!model.isPointcloud && prop.raw.wgs84) {
|
|
|
+ if (!model.isPointcloud && prop.raw.wgs84 || model.fileType == 'shp') {
|
|
|
//有经纬度
|
|
|
- var locationLonLat = prop.raw.wgs84.split(',').map(e => parseFloat(e));
|
|
|
- var location = viewer.transform.lonlatToLocal.forward(locationLonLat);
|
|
|
- MergeEditor.moveBoundCenterTo(model, new Vector3().fromArray(location));
|
|
|
- model.hasLonLat = true;
|
|
|
- model.lonLatPos = model.position.clone();
|
|
|
- } else if (model.fileType == 'shp') {
|
|
|
+ if (prop.raw.wgs84) {
|
|
|
+ var locationLonLat = prop.raw.wgs84.split(',').map(e => parseFloat(e));
|
|
|
+ var location = viewer.transform.lonlatToLocal.forward(locationLonLat);
|
|
|
+ MergeEditor.moveBoundCenterTo(model, new Vector3().fromArray(location));
|
|
|
+ }
|
|
|
model.hasLonLat = true;
|
|
|
model.lonLatPos = model.position.clone();
|
|
|
}
|
|
|
- MergeEditor.setModelBtmHeight(model, 0); // 离地高度为0 (因为不想在地图下方所以高程不管了,都在地面上即可)
|
|
|
+ MergeEditor.setModelBtmHeight(model, 0.1); // 离地高度为0 (因为不想在地图下方所以高程不管了,都在地面上即可)
|
|
|
}
|
|
|
}
|
|
|
if (prop.rotation && (prop.rotation.x != 0 || prop.rotation.y != 0 || prop.rotation.z != 0)) {
|
|
@@ -38916,6 +38915,15 @@
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+ /* proj4.defs("CGCS2000","+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=WGS84 +units=m +no_defs")
|
|
|
+
|
|
|
+ function transformCGCS2000ToWGS84([lng, lat]) {
|
|
|
+ // Define the CGCS2000 and WGS84 coordinate systems
|
|
|
+ const transformed = proj4("CGCS2000", "LOCAL", [lng, lat]);
|
|
|
+ return transformed
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
class ShapefileLoader {
|
|
|
constructor() {
|
|
|
//this.transform = null;
|
|
@@ -38929,12 +38937,15 @@
|
|
|
dashed: false
|
|
|
});
|
|
|
var features = await this.loadShapefileFeatures(path);
|
|
|
- var node = new Object3D();
|
|
|
if (!features) {
|
|
|
- console.error('no features');
|
|
|
+ console.error('no features', path);
|
|
|
return;
|
|
|
}
|
|
|
- var transform = this.analyseTransform(features, path);
|
|
|
+ var node = new Object3D();
|
|
|
+ var transform = await this.loadProj(path);
|
|
|
+ if (!transform) {
|
|
|
+ transform = this.analyseTransform(features, path);
|
|
|
+ }
|
|
|
var jump = 0;
|
|
|
for (var feature of features) {
|
|
|
//5是碎的
|
|
@@ -38958,7 +38969,7 @@
|
|
|
if (viewer.transform) {
|
|
|
var count = 0,
|
|
|
maxCount = 100;
|
|
|
- var notLonLat, transform;
|
|
|
+ var notLonLat, _transform;
|
|
|
var judge = coord => {
|
|
|
if (!(coord[0] >= -180 && coord[0] <= 180 && coord[1] >= -90 && coord[1] <= 90)) {
|
|
|
//如果超出经纬度范围,那就不是经纬度
|
|
@@ -38981,18 +38992,21 @@
|
|
|
}
|
|
|
}
|
|
|
if (notLonLat) {
|
|
|
- transform = v => {
|
|
|
+ _transform = v => {
|
|
|
var a = viewer.transform.lonlatTo4550.inverse(v); //这种类型和不使用transform很接近
|
|
|
return viewer.transform.lonlatToLocal.forward(a);
|
|
|
};
|
|
|
- console.log('该shape使用大地坐标', path.split('/').pop());
|
|
|
+ //transform = transformCGCS2000ToWGS84
|
|
|
+ console.log('该shape使用4550大地坐标', path.split('/').pop());
|
|
|
} else {
|
|
|
- transform = viewer.transform.lonlatToLocal.forward;
|
|
|
+ _transform = viewer.transform.lonlatToLocal.forward;
|
|
|
console.log('该shape使用经纬度', path.split('/').pop());
|
|
|
}
|
|
|
- return transform;
|
|
|
+ return _transform;
|
|
|
|
|
|
//loaders.shapeLoader.transform = viewer.transform.lonlatToLocal.forward;
|
|
|
+ } else {
|
|
|
+ console.log('该shape没用任何transform 因为场景没有设置经纬度', path.split('/').pop());
|
|
|
}
|
|
|
}
|
|
|
featureToSceneNode(feature, matLine, transform) {
|
|
@@ -39126,8 +39140,293 @@
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
+ async loadProj(path) {
|
|
|
+ var a = path.split('/');
|
|
|
+ var name = a.pop().split('.')[0];
|
|
|
+ path = a.join('/') + '/' + name + '.prj';
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ Potree.loadFile(path, {
|
|
|
+ returnText: true
|
|
|
+ }, e => {
|
|
|
+ name += '_proj';
|
|
|
+ var projDef = parsePrjToProj4(e);
|
|
|
+ proj4.defs(name, projDef);
|
|
|
+ console.log('loadedProj:', name, '解析得def: ', projDef, '原:', e);
|
|
|
+ try {
|
|
|
+ var proj = proj4(name, "LOCAL");
|
|
|
+ var _transform2 = _ref => {
|
|
|
+ var [lng, lat] = _ref;
|
|
|
+ return proj.forward([lng, lat]);
|
|
|
+ };
|
|
|
+ resolve(_transform2);
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e, 'build proj4 failed', name);
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ }, () => {
|
|
|
+ resolve();
|
|
|
+ console.log('prj load failed', name);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ //let transformed = c.forward([lng, lat])
|
|
|
+ return transform;
|
|
|
+ }
|
|
|
}
|
|
|
;
|
|
|
+ function parsePrjToProj4(prjString) {
|
|
|
+ var def = '';
|
|
|
+ var json = prjToJson(prjString);
|
|
|
+ var projectionType;
|
|
|
+ var datum = '';
|
|
|
+ var ellipsoid = '';
|
|
|
+ var centralMeridian = '';
|
|
|
+ var scaleFactor = '1';
|
|
|
+ var falseEasting = '0';
|
|
|
+ var falseNorthing = '0';
|
|
|
+ var latitudeOfOrigin = '0';
|
|
|
+ if (json.projection == 'Transverse_Mercator') {
|
|
|
+ projectionType = 'tmerc';
|
|
|
+ } else if (!json.projection) {
|
|
|
+ projectionType = 'lonlat';
|
|
|
+ } else {
|
|
|
+ projectionType = projection;
|
|
|
+ console.log('unknown projection:', json.projection);
|
|
|
+ }
|
|
|
+ if (json.parameters) {
|
|
|
+ falseEasting = json.parameters.false_easting;
|
|
|
+ falseNorthing = json.parameters.false_northing;
|
|
|
+ centralMeridian = json.parameters.central_meridian;
|
|
|
+ latitudeOfOrigin = json.parameters.latitude_of_origin;
|
|
|
+ scaleFactor = json.parameters.scale_factor;
|
|
|
+ }
|
|
|
+ if (json.spheroid) {
|
|
|
+ if (json.spheroid.name.toLowerCase().includes('wgs84')) ellipsoid = 'WGS84';
|
|
|
+ }
|
|
|
+ def += "+proj=".concat(projectionType);
|
|
|
+ def += "+lat_0=".concat(latitudeOfOrigin, " ");
|
|
|
+ def += "+lon_0=".concat(centralMeridian, " ");
|
|
|
+ def += "+k=".concat(scaleFactor, " ");
|
|
|
+ def += "+x_0=".concat(falseEasting, " ");
|
|
|
+ def += "+y_0=".concat(falseNorthing, " ");
|
|
|
+ return def;
|
|
|
+ }
|
|
|
+ function prjToJson(prjString) {
|
|
|
+ var result = {};
|
|
|
+
|
|
|
+ // 提取 PROJCS 和 GEOGCS 信息
|
|
|
+ var projcsMatch = prjString.match(/PROJCS\["([^"]+)",(.*)\]/);
|
|
|
+ if (projcsMatch) {
|
|
|
+ result.projcsName = projcsMatch[1];
|
|
|
+ var geoPart = projcsMatch[2];
|
|
|
+
|
|
|
+ // 解析 GEOGCS 部分
|
|
|
+ var geoMatch = geoPart.match(/GEOGCS\["([^"]+)",DATUM\["([^"]+)",SPHEROID\["([^"]+)",([0-9.]+),([0-9.]+)\]\],PRIMEM\["([^"]+)",([0-9.]+)\],UNIT\["([^"]+)",([0-9.]+)\]/);
|
|
|
+ if (geoMatch) {
|
|
|
+ result.geogcs = {
|
|
|
+ name: geoMatch[1],
|
|
|
+ datum: geoMatch[2],
|
|
|
+ spheroid: {
|
|
|
+ name: geoMatch[3],
|
|
|
+ semiMajorAxis: parseFloat(geoMatch[4]),
|
|
|
+ inverseFlattening: parseFloat(geoMatch[5])
|
|
|
+ },
|
|
|
+ primeMeridian: {
|
|
|
+ name: geoMatch[6],
|
|
|
+ value: parseFloat(geoMatch[7])
|
|
|
+ },
|
|
|
+ unit: {
|
|
|
+ name: geoMatch[8],
|
|
|
+ conversionFactor: parseFloat(geoMatch[9])
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 PROJECTION 部分
|
|
|
+ var projMatch = geoPart.match(/PROJECTION\["([^"]+)"\]/);
|
|
|
+ if (projMatch) {
|
|
|
+ result.projection = projMatch[1];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 PARAMETER 部分
|
|
|
+ var parameters = {};
|
|
|
+ var paramMatches = geoPart.matchAll(/PARAMETER\["([^"]+)",([-\d.]+)\]/g);
|
|
|
+ for (var match of paramMatches) {
|
|
|
+ parameters[match[1]] = parseFloat(match[2]);
|
|
|
+ }
|
|
|
+ result.parameters = parameters;
|
|
|
+
|
|
|
+ // 解析 UNIT 部分
|
|
|
+ var unitMatch = geoPart.match(/UNIT\["([^"]+)",([-\d.]+)\]/);
|
|
|
+ if (unitMatch) {
|
|
|
+ result.unit = {
|
|
|
+ name: unitMatch[1],
|
|
|
+ conversionFactor: parseFloat(unitMatch[2])
|
|
|
+ };
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果没有 PROJCS,则尝试解析 GEOGCS
|
|
|
+ var _geoMatch = prjString.match(/GEOGCS\["([^"]+)",DATUM\["([^"]+)",SPHEROID\["([^"]+)",([0-9.]+),([0-9.]+)\]\],PRIMEM\["([^"]+)",([0-9.]+)\],UNIT\["([^"]+)",([0-9.]+)\]/);
|
|
|
+ if (_geoMatch) {
|
|
|
+ result.geogcs = {
|
|
|
+ name: _geoMatch[1],
|
|
|
+ datum: _geoMatch[2],
|
|
|
+ spheroid: {
|
|
|
+ name: _geoMatch[3],
|
|
|
+ semiMajorAxis: parseFloat(_geoMatch[4]),
|
|
|
+ inverseFlattening: parseFloat(_geoMatch[5])
|
|
|
+ },
|
|
|
+ primeMeridian: {
|
|
|
+ name: _geoMatch[6],
|
|
|
+ value: parseFloat(_geoMatch[7])
|
|
|
+ },
|
|
|
+ unit: {
|
|
|
+ name: _geoMatch[8],
|
|
|
+ conversionFactor: parseFloat(_geoMatch[9])
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+
|
|
|
+ function parsePrjToProj4(prjString) {
|
|
|
+ // 初始化 Proj4 字符串的部分
|
|
|
+ let proj4Def = ''
|
|
|
+
|
|
|
+ // 提取关键信息
|
|
|
+ const prjParts = prjString.match(/(\w+)\[(.*?)\]/g);
|
|
|
+
|
|
|
+ let projectionType = '';
|
|
|
+ let datum = '';
|
|
|
+ let ellipsoid = '';
|
|
|
+ let centralMeridian = '';
|
|
|
+ let scaleFactor = '1';
|
|
|
+ let falseEasting = '0';
|
|
|
+ let falseNorthing = '0';
|
|
|
+ let latitudeOfOrigin = '0';
|
|
|
+
|
|
|
+ prjParts.forEach(part => {
|
|
|
+ if (part.includes('PROJECTION')) {
|
|
|
+ projectionType = part.match(/"([^"]+)"/)[1].toLowerCase().replace('_', '');
|
|
|
+ //xzw:
|
|
|
+ if(projectionType == 'transversemercator') projectionType = 'tmerc'
|
|
|
+
|
|
|
+ }else if (part.includes('DATUM')) {
|
|
|
+ datum = part.match(/"([^"]+)"/)[1];
|
|
|
+ } else if (part.includes('SPHEROID')) {
|
|
|
+ ellipsoid = part.match(/"([^"]+)"/)[1].toLowerCase();
|
|
|
+ } else if (part.includes('PARAMETER')) {
|
|
|
+ let paramName = part.match(/"([^"]+)"/)[1].toLowerCase().replace(/ /g, '_');
|
|
|
+ let paramValue = part.match(/(-?\d+\.?\d*)/)[1];
|
|
|
+ switch (paramName) {
|
|
|
+ case 'central_meridian':
|
|
|
+ centralMeridian = paramValue;
|
|
|
+ break;
|
|
|
+ case 'scale_factor':
|
|
|
+ scaleFactor = paramValue;
|
|
|
+ break;
|
|
|
+ case 'false_easting':
|
|
|
+ falseEasting = paramValue;
|
|
|
+ break;
|
|
|
+ case 'false_northing':
|
|
|
+ falseNorthing = paramValue;
|
|
|
+ break;
|
|
|
+ case 'latitude_of_origin':
|
|
|
+ latitudeOfOrigin = paramValue;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 构建完整的 Proj4 定义字符串
|
|
|
+ if(!projectionType && prjString.includes('GCS_WGS_1984')) projectionType = 'longlat'
|
|
|
+
|
|
|
+
|
|
|
+ projectionType && (proj4Def += `+proj=${projectionType} `)
|
|
|
+ proj4Def += `+lat_0=${latitudeOfOrigin} `;
|
|
|
+ proj4Def += `+lon_0=${centralMeridian} `;
|
|
|
+ proj4Def += `+k=${scaleFactor} `;
|
|
|
+ proj4Def += `+x_0=${falseEasting} `;
|
|
|
+ proj4Def += `+y_0=${falseNorthing} `;
|
|
|
+ ellipsoid && (proj4Def += `+ellps=${ellipsoid} `);
|
|
|
+ proj4Def += '+units=m +no_defs';
|
|
|
+
|
|
|
+ return proj4Def;
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ function parsePrjToProj4(prjString) {
|
|
|
+ // 初始化 Proj4 参数对象
|
|
|
+ let proj4Params = {};
|
|
|
+
|
|
|
+ // 提取 PROJCS 和 GEOGCS 部分
|
|
|
+ const projcsMatch = prjString.match(/PROJCS\["([^"]+)",(.*)\]/);
|
|
|
+ if (projcsMatch){
|
|
|
+
|
|
|
+ const projcsName = projcsMatch[1];
|
|
|
+ const geoPart = projcsMatch[2];
|
|
|
+
|
|
|
+ // 解析 GEOGCS 部分
|
|
|
+ const datumMatch = geoPart.match(/DATUM\["([^"]+)",SPHEROID\["([^"]+)",([0-9.]+),([0-9.]+)\]\]/);
|
|
|
+ if (datumMatch) {
|
|
|
+ proj4Params.datum = datumMatch[1].toLowerCase();
|
|
|
+ proj4Params.ellps = datumMatch[2].toLowerCase();
|
|
|
+ proj4Params.a = parseFloat(datumMatch[3]); // Semi-major axis
|
|
|
+ proj4Params.rf = parseFloat(datumMatch[4]); // Inverse flattening
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 PROJECTION 部分
|
|
|
+ const projMatch = geoPart.match(/PROJECTION\["([^"]+)"\]/);
|
|
|
+ if (projMatch) {
|
|
|
+ proj4Params.proj = projMatch[1].toLowerCase().replace(/_/g, '');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 PARAMETER 部分
|
|
|
+ const paramMatches = geoPart.matchAll(/PARAMETER\["([^"]+)",([-\d.]+)\]/g);
|
|
|
+ for (const match of paramMatches) {
|
|
|
+ const paramName = match[1].toLowerCase().replace(/ /g, '_');
|
|
|
+ const paramValue = parseFloat(match[2]);
|
|
|
+ switch (paramName) {
|
|
|
+ case 'false_easting':
|
|
|
+ proj4Params.x_0 = paramValue;
|
|
|
+ break;
|
|
|
+ case 'false_northing':
|
|
|
+ proj4Params.y_0 = paramValue;
|
|
|
+ break;
|
|
|
+ case 'central_meridian':
|
|
|
+ proj4Params.lon_0 = paramValue;
|
|
|
+ break;
|
|
|
+ case 'scale_factor':
|
|
|
+ proj4Params.k = paramValue;
|
|
|
+ break;
|
|
|
+ case 'latitude_of_origin':
|
|
|
+ proj4Params.lat_0 = paramValue;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置单位
|
|
|
+ proj4Params.units = "m"; // 默认米
|
|
|
+ proj4Params.no_defs = true;
|
|
|
+
|
|
|
+ // 构建 Proj4 字符串
|
|
|
+ let proj4Def = '+proj=' + proj4Params.proj;
|
|
|
+ proj4Def += ' +lat_0=' + proj4Params.lat_0;
|
|
|
+ proj4Def += ' +lon_0=' + proj4Params.lon_0;
|
|
|
+ proj4Def += ' +k=' + proj4Params.k;
|
|
|
+ proj4Def += ' +x_0=' + proj4Params.x_0;
|
|
|
+ proj4Def += ' +y_0=' + proj4Params.y_0;
|
|
|
+ proj4Def += ' +ellps=' + proj4Params.ellps;
|
|
|
+ proj4Def += ' +units=' + proj4Params.units;
|
|
|
+ proj4Def += ' +no_defs';
|
|
|
+
|
|
|
+ return proj4Def;
|
|
|
+ }
|
|
|
+ */
|
|
|
|
|
|
var defaultColors = {
|
|
|
"landuse": [0.5, 0.5, 0.5],
|
|
@@ -78696,6 +78995,7 @@
|
|
|
this.panDelta.set(0, 0);
|
|
|
}
|
|
|
zoomToLocation(mouse) {
|
|
|
+ var _viewer$modules$Merge;
|
|
|
var I = viewer.inputHandler.intersect;
|
|
|
var object;
|
|
|
if (I) {
|
|
@@ -78711,10 +79011,15 @@
|
|
|
}
|
|
|
var dis = this.currentViewport.view.position.distanceTo(I);
|
|
|
var distance;
|
|
|
- if (object) {
|
|
|
- distance = this.updateRadiusByModel(object, dis);
|
|
|
- } else {
|
|
|
- distance = Math.min(dis, 50); //方便从高空回到地面
|
|
|
+ var object_ = object || ((_viewer$modules$Merge = viewer.modules.MergeEditor) === null || _viewer$modules$Merge === void 0 ? void 0 : _viewer$modules$Merge.selected);
|
|
|
+ if (object_) {
|
|
|
+ distance = this.updateRadiusByModel(object_, dis);
|
|
|
+ }
|
|
|
+ if (!object) {
|
|
|
+ if (!distance || distance < 50) {
|
|
|
+ //方便从高空回到地面
|
|
|
+ distance = Math.min(dis, 50);
|
|
|
+ }
|
|
|
this.updateRadius('focus');
|
|
|
}
|
|
|
viewer.focusOnObject({
|
|
@@ -87214,6 +87519,10 @@
|
|
|
}).catch(onError);
|
|
|
} else {
|
|
|
var response = await fetch(path, info);
|
|
|
+ if (!response.ok) {
|
|
|
+ console.log('loadFile失败', path);
|
|
|
+ return onError && onError();
|
|
|
+ }
|
|
|
var text = await response.text();
|
|
|
var data = params.returnText ? text : JSON.parse(text);
|
|
|
if (data.data) data = data.data;
|