Openlayers,更改聚类标记

时间:2012-06-20 12:23:38

标签: javascript map icons openlayers markers

我根据此Example创建了一张地图。现在我想将群集中的圆圈更改为外部图形,如果群集只包含一个点。

你知道任何解决方案吗?

编辑:

到目前为止我的代码:

PROJECTION_4326 = new OpenLayers.Projection("EPSG:4326");
PROJECTION_MERC = new OpenLayers.Projection("EPSG:900913");
var map, template, evt, features = [];

var stylesMarkerImage = {
        externalGraphic : 'markerimage.png',
        graphicHeight : 37,
        graphicWidth : 32,
        graphicYOffset : -35,
        graphicXOffset : -16
    };

/**
 * A specific format for parsing Flickr API JSON responses.
 */
OpenLayers.Format.Flickr = OpenLayers.Class(OpenLayers.Format, {
    read: function(obj) {
        var photos = new Array();
        var photo, point,
            feature;
        photos.push({longitude: 8.807357, latitude: 53.075813, title: "Title1", bild: "sample1.png", description: "Some desc1"});
        photos.push({longitude: 8.808367, latitude: 53.075813, title: "Title2", bild: "sample2.png", description: "Some desc2"});
        photos.push({longitude: 8.807357, latitude: 53.076823, title: "Title3", bild: "sample3.png", description: "Some desc3"});
        photos.push({longitude: 8.809357, latitude: 53.076823, title: "Title4", bild: "sample4.png", description: "Some desc4"});
        for(var i=0,l=photos.length; i<l; i++) {
        photo = photos[i];
        point = new OpenLayers.Geometry.Point(photo.longitude, photo.latitude);
            feature = new OpenLayers.Feature.Vector(point, {
                    id: i,
                    lon: photo.longitude,
                    lat: photo.latitude,
                title: photo.title,
                bild: photo.bild,
                description: photo.description
            }, stylesMarkerImage);
            features.push(feature);
        }
        return features;
    }
});

function init() {
    map = new OpenLayers.Map('map', {
    controls : [ new OpenLayers.Control.PanZoomBar(),
                    new OpenLayers.Control.Navigation(),
                    new OpenLayers.Control.ScaleLine(),
                    new OpenLayers.Control.MousePosition(),
                    new OpenLayers.Control.OverviewMap() ],
                numZoomLevels : 18,
                maxResolution : 156543,
                units : 'm',
                projection : PROJECTION_MERC,
                displayProjection : PROJECTION_4326
            });
    var base = new OpenLayers.Layer.OSM();

    var style = new OpenLayers.Style({
        pointRadius: "${radius}",
        fillColor: "#ffcc66",
        fillOpacity: 0.8,
        strokeColor: "#cc6633",
        strokeWidth: 2,
        strokeOpacity: 0.8
    }, {
        context: {
            radius: function(feature) {
                return Math.min(feature.attributes.count, 7) + 3;
            }
        }
    });

    var photos = new OpenLayers.Layer.Vector("Photos", {
        projection: "EPSG:4326",
        strategies: [
            new OpenLayers.Strategy.Fixed(),
            new OpenLayers.Strategy.Cluster()
        ],
        protocol: new OpenLayers.Protocol.Script({
            url: "http://api.flickr.com/services/rest",
            params: {
                api_key: '',
                format: 'json',
                method: '',
                extras: '',
                per_page: 150,
                page: 1,
                bbox: [-180, -90, 180, 90]
            },
            callbackKey: 'jsoncallback',
            format: new OpenLayers.Format.Flickr()
        }),
        styleMap: new OpenLayers.StyleMap({
            "default": style,
            "select": {
                fillColor: "#8aeeef",
                strokeColor: "#32a8a9"
            }
        })
    });

    selectControl = new OpenLayers.Control.SelectFeature(
            photos, {
                onSelect : onFeatureSelect,
                onUnselect : onFeatureUnselect
            });

    map.addControl(selectControl);
        selectControl.activate();

    map.addLayers([base, photos]);
    var center = new OpenLayers.LonLat(8.807357, 53.075813);
        var centerAsMerc = center.transform(PROJECTION_4326, PROJECTION_MERC);
        map.setCenter(centerAsMerc, 9);

        function onFeatureSelect(event) {
            evt = event.layer;
            console.log(event);
            if (event.cluster === 0) { return; }
            var features = event.cluster;
            text = '<div class="popupcontent">';
            console.log(features.length);
            var length = features.length;
            if (length > 5) {
                length = 5;
            }
            if (features.length > 1) {
            for(var i=0, len = length; i<len; ++i) {
                var feature = features[i].attributes;
                if (i == 0) {
                    text += '<a class="zoom-plus" href="#" onclick="zoomPlus('+feature.lon+', '+feature.lat+');">Zoom in</a> - <a class="zoom-minus" href="#" onclick="zoomMinus('+feature.lon+', '+feature.lat+');">Zoom out</a>';
                }
                text += '<div><b><a class="zoom-to-location" href="#" onclick="zoomToFeature('+feature.lon+', '+feature.lat+', true, '+feature.id+', \''+feature.title+'\', \''+feature.description+'\', \''+feature.bild+'\');">' + feature.title + '</a></b></div>' + feature.description;
            }
            }
            else {
                var feature = features[0].attributes;
                text += '<img src="'+feature.bild+'" alt="" width="100" height="100" style="float: left; padding: 1px; border: 1px solid #cccccc; margin: 1px 4px 2px 1px;"/><a class="zoom-to-location" href="#" onclick="zoomToFeature('+feature.lon+', '+feature.lat+');">Zoom in</a><br /><a class="zoom-out" href="#" onclick="zoomOut('+feature.lon+', '+feature.lat+');">Zoom out</a><div style="font-size: x-large;">'
            + feature.title + "</div>" + feature.description;
            }
        text += '</div>';
            popup = new OpenLayers.Popup.FramedCloud("feature", event.geometry
                .getBounds().getCenterLonLat(), null, text, event.marker, true,
                    function(b) {
                        if (event.layer == null) {
                            event.layer = evt;
                            evt = null;
                        }
                        selectControl.unselect(event)
                    });
            event.popup = popup;
            map.addPopup(popup);
            popup.updateSize();
        }
        function onFeatureUnselect(a) {
            map.removePopup(a.popup);
            a.popup.destroy();
            a.popup = null
        }

}

