由于最近在写一个数据可视化页面,由于地图不规则,有的省份是比较长,有的省份比较宽,就会导致将地图放到页面上去时显得div盒子左右比较空旷,显得不好看所以就要将地图进行旋转在显示,如下图是旋转之前的效果:
下面是放到项目中没有做旋转处理的效果
1.下载需要转换的全国各地省市的地图JSON数据:阿里云 DataV - 数据可视化平台
2.将转换后的地图JSON数据复制到geojson.io编辑器( geoJson编辑器)中查看旋转处理后的地图样子,处理后的地图JSON数据显示效果如下图:
这是做了旋转之后的效果,没有放到项目中
实现思路:
网上的geoJson数据其实就是一个字段标准化的json数据,地图轮廓就是一个个经纬度坐标点绘出来的,既然是数据,那就可以获取地图的中心点(就是所有数据的中心点,这个我是通过百度地图瓦片下载器软件来快速定位的,也可以经纬度查询,这个就只能手动定位,不够精准,但是快速。还有通过一些gis服务api来获取中心点,不过这个更麻烦,难度更高),获取到中心点后,通过公式可以让所有轮廓坐标绕中心点进行旋转一定角度获得新的坐标点,这就是你要的geoJson数据了。
项目需求:
我的项目需要使用echart展示地图,但是网上能找到的地图数据是按照实际地理坐标。然后省市这些数据难免会长宽不等,角度刁钻,而echart只会根据geoJson数据生成地图,不能对数据进行旋转操作,所以只能从源数据想办法,搜索了一番,没发现有在线旋转geoJson数据的工具,也没发现有谁有这需求,只能自力更生。先下载好相关数据,搜索相关旋转公式,将数据转换为新数据,查看数据最终模样,重复调整旋转角度到合适位置。
一个点相对另一个点的旋转公式
我的转换json坐标的全部源码,旋转角度不能太大,可能有大约5到6倍左右的放大,就是说你计划是旋转16度17度左右,那么旋转角度就是15/5=0.3,这个数字不准确,只是根据我项目得出的一个猜测结果,实际情况请自己测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <script src="./js/jquery-3.4.1.min.js"></script> -->
<!-- <script src="./js/echarts.min.js"></script> -->
</head>
<body>
<button onclick="MapJsonSave()">保存</button>
<script>
window.onload = function(){
MapRotate()
}
// 地图旋转处理函数
function MapRotate(){
/*let jwd = [113.49931,22.89819];//要旋转地图的中心点坐标(经纬度)
sub[0]是geoJson数据的经度,sub[1]是纬度,deg是旋转角度,负数是顺时针旋转,正数是逆时针旋转
经度: (sub[0] - jwd[0])*Math.cos(deg) - (sub[1] - jwd[1])*Math.sin(deg) + jwd[0]
纬度: (sub[0] - jwd[0])*Math.sin(deg) + (sub[1] - jwd[1])*Math.cos(deg) + jwd[1]*/
var finaljson;
const jwd = [113.49931,22.89819];//要旋转地图的中心点坐标(经纬度)
const deg = 45;//设置地图旋转角度
var url = "./jiangsu.json"/*json文件url,本地的就写本地的位置,如果是服务器的就写服务器的路径*/
var request = new XMLHttpRequest();
request.open("get", url);/*设置请求方法与路径*/
request.send(null);/*不发送数据到服务器*/
request.onload = function () {/*XHR对象获取到返回信息后执行*/
if (request.status == 200) {/*返回状态为200,即为数据获取成功*/
let res = request.responseText;
let json = JSON.parse(res);
console.log("AAA",json,json.features)
// 处理要旋转的地图JSON数据
let features = json.features.map((item,i)=>{
let Coordinates = item.geometry.coordinates.map((son,i)=>{
return son[0].map((sub,ii)=>{
return [
(sub[0] - jwd[0])*Math.cos(deg) - (sub[1] - jwd[1])*Math.sin(deg) + jwd[0],
(sub[0] - jwd[0])*Math.sin(deg) + (sub[1] - jwd[1])*Math.cos(deg) + jwd[1]
]
})
})
return (
{
type: "Feature",
properties:item.properties,
geometry:{
coordinates:[Coordinates],
type: "MultiPolygon"
}
}
);
})
// 旋转后的地图JSON数据
finalgeoJson = {
type: "FeatureCollection",
features:features
}
MapJsonDownload()
}
}
}
// 下载转换文件方法一:
function MapJsonSave(){
var content = JSON.stringify(finalgeoJson);
var eleLink = document.createElement('a');
eleLink.download = "province.json";
eleLink.style.display = 'none';
// 字符内容转变成blob地址
console.log(finaljson)
var blob = new Blob([content]);
eleLink.href = URL.createObjectURL(blob);
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
}
// 下载转换文件方法二:
function MapJsonDownload(){
console.log("下载---")
data = JSON.stringify(finalgeoJson);
//解决中文乱码
let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(data);
console.log("URI",uri)
//通过创建a标签实现
let link = document.createElement('a');
// link.a = uri;
link.href = uri;
// 对下载的文件命名
let date = `abc`
link.download = `${date}.json`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
</script>
</body>
</html>
上面的源码保存为html后点击页面保存会把新的json保存为json文件,打开文件复制转换后的数据到geoJson编辑器查看转换效果。
还有一点高德地图的json数据和百度的json数据在propertity这个属性对象的字段有所不同,echart默认使用propertity的cp属性名的经纬度作为legend的标记位置,高德则是center,没有cp字段,貌似echart是在没有cp字段的情况下是它自动计算了中心点位置,所有有可能出现一个这样的意外情况,一个地市计算出来的中心点位置过于偏向另一个地市的边缘,甚至坐标点就位于另一个地市的范围内,这样就会导致本来是显示A市的数据变成了显示B市的数据,但鼠标移动到对应地市显示的数据是正常的。这就需要同时去旋转propertity里面的center字段,并且把名称center改为cp
原文链接:https://blog.youkuaiyun.com/chensong8331/article/details/103486312