如何完整显示一条线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);
            });