前言
最近项目上需要做水路演变动画,我说用轨迹播放不就完事了。产品经理却说,我要的面不是线!!!我心想线段宽点不就是面了吗(无语.jpg)。
在我不懈的努力(能摸鱼就摸鱼.jpg)下,最终将需求变为下层是现存水路,上层添加线段并采取纹理发光的方式来表现动画。
实现思路
- 使用truf.js的
truf.bbox方法获取多边形边界。 - 根据需求如需生成上下方向的中心线,则取上边界坐标,组成分割线。
- 使用truf.js的
truf.polygonToLine方法将面转化为线。 - 使用truf.js的
turf.lineIntersect方法获取线段交点。 - 使用truf.js的
turf.midpoint方法获取两点间的中点。 - 将中点连成线。
具体实现
1、获取多边形坐标边界,并确认分割方向
// 将坐标转换为
const polygon = turf.polygon([
[-5, 52],
[-4, 56],
[-2, 51],
[-7, 54],
[-5, 52]
]);
// 获取边界
const bbox = turf.bbox(polyons);
// 从上到下分割
const startLine = [
[bbox[0], bbox[3]],
[bbox[2], bbox[3]],
];
- 确认分割颗粒度
// 切割线段纬度差值
const Diff = bbox[3] - bbox[1];
// 将维度差值分为100份
const rang = Diff / 100;
- 进行循环切分,并生成中线
// centerLine 放置生成好的中点 i 记录循环次数
let centerLine = [],i = 0;
do {
const LINE = turf.lineString([
[bbox[0], bbox[3] - rang * i],
[bbox[2], bbox[3] - rang * i],
], { name: "line" })
i++;
// 将面转化为线段并获取两线段交点
const splitted = turf.lineIntersect(
LINE.toGeoJSON(),
turf.polygonToLine(polygon)
);
// 仅获取不多于3三个交点的数据
if (splitted.features.length > 0 && splitted.features.length <= 2) {
if (splitted.features.length % 2 !== 0) {
centerLine.push(splitted.features[0].geometry.coordinates);
} else {
// 获取交点
const intersect = splitted.features;
// 计算交点的中点
const midpoints = turf.midpoint(
intersect[0].geometry.coordinates,
intersect[1].geometry.coordinates
);
centerLine.push(midpoints.geometry.coordinates);
}
// 将中点转换为线串
// const midline = turf.lineString(midpoints.coordinates);
// maptalks.GeoJSON.toGeometry(midline).addTo(layerLine);
} else if (splitted.features.length > 0 && splitted.features.length > 2 ) {
// 两个以上交点处理
}else if (i > 1 && splitted.features.length == 0) {
// 无交点处理
}
} while (bbox[3] - rang * i >= bbox[1]);
// 生成中心线
const cLINE = turf.lineString(centerLine, { name: "centerline" })
存在问题
目前还未解决关于两个以上的交点处理方法,仅仅有一个大致思路:
- 每两个相邻交点组成一段线。
- 获取上一次生成中点与线段之间的夹角与中心线角度进行对比,获取合适的线段计算中点。
- 怎么判断“合适”。
最后
jym如有其他的思路或者更好的解决方法,欢迎留言探讨。
欢迎留言加关注。
祝jym: 彩票发发发; 钓鱼中中中; 头发长长长;