【问题标题】:Leaflet - access specific polyline feature (GeoJSON)?Leaflet - 访问特定的折线功能(GeoJSON)?
【发布时间】:2017-06-27 11:34:20
【问题描述】:

情况:我的 Web 应用程序显示了一个包含不同兴趣路径(我所谓的 POI)的地图和一个包含每个 POI 信息的侧边栏。选择侧边栏的一个面板,应该在地图上选择/突出显示相关的 POI。

使用的数据和平台:我使用 Leaflet 和 JavaScript,没有 jQuery。数据作为 GeoJSON 添加到 Leaflet 中。轨迹表示为折线,但我称它们为 POI(只是为了澄清)。我没有也不能使用 jQuery。

什么是有效的:轨迹(折线)是这样添加的:

var pois = L.geoJson(pois, 
{
  style: style_pois,
  onEachFeature: onEachFeature
 });
 pois.addTo(map);

function onEachFeature(feature, layer)
{
layer.on('click', function (e)
{
    sidebar.open('pois');

    //get the ID of the clicked POI
    number = feature.properties.number;

    //Open the accordion tab
    var panel = document.getElementsByClassName('accordion-panel');
    panel[number-1].style.display="block";

    //highlight the selected POI
    var selectedFeature = e.target;
    selectedFeature.setStyle(style_pois_selected);
}); 
}

什么不起作用:选择手风琴面板,我得到了相关路径(折线)的 ID,但我无法在 Leaflet 中访问和突出显示这个特定的折线功能。

这是控制手风琴行为的 JavaScript 代码:

var acc = document.getElementsByClassName('accordion');
var panel = document.getElementsByClassName('accordion-panel');

for (var i = 0; i < acc.length; i++) 
{
(function(index){
    acc[i].onclick = function()
    {           
        // Toggle between adding and removing the "active" class,
        //to highlight the button that controls the panel 
        this.classList.toggle("active");

        //Toggle between hiding and showing the active panel
        var panel = this.nextElementSibling;
        console.log("panel " + acc[0]);

        if (panel.style.display === "block") {
            panel.style.display = "none";
        } else {
            panel.style.display = "block";
        }
        var myIndex = index + 1;
        alert("INDEX " + myIndex);
    }
})(i);
}

问题:是否有可能基于作为 GeoJSON 包含在 Leaflet 中的层来访问基于任何属性的特定功能?

我尝试了什么:我只遇到了在 onclick 函数中访问某个折线的不同行为的解决方案。在那里可以很容易地应用另一种颜色(setStyle)。我需要从层外访问它。我已经尝试像上面那样再次加载 pois 层,就在手风琴 JavaScript 内部,并针对特定 ID 对其进行过滤,以便只表示一条折线,但它只给了我一个错误,即它是一个无效的 GeoJSON 对象(也许是范围问题?)。

感谢您的帮助!

【问题讨论】:

    标签: javascript web-applications leaflet geojson


    【解决方案1】:

    对于任何可能遇到相同问题的人 - 我找到了解决方案。

    我找了好几个小时才知道是否可以从 Leaflet 中的 GeoJSON 层访问特定功能,但似乎没有这种方法。

    虽然没有官方的方法,但对我来说,我做了以下工作。 当在手风琴内部时,可以访问已经加载的 GeoJSON 数据集,在我的例子中是 pois 并在索引位置获取图层(这实际上是获取特征,而不是图层!有点误导)。对于这个,可以应用一种样式。

    pois.getLayer(index).setStyle(style_pois)
    

    为了读出被点击的手风琴面板的索引,我又问了一个问题并指出了正确的方向:Simple JavaScript accordion - how to get the index of the clicked panel?

    【讨论】:

      【解决方案2】:

      注意:我建议您设置一些 JFiddle 来重现您的问题。

      我经常使用的一个解决方案是在每个标记/点中设置 ID/Class 属性:

      $.getJSON("data/displacement.geojson", function(data){
          pathsLayer = L.geoJson(data,{
              className: function(feature){ //Sets the class on element
                  //Assuming your JSON has a property called ID
                  return "ID-" + feature.properties.ID;
              },
              style: function (feature) {
                  //If needed, you can also set style based on properties
              },
          })
      });
      

      之后,您可以设置一个全局变量来记录选择ID,然后使用它来选择和修改特定元素。由于 Leaflet 使用 SVG 元素,我建议您使用 D3.js 来选择/修改元素,例如:

      var selectedID = null; //Declare global variable
      
      // You modify selectedID by actions on sidebar, e.g.:
      selectedID = 001
      
      d3.select(".ID-" + selectedID)
          .transition() //You can set easily transitions on attribute changes
          .duration(1000) // in ms
          .attr("attributeName", "attributeValue");
      

      您可以找到一个示例 here(虽然我知道使用 View Page Source (Ctrl + U) 阅读起来有点棘手)

      【讨论】:

      • 我的数据(顺便说一句折线)有一个 ID。问题是,虽然我有某个折线要素的 ID,但我无法访问它。
      • 如果你上传一些 JSFiddle 来看看你的代码会更好。在任何情况下,您必须首先将类设置为每个多线段(基于 JSON 属性),然后才能选择它们,这就是我包含 className: function(feature) 行的原因。
      • 假设我为每个功能设置了 className - d3.select() 行是如何工作的?,什么是 d3?在我的例子中,GeoJSON 层是 pois,但 pois.select 会导致错误,即“select”没有为 pois 定义。
      • 1. D3.js 是一个 JavaScript 库,用于使用 HTML、SVG 和 CSS 基于数据操作文档。由于传单库将地图上的元素呈现为 SVG 元素,因此您可以使用 d3 来操作这些元素。您可以找到一个介绍性示例here。开始使用 D3 的一个好点是查看 this workshop。 2. 要了解更多关于 d3 选择的信息,您可以查看 M. Bostock 的 this article。 3. select() 不是JSON对象的有效方法,所以不能使用。
      • 我试图用 D3 实现它,但我无法让它工作。 Leaflet 是否提供访问 GeoJSON 层的各个功能的可能性?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 2021-02-14
      • 2014-04-28
      相关资源
      最近更新 更多