如何完整显示一条线5公里以内的区域
How to display the area fully within 5km of a line
我想围绕一条线绘制一个多边形,显示 完全在该线 5 公里范围内的区域。
有点像缓冲区,显示距离一条线 5 公里的区域,我想显示一个始终在 [=25] 范围内的区域=] 整条线5km - 因此面积将小于缓冲区。
现实生活中的情况是,我们现在有旅行限制,这在一定程度上意味着您必须留在离家 5 公里以内的地方。所以我想在远足径周围画一个区域——如果这个人的房子在这个区域内,那么他们就可以走完全程。部分问题是我什至不知道这种区域叫什么。
目前像这样使用 Leaflet 和 turf -- 但这只是一个屏蔽缓冲区。
var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]);
var polygon = turf.mask(turf.buffer(geojsonLines[0], 5, {
units: 'kilometers'
}),mask);
L.geoJSON(polygon, {
style: function(feature) {
return {
color: "red"
};
}
}).addTo(journey_map);
(不是我将如何处理距离 BBOX 超过 5 公里的轨道——但会处理)。
Image of buffer area similar to what I want to make
你想要形状中每个点5公里范围内的区域,而不是任何5公里范围内的缓冲区,我说得对吗] 点成一个形状?
如果是这样,我不知道现有的操作来计算它或它是如何调用的,但它似乎很容易计算。
如果你看一条线段[A,B]和这条线段上任意一点C到某个远点D的距离,很容易看出CD
小于等于max(AD, BD)
。因此,如果 D 与角 A 和 B 的距离在 5 公里以内,则它与 AB 上所有点的距离都在 5 公里以内。三角形相同 - 三角形中所有点的 5 公里范围内的点应该在三角形每个角的 5 公里范围内。
这导致了简单的(尽管可能不是很有效)算法:获取描述路径的线串或描述公园的多边形中的所有顶点,将每个顶点分别缓冲 5 公里,然后与所有生成的圆相交(https://turfjs.org/docs/#intersect).相交的结果在每个顶点的5km以内,因此与trail中所有点的5km以内。
您所做的一个简单优化是首先计算形状的凸包 - 这将简化典型的轨迹,减少顶点数量以及需要相交的圆圈数量。
谢谢迈克尔
知道了 :)
我最终对每个点(而不是线段)的缓冲区进行了相交,因为我的线上有很多点可以工作——但线段会更完整。好的。这是我使用传单和草皮的代码。
var travel_radius = 5;
var simplify_options = {tolerance: 0.01, highQuality: false};
var exploded = turf.explode(turf.simplify(geojsonLines[0],simplify_options));
var intersection = turf.intersect(turf.buffer(exploded['features'][0]['geometry'], travel_radius, {units: 'kilometers'}), turf.buffer(exploded['features'][1]['geometry'], travel_radius, {units: 'kilometers'}));
var i = 2;
while (i < exploded['features'].length ) {
if(intersection == null){break;} // for walks that are bigger than the travel radius -- result will get to null
intersection = turf.intersect(intersection, turf.buffer(exploded['features'][i]['geometry'], travel_radius, {units: 'kilometers'}));
i++;
}
if(intersection == null){ // just draw a small circle at the start so the rest of the map is red.
intersection = turf.buffer(exploded['features'][0]['geometry'], 5, {units: 'meters'});
}
// subtract travel area from the mask
var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]);
var polygon = turf.mask(intersection,mask);
L.geoJSON(polygon, {
style: function(feature) {
return {
color: "red"
};
}
}).addTo(journey_map);
});
我想围绕一条线绘制一个多边形,显示 完全在该线 5 公里范围内的区域。
有点像缓冲区,显示距离一条线 5 公里的区域,我想显示一个始终在 [=25] 范围内的区域=] 整条线5km - 因此面积将小于缓冲区。
现实生活中的情况是,我们现在有旅行限制,这在一定程度上意味着您必须留在离家 5 公里以内的地方。所以我想在远足径周围画一个区域——如果这个人的房子在这个区域内,那么他们就可以走完全程。部分问题是我什至不知道这种区域叫什么。
目前像这样使用 Leaflet 和 turf -- 但这只是一个屏蔽缓冲区。
var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]);
var polygon = turf.mask(turf.buffer(geojsonLines[0], 5, {
units: 'kilometers'
}),mask);
L.geoJSON(polygon, {
style: function(feature) {
return {
color: "red"
};
}
}).addTo(journey_map);
(不是我将如何处理距离 BBOX 超过 5 公里的轨道——但会处理)。 Image of buffer area similar to what I want to make
你想要形状中每个点5公里范围内的区域,而不是任何5公里范围内的缓冲区,我说得对吗] 点成一个形状?
如果是这样,我不知道现有的操作来计算它或它是如何调用的,但它似乎很容易计算。
如果你看一条线段[A,B]和这条线段上任意一点C到某个远点D的距离,很容易看出CD
小于等于max(AD, BD)
。因此,如果 D 与角 A 和 B 的距离在 5 公里以内,则它与 AB 上所有点的距离都在 5 公里以内。三角形相同 - 三角形中所有点的 5 公里范围内的点应该在三角形每个角的 5 公里范围内。
这导致了简单的(尽管可能不是很有效)算法:获取描述路径的线串或描述公园的多边形中的所有顶点,将每个顶点分别缓冲 5 公里,然后与所有生成的圆相交(https://turfjs.org/docs/#intersect).相交的结果在每个顶点的5km以内,因此与trail中所有点的5km以内。
您所做的一个简单优化是首先计算形状的凸包 - 这将简化典型的轨迹,减少顶点数量以及需要相交的圆圈数量。
谢谢迈克尔 知道了 :) 我最终对每个点(而不是线段)的缓冲区进行了相交,因为我的线上有很多点可以工作——但线段会更完整。好的。这是我使用传单和草皮的代码。
var travel_radius = 5;
var simplify_options = {tolerance: 0.01, highQuality: false};
var exploded = turf.explode(turf.simplify(geojsonLines[0],simplify_options));
var intersection = turf.intersect(turf.buffer(exploded['features'][0]['geometry'], travel_radius, {units: 'kilometers'}), turf.buffer(exploded['features'][1]['geometry'], travel_radius, {units: 'kilometers'}));
var i = 2;
while (i < exploded['features'].length ) {
if(intersection == null){break;} // for walks that are bigger than the travel radius -- result will get to null
intersection = turf.intersect(intersection, turf.buffer(exploded['features'][i]['geometry'], travel_radius, {units: 'kilometers'}));
i++;
}
if(intersection == null){ // just draw a small circle at the start so the rest of the map is red.
intersection = turf.buffer(exploded['features'][0]['geometry'], 5, {units: 'meters'});
}
// subtract travel area from the mask
var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]);
var polygon = turf.mask(intersection,mask);
L.geoJSON(polygon, {
style: function(feature) {
return {
color: "red"
};
}
}).addTo(journey_map);
});