Nuno Oliveira
Nuno Oliveira

Reputation: 33

Openlayers Popup in React | How to?

Is there anyway to get popup overlay of OpenLayers working in react? I have no ideia how to get this working..

Upvotes: 3

Views: 4132

Answers (1)

Paddy
Paddy

Reputation: 625

I've included a regular react openlayer overlay that stays over Viena on the map and a second overlay that pops up where ever a user clicks.

First install openlayers with npm i ol

Then create a class MapExample.js:

import React, { Component } from "react";
import ReactDOM from 'react-dom';
import Map from "ol/Map.js";
import View from "ol/View.js";
import Overlay from "ol/Overlay.js";
import LayerTile from "ol/layer/Tile.js";
import SourceOSM from "ol/source/OSM.js";
import * as proj from 'ol/proj';
import './MapExample.css';

const posViena = proj.fromLonLat([16.3725, 48.208889]);

export default class MapExample extends Component {
  constructor(props) {
    super(props);
    this.state = { center: posViena, zoom: 3 };

    this.map = new Map({
      target: null, // set this in componentDidMount
      layers: [
        new LayerTile({
          source: new SourceOSM()
        })
      ],
      view: new View({
        center: this.state.center,
        zoom: this.state.zoom
      })
    });
  }

  componentDidMount() {
    this.map.setTarget("map");
    // Listen to map changes
    this.map.on("moveend", () => {
      let center = this.map.getView().getCenter();
      let zoom = this.map.getView().getZoom();
      this.setState({ center, zoom });
    });

    // Basic overlay
    const overlay = new Overlay({
      position: posViena,
      element: ReactDOM.findDOMNode(this).querySelector('#overlay'),
      positioning: 'center-center',
      stopEvent: false
    });
    this.map.addOverlay(overlay);

    // Popup showing the position the user clicked
    this.popup = new Overlay({
      element: ReactDOM.findDOMNode(this).querySelector('#popup')
    });

    // Listener to add Popup overlay showing the position the user clicked
    this.map.on('click', evt => {
      this.popup.setPosition(evt.coordinate);
      this.map.addOverlay(this.popup);
    })
  }

  componentWillUnmount() {
    this.map.setTarget(null);
  }

  render() {
    return (
      <div>
        <div id="map" style={{ width: "100%", height: "360px" }}/>
        <div className="blue-circle" id="overlay" title="overlay"/>
        <div className="blue-circle" id="popup" title="Welcome to OpenLayers"/>
      </div>
    );
  }
}

With a MapExample.css file like this:

.blue-circle {
  width: 30px;
  height: 30px;
  border: 1px solid #088;
  border-radius: 15px;
  background-color: #0FF;
  opacity: 0.5;
  z-index: 9999; /* Watch out for this!!! */
}

Finally have your App.js like this:

import React from 'react';
import './App.css';
import MapExample from "./MapExample";

function App() {
  return (
    <div className="App">
      <MapExample />
    </div>
  );
}

export default App;

Upvotes: 5

Related Questions