GPS坐标和百度地图坐标因为坐标系的不同,GPS的经纬度坐标在百度地图中直接定位是不正确的,必须要要转换为百度地图经纬度,才能正确显示。最近有个百度地图定位项目,要将已经取得的大量GPS经纬度在百度地图上定位,还要显示一个动画,并添加一个文字标签。由于数据量比较大,使用循环实现会“卡死”屏幕,效果不佳,故尝试用递归解决,经过几天的努力终于实现了,现将活字格JS源码附上共享。
// 获取map对象,下例Map为页面上百度地图插件单元格名称,
var cell = Forguncy.ForguncyData.pageInfo.pageElementManager.cells.getCellByName("Map");
var map = cell.cellType.map;
map.clearOverlays();//清除百度地图上原来所有覆盖物
// 创建转换器对象convertor
var convertor = new BMap.Convertor();
//通过TEXTJOIN()函数将表格中某列所有数据用“;”号拼接在一起到CoordinateCell2单元格。拼接完格式为: 经度,纬度@标签;经度,纬度@标签;......
// 从CoordinateCell2单元格获取GPS坐标及标签字符串,并按";"分割为坐标对数组。
var coordWithTagString = Forguncy.Page.getCell("CoordinateCell2").getValue() || "";
var coordWithTagPairs = coordWithTagString.split(';');
// 转换函数每次处理的最大点数为10,10为百度地图API里convertor.translate()规定最大转换数
var batchSize = 10;
var respoints = [];
var labels = [];
// 收集所有的GPS点和标签
// GPS经纬度装入respoints数组
// GPS经纬度对应的标签装入labels数组
coordWithTagPairs.forEach(function(pairWithTag) {
if (pairWithTag) {
var parts = pairWithTag.split('@');
if (parts.length === 2) {
var [longitude, latitude] = parts[0].split(',').map(parseFloat);
var labelContent = parts[1];
respoints.push(new BMap.Point(longitude, latitude));
labels.push(labelContent);
}
}
});
// 分批次进行坐标转换
// startIndex: 开始位置
// endIndex: 结束位置
function processBatch(startIndex) {
var endIndex = Math.min(startIndex + batchSize, respoints.length);
var batch = respoints.slice(startIndex, endIndex);
// 截取respoints里大小为10的子数组
convertor.translate(batch, 1, 5, function(data) {
if (data.status === 0) {
// 遍历每10个转换完成的点数组data.points[]
data.points.forEach(function(point, index) {
var marker = new BMap.Marker(point);
//var opts = {position: point, offset: new BMap.Size(20,-10)};
var opts = {offset: new BMap.Size(20,-10)};
var label = new BMap.Label(labels[startIndex + index], opts);
// 为marker绑定label并绘制marker
marker.setLabel(label);
map.addOverlay(marker);
//map.addOverlay(label);
marker.setAnimation(BMAP_ANIMATION_BOUNCE); // marker跳动动画
});
}
else {
console.warn("坐标转换失败,状态码:", data.status);
}
// 如果还有未处理的批次,继续处理下一批10个
if (endIndex < respoints.length) { // if (上次结束的地方小于需要转换的GPS点的总大小)
processBatch(endIndex); // 那就从这次结束的地方开始转换下一组10个点, 递归
}
else {
// 所有批次处理完毕后,设置地图中心
if (respoints.length > 0) {
// 经度平均值avgLng,纬度平均值avgLat
var avgLng = respoints.reduce((sum, p) => sum + p.lng, 0) / respoints.length;
var avgLat = respoints.reduce((sum, p) => sum + p.lat, 0) / respoints.length;
map.centerAndZoom(new BMap.Point(avgLng, avgLat), 10);
}
}
});
}
// 开始处理第一个批次
processBatch(0);
|
|