maplibre / maplibre-react-native

A MapLibre react native module for creating custom maps
Other
207 stars 51 forks source link

Unable to integrate Ola Maps (Recently Released) #415

Closed dsardar099 closed 1 month ago

dsardar099 commented 1 month ago

Unable to integrate Ola Maps.

Using React Native Expo.

When using https://demotiles.maplibre.org/style.json as styleUrl, everything is working fine.  

import { StyleSheet, Platform, Dimensions } from "react-native";
import ThemedScrollView from "@/components/ThemedScrollView";
import MapLibreGL, { Logger } from '@maplibre/maplibre-react-native';
// MapLibreGL.setConnected(true);
MapLibreGL.setAccessToken(null);

if (Platform.OS !== 'web') {
  const originalFetch = global.fetch;

  global.fetch = async (input, init = {}) => {
    let url;

    if (typeof input === 'string') {
      url = input;
    } else if (input instanceof Request) {
      url = input.url;
    } else if (input instanceof URL) {
      url = input.toString();
    }

    // Replace the wrong URL with the correct one
    console.info("URL", url);
    if (url) {
      url = url.replace("app.olamaps.io", "api.olamaps.io");

      if (url.includes("api.olamaps.io")) {
        // Add the API key to the URL based on existing parameters
        if (url.includes("?")) {
          url += "&api_key={MY_API_KEY}";
        } else {
          url += "?api_key={MY_API_KEY}";
        }
        console.log(input, url);
      }
    }

    const modifiedRequest = new Request(url as any, init);

    return originalFetch(modifiedRequest);
  };
}

export default function HomeScreen() {
  return (
    <ThemedScrollView>
      <MapLibreGL.MapView
        style={styles.map}
        logoEnabled={true}
        // styleURL="https://demotiles.maplibre.org/style.json"
        styleURL="https://api.olamaps.io/tiles/vector/v1/styles/default-light-standard/style.json?api_key={MY_API_KEY}"
      >

        <MapLibreGL.Camera
          zoomLevel={5}
        />
      </MapLibreGL.MapView>
    </ThemedScrollView>
  );
}

const styles = StyleSheet.create({
  page: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  map: {
    flex: 1,
    height: Dimensions.get('window').height,
    alignSelf: 'stretch',
  },
});

Error from console- MapLibre error {mous.myproj}[Setup]: loading style failed: HTTP status code 401 {"level": "error", "message": "{mous.myproj}[Setup]: loading style failed: HTTP status code 401", "tag": "Mbgl"} INFO URL http://192.168.29.132:8081/symbolicate

tenhtof commented 1 month ago

The styleURL has to go through the same transformation similar to the condition block .. that will ensure the other pre-appended params are treated well. url.includes("?")

dsardar099 commented 1 month ago

@tenhtof Can you please help me? What exactly I have to do?

tenhtof commented 1 month ago

You are close. When supplying Ola map URL to the <MapLibreGL.MapView> you need to make sure you use '?' only if there is no prior param added to the URL. If present, use '&' instead. The following code from your own sample should be used before supplying URL to the map tag

      if (url.includes("api.olamaps.io")) {
        // Add the API key to the URL based on existing parameters
        if (url.includes("?")) {
          url += "&api_key={MY_API_KEY}";
        } else {
          url += "?api_key={MY_API_KEY}";
        }
        console.log(input, url);
      }
    }

You may also refer to this page which has similar implementation - https://github.com/tofables/poc.olamaps/blob/main/src/App.js

dsardar099 commented 1 month ago

@tenhtof but we don't have transformRequest props for MapView component

tyrauber commented 1 month ago

You need transformRequest to handle this. Just use React useState or useMemo to add the api_key?

const style_url = React.useMemo(()=> `${url}${ url.includes("?") ? '&' : '?'}api_key=${api_key}`, [url, api_key])

Or, you know, just include the api_key in the styleUrl prop:

style: `https://api.olamaps.io/tiles/vector/v1/styles/default-light-standard/style.json?api_key=${api_key}`,
dsardar099 commented 1 month ago

@tyrauber tried this. Not working.

tyrauber commented 1 month ago

Sorry, @dsardar099, You are correct. You do need transformRequest in order to pass the api-key to the tile server. Unfortunately, that function doesn't exist. Let's close this in favor of ticket #424. In the meantime, the best you can do is copy the content of the style.json from the server, add it to your rn app, and update it to include the api-key, and then pass the json to the styleJSON prop.

dsardar099 commented 1 month ago

Thanks @tyrauber. I will do that for now.