function zoomToFeature(lon, lat, isCluster, id, title, description, bild) {
    var center = new OpenLayers.LonLat(lon, lat);
    var centerAsMerc = center.transform(PROJECTION_4326, PROJECTION_MERC);
    map.setCenter(centerAsMerc, 18);
    if(isCluster) {
        var pops = map.popups;
        for(var a = 0; a < pops.length; a++){
           map.removePopup(map.popups[a]);
        };
        text = '<div class="popupcontent">';
        text += '<img src="'+bild+'" alt="" width="100" height="100" style="float: left; padding: 1px; border: 1px solid #cccccc; margin: 1px 4px 2px 1px;"/><a class="zoom-out" href="#" onclick="zoomOut('+lon+', '+lat+');">Zoom out</a><div style="font-size: x-large;">'
            + title + "</div>" + description;
        var popup = new OpenLayers.Popup.FramedCloud("feature", center, null, text, null, true);
        text += '</div>';
        map.addPopup(popup);
        popup.updateSize();
    }
}

function zoomOut(lon, lat) {
    var center = new OpenLayers.LonLat(lon, lat);
    var centerAsMerc = center.transform(PROJECTION_4326, PROJECTION_MERC);
    map.setCenter(centerAsMerc, 8);
}

function zoomPlus(lon, lat) {
    var center = new OpenLayers.LonLat(lon, lat);
    var centerAsMerc = center.transform(PROJECTION_4326, PROJECTION_MERC);
    map.setCenter(centerAsMerc, map.getZoom()+1);
    var pops = map.popups;
    for(var a = 0; a < pops.length; a++){
       map.removePopup(map.popups[a]);
    };
}

function zoomMinus(lon, lat) {
    var center = new OpenLayers.LonLat(lon, lat);
    var centerAsMerc = center.transform(PROJECTION_4326, PROJECTION_MERC);
    map.setCenter(centerAsMerc, map.getZoom()-1);
    var pops = map.popups;
    for(var a = 0; a < pops.length; a++){
       map.removePopup(map.popups[a]);
    };
}

我不知道该解释更多。默认情况下,群集会显示一个圆圈以显示其位置。如果群集有少于两个poi includet,我想用markerimage替换这个圆圈。我不知道如何做到这一点,我不知道在哪里。也许在zoomevent上?

1 个答案:

答案 0 :(得分:2)

您需要为群集策略建立THRESHOLD。阈值是群集可以分组的最小功能数。

strategies: [
        new OpenLayers.Strategy.Fixed(),
        new OpenLayers.Strategy.Cluster({ distance: 35, threshold: 2 })
    ],

你必须明确地在其他地方(在你的json中)定义了各个功能的图标。