22

It sounds so simple but I can't find any newbie tutorial: Could anybody give me a simple example how I create (vektor)markers in OpenLayers that open an infowindow on mouseover and even close it on mouseout?

I found parts of this explained but not all of it....

Bruno Machado - vargero
  • 2,690
  • 5
  • 33
  • 52
JoergP
  • 1,349
  • 2
  • 13
  • 28

8 Answers8

18

For a simple example of how to do this, you need to do a couple of things:

Create a vector layer to contain your markers and add it to the map:

this.markerLayer = new OpenLayers.Layer.Vector(
    "My Marker Layer",
    { /* configuration options are set here */ }
);
map.addLayer(this.markerLayer);

Create your marker and add it to the map:

var marker = new OpenLayers.Feature.Vector(point, attributes, markerStyle);
this.markerLayer.addFeatures([marker]);

Create a select control for your layer, and register a function to build your popup when the user hovers over your marker:

var selectControl = new OpenLayers.Control.SelectFeature(this.markerLayer, {
    hover: true
});
selectControl.events.register('featurehighlighted', null, onFeatureHighlighted);

Build your popup:

onFeatureHighlighted: function (evt) {
    // Needed only for interaction, not for the display.
    var onPopupClose = function (evt) {
        // 'this' is the popup.
        var feature = this.feature;
        if (feature.layer) {
            selectControl.unselect(feature);
        }  
        this.destroy();
    }

    feature = evt.feature;
    popup = new OpenLayers.Popup.FramedCloud("featurePopup",
            feature.geometry.getBounds().getCenterLonLat(),
            new OpenLayers.Size(100,100),
            "<h2>"+feature.attributes.station_na + "</h2>" +
            "Location: " + feature.attributes.location + '<br/>' +
            "Elevation: " + feature.attributes.elev_,
            null, true, onPopupClose);
    feature.popup = popup;
    popup.feature = feature;
    map.addPopup(popup, true);
}, // ...
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Kyle
  • 4,202
  • 1
  • 33
  • 41
13

You can use marker and popup, as below.

var popup;
var marker_layer = new OpenLayers.Layer.Markers( "Markers" );
var size = new OpenLayers.Size(32,32);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon_marker = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png',
                                        size, 
                                        offset);
marker = new OpenLayers.Marker(new OpenLayers.LonLat(5.6, 50.6), icon_marker);

//here add mouseover event
marker.events.register('mouseover', marker, function(evt) {
    popup = new OpenLayers.Popup.FramedCloud("Popup",
        new OpenLayers.LonLat(5.6, 50.6),
        null,
        '<div>Hello World! Put your html here</div>',
        null,
        false);
    map.addPopup(popup);
});
//here add mouseout event
marker.events.register('mouseout', marker, function(evt) {popup.hide();});

marker_layer.addMarker(marker);
map.addLayer(marker_layer);
Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
bsuttor
  • 2,716
  • 2
  • 17
  • 10
  • Thanks. Probably You should add a check, if the marker exists already, and to show it instead of multiple creation. In another way on complex maps it could provoke memory leaks. – Fedir RYKHTIK Apr 23 '13 at 16:24
3

This works for me. Ended up being simple, but took a while:

 var marker = new OpenLayers.Marker(position, icon.clone());           
 boothLayer.addMarker(marker);                                         

 marker.events.register('mouseover', marker, function() {           
   var msg = booth.get('name') +' - ' + booth.get('premises');      
   var popup = new OpenLayers.Popup.FramedCloud("Popup",            
       position, null, '<div>'+msg+'</div>', null, false);          
   map.addPopup(popup);                                             
   marker.events.register('mouseout', marker,                       
     setTimeout( function() { popup.destroy(); }, 4000));           
   });                                                              

Note the 4000 microsecond delay on the mouse out event - maybe could be shorter, depends on your use.

ErichBSchulz
  • 15,047
  • 5
  • 57
  • 61
1

I use a function to add it, here's a simplified version. Note that you set the details and call the function at the bottom. Also note that you can't have multiple selectors on multiple layers - I think only the last one added will work, so you'll have to tweak it if you want multiple features in one layer:

function addMarkerLayer(markerInfo){
    var details= markerInfo.details || "<h3>"+markerInfo.title+"</h3>"+
        "[Location] Lat:"+markerInfo.latitude + " Lon:"+markerInfo.longitude;

    var features=[];
    features.push(new OpenLayers.Feature.Vector(
        new OpenLayers.Geometry.Point(markerInfo.longitude, markerInfo.latitude),
        {title: markerInfo.title, details:details, externalGraphic:markerInfo.icon},
        {
            externalGraphic:markerInfo.icon,
            fillColor: markerInfo.markerColor || '#ff0',
            fillOpacity: markerInfo.iconOpacity || 0.8,
            graphicWidth   : markerInfo.iconSize || 24,
            graphicHeight  : markerInfo.iconSize || 24,
            strokeColor: markerInfo.markerStrokeColor || "#ee9900",
            strokeOpacity: 1,
            strokeWidth: 1,
            pointRadius: 7
        }
    ));

    // create the layer with listeners to create and destroy popups
    var vector = new OpenLayers.Layer.Vector(markerInfo.layerName, {
        eventListeners: {
            'featureselected': function(evt) {
                var feature = evt.feature;
                var popup = new OpenLayers.Popup.FramedCloud("popup",
                    OpenLayers.LonLat.fromString(feature.geometry.toShortString()),
                    null,
                    feature.attributes.details,
                    null,
                    true);
                feature.popup = popup;
                map.addPopup(popup);
            },
            'featureunselected': function(evt) {
                var feature = evt.feature;
                map.removePopup(feature.popup);
                feature.popup.destroy();
                feature.popup = null;
            }
        }
    });
    vector.addFeatures(features);

    var selector = new OpenLayers.Control.SelectFeature(vector, {
        hover: true
    });

    map.addLayer(vector);
    map.addControl(selector);
}


var markerInfo={
    title:'Washington DC',
    latitude:38.8,
    longitude:-77,
    icon:"/icons/event.png",
    iconSize:24
};
addMarkerLayer(markerInfo);
JayCrossler
  • 2,079
  • 2
  • 22
  • 22
1

I wrote a working exemple of this with ol 5.2 exemple "Custom Interaction" openlayers.org/en/latest/examples/select-features.html

So you add features to a layer and add it to the map and then you create a new Interaction like this

const interact = new ol.interaction.Select({condition: ol.events.condition.pointerMove});

It specifies that it will select a feature on hover (pointermove) Then you add it to your map and associate the function that should be called when the interaction selects a feature (i.e. when you hovers over one).

map.addInteraction(interact);
interact.on('select', showInfoWindow);

And you declare your function that shows the info window

function showInfoWindow(evt){
    if(evt.selected.length>0){
        const feature = evt.selected[0];
        const id = feature.getId();

        infoWindow.innerHTML = '<p>' + id + '</p>';
        infoWindow.show();//if you have something like that, you could use an openLayers overlay
    }
}

You should note that the event will return (in this case) an object where you can find the selected feature in the 'selected' attribute when you hover in it. When you hover out, in this case, the same object will be available in the 'deselected' attribute until you select a new one

Clement
  • 281
  • 1
  • 2
  • 8
1

You need to use a selectControl to create your popup. To make it respond to hover instead of click set hover:true in the constructor.

Jon Lynch
  • 136
  • 3
0

This example from a userlist was very helpful in showing how to have both hover and click events assigned to a vector layer.

Evan Siroky
  • 9,040
  • 6
  • 54
  • 73
-1

It sounds like you want to look at "OpenLayers.Popup()"

this example shows a popup after you draw a polygon, then click on it, but you should be able to change it to respond to hover instead. http://openlayers.org/dev/examples/select-feature-openpopup.html

rocketsarefast
  • 4,072
  • 1
  • 24
  • 18