【问题标题】:Hide leaflet features out of specified area在指定区域之外隐藏传单特征
【发布时间】:2020-09-09 12:34:53
【问题描述】:

我正在尝试在指定区域之外隐藏一些传单功能。

我有一张传单地图,将河流显示为 RiverLayer 上的要素,而 circleLayer 用于在地图当前中心周围绘制区域。

每条河流在我的数据库中被分成多个部分,我只检索与当前圆圈区域相交的部分。

结果如下所示:

河流显示在该区域之外,因为我选择了与它相交的部分。 我可以在我的数据库中选择该区域内的所有部分,但我会丢失不完全位于该区域内的部分。

计算每个相关部分的交点以调整坐标是一种解决方案,但很复杂。

事实上,我更愿意在客户端简单地隐藏这些溢出,但我找不到解决方案。

传单是否有可能做这样的事情?

感谢您的宝贵时间

【问题讨论】:

  • 我肯定会先查看 turf 以在显示数据之前对其进行裁剪turfjs.org
  • 是的,我看到了草皮,这可能是一个解决方案。但似乎我需要自己做很多计算(对于河流部分,我需要过滤每个geojson点以验证距离,删除区域外的点,计算我的圆圈和我的河流部分之间的交点, 并将此交点添加到河流部分的起点或终点,具体取决于与每个的距离...)。或者可能在 Turf 中有一个现有的功能,但我没有找到它。
  • 确实,使用带有剪辑功能 turfjs.org/docs/#bboxClip 的正方形或矩形会很容易。与点和多边形 pointsWithin 正在做这项工作turfjs.org/docs/#pointsWithinPolygon
  • 请分享一个在线演示 f.e.在 jsfiddle.net 上

标签: javascript leaflet


【解决方案1】:

这是一个使用 booleanWithin 和 lineSplit 函数使用 turfJS 的示例。

我在一个简单的基本 HTML 和 Vanilla JS 上做了示例。我在“河”上添加了另一个线串来模拟圈外河


var mymap = L.map('mapid').setView([43.63458105967136, 1.1613321304321291], 13);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 20,
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
}).addTo(mymap);

var center = [43.63458105967136, 1.1613321304321291];
var radius = 1500;

// L.circle(center, radius, {
//     color: '#ff4081', fillColor: '#ff4081', fillOpacity: 0.5
// }).addTo(mymap);

var riverGeoJSON = [
    { "type": "Feature", "geometry": { "coordinates": [[1.159444487444759, 43.633815447205706], [1.160243520516838, 43.634633600388156], [1.160731009187281, 43.6350432633719], [1.161774921971743, 43.63541373375439], [1.162079879908259, 43.63564209781788], [1.162320030539753, 43.635959368371424], [1.162373764624914, 43.636409391647234], [1.161800286153361, 43.637212422659154], [1.160910734693605, 43.63832601539633], [1.160651867030764, 43.63886255455486], [1.160332394101095, 43.639317964879666], [1.159189872203288, 43.640743176542664], [1.158053840843969, 43.641810274789506], [1.156922548158863, 43.642651534145514], [1.155851918485514, 43.64349381183714], [1.155156982509935, 43.644214650781954], [1.15326441791592, 43.64594659208024], [1.152374775964331, 43.6470151231795], [1.151428904349222, 43.64790448439313], [1.151107886218696, 43.64840394819371]], "type": "LineString" } },
    { "type": "Feature", "geometry": { "coordinates": [[1.156570800342349, 43.632121495293006], [1.158291185472127, 43.63272397754135], [1.158901458643683, 43.633090727638866], [1.159444487444759, 43.633815447205706]], "type": "LineString" } },
    { "type": "Feature", "geometry": { "coordinates": [[1.168152938761366, 43.62917262321181], [1.167467920251437, 43.62939958202886], [1.166101976396903, 43.62960874939632], [1.164673843635074, 43.629863651007135], [1.163738326615552, 43.63021236020524], [1.163236303364402, 43.630566588076604], [1.162728104605807, 43.63119071739829], [1.161282685092185, 43.632253508072225], [1.160336935333006, 43.633151033736986], [1.159444487444759, 43.633815447205706]], "type": "LineString" } },
    {
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    1.0526275634765625,
                    43.550289946081115
                ],
                [
                    1.07940673828125,
                    43.63334186269
                ],
                [
                    1.0764884948730469,
                    43.6336524704596
                ]
            ]
        }
    }
];
// L.geoJSON(riverGeoJSON, {}).addTo(mymap);

var centerGeoJSON = [center[1], center[0]];
var radiusGeoJSON = radius / 1000;
var options = { steps: 50, units: 'kilometers' };
var circleGeoJSON = turf.circle(centerGeoJSON, radiusGeoJSON, options);

L.geoJSON(circleGeoJSON, {}).addTo(mymap);

var riverClipped = {}

for (let index = 0; index < riverGeoJSON.length; index++) {
    const feature = riverGeoJSON[index];
    var within = turf.booleanWithin(feature, circleGeoJSON);
    console.log({ within });
    var split = turf.lineSplit(feature, circleGeoJSON);
    console.log({ split });
    if (within && split.features.length === 0) {
        L.geoJSON(feature, {}).addTo(mymap);
    } else {
        L.geoJSON(split.features[0], {}).addTo(mymap);
    }


}


Circle 使用 turfJS 计算以具有有效的 GeoJSON 功能。然后将此功能用作拆分器。

当线完全在圆内时,within 函数返回true,分割函数不返回分割特征。

当线完全在圆外时,within 函数为false,并且分割函数不返回分割特征。

当直线与圆相交时,within 函数返回false,分割特征集合中的第一个特征就是圆内的那个。

JSFiddle 上的完整源代码:https://jsfiddle.net/tsamaya/6sc58m7u/

【讨论】:

  • 非常感谢您的回答。只是一种精度,当您说“拆分特征集合中的第一个特征是圆圈内的那个”时,它并不完全正确。它取决于线串的坐标和圆的坐标。在某些情况下,返回的第一个特征是圆外的特征。我只是使用 booleanPointInPolygon (turfjs.org/docs/#booleanPointInPolygon) 方法来确定第一个特征是否是第一个特征,如果不是,则采用第二个特征并且现在一切都很好。
猜你喜欢
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多