背景:
公司有相关需求,需要从一堆包括坐标的企业数据里筛选出坐标在指定区域内的企业。
思路:
有企业的坐标,只要知道指定区域的边缘坐标集,就可以用高德地图的数学计算库函数来判断企业是否在指定区域内。
AMap.GeometryUtil.isPointInRing()
我不想用前端页面加载高德地图来实现,就用Nodejs写个脚本实现,后续还可以做成服务,直接连数据库来执行查询操作。
实现:
先初始化一个工程:
npm init
高德地图jsApi需要在浏览器的运行环境下运行,在nodejs里,就需要用到 jsdom 来模拟浏览器环境,安装jsdom:
npm install jsdom
需要注意jsdom和Nodejs的版本兼容性问题,我这儿nodejs版本为v12,jsdom只能用v16.7.0。
注册高德账号,新增jsapi的key,具体操作请自行百度。
完成上面操作以后,就可以写nodejs的代码了,直接贴代码:
const jsdom = require("jsdom");
const fs = require("fs");
const { JSDOM } = jsdom;
// 指定区域边缘坐标
const AREA = [
[lng, lat],
...
];
//企业坐标文件.json数据示例
// {
// list: [
// {
// "lon": lon,
// "lat": lat,
// "credit_code": code
// }
// ...
// ]
// }
// 读取企业坐标文件,获取企业坐标数组
fs.readFile(
"./json/企业坐标文件.json",
"utf-8",
(err, data) => {
if (err) {
console.log(err);
return;
}
// 在jsdom中加载AMap对企业坐标进行筛查,选出坐标在指定范围内的企业
const dom = new JSDOM(
`<!DOCTYPE html><html>
<body>
<script type="text/javascript">
//模拟浏览器环境下没有这个函数,会报错,这里声明一个空的
window.URL.createObjectURL = function () {
return "";
};
window._AMapSecurityConfig = {
securityJsCode:'应用对应的安全密钥',
}
</script>
<script src='https://webapi.amap.com/maps?v=2.0&key=你注册地图应用的key' type="text/javascript" > </script>
<script type="text/javascript">
let pointList = ${JSON.stringify(JSON.parse(data).list)};
let area = ${JSON.stringify(AREA)};
window.IN_AREA_POINTS = [];
for (let index = 0; index < pointList.length; index++) {
const point = [pointList[index].lon, pointList[index].lat];
if(AMap.GeometryUtil.isPointInRing(point, area)){
window.IN_AREA_POINTS.push(pointList[index].credit_code)
}
}
// 将点位数据传到nodejs环境
window.onModulesLoaded(window.IN_AREA_POINTS);
</script>
</body></html>`,
{ runScripts: "dangerously", resources: "usable" }
);
const window = dom.window;
//监听onModulesLoaded,获取过滤后的企业列表
window.onModulesLoaded = (e) => {
const jsonData = JSON.stringify(e);
//将企业数据写入文件
fs.writeFile('./json/data.json', jsonData, (err) => {
if (err) {
console.error(err);
return;
}
console.log('数据写入完毕 data.json');
});
};
}
);
简单来说,就是在Nodejs中模拟了一个浏览器环境,并且模拟了一个html页面,在html页面中加载了高德地图的js,js加载完成后再执行企业坐标过滤,最后通过监听onModulesLoaded函数将过滤后的企业传回nodejs环境中,用于下一步的操作。