Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/giulioz/react-ol-fiber

πŸ—ΊοΈβš›οΈ A React renderer for OpenLayers
https://github.com/giulioz/react-ol-fiber

gis maps openlayers react wrapper

Last synced: 4 days ago
JSON representation

πŸ—ΊοΈβš›οΈ A React renderer for OpenLayers

Lists

README

        

# react-ol-fiber

[![Version](https://img.shields.io/npm/v/react-ol-fiber)](https://npmjs.com/package/react-ol-fiber)
[![Downloads](https://img.shields.io/npm/dt/react-ol-fiber.svg)](https://npmjs.com/package/react-ol-fiber)
[![Test](https://github.com/giulioz/react-ol-fiber/actions/workflows/test.yml/badge.svg)](https://github.com/giulioz/react-ol-fiber/actions/workflows/test.yml)

react-ol-fiber is a React renderer for OpenLayers.

Build your maps declaratively with re-usable, self-contained components that react to state, are readily interactive and can participate in React's ecosystem.

```bash
npm install ol react-ol-fiber
```

Being a renderer and not a wrapper it's not tied to a specific version of OpenLayers, and allows easy extensibility.

## Quick Start Code

[![Edit react-ol-fiber-qs](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-ol-fiber-qs-32s5j?fontsize=14&hidenavigation=1&theme=dark&view=preview)

```tsx
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import { MapComponent } from 'react-ol-fiber';
import 'ol/ol.css';

function Shapes() {
const [active, setActive] = useState(false);
useEffect(() => {
const interval = setInterval(() => setActive(a => !a), 500);
return () => clearInterval(interval);
}, []);

return (





{new Array(32 * 32).fill(0).map((_, i) => (



))}


);
}

function App() {
return (






);
}

ReactDOM.render(, document.getElementById('root'));
```

## Docs

### The MapComponent component

The most important component in react-ol-fiber is `` it instantiate an OpenLayer `Map` object and mounts it in a full-width and full-height div. As children you can provide OpenLayer elements that can be mounted inside the map, such as layers, controls and interactions.

```tsx
function App() {
return (





);
}
```

### Using OpenLayers classes

To create instances of OpenLayers classes in react-ol-fiber you can use JSX primitives. As component name, use the original class name with the first letter in lower case, followed by its category.

To provide arguments to the class constructor use the `args` prop, or `arg` if the constructor has a single parameter. To attach the children to the parent you can use the `attach` and `attachAdd` props (even though they are inferred automatically whenever possible by the reconciler).

Some examples:

```tsx
function Component() {
return (
<>
{/* ol/Feature */}
{/* ol/layers/Tile */}
{/* ol/layers/Vector */}
{/* ol/geom/Circle */}
{/* ol/geom/Point */}
{/* ol/geom/Point */}
{/* ol/style/Style */}
{/* ol/style/Stroke */}
>
);
}
```

### Props

The props are applied using the setters found in the target object. The reconciler is optimized to call only the setters of the modified values.

```tsx
function Component() {
// This will call setOpacity in the VectorLayer
return ;
}
```

### Event handlers

All the events described in the OpenLayers documentation are capitalized and prefixed with "on".

```tsx
function Component() {
// This will set the 'select' event
return console.log(e)} />;

// This will set the 'change' event
return console.log(e)} />;

// It also works on the map component!
return console.log(e.coordinate)} />;
}
```

### Hooks

Whenever you need to access the underlying OpenLayers map instance, you can use the `useOL()` hook. Remember that this can work only inside a component that is child of a MapComponent. :warning:

```tsx
function Inner() {
const { map } = useOL();
function centerOnFeatures(extent: number[]) {
const view = map.getView();
view.fit(extent);
}

return (

centerOnFeatures(e.target.getExtent())}>





);
}

function Parent() {
// WARNING: you can't use useOL() here
return (



);
}
```

### Spring Animation

Provisional [react-spring](https://react-spring.io/) support is available! You can use the spring api to animate your maps, using the `a.` components. See [this example](https://github.com/giulioz/react-ol-fiber/blob/main/example/src/examples/Spring.tsx) to see how.

### Using primitives

If you want to use your own already instanced objects, you can use the `olPrimitive` wrapper and set a custom attach:

```tsx
function Component() {
const features = myLoadFeatures();
return (

{features.map((feature, i) => (

))}

);
}
```

:warning: Using the `` instrinsic the props will not be checked. To have a generic primitive component, based on the `object` prop type, use the `` wrapper instead.

### Using functions

Sometimes in OpenLayers it's convenient to use a function for some objects, such as style functions, to avoid creating too many objects.

```tsx
function Component() {
return (

new Style({ fill: new Fill({ color: feature.get('color') }) })} attach='style' />

{/* OR */}

(



)}
attach='style'
/>







);
}
```

:warning: Please note that the second option, using JSX, does NOT use React to render the elements, it manually creates instances reading the JSX. Please use it with caution and DON'T use components in there.

### Extending the catalogue

To extend the available components reachable by react-ol-fiber, you can use the `extend()` command. You can even implement your own props application logic using setters!

```tsx
import BaseLayer from 'ol/layer/Base';
class MyLayer extends BaseLayer {
constructor(args: { ctorArg: boolean }) {
super({});
}

setMyNumber(value: number) {
console.log(value);
}
}

import { extend, MapComponent, TypeOLCustomClass } from 'react-ol-fiber';
extend({ MyLayer: MyLayer as any });
declare global {
namespace JSX {
interface IntrinsicElements {
myLayer: TypeOLCustomClass;
}
}
}

function Test() {
return (



);
}
```

## FAQ

### I'm not seeing my map and the entire page is blank

You need to add make your parent DOM elements full-height:

```css
html,
body,
#root {
width: 100%;
height: 100%;
margin: 0;
}
```

## Credits

This library was strongly inspired by react-three-fiber and the technical details given by this amazing article by Cody Bennet.