Showing a popup on feature click

OpenLayers can anchor markup to a position on the map. This can be used to display a popup at a user clicked location. In this case, we just want to show the latitude and longitude of the current user location in a nice little popup.

CSS and markup for the popup

For nice styling of the popup, we can go to http://www.cssarrowplease.com/ and design a container for our popup. I changed the arrow size to 10 and played a bit with the colors. The resulting css is simply copied to the <style> section of our index.html:

.arrow_box {
    position: relative;
    background: #fff;
    border: 1px solid #003c88;
}
.arrow_box:after, .arrow_box:before {
    top: 100%;
    left: 50%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.arrow_box:after {
    border-color: rgba(255, 255, 255, 0);
    border-top-color: #fff;
    border-width: 10px;
    margin-left: -10px;
}
.arrow_box:before {
    border-color: rgba(153, 153, 153, 0);
    border-top-color: #003c88;
    border-width: 11px;
    margin-left: -11px;
}

To make the popup look nicer, we give the .arrow-box some padding and rounded corners:

.arrow_box {
  border-radius: 5px;
  padding: 10px;
}

In addition to the css, we also need to add the markup for the container the body of our index.html:

<div class="arrow_box" id="popup-container"></div>

Application code for interacting with the map

The Overlay module is responsible for anchoring markup to a position on the map, and the coordinate module provides a function to format a position in degrees, minutes and seconds. Let's import these two modules:

import Overlay from 'ol/overlay';
import coordinate from 'ol/coordinate';

To create the overlay and connect it to the popup, we append the following code to our main.js:

var overlay = new Overlay({
  element: document.getElementById('popup-container'),
  positioning: 'bottom-center',
  offset: [0, -10]
});
map.addOverlay(overlay);

Note the offset we configured for the Overlay. The y offset (-10) has to compensate for the arrow size we provided on http://www.cssarrowplease.com/.

The last step is to append another code snippet to main.js, where we listen for user clicks on the map and handle them by showing the popup at the position of the clicked vector feature:

map.on('click', function(e) {
  overlay.setPosition();
  var features = map.getFeaturesAtPixel(e.pixel);
  if (features) {
    var coords = features[0].getGeometry().getCoordinates();
    var hdms = coordinate.toStringHDMS(proj.toLonLat(coords));
    overlay.getElement().innerHTML = hdms;
    overlay.setPosition(coords);
  }
});

The on() function is used to register a listener for clicks, and Map#getFeaturesAtPixel() returns the features at the pixel position, where pixels are relative to the map viewport. That pixel is provided by the event object (e) we get as argument for the listener function.

Now look at the working map in the web browser: http://localhost:3000/. Once you are zoomed to the current location and see the circle marker, click on it to get the popup. When you click somewhere else on the map, the popup will disappear again.

A map with a popup at our location
A map with a popup at our location

results matching ""

    No results matching ""