Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native Webview with openlayers

Tags:

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',    } }); 
like image 405
Javier Avatar asked Mar 30 '18 14:03

Javier


People also ask

How do you communicate between WebView and react native?

Import the React Native WebView package in App. js . We will create a normal HTML page in WebView and use “script” tags to let the HTML page communicate with the React Native app. In the “script” tag, we are going to call a sendDataToReactNativeApp() function in which we will use a window property called window.

How do I inject javascript into WebView react native?

Use injectJavaScript as per (Guide > Communicating between JS and Native > The injectJavaScript method)[https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#the-injectjavascript-method"]. In your case, that would be something like this. webview. injectJavaScript(jsCode)

How does react native WebView work?

React Native WebView PropertiesIt simply loads the html of the given url into the app. automaticallyAdjustContentInsets: It manages the content inset for web view which is placed behind a navigation bar or tab bar or toolbar. In case we do not define its value then it will be true.


1 Answers

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:         '&amp;copy <a href=&quot;http://osm.org/copyright&quot;>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).

like image 102
Rafael Barbosa Avatar answered Sep 23 '22 07:09

Rafael Barbosa