A React wrapper for OpenLayers providing easy-to-use components for map integration.
# npm
npm install @essercodes/r-ol ol
# yarn
yarn add @essercodes/r-ol ol
# pnpm
pnpm add @essercodes/r-ol ol
import {fromLonLat} from 'ol/proj';
import {Map, View, TargetDiv, Overlay} from '@essercodes/r-ol';
import {TileLayer} from '@essercodes/r-ol/layer';
import {ImageTileSource} from '@essercodes/r-ol/source';
import 'ol/ol.css'; // Important! Import the OpenLayers CSS in your application
const lonLat = fromLonLat([-89.38, 43.07])
export function MyMap() {
return (
<Map>
<TargetDiv style={{height: '100svh', width: '100svw'}}/>
<View zoom={12} center={lonLat}/>
<Overlay position={lonLat}>
<h1 style={{color: 'black'}}>HELLO WORLD</h1>
</Overlay>
<TileLayer>
<ImageTileSource
url={'https://tile.openstreetmap.org/{z}/{x}/{y}.png'}
attributions={"Map data from OpenStreetMap"}
/>
</TileLayer>
</Map>
);
}
export default React.memo(MyMap);
- Remember to import OpenLayers CSS in your application:
import 'ol/ol.css';
- This library uses OpenLayers as a peer dependency, so you need to install it separately.
import React from 'react';
const LazyMyMap = React.lazy(() => import('~/components/MyMap'));
export function ServerSideComponentWithMap() {
return (
<React.Suspense fallback={<div style={{width: '100%', height:'50dvh'}}>Loading...</div>}>
<SafeHydrate>
<LazyMyMap
zoom={zoom} lon={lon} lat={lat}
accessKey={accessKey}
style={{width: '100%', height:'50dvh'}}
/>
</SafeHydrate>
</React.Suspense>
);
}
function SafeHydrate({children}: React.PropsWithChildren) {
return (
<div suppressHydrationWarning>
{typeof window === 'undefined' ? null : children}
</div>
);
}
The main container for your map.
<Map>
{/* Map components */}
</Map>
Controls the map view.
<View
center={fromLonLat([longitude, latitude])}
zoom={zoom}
/>
Layer component that contains other layers.
<LayerGroup>
{/*Layer Components*/}
</LayerGroup>
A standard tile layer.
<TileLayer>
{/* Source Component */}
</TileLayer>
A standard vector tile layer.
<VectorTileLayer>
<VectorTileSource />
</VectorTileLayer>
Creates a div element that serves as the map container.
<TargetDiv style={{height: '100svh', width: '100svw'}} />
Adds html elements to the map at a coordinate.
<Overlay position={fromLonLat([lon, lat])}>
{/* Displayed Element */}
</Overlay>
<ImageTileSource
url={'https://tile.openstreetmap.org/{z}/{x}/{y}.png'}
attributions={"Map data from OpenStreetMap"}
/>
<VectorTileSource
attributions={
'© <a href="https://www.mapbox.com/map-feedback/">Mapbox</a> ' +
'© <a href="https://www.openstreetmap.org/copyright">' +
'OpenStreetMap contributors</a>'}
url={'https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/' +
'{z}/{x}/{y}.mvt?access_token=' + YOUR_MAPBOX_API_KEY}
initialOptions={{format: new MVT()}}
/>
Many components represent OpenLayers objects. If a represented object inherits from a parent, then you can use the hooks provided by the component representing the parent. For example, all components can use Observable's component hooks because all objects inherit from Observable.
Hooks that return an array follow the useState
convention and "name state variables like
[something, setSomething] using array destructuring." Like useState
'something' returns an
immutable snapshot, and setSomething accepts a value or and updater function. The updater function
will immediately pull the current value from the object.
Component props will override properties set in hooks.
https://react.dev/reference/react/useState
Hooks for the closest parent component BaseLayer
or any component derived from it.
import {
useBaseLayer, useBaseLayerMaxResolution, useBaseLayerMaxZoom, useBaseLayerMinResolution,
useBaseLayerMinZoom, useBaseLayerOpacity, useBaseLayerVisible, useBaseLayerZIndex
} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent BaseLayer component
const baseLayer = useBaseLayer();
// Set properites of the closest parent BaseLayer component
const [maxResolution, setMaxResolution] = useBaseLayerMaxResolution();
const [maxZoom, setMaxZoom] = useBaseLayerMaxZoom();
const [minResolution, setMinResolution] = useBaseLayerMinResolution();
const [minZoom, setMinZoom] = useBaseLayerMinZoom();
const [opacity, setOpacity] = useBaseLayerOpacity();
const [visibility, setVisibility] = useBaseLayerVisible();
const [zIndex, setZIndex] = useBaseLayerZIndex();
Hooks for the closest parent component Layer
or any component derived from it.
import {useLayer, useLayerSource} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent Layer component
const baseLayer = useLayer();
// Set properites of the closest parent Layer component
const [source, setSource] = useLayerSource();
Hooks for the closest parent component LayerGroup
or any component derived from it. If there is no
parent LayerGroup
component this will represent the Map
components layer group.
import {useLayerGroup, useLayerGroupArray} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent LayerGroup component
const layerGroup = useLayerGroup();
// Set properites of the closest parent LayerGroup component
const [layerGroupArray, setLayerGroupArray] = useLayerGroupArray();
Hooks for the closest parent component Map
or any component derived from it.
import {useMap, useMapLayerGroup, useMapSize, useMapTarget, useMapView} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent Map component
const map = useMap();
// Set properites of the closest parent Map component
const [mapLayerGroup, setMapLayerGroup] = useMapLayerGroup();
const [size, setSize] = useMapSize();
const [target, setTarget] = useMapTarget();
const [view, setView] = useMapView();
Hooks for the closest parent component Observable
or any component derived from it.
import {useObservable, useRevision} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent LayerGroup component
const observable = useObservable();
// Get the revision count, and call the changed() function to increment the revision count.
const [revision, changed] = useRevision();
Hooks for the closest parent component VectorSource
or any component derived from it.
import {useVectorSource} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent VectorSource component.
const vectorSource = useVectorSource();
Hooks for the closest parent component View
or any component derived from it.
import {useView, useViewCenter, useViewResolution, useViewRotation} from "@essercodes/r-ol/context";
// Access the object represented by the closest parent View component
const view = useView();
// Set properites of the closest parent View component
const [viewCenter, setViewCenter] = useViewCenter();
const [viewResolution, setViewResolution] = useViewResolution();
const [viewRotation, setViewRotation] = useViewRotation();
MIT