maplibre-react-native icon indicating copy to clipboard operation
maplibre-react-native copied to clipboard

Rendering from local .mbtiles file?

Open aLemonFox opened this issue 1 year ago • 6 comments
trafficstars

Is it possible to add a local .mbtiles file onto the map using a <VectorSource>? I was thinking of doing something like this but I couldn't figure out a way to make it work:

const Overlay: FC<OverlayProps> = ({}) => {
   return (
      <VectorSource id={'overlay-layer'} url={'mbtiles://my-file.mbtiles'}>
         <FillLayer props-... />
      </VectorSource>
   );
}

If this is not supported, what are the options to do such a thing without using a remote server?

aLemonFox avatar Feb 19 '24 19:02 aLemonFox

I believe it should be possible, I have done it with the pre-forked version of Mapbox-gl-native. You will have to include the mbtiles file in the bundle somehow. I ended up doing it manually (dragging it into the project in Xcode and android studio) and then used something like react-native-filesystem to get the proper local uri for the file, then fed that into the url prop.

It's been a while so I don't remember some of the exact details, but the hardest part was getting the mbtiles file included in the bundle. I spent a number of hours trying to coax metro into including it with a require, but couldn't make that work, so had to resort to the manual method I mentioned above.

gorbypark avatar Feb 24 '24 16:02 gorbypark

@gorbypark Hm, I don't seem to get it to work using filesystem either. Did you use the .mbtiles file or extract a pbf from it?

aLemonFox avatar Feb 26 '24 14:02 aLemonFox

Hi @aLemonFox check this out https://osmus.slack.com/archives/C065DB4T2UB/p1711978657053129

mohanedmoh avatar May 20 '24 10:05 mohanedmoh

it worked with me

mohanedmoh avatar May 20 '24 10:05 mohanedmoh

@mohanedmoh, please post the context of the slack conversation in question. Unfortunately, the slack history isn't publicly accessible, nor is it long lived. Some mock code with explanations of how you made it work, I am sure that would be appreciated by all. Thanks!

tyrauber avatar May 20 '24 11:05 tyrauber

@tyrauber, @aLemonFox Sure, so you will save the MBtiles locally and load it using <MapLibreGL.RasterSource id="testSource" tileUrlTemplates={["mbtiles:///" + path]} tileSize={512} minZoomLevel={10} maxZoomLevel={14}> <MapLibreGL.RasterLayer id="testLayer" sourceID="testSource" /> </MapLibreGL.RasterSource>

Which is normal RasterSource but with tileURLTemplate of (mbtiles:///path_to_your_mbtiles_file.mbtiles) make sure to change the tileSize based on your MBtile configuration, mine was 512 if it's the wrong tileSize the map will start showing some tiles in dark mode and others in light mode

hope this was helpful

mohanedmoh avatar May 20 '24 11:05 mohanedmoh

Here is an example a put together the other day with expo-asset:

import { MapView } from "@maplibre/maplibre-react-native";
import { useAssets } from "expo-asset";

export function App() {
  const [assets] = useAssets([require("../assets/tiles/maplibre.mbtiles")]);

  if (!assets?.[0]?.localUri) {
    return null;
  }

  return (
    <MapView
      style={{ flex: 1 }}
      mapStyle={{
        name: "MapLibre",
        version: 8,
        sources: {
          mbtiles: {
            url: assets[0].localUri.replace("file://", "mbtiles://"),
            type: "vector",
          },
        },
        layers: [
          {
            id: "background",
            type: "background",
            paint: {
              "background-color": "#285daa",
            },
          },
          {
            id: "countries-fill",
            type: "fill",
            source: "mbtiles",
            "source-layer": "countries",
            paint: {
              "fill-color": "#ffffff",
            },
          },
        ],
      }}
    />
  );
}

Will look, if we can add this to the examples. It's more difficult, because assets are different on Expo and React Native.

KiwiKilian avatar Jan 04 '25 22:01 KiwiKilian