Search code examples
javascriptjqueryhtmlopenstreetmapopenlayers-3

Display Markers, Popups with OpenLayer3


I'm trying to understand how can I display markers/popups on osm map with openlayers3, I have found examples in examples on ol3 web page, but...

Is there more examples for coding markers/popups with javascript or jquery, preferably something like this or similar examples.

The idea is to mark a building, by clicking on the marker it will popup some info for the building, further more I would like to connect important places from the city to this building (library, restaurants, bus stops, etc). I wish if someone can explain me how to start up building this, and I don't want to use bootstrap3 for this ( I have seen overlay example), instead want pure html5, css3, javascript/jquery)


Solution

  • You can create a popup with pure HTML, CSS and JavaScript, as shown in the popup example. A fully working example for what you want is here: http://jsfiddle.net/ahocevar/z86zc9fz/1/.

    The HTML for the popup is simple:

    <div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content"></div>
    </div>
    

    The CSS is a bit more involved:

    .ol-popup {
      position: absolute;
      background-color: white;
      -webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
      filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
      padding: 15px;
      border-radius: 10px;
      border: 1px solid #cccccc;
      bottom: 12px;
      left: -50px;
      min-width: 80px;
    }
    .ol-popup:after, .ol-popup:before {
      top: 100%;
      border: solid transparent;
      content: " ";
      height: 0;
      width: 0;
      position: absolute;
      pointer-events: none;
    }
    .ol-popup:after {
      border-top-color: white;
      border-width: 10px;
      left: 48px;
      margin-left: -10px;
    }
    .ol-popup:before {
      border-top-color: #cccccc;
      border-width: 11px;
      left: 48px;
      margin-left: -11px;
    }
    .ol-popup-closer {
      text-decoration: none;
      position: absolute;
      top: 2px;
      right: 8px;
    }
    .ol-popup-closer:after {
      content: "✖";
    }
    

    To make a popup, use ol.Overlay:

    var container = document.getElementById('popup');
    var overlay = new ol.Overlay({
      element: container,
      autoPan: true,
      autoPanAnimation: {
        duration: 250
      }
    });
    map.addOverlay(overlay);
    
    var closer = document.getElementById('popup-closer');
    closer.onclick = function() {
      overlay.setPosition(undefined);
      closer.blur();
      return false;
    };
    

    To make features clickable, use

    var content = document.getElementById('popup-content');
    map.on('singleclick', function(evt) {
      var name = map.forEachFeatureAtPixel(evt.pixel, function(feature) {
        return feature.get('name');
      });
      var coordinate = evt.coordinate;
      content.innerHTML = name;
      overlay.setPosition(coordinate);
    });
    

    For visual feedback when the pointer is over a feature, use

    map.on('pointermove', function(evt) {
      map.getTargetElement().style.cursor = map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : '';
    });
    

    The features (i.e. markers) come from a vector layer:

    var markers = new ol.layer.Vector({
      source: new ol.source.Vector({
        features: [
          new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.fromLonLat([16.37, 48.2])),
            name: 'Vienna',
            type: 'City'
          }),
          new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.fromLonLat([-0.13, 51.51])),
            name: 'London',
            type: 'City'
          })
        ]
      }),
      style: new ol.style.Style({
        image: new ol.style.Icon({
          src: '//openlayers.org/en/v3.12.1/examples/data/icon.png',
          anchor: [0.5, 1]
        })
      })
    });
    map.addLayer(markers);
    

    The above snippet uses a fixed style, i.e. the same icon for all types of features. If you have different types of features, you can define a style function instead of a fixed style:

    var cityStyle = new ol.style.Style({
      image: new ol.style.Icon({
        src: '//openlayers.org/en/v3.12.1/examples/data/icon.png',
        anchor: [0.5, 1]
      })
    });
    var otherStyle = new ol.style.Style({
      image: new ol.style.Icon({
        src: '//openlayers.org/en/v3.12.1/examples/data/Butterfly.png'
      })
    });
    var markers = new ol.layer.Vector({
      // ...
      style: function(feature, resolution) {
        if (feature.get('type') == 'City' {
          return cityStyle;
        }
        return otherStyle;
      }
    });