如何访问和隐藏loadGeoJson()创建的标记?

时间:2015-12-04 16:17:19

标签: google-maps-api-3

我通过JSON将自定义坐标加载到我的地图应用程序中。我已经能够找到如何根据要素属性对标记进行颜色编码,但我接下来的步骤之一是创建过滤器以根据属性显示或隐藏标记。

我的代码是这样开始的:

var map;
var infowindow = new google.maps.InfoWindow();

function initialize()
{
    var mapCanvas = document.getElementById('map');
    var mapOptions = {
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map(mapCanvas, mapOptions);
    map.data.loadGeoJson('/map_json.php', null, SetBounds);

    map.data.setStyle(function(feature) {
        var color = 'FF0000';
        var symbol = '%E2%80%A2';  // dot
        // color selection code here [...]

        return /** @type {google.maps.Data.StyleOptions} */ {
            icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=' + symbol + '|' + color
        };
}

我已经找到了如何通过jquery自动完成搜索访问导入的数据:

$(input).autocomplete({
    minLength: 0,
    source: function(request, response) {
        data = [];
        map.data.forEach(function(feature)
        {
            var str = request.term.toUpperCase();
            if (String(feature.getProperty('name')).toUpperCase().indexOf(str) > -1)
            {
                data.push({id: feature.getProperty('id'), name: feature.getProperty('name'), address: feature.getProperty('address')});
            }
        });
        response(data);
    },
    select: function(event, ui)
    {
        map.data.forEach(function(feature)
        {
            if (feature.getProperty('id') == ui.item.id)
            {
                var content = GetContent(feature);
                infowindow.setContent(content);
                infowindow.setPosition(feature.getGeometry().get());
                infowindow.setOptions({pixelOffset: new google.maps.Size(0, -34)});
                infowindow.open(map);

                // zoom in
                map.setZoom(15);
                map.panTo(feature.getGeometry().get());

                return false;
            }
        });
    }
})
.autocomplete().data('uiAutocomplete')._renderItem = function(ul, item)
{
    return $('<li>')
        .append('<a>' + item.name + ' (ID: ' + item.id + ')<br>' + item.address + '</a>')
        .appendTo(ul)
};

因此使用相同的原理运行我的过滤器不是问题。

问题是我还没有找到根据feature中的map.data信息访问可见标记的方法。

到目前为止,我发现的所有示例均基于手动添加标记并将其存储在数组中以便以后访问的原则,例如:

var marker = new google.maps.Marker({
    position: myLatLng,
    map: map,
    title: 'Hello World!'
});

但我没有 - 我使用getGeoJson()加载整套数据。

如何根据我可以使用map.data.forEach()访问的信息来访问标记并对其进行操作(例如隐藏或显示标记)?

---更新---

以下是该项目的更多细节。

地图将显示从客户列表中生成的标记。客户有不同的类别和属性,因此GeoJSON字符串的典型条目如下所示:

{"type":"Feature","geometry":{"type":"Point","coordinates":[0,0]},"properties":{"name":"Customer 1","id":"1001","address":"1234 Test Street, Test City, TX 12345, USA","category":"vendor","active":1}}

在地图上还有一个带有复选框的过滤器框,默认情况下会选中这些复选框。单击其中任何一个将运行过滤代码,该代码应隐藏或删除与该过滤器匹配的任何客户关联的标记。

因此,如果我禁用过滤“非活动”的复选框,则只有具有属性"active":1的客户才会保留在地图上。如果我禁用过滤“供应商”的复选框,则所有具有“供应商”类别的客户将被隐藏。

稍后再次选中复选框将撤消隐藏这些条目。

我在研究中发现的很多都是标记,但只有手动添加才能 - 而不是通过GeoJSON导入。

我可以看到一些可能解决我问题的方法 - 我可以忽略GeoJSON格式,而是手动将客户端列表导入jQuery,然后从那里解析成标记然后进入数组。但是为什么要使用GeoJSON格式?

我目前使用map.data.setStyle()的解决方案(请参阅评论)似乎可以正常工作。但如果没有其他更直接的方式,我很好奇。

我想,过滤器功能会遍历所有数据(map.data.forEach())以根据过滤器找到应隐藏的任何项目,然后每个项目将与标记所需的相关标记进行通信隐。但是到目前为止我还没有弄清楚这种关联。

当我遍历所有功能(map.data.forEach())时,我可以访问我上传的数据,但不能访问因导入而放置的标记。

我的问题是,是否有直接从该功能访问标记的方法。

我希望现在更清楚了。

---更新---

我为它创建了一个非常简单的jsfiddle:

http://jsfiddle.net/semmelbroesel/9bv68ngp/

这是我想要实现的概念,它可以按原样运行。我唯一的问题是,如果有另一种方法可以通过直接访问已放置的标记来获得相同的结果,而不是使用setStyle()隐藏/显示它们。

1 个答案:

答案 0 :(得分:4)

您不需要使用forEach,因为setStyle已经遍历了功能。

如果将样式函数声明为:

map.data.setStyle(function(feature) {
    var color = 'FF0000';
    var symbol = '%E2%80%A2';  // dot

    return /** @type {google.maps.Data.StyleOptions} */ {
        visible: feature.getProperty('active'), // this links visibility to feature property
        icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=' + symbol + '|' + color
    };
});

您不需要再次调用该方法,因为样式绑定到要素属性。将active属性设置为false将无缝传播到标记样式。

之后,你可以使你的过滤器像(粗略的例子)

var setFilter = function(property, value) {
    map.data.forEach(function(feature) {
        feature.setProperty('active', feature.getProperty(property) === value);
    });
};

并呼吁举例setFilter('name','John');

同样,这是一个粗略的例子。我宁愿在google.maps.Data原型上实现过滤方法,但这应该指向正确的方向。