React Native Webview with openlayers
I have seen this info: https://stackshare.io/stackups/leaflet-vs-mapbox-vs-openlayers
I’m developing at the same time a web application with react using OpenLayers. And I have to make the same app on mobile using react native but I don’t know how to make it works.
Here is my code to web app using React + Openlayers:
import React, { Component } from 'react';
import './App.css';
// openlayers
import View from 'ol/view';
import Projection from 'ol/proj/projection';
import Map from 'ol/map';
import Zoom from 'ol/control/zoom';
import Tile from 'ol/layer/tile';
import OSM from 'ol/source/osm';
class App extends Component {
constructor(props) {
super(props);
this.view = new View({
center: [-41925.302985762304, 4789880.268977703],
zoom: 12,
minZoom: 2,
maxZoom: 28,
projection: new Projection({
code: 'EPSG:3857',
units: 'm'
})
});
}
componentDidMount() {
this.map = new Map({
view: this.view,
controls: [ new Zoom() ],
layers: [new Tile({ source: new OSM() })],
target: 'map'
});
}
render() {
console.log('-> render App')
return (
<div id="map" class="map"></div>
);
}
}
export default App;
And here is my problem, I don’t know how to make it works in react native.
How can you add this.map ( javascript Map object ) inside WebView?
I have seen this example in other question React Native and WMS but I would like to work with React because I need to modify, add layers dynamically, etc.
import React, { Component } from 'react';
import { StyleSheet, View, WebView } from 'react-native';
// openlayers
import View from 'ol/view';
import Projection from 'ol/proj/projection';
import Map from 'ol/map';
import Zoom from 'ol/control/zoom';
import Tile from 'ol/layer/tile';
import OSM from 'ol/source/osm';
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.view = new View({
center: [-41925.302985762304, 4789880.268977703],
zoom: 12,
minZoom: 2,
maxZoom: 28,
projection: new Projection({
code: 'EPSG:3857',
units: 'm'
})
});
}
componentDidMount() {
this.map = new Map({
view: this.view,
controls: [ new Zoom() ],
layers: [new Tile({ name:'tile', source: new OSM() })],
target: 'map'
});
}
render() {
var html="<div id="map" class="map"></div>";
return (
<View style={styles.container}>
<WebView
ref={webview => { this.webview = webview; }}
source={{html}}
onMessage={this.onMessage}/>
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
Well, I’ve been working with ReactJS and Leaflet and I’m quite satisfied. I can integrate leaflet pluggins with React easily, do my own pluggin, add styles, and so on. But if you need to add some kind of map rotation, leaflet will not work, you’ll have to do it.
About the ReactNative issue: you can see this link, its a ‘Webview based Leaflet Component for React Native’.
You can replace the WebView component by this component:
<WebViewLeaflet
ref={(component) => (this.webViewLeaflet = component)}
onLoad={this.onLoad}
eventReceiver={this} // the component that will receive map events
/>
And add a function named onLoad to load the layers:
onLoad = (event) => {
// log a message showing the map has been loaded
console.log('onLoad received : ', event);
//example of array of layers
const mapLayers = [
{
name: 'streets', // the name of the layer, this will be seen in the layer selection control
checked: 'true', // if the layer is selected in the layer selection control
type: 'TileLayer', // the type of layer as shown at https://react-leaflet.js.org/docs/en/components.html#raster-layers
baseLayer: true,
// url of tiles
url: `https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=${mapboxToken}`,
// attribution string to be shown for this layer
attribution:
'&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}
]
// set state
this.setState(
{
...this.state,
mapState: { ...this.state.mapState, mapLoaded: true }
},
() => {
// send an array of map layer information to the map
this.webViewLeaflet.sendMessage({
mapLayers
});
}
);
}
If you need to add some Google map tiles or map data from Open Street Maps it will not work. If this is your case, you can try that link, (I never used it, is just a sugestion).
This is a bit outdated question, but since it has still active voting let’s take a closer look. I would recommend you to use react-native-maps, since it’s broadly supported with nice documentation. Other 3rd party libraries like react-native-webview-leaflet has a bit less flexibility.