OpenLayers (https://openlayers.org/) is a "high-performance, feature-packed (Javascript) library for all your mapping needs" for web sites. I spent some time figuring out how to use it with ReactJS. As most of the available examples in the official documentation are for plain vanilla HTML/Javascript, I stumbled a few times trying to get it to work. This post summarises the steps to get a minimal OpenLayers - React component to work.
Assuming a ReactJS project has been created e.g. /path/to/React/project/, the first thing is to install the prerequisite software.
- Install OpenLayers package for node. Open a Terminal, change directory to the project root directory and type in the following command.
$ npm install ol --save - Optional. Install Proj4Js and Material-UI.
$ npm install proj4 @material-ui/core --save
Under the ReactJS project e.g. /path/to/React/project/src/components/, create the OpenLayers React component e.g. OLMapFragment.js.
Code listing of OLMapFragment.js
import React from 'react' import Grid from '@material-ui/core/Grid' // Start Openlayers imports import { Map, View } from 'ol' import { GeoJSON, XYZ } from 'ol/format' import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer' import { Vector as VectorSource, OSM as OSMSource, XYZ as XYZSource, TileWMS as TileWMSSource } from 'ol/source' import { Select as SelectInteraction, defaults as DefaultInteractions } from 'ol/interaction' import { Attribution, ScaleLine, ZoomSlider, Zoom, Rotate, MousePosition, OverviewMap, defaults as DefaultControls } from 'ol/control' import { Style, Fill as FillStyle, RegularShape as RegularShapeStyle, Stroke as StrokeStyle } from 'ol/style' import { Projection, get as getProjection } from 'ol/proj' // End Openlayers imports class OLMapFragment extends React.Component { constructor(props) { super(props) this.updateDimensions = this.updateDimensions.bind(this) } updateDimensions(){ const h = window.innerWidth >= 992 ? window.innerHeight : 400 this.setState({height: h}) } componentWillMount(){ window.addEventListener('resize', this.updateDimensions) this.updateDimensions() } componentDidMount(){ // Create an Openlayer Map instance with two tile layers const map = new Map({ // Display the map in the div with the id of map target: 'map', layers: [ new TileLayer({ source: new XYZSource({ url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png', projection: 'EPSG:3857' }) }), new TileLayer({ source: new TileWMSSource({ url: 'https://ahocevar.com/geoserver/wms', params: { layers: 'topp:states', 'TILED': true, }, projection: 'EPSG:4326' }), name: 'USA' }), ], // Add in the following map controls controls: DefaultControls().extend([ new ZoomSlider(), new MousePosition(), new ScaleLine(), new OverviewMap() ]), // Render the tile layers in a map view with a Mercator projection view: new View({ projection: 'EPSG:3857', center: [0, 0], zoom: 2 }) }) } componentWillUnmount(){ window.removeEventListener('resize', this.updateDimensions) } render(){ const style = { width: '100%', height:this.state.height, backgroundColor: '#cccccc', } return ( <Grid container> <Grid item xs={12}> <div id='map' style={style} > </div> </Grid> </Grid> ) } } export default OLMapFragment
Use the React OpenLayers map component
Now in the ReactJS project's index.js file under /path/to/React/project/src/, import in the newly created OLMapFragment component and render it.
Listing of index.js
import React from 'react' import { render} from 'react-dom' import OLMapFragment from './js/components/OLMapFragment' render( <OLMapFragment /> , document.getElementById('react-container') )
Create the default index.html file
Finally, include links to OpenLayer's style sheets in the project's index.html file under /path/to/React/project/src/.
Listing of index.html file
<!DOCTYPE html> <html class="no-js" lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content='ie=edge'> <title>Openlayers React</title> <meta name="description" content="Explore planet Mars"> <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no" /> <!-- material-ui prerequisites --> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" /> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" /> <!-- end material-ui prerequisites --> <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" type="text/css" /> </head> <body> <!--[if lte IE 8] <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com">upgrade your browser</a></p> <![endif]--> <div id='react-container'></div> </body> </html>
Now, run the ReactJS project with a web server and open the web page with an Internet browser.
The web map tiles are rendered in the React OpenLayers component.
This comment has been removed by the author.
ReplyDelete