Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enable react-leaflet to use be usable offline

I have been using the react-leaflet library, so far it worked well.

Now I wanted the site to pre-load as much of the tiles as possible so that the web-app(also a PWA) could be used w/o internet.

I found some existing solutions(although not dedicated for react)

  • leaflet-offline
  • leaflet.offline

This is what i've tried so far - using leaflet-offline

import React from 'react';
import 'leaflet-offline';

import {
  Map as LeafletMap,
  TileLayer,
  CircleMarker,
  Marker,
  Popup,
} from 'react-leaflet';

import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
import localforage from 'localforage';

const defaultCoords = {
  latitude: 0,
  longitude: 0,
};

export class MapPage extends React.Component {
  constructor(props) {
    super(props);
    this.map = React.createRef();
  }
  componentDidMount() {
    const map = L.map('map');
    const offlineLayer = L.tileLayer.offline(
      'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      localforage,
      {
        attribution:
          '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
        minZoom: 5,
        maxZoom: 20,
        crossOrigin: true,
      },
    );
    // offlineLayer.addTo(this.map); // tried to add to the reference, didn't work
    offlineLayer.addTo(map);
  }
  render() {
    const { latitude, longitude } = this.props.coords || defaultCoords;
    return (
      <LeafletMap
        center={this.props.initialLocation}
        zoom={16}
        // ref={this.map} // tried referencing it also, didn't work
        id="map"
      >
        <TileLayer
          attribution="&copy; <a href=&quot;https://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
          url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
        />
        <CircleMarker center={[latitude, longitude]}>
          <Popup>You are here!</Popup>
        </CircleMarker>
        <Marker
          icon={markerIcon}
          position={newPerson.location || this.props.initialLocation}
          draggable
          onDragEnd={this.props.handleNewPersonPositionChange}
        />
      </LeafletMap>
    );
  }
}

There error on this example says that, map is already initialized

Map container is already initialized.

Is there a way to make one existing solution play well with react-leaflet? Or are there better ways to add offline mode for the PWA?

Any insight would be highly appreciated. Thanks in advance!

like image 773
Theo Avatar asked Oct 15 '18 05:10

Theo


People also ask

Can I use leaflet offline?

Check the master branch for the published 2. x version! This library can be used to create maps, which are still available when you are offline and are fast when your connection is not. It works in the browser or can be used in an mobile app based on html and in progressive webapps.

Can you use leaflet with react?

Leaflet and its React counterpart, React Leaflet, are a fantastic open source and free mapping alternative to Google Maps and MapBox, no API key required! It is an easy package to work with and one worth trying out.

Is react leaflet open source?

In this article, we have learned that React-Leaflet is a great open-source free mapping library alternative to Google Maps and MapBox.


1 Answers

Yeah you'll need to extend react-leaflet's TileLayer class. If you're using V1 that's pretty straightforward. Here's a fiddle: https://jsfiddle.net/q2v7t59h/1965/ Currently it's breaking on the localforage usage (never used that before) so you'll have to fix that. But the crux of defining a createLeafletElement function is still correct.

If you're using react-leaflet V2 then extending TileLayer is a bit more of a pain. Read through https://github.com/PaulLeCam/react-leaflet/issues/506 and you should be able to figure it out. Oh and vote for that issue if you think it deserves attention.

like image 145
jbccollins Avatar answered Oct 04 '22 18:10

jbccollins