文章目录
概要
项目架构:前端Vue3、ts
后端:springboot+mongoDB
需要将GDB文件的CGCS2000坐标转为GCJ02,然后在前端的高德地图api上进行显示
包括MultiLineString、MultiPolygon、Point等类型的转换
教程包括批量geojson文件转为gcj02,并上传到后端的示例
需要用到前端的 coordtransform
注意事项:因为CGCS2000坐标大部分精度非常大,所以如果以Number类型导入或输入,简单的前端处理会遇到问题 ,需要使用 json-bigint库配和处理
GDB文件导出
首先使用QGIS软件打开.GDB文件,然后导出图层
这里选择WGS84
导出后得到geojson文件
tip:geometryType定义
导出的坐标有多种类型
Point:一维数组[]
MultiLineString:三维数组[[[]]]
MultiPolygon:四维数组[]
转换步骤
- 前端安装 coordtransform、 json-bigint
npm install coordtransform
npm install json-bigint
(看情况安装) - 时刻注意数据精度细节问题
注:我的geojson文件结构为:
{
"features": [
{ "type": "Feature", "properties": { "XXX": 1, ...},
"geometry": { "type": "Point", "coordinates": [ 123456.132465789012345, 123456.132465789012345 ] } },
{....}
]
}
1. Point类型转换代码:
const convertedFeaturesAll: Ref<any[]> = ref([]);
const convertedFeatures = geojsonData.features.map((feature: any) => {
const { coordinates } = feature.geometry;
const [lon, lat] = coordinates;
const [gcjLon, gcjLat] = coordtransform.wgs84togcj02(lon, lat);
return {
coordinates: [gcjLon, gcjLat],
};
});
2. MultiLineString类型转换代码:
const convertedFeatures = geojsonData.features.map((feature: any) => {
// 获取当前feature的MultiLineString坐标数组
const multiLineCoordinates = feature.geometry.coordinates;
// 遍历每个LineString
const convertedCoordinates = multiLineCoordinates.map((line: any) => {
// 遍历LineString中的每个坐标点,并转换坐标
return line.map((coordinate: any) => {
const [lon, lat] = coordinate;
// 使用coordtransform将WGS84坐标转换为GCJ02坐标
return coordtransform.wgs84togcj02(lon, lat);
});
});
// 返回新的feature对象,包括转换后的坐标和其他属性
return {
// 使用转换后的坐标
coordinates: convertedCoordinates
};
});
MultiPolygon请自行实现
3. 通过批量上传文件、批量转换的方式代码(需要根据geojson文件结构修改代码):
<el-upload
style="margin-left: 10px"
:file-list="uploadFileList"
action=""
multiple
accept=".txt , .csv , .geojson , .json"
:auto-upload="false"
:on-change="handleChange"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="uploadSuccess"
>
<el-tooltip
class="box-item"
effect="dark"
content="需要从QGIS或类似软件导出图层,CRS选择WGS84"
placement="top"
>
<el-button type="primary">坐标文件上传</el-button>
</el-tooltip>
const uploadFileList = ref<any[]>([])
// 用于存储转换后的所有 features 的大数组
const convertedFeaturesAll: Ref<any[]> = ref([]);
const handleChange = (file: File, fileList: File[]) => {
uploadFileList.value.push(file)
};
const handleRemove = (file: File, fileList: Files[]) => {
uploadFileList.value = fileList.filter((item) => item.uid !== file.uid);
}
const handleSubmit = async () => {
if (uploadFileList.value.length === 0) {
ElMessage.warning('请先上传文件')
return
}
// 将每个文件读取操作封装成一个 Promise,存放到数组中
const promises = uploadFileList.value.map((file: any) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
const content = e.target?.result;
if (content) {
const geojsonData = JSONbig.parse(content as string); //这里要用JSONbig处理
//!!!!!!!!!!!!!!!!!! 注意 这里以 MultiString为例 !!!!!!!!!!!!!!!!!!!
const convertedFeatures = geojsonData.features.map((feature: any) => {
// 获取当前feature的MultiLineString坐标数组
const multiLineCoordinates = feature.geometry.coordinates;
// 遍历每个LineString
const convertedCoordinates = multiLineCoordinates.map((line: any) => {
// 遍历LineString中的每个坐标点,并转换坐标
return line.map((coordinate: any) => {
const [lon, lat] = coordinate;
// 使用coordtransform将WGS84坐标转换为GCJ02坐标
return coordtransform.wgs84togcj02(lon, lat);
});
});
// 返回新的feature对象,包括转换后的坐标和其他属性
return {
xx:xx,
// 使用转换后的坐标
coordinates: convertedCoordinates
};
});
resolve(convertedFeatures);
} else {
reject(new Error('File read error'));
}
};
reader.onerror = () => reject(new Error('File read error'));
reader.readAsText(file.raw);
});
});
// 等待所有文件处理完成
try {
const results = await Promise.all(promises);
// Flatten the results and update the convertedFeaturesAll array
convertedFeaturesAll.value = results.flat();
const res = await updateCoords({lists: convertedFeaturesAll.value});
ElMessage.success('更新成功');
uploadFileList.value = [];
getTableData()
} catch (err) {
console.error(err);
ElMessage.error('更新失败');
}
};