在JavaScript中按类别对地图点进行分组

时间:2012-01-03 00:29:53

标签: javascript json grouping geojson

我通过解析动态创建的GeoJSON文件将点放在地图上。我想按照它的类别属性对这些点进行分组(每个点都有一个类别属性)。我已经找到了如何在我的映射库中添加点对象组(Leaflet:http://leaflet.cloudmade.com/examples/layers-control.html),但它假设我知道类别将是什么(例如var citiesLayer = new L.LayerGroup();)。

我更喜欢做的是解析每个点(已经在做那个部分),然后检查是否存在类别X的组,并将该点添加到该组或创建一个组加点。这样我就可以立即打开/关闭某个类别的所有点。关于我怎么做的任何想法?我对JavaScript知之甚少(我是一个Python人)。

这是我的JS:

// http://geoserving.net/odk_geoserver/

function init(){
    $.getJSON(geoJSONURL, makeMap);
}

function makeMap(data) {
    // Assign GeoJSON to variable
    var eventPoints = data;
    // Create new map instance
    var map = new L.Map('map');
    var eventsGeoJSON = new L.GeoJSON(null, {
            pointToLayer: function (latlng){
                return new L.CircleMarker(latlng, {
                    radius: 5,
                    fillColor: "#A3C990",
                    color: "#000",
                    weight: 1,
                    opacity: 1,
                    fillOpacity: 0.4
                });
            }
        });

    // Event Listener for Addition of Data to Boundary Layer
    eventsGeoJSON.on('featureparse', function (e) {
        var popupText = 
        '<div id="feature">';

        for(var i = 0, l = e.properties.event_set__all.length; i < l; i++) {  
            popupText += '<div class="event">' +
            '<p>' +
                '<h3 class="featureInfo">' +
                        e.properties.event_set__all[i].title + 
                '</h3>' +
            '</p>';
            if (e.properties.event_set__all[i].category__category) {
                popupText +=
                '<p>' +
                    '<span class="featureLabel">Category: </span>' +
                    '<span class="featureInfo">' +
                        e.properties.event_set__all[i].category__category + 
                    '</span>' +
                '</p>';
            }
            popupText += '</div>';
        }

        popupText +=
            '<div class="venue">' +
                    '<span class="featureLabel">Venue: </span>' +
                    '<span class="featureInfo">' + 
                        '<a href="../' + e.properties.neighborhood__slug + '/' + e.properties.slug + '">' + 
                            e.properties.venue + 
                        '</a>' +
                    '</span>' +
            '</div>';

        e.layer.bindPopup(popupText);
    }); // End feature parse

    // Populate Points Layer with Data
    eventsGeoJSON.addGeoJSON(eventPoints);

    var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/<My Key>/256/{z}/{x}/{y}.png',
        cloudmadeAttrib = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade',
        cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttrib});
    var seattle = new L.LatLng(47.64, -122.34); // geographical point (longitude and latitude)
    map.setView(seattle, 12).addLayer(cloudmade);
    map.addLayer(eventsGeoJSON);
}

GeoJSON点示例:

{
    "crs": null,
    "type": "FeatureCollection",
    "features": [
        {
            "geometry": {
                "type": "Point",
                "coordinates": [
                    -122.382626,
                    47.6657641
                ]
            },
            "type": "Feature",
            "id": 18,
            "properties": {
                "event_set__all": [
                    {
                        "category__category": "Live",
                        "title": "the Tallboys",
                        "cost": "$5",
                        "description": "",
                        "slug": "the-tallboys"
                    }
                ],
                "neighborhood__slug": "ballard",
                "venue": "Tractor Tavern",
                "neighborhood__neighborhood": "Ballard",
                "address": "5213 Ballard Ave NW, Seattle, WA 98107, USA",
                "slug": "tractor-tavern"
            }
        }
    ]
}

用于对每个点进行分组的属性为e.properties.event_set__all[0].category__category

1 个答案:

答案 0 :(得分:1)

您可以使用Alasql库对所有点进行分组:

var res = alasql('SELECT features->0->properties->event_set__all->0->category__category \
                      AS category, ARRAY(_) AS points FROM ? GROUP BY category',[data]);

它将从这个长点名称中选择的类别的所有点分组,如:

[
    {category:"Live1", points: [{point},{point},...] },
    {category:"Live2", points: [{point},{point},...] }
]

试试这个例子at jsFiddle