Create Openlayers map in React Part 1
Believe it or not! There is no active package available which harnesses the power of Openlayers with the Components of react. ( We're building it anyways ?? ).
In this blog I'll show you faster way to create an openlayers application. We'll be using following technologies for this.
I'll show case each and every step as we move forward.
Step 1 : Create React App
Let us start by creating simple react app on desktop using
npx create-react-app olreact
This will create olreact folder on desktop with all necessary files to run react project.
If you have code editor like VSCode , open the folder to see all available files
We'll not worry about any other folder apart from src for now. To run the project simply use following command
npm run start
this will start the basic project on browser
Step 2 : Figure out context
One of the most confusing and frustrating part of react is state management. Often times we start developing the application and realise later that we need to pass some value from Child to parent component. To over come this, we have context API out of the box from react, for advance use case, we use redux toolkit, which again is little bit complicated to understand and use. Thus I'll be using zustand . I personally find it easy to use and powerful.
Using Zustand, we can create store js files, in which we mention variables and functions to change states of variable.
Setting up map store context
To begin with, create folder names stores in which we'll create store js files. In these files, we write all context related information. We start by create mapStore.js in which we mention map variable and functions related to it, such as updating map variable, destroying map, etc.
import create from "zustand";
const useMapStore = create((set) => ({
map: null,
populateMap: (mapGenerated) => set((state) => ({ map: mapGenerated })),
removeMap: () => set({ map: null }),
}));
export default useMapStore;
As per code snippet, we have
Step 3 : Creating Openlayers component
The basic idea to create Openlayers components is to create nested parent-children tag using which we can add/remove layers whenever we want. Ideally it will look like this
<ReMap>
<Layers>
<TileLayer />
<VectorLayer />
</Layers>
<Controls>
<Draw />
</Controls>
<Interactions>
<FullScreen />
</Interactions>
</ReMap>
Each of these tags will have methods and properties attached to it. Now let us create each of these components.
Creating Main Map Component
We'll start by creating main Map component, for this create a folder Map and add Map.css with following style
.map {
width: 100%;
height: 80vh;
}
then ReMap.js file inside it.
import "./Map.css";
import React, { useEffect, useRef } from "react";
import Map from "ol/Map";
import View from "ol/View";
import "../../../../node_modules/ol/ol.css";
import useMapStore from "../../zuStore/mapStore";
export const ReMap = ({ children, zoom, center }) => {
const map = useMapStore((state) => state.map);
const setMap = useMapStore((state) => state.populateMap);
const destroyMap = useMapStore((state) => state.removeMap);
const mapId = useRef();
useEffect(() => {
let theMap = new Map({
layers: [],
view: new View({
center,
zoom,
}),
});
theMap.setTarget(mapId.current);
setMap(theMap);
return () => {
if (!theMap) return;
theMap.setTarget(undefined);
destroyMap();
};
}, []);
return (
<div ref={mapId} className='map'>
{children}
</div>
);
};
After this, we can use <ReMap> Component in App.js file
import "./App.css";
import { ReMap } from "./components/map/map/ReMap";
function App() {
return (
<div className='App'>
<ReMap center={[0,0]} zoom={12} />
</div>
);
}
export default App;
Once this is saved, the react application will look like a blank map
Creating Layers
Layers itself will be just a parent component inside which we can add Layers (Tile layers, vector layer, Image layers,etc.)
I'll start with creating Layer folder inside which I'll create Layers.js which will serve as parent component
import React from "react";
const Layers = ({ children }) => {
return <>{children}</>;
};
export default Layers;
After this we can start creating layers. For the sake of simplicity I'll only create Tile Layer for this blog, but it will give you an idea about how you can create other layers. I'll create a file OlTileLayer.js
import React, { useEffect } from "react";
import TileLayer from "ol/layer/Tile";
import useMapStore from "../zuStore/mapStore";
export const OlTileLayer = ({ source, name }) => {
const map = useMapStore((state) => state.map);
useEffect(() => {
if (!map) return;
let Tlayer = new TileLayer({
source,
name,
});
map.addLayer(Tlayer);
return () => map.removeLayer(Tlayer);
});
return null;
};
Now, to fill the life into this layer, I'll create source. To create it, I'll create a Source folder in components. Inside this folder, I'll create a WMSTile.js
import React from "react";
import TileWMS from "ol/source/TileWMS";
export const WMSTile = (url, params) => {
return new TileWMS({
url,
params,
});
};
Once the source and layer is created, we can use it in App.js to create layer.
import "./App.css";
import Layers from "./components/layers/Layers";
import { OlTileLayer } from "./components/layers/OlTileLayer";
import { OSMLayer } from "./components/layers/OSMLayer";
import { ReMap } from "./components/map/map/ReMap";
import { WMSTile } from "./components/source/WMSTile";
function App() {
return (
<div className='App'>
<ReMap center={[0, 0]} zoom={12}>
<Layers>
<OlTileLayer
source={WMSTile("https://ahocevar.com/geoserver/wms", {
LAYERS: "topp:states",
Tiled: true,
})}
/>
</Layers>
</ReMap>
</div>
);
}
export default App;
This way we can add WMS Tile layer on map
Here is the GitHub Link for code
In the next blog, we'll see how to add following things to the map
Who am I ? ?????
Hi, I'm Krishna Lodha, I'm an open source GIS Developer, Contributor and Content creator. I have my agency?Rotten Grapes Pvt. Ltd.??where we develop Web GIS Applications using Open source stack.?
Apart from development, I upload Videos about such technologies on?YouTube. I upload new blogposts every now and then on this LinkedIn Newsletter. Make sure you Subscribe before you leave ?.
Notice period - 30 days GIS Web Developer / GIS Engineer /React Developer
2 个月Waiting for the next part
ArcGIS Enterprise | ArcGISPro | ArcGIS Web App Builder | Python | Google Earth Engine |Power BI | Openlayers| Geoserver |PostGIS
2 年U told about node js before. Can u share that link
GIS Specialist at Applus Technical Services LLC. Abu Dhabi
2 年There is a react-leaflet package but surprisingly nothing with openlayer. So, very timely to adress this one...
Realtor Associate @ Next Trend Realty LLC | HAR REALTOR, IRS Tax Preparer
2 年Thanks for the updates.
Advanced GIS Analysis for Environmental Conservation
2 年Thanks my big teacher and someone i look upto