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

标签 javascript google-maps-api-3

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

我的代码是这样开始的:

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)
};

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

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

到目前为止我找到的所有示例都是基于手动添加标记并将其存储在数组中以供以后访问的原理,例如:

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

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

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

--- 更新 ---

以下是有关该项目的更多详细信息。

map 将标记从客户列表生成的标记。客户有不同的类别和属性,因此 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}}

map 上还有一个过滤框,其中包含默认选中的复选框。单击其中任何一个都将运行过滤代码,该代码应隐藏或删除与匹配该过滤器的任何客户关联的标记。

因此,如果我禁用过滤“非事件”的复选框,则只有具有属性 "active":1 的客户才会保留在 map 上。如果我禁用过滤“vendor ”的复选框,则所有类别为“vendor ”的客户都将被隐藏。

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

我在研究中发现大量提及标记,但仅限于手动添加它们 - 而不是通过 GeoJSON 导入。

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

我当前使用map.data.setStyle()的解决方案(参见评论)似乎有效并完成了工作。但我很好奇是否还有其他更直接的方法。

我想,过滤器函数将遍历所有数据(map.data.forEach())以根据过滤器找到应隐藏的任何项目,然后每个项目将与需要隐藏该标记的关联标记。但到目前为止我还无法弄清楚这种关联。

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

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

我希望现在更清楚了。

--- 更新 ---

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

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

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

最佳答案

您不需要使用 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
    };
});

您不需要再次调用该方法,因为样式已绑定(bind)到功能属性。将 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 原型(prototype)上实现过滤方法,但这应该会为您指明正确的方向。

关于javascript - 如何访问和隐藏由 loadGeoJson() 创建的标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34092711/

相关文章:

javascript - 单击 "page jump"链接时部分网站消失

php - 如何让 ajax 评论系统从不同的目录工作?

javascript - 可缩放当前幻灯片的轮播

javascript - 如何使用单选按钮值检查单选按钮

javascript - Google map - 热图层位于数据层之后

google-maps - 计算在Google map 上绘制的多边形的面积

Javascript - 我写的淡入淡出图像的函数有问题

javascript - 在父容器调整大小上重绘谷歌地图

google-maps - 如果达到免费API上限,我可以停止向Google收费吗?

reactjs - 使用 react-places-autocomplete 包获取邮政编码