最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Mapbox React Native: Black screen when device is offline - Stack Overflow

programmeradmin0浏览0评论

I am working on a react native application that uses Mapbox React Native SDK. The app requires a feature to display maps offline. The SDK has an example on how to implement offline maps functionality: offline example. The offline map appears to work when you turn off the internet WHILE browsing the app. However, when I exit the app, turn off the internet connection and then start a fresh app session, I get a black screen instead of the downloaded maps.

I have submitted an issue on the SDK's repository but I haven't gotten a response from the maintainers. This feature is very important and needs to work.

The following code shows a snippet of how I implemented the offline maps in the app:

import React, { useState, useRef } from 'react';
import { View, TouchableOpacity, Platform, Dimensions, Alert } from 'react-native';
import Mapbox from '@rnmapbox/maps';
import geoViewport from '@mapbox/geo-viewport';

const MAPBOX_VECTOR_TILE_SIZE = 512;

const Home = () => {
  const mapRef = useRef(null);
  const cameraRef = useRef(null);
  const [followUserLocation, setFollowUserLocation] = useState(true);
  const [userLocation, setUserLocation] = useState([-80.1918, 25.7617]);
  const [showBasemapSelector, setShowBasemapSelector] = useState(false);
  const [rotation, setRotation] = useState(0);
  const [centerToDisplay, setCenterToDisplay] = useState([-80.1918, 25.7617]);

  const startDownload = async () => {
    const {width, height} = Dimensions.get('window');

    const region = {
      name: "Region",
      styleURL: "selectedStyle.url",
      bounds: geoViewport.bounds(
        centerToDisplay,
        12,
        [width, height],
        MAPBOX_VECTOR_TILE_SIZE,
      ),
      minZoom: 1,
      maxZoom: 16,
    };

    try {
      const pack = await Mapbox.offlineManager.createPack(
        {
          name: region.name,
          styleURL: region.styleURL,
          bounds: [
            [region.bounds[0], region.bounds[1]],
            [region.bounds[2], region.bounds[3]],
          ],
          minZoom: region.minZoom,
          maxZoom: region.maxZoom,
          metadata: {},
        },
      );
    } catch (error) {
      console.error('Error downloading region:', error);
      Alert.alert(
        'Download Failed',
        'Please try selecting a smaller area or check your internet connection.',
      );
    } finally {
    }
  };

  const handleCameraChanged = (event) => {
    setRotation(event.properties.heading);
    setCenterToDisplay(event.properties.center);
  };

  const resetNorth = () => {
    cameraRef.current?.setCamera({
      heading: 0,
      animationDuration: 500,
    });
  };

  const zoomIn = () => {
    cameraRef.current?.zoomTo(cameraRef.current?.getZoom() + 1, 500);
  };

  const zoomOut = () => {
    cameraRef.current?.zoomTo(cameraRef.current?.getZoom() - 1, 500);
  };

  return (
    <View style={styles.page}>
      <Mapbox.MapView
        onPress={() => setShowBasemapSelector(false)}
        attributionEnabled={false}
        ref={mapRef}
        style={styles.map}
        styleJSON={JSON.stringify({ /* style json object */})}
        logoEnabled={false}
        scaleBarEnabled={true}
        scaleBarPosition={{
          bottom: 45,
        }}
        onTouchMove={() => followUserLocation && setFollowUserLocation(false)}
        onCameraChanged={handleCameraChanged}>
        <Mapbox.UserLocation
          visible={true}
          animated={true}
          minDisplacement={10}
          showsUserHeadingIndicator={true}
          requestsAlwaysUse={true}
          onUpdate={loc => {
            if (followUserLocation) {
              setUserLocation([loc?.coords?.longitude, loc?.coords.latitude]);
            }
          }}
        />
        <Mapbox.Camera
          maxZoomLevel={19}
          minZoomLevel={0}
          ref={cameraRef}
          centerCoordinate={userLocation || [-80.1918, 25.7617]}
          defaultSettings={{
            centerCoordinate: userLocation,
            zoomLevel: 8,
            animationDuration: 1,
          }}
          allowUpdates={true}
          animationMode="flyTo"
        />
      </Mapbox.MapView>

      {/* Compass */}
      <TouchableOpacity
        activeOpacity={0.8}
        style={stylespass}
        onPress={resetNorth}>
      </TouchableOpacity>

      {/* Zoom controls */}
      <View style={styles.zoomControls}>
        <TouchableOpacity style={styles.zoomButton} onPress={zoomIn}>
        </TouchableOpacity>
        <TouchableOpacity style={styles.zoomButton} onPress={zoomOut}>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  page: {
    flex: 1,
  },
  map: {
    flex: 1,
  },
  compass: {
    position: 'absolute',
    top: 20,
    right: 20,
    backgroundColor: 'white',
    borderRadius: 20,
    padding: 8,
    elevation: 5,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
  },
  zoomControls: {
    position: 'absolute',
    right: 20,
    bottom: 100,
    backgroundColor: 'white',
    borderRadius: 10,
    elevation: 5,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
  },
  zoomButton: {
    padding: 10,
  },
});

export default Home;

I have found a similar issue in the Mapbox Flutter SDK: issue. This issue seems to have been resolved and I wonder if someone can help point me towards solving the issue in the Mapbox React Native SDK.

发布评论

评论列表(0)

  1. 暂无评论