sbqq
sbqq

Reputation: 1111

react-native-maps custom Tiles are not shown

I would like to implement Custom tiles system in my react-native app for offline mode usage. I've implemented the system of downloading and saving custom tiles into my android emulator device. The files does exist at the time of map rendering. My tiles are saved in /data/user/0/com.myapp/files/maps/COUNTRY_CODE/{z}/{x}/{y}.png so for example for Czech, my device folder structure looks like:

/data/user/0/com.myapp/files/maps/CZ/:
  - 4/
    - 8/
      - 5.png
  - 5/
    - 17/
      - 10.png
      - 11.png
  - 6/
    - 34/
      - 21.png
      - 22.png
    - 35/
      - 21.png
      - 22.png
  - 7/
    ...
  - 8/
    ...
  - 9/
    ...
  - 10/
    ...

for tiles download and filesystem management I'm using rn-fetch-blob and unzip/saving is handled by react-native-zip-archive.

My map component looks like:

// this returns /data/user/0/com.myapp/files/maps
const tilesPath = RNFetchBlob.fs.dirs.DocumentDir + "/maps";

// prints to the console that one of the tiles choosed randomly really exists
// maybe I should make more detailed check if every of the tiles exist for testing?
const czMapFound = RNFetchBlob.fs
  .exists(tilesPath + "/CZ/4/8/5.png")
  .then(res => {
     console.log(res);
     return res;
   });

if (czMapFound) {
  // log just to make sure that this branch of statement is executed
  console.log(tilesPath + "/CZ/{z}/{x}/{y}.png");
  return (
    <MapView
      style={styles.map}
      onRegionChange={mapRegion => this.setState({ mapRegion })}
      region={{
        // In this example, map is pointing at Czech Republic correctly
        latitude: selectedMap ? selectedMap.centerX : 52.519325,
        longitude: selectedMap ? selectedMap.centerY : 13.392709,
        latitudeDelta: selectedMap ? selectedMap.sizeX : 50,
        longitudeDelta: selectedMap ? selectedMap.sizeY : 50
      }}
    >
      <LocalTile
        pathTemplate={tilesPath + "/CZ/{z}/{x}/{y}.png"}
        size={256}
      />
    </MapView>
  );
}

My map isn't showing any custom tiles and all I can see are default google maps tiles all over the Czech Republic. I'm not able to make it work.

However, custom tiles are working when I use UrlTile and set the urlTemplate to http://c.tile.openstreetmap.org/{z}/{x}/{y}.png. Maybe I'm just saving tiles to the wrong device's folder and my device cant read files from there?

Note: the tiles are downloaded from openStreetMap service and stored locally by countries.

Upvotes: 4

Views: 5769

Answers (2)

2682562
2682562

Reputation: 139

You are building the path right, however there's an error on the second attribute of LocalTile, you are writing size when it should actually be tileSize.

<LocalTile 
   pathTemplate="/path/to/locally/saved/tiles/{z}/{x}/{y}.png"
   tileSize={256}
   zIndex={-1}
/>

As seen on the official repo of react-native-maps

In any case, I do agree that UrlTile is more straight forward.

Upvotes: 0

sbqq
sbqq

Reputation: 1111

Actually, I figured it out by myself. So if anyone else will encounter this type of problem in a future, I would recommended you to use UrlTile instead of LocalTile even if you are trying to load a custom tiles. Your code will look like:

<MapView
  style={styles.map}
  // keep the reference for region inside your local state..
  onRegionChangeComplete={mapRegion => this.setState({ mapRegion })}
  region={this.state.mapRegion}
 >
   <UrlTile urlTemplate={urlTemplate} zIndex={1} />
 </MapView>

To make it work make sure that your path to the tiles starts with file:// prefix for example const urlTemplate = "file://"+"RNFetchBlob.fs.dirs.DocumentDir"+"/maps/CZ/{z}/{x}/{y}.png"

Upvotes: 1

Related Questions