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.
1 comment:
Post a Comment