等时圈是指从某点出发,以某种交通方式在特定时间内能到达的距离覆盖的范围。前段时间看到一个站点,该站点能够计算自驾、骑行、步行三种方式的等时圈。效果如下图
mapbox出品的图还是相当漂亮的,但毕竟是别人的东西,能自己做出来当然是好的(这个功能还是学生的时候就想做)。那就试试呗。
当然先看看mapbox是怎么做的,查看站点使用什么接口,如下图发生数据请求,接口连接:
对所有接口坐标进行分析,发现所有坐标的分布如下图:
从这些点就能猜出mapbox实现思路
参照这个思路,借助mapbox的接口完全能够自己实现等时圈功能。
- 生成网格,使用turf实现,上代码:
var centerPoint = turf.point([116.46, 39.92]);
//生成缓冲区
var buffered = turf.buffer(centerPoint, 12, {units: 'kilometers'});
//根据缓冲区生成bbox
var bbox = turf.bbox(buffered);
var cellSide = 1;
var options = {units: 'kilometers'};
//生成网格
var grid = turf.pointGrid(bbox, cellSide, options);
- 利用mapbox接口计算网格各点时间属性。
/**
*
* @param startPoint
* @param endPoints
* @param travelType walking driving,cycling
*/
function makeRequest(startPoint,endPoints,travelType){
var url= "https://api.mapbox.com/directions-matrix/v1/mapbox/"+travelType+"/"+startPoint.geometry.coordinates[0].toFixed(4)+","+startPoint.geometry.coordinates[1].toFixed(4)+";"
if(endPoints.length>0){
for(var i=0;i
- 生成等值线
turf有生成等值线的功能
var collections = turf.featureCollection(features);
var breaks = [0, 600,700,800,900, 1200,1500, 1800,2100, 2400,2700, 3000, 3600, 4200, 4800,5400, 6000];
var lines = turf.isolines(collections, breaks, {zProperty: 'duration'});
看效果,虽然能实现,但是和mapbox效果感觉差了点什么,查看mapbox例子的代码,发现它使用该组件link进行等时线生成。
//它是这么使用的,但是实在看不懂这些参数是个啥意思
var data = [[0, 1, 0], [1, 2, 1], [0, 1, 0]];
var c = new Conrec;
c.contour(data, 0, 2, 0, 2, [1, 2, 3], [1, 2, 3], 3, [0, 1, 2]);
但是貌似这个组件效果是蛮好的。
function getNearestPoint(x,y,pts){
var ptsjson = turf.featureCollection(pts);
var targetPoint = turf.point([x, y]);
var nearest = turf.nearestPoint(targetPoint, ptsjson);
return nearest;
}
//这里为啥要这么写,琢磨了好久,就不解释了
xs=[];
ys=[];
for(var i=0;i
- 将等时线连成等时面
function polygonize(contourList){
var shapes = []
var results=[];
polygons = [];
for(var cIndex=0;cIndex
- 等时圈生成,并可视化
使用turf进行处理,将大圈内的小圈叠加掉。
function polygonize(contourList){
var shapes = []
var results=[];
polygons = [];
for(var cIndex=0;cIndex
没有正儿八经的进行可视化,但也能看到和mapbox的效果相差不多。但是这个方案存在一个问题,就是mapbox的接口由于网络问题太不稳定。为了保证稳定性需要自己开发该接口,当然可以使用高德的接口 link