Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Offline pack not visible in mapview when device is offline #3790

Open
sahni01 opened this issue Feb 24, 2025 · 3 comments
Open

[Bug]: Offline pack not visible in mapview when device is offline #3790

sahni01 opened this issue Feb 24, 2025 · 3 comments
Labels
bug 🪲 Something isn't working

Comments

@sahni01
Copy link

sahni01 commented Feb 24, 2025

Mapbox Implementation

Mapbox

Mapbox Version

default

React Native Version

0.76.0

Platform

Android

@rnmapbox/maps version

10.1.36

Standalone component to reproduce

import React, { useCallback, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import {
  View,
  Text,
  TextInput,
  StyleSheet,
  FlatList,
  Modal,
  Pressable,
  Alert,
  TouchableOpacity,
  ToastAndroid,
  KeyboardAvoidingView,
  Dimensions,
  Image,
} from 'react-native';
import Mapbox from '@rnmapbox/maps';
import { useFocusEffect } from '@react-navigation/native';
import IonIcons from 'react-native-vector-icons/Ionicons';
import Geolocation from '@react-native-community/geolocation';
import { Picker } from '@react-native-picker/picker';

const MAPBOX_API_KEY = 'API_KEY';
const MAPBOX_SATELITE_STYLE = 'mapbox://styles/mapbox/satellite-streets-v12';
const MAPBOX_OUTDOOR_STYLE = 'mapbox://styles/mapbox/outdoors-v12';

Mapbox.setAccessToken(MAPBOX_API_KEY);

const MapRegionCaching = () => {
  const [offlineRegions, setOfflineRegions] = useState([]);
  const [isModalVisible, setModalVisible] = useState(false);
  const [regionName, setRegionName] = useState('');
  const [isDownloading, setIsDownloading] = useState(false);
  const [downloadProgress, setDownloadProgress] = useState(0);
  const [centerCoordinates, setCenterCoordinates] = useState();
  const [selectedRegion, setSelectedRegion] = useState();
  const [selectedMap, setSelectedMap] = useState();
  const [selectedMapStyle, setSelectedMapStyle] = useState(MAPBOX_OUTDOOR_STYLE);
  const [showMap, setShowMap] = useState(false);
  const mapCameraRef = useRef();
  const [mapStyle, setMapStyle] = useState(MAPBOX_OUTDOOR_STYLE);
  const [zoomLevel, setZoomLevel] = useState(12);
  const [zoomOpen, setZoomOpen] = useState(false);

  const zoomLevels = Array.from({ length: 23 }, (_, i) => ({
    label: `Zoom Level ${i}${i === 12 ? ' (Standard)' : ''}`,
    value: i,
  }));

  // Save a new offline region
  const saveOfflineRegion = async () => {
    if (!regionName.trim() || !selectedRegion) {
      Alert.alert('Error', 'A region name is required and region is required to be saved.');
      return;
    }

    const isExists = offlineRegions.find(
      (item) => item?.metadata?.name === regionName
    );

    if (isExists) {
      ToastAndroid.show('Duplicate Region Name', ToastAndroid.SHORT);
      return;
    }

    console.log('Creating offline ...');
    try {
      setModalVisible(false);
      setIsDownloading(true);
      ToastAndroid.show('Starting Download...', ToastAndroid.SHORT);
      Mapbox.offlineManager.setTileCountLimit(9999999);
      const offlineRegion = await Mapbox.offlineManager.createPack(
        {
          bounds: selectedRegion,
          name: regionName,
          minZoom: 18,
          maxZoom: 20,
          styleURL: mapStyle,
        },
        (progress) => {
          console.log('PROGRESS ====> ', progress);
          progress.status().then((value) => {
            console.log('STATUS ====> ', value);
            setDownloadProgress(value.percentage.toFixed(2));
            if (value.percentage === 100) {
              setIsDownloading(false);
              setDownloadProgress(0);
              ToastAndroid.show('Downloaded Successfully', ToastAndroid.SHORT);
              setRegionName('');
              setZoomLevel(12);
              setSelectedRegion();
              loadOfflineMaps();
            }
          });
        },
        (error) => {
          Mapbox.offlineManager.deletePack(regionName);
          console.log('DOWNLOAD_ERROR ====> ', error);
          setIsDownloading(false);
          setDownloadProgress(0);
          setModalVisible(true);
          ToastAndroid.show("Couldn't Download! please try smaller regions", ToastAndroid.LONG);
          error.status().then((value) => {
            console.log('ERROR_STATUS ====> ', value);
          });
        }
      );

      console.log('OFFLINE REGION ====> ', offlineRegion);
    } catch (error) {
      Mapbox.offlineManager.deletePack(regionName);
      ToastAndroid.show(error.toString(), ToastAndroid.SHORT);
      console.log('ERROR ====> ', error);
    }
  };

  const loadOfflineMaps = async () => {
    try {
      const offlineMaps = await Mapbox.offlineManager.getPacks();
      setOfflineRegions(offlineMaps);
      console.log('OFFLINE_MAPS ===> ', JSON.stringify(offlineMaps));
    } catch (error) {
      console.log('ERROR ====> ', error.toString());
    }
  };

  const cancelDownload = async (packName) => {
    try {
      const deletedPack = await Mapbox.offlineManager.deletePack(packName);
      console.log('CANCELLED_DOWNLOAD ====> ', deletedPack);
      ToastAndroid.show('Download Cancelled', ToastAndroid.SHORT);
      setIsDownloading(false);
      setDownloadProgress(0);
      setModalVisible(true);
    } catch (error) {
      ToastAndroid.show("Couldn't Cancel Download", ToastAndroid.SHORT);
      console.log('ERROR ===> ', error);
    }
  };

  const deleteMap = async (packName) => {
    try {
      const deletedPack = await Mapbox.offlineManager.deletePack(packName);
      console.log('MAP_DELETED ====> ', deletedPack);
      ToastAndroid.show(packName + ' Deleted', ToastAndroid.SHORT);
      loadOfflineMaps();
    } catch (error) {
      ToastAndroid.show("Couldn't Delete " + packName, ToastAndroid.SHORT);
      console.log('ERROR ===> ', error);
    }
  };

  useFocusEffect(
    useCallback(() => {
      Geolocation.getCurrentPosition((info) => {
        console.log(info);
        setCenterCoordinates([info.coords.longitude, info.coords.latitude]);
      });
      loadOfflineMaps();
    }, [])
  );

  const rectangleGeoJSON = {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        geometry: selectedMap?._metadata?._rnmapbox?.bounds,
        properties: {},
      },
    ],
  };

  // Render saved offline regions
  const renderOfflineRegion = ({ item }) => (
    <View style={styles.regionItem}>
      <View style={styles.regionItemContainer}>
        <View style={styles.infoContainer}>
          <IonIcons name="map" size={40} color="#4CAF50" style={styles.icon} />
          <View style={styles.textContainer}>
            <Text style={styles.regionName}>
              {item?.metadata?.name || 'Unknown Region'}
            </Text>
            <Text style={styles.regionInfo}>
              Expires on: {item?.pack?.expires}
            </Text>
          </View>
        </View>
        <View style={styles.actionIcons}>
          <TouchableOpacity
            onPress={() => {
              console.log('SELECTED_MAP ====> ', JSON.stringify(item));
              setSelectedMap(item);
              setShowMap(true);
              setTimeout(() => {
                mapCameraRef?.current?.fitBounds(
                  [item?.pack?.bounds[0], item?.pack?.bounds[1]],
                  [item?.pack?.bounds[2], item?.pack?.bounds[3]],
                  [50, 50],
                  2000
                );
              }, 1000);
            }}
            style={styles.iconButton}
          >
            <IonIcons name="eye" size={24} color="#4CAF50" />
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => deleteMap(item?.metadata?.name)}
            style={styles.iconButton}
          >
            <IonIcons name="trash" size={24} color="#F44336" />
          </TouchableOpacity>
        </View>
      </View>
    </View>
  );

  return (
    <View style={styles.container}>
      {/* List of Offline Regions */}
      <FlatList
        data={offlineRegions}
        renderItem={renderOfflineRegion}
        keyExtractor={(item, index) => index.toString()}
        contentContainerStyle={styles.regionList}
        ListEmptyComponent={
          <Text style={styles.emptyText}>No offline regions saved.</Text>
        }
      />

      {/* Floating Action Button */}
      <TouchableOpacity
        style={styles.fab}
        onPress={() => setModalVisible(true)}
      >
        <Text style={styles.fabText}>+</Text>
      </TouchableOpacity>

      <ProgressModal
        title="Downloading"
        progress={downloadProgress}
        cancelButtonTitle="Cancel Download"
        visible={isDownloading}
        onCancelPress={() => cancelDownload(regionName)}
      />

      <Modal
        visible={showMap}
        animationType="slide"
        transparent={true}
        onRequestClose={() => setShowMap(false)}
      >
        <KeyboardAvoidingView style={{ flex: 1 }}>
          <View style={styles.modalBackground}>
            <View style={styles.modalContent}>
              <Text style={styles.modalHeader}>View Offline Map</Text>
              <View style={styles.mapContainer}>
                <Mapbox.MapView
                  logoEnabled={false}
                  attributionEnabled={false}
                  style={{ ...styles.map, width: '100%', borderWidth: 0 }}
                  styleURL={selectedMap?._metadata?._rnmapbox?.styleURI}
                >
                  <Mapbox.Camera
                    animationDuration={2000}
                    zoomLevel={12}
                    ref={mapCameraRef}
                    bounds={{
                      ne: [
                        selectedMap?.pack?.bounds[0],
                        selectedMap?.pack?.bounds[1],
                      ],
                      sw: [
                        selectedMap?.pack?.bounds[2],
                        selectedMap?.pack?.bounds[3],
                      ],
                    }}
                  />
                  <Mapbox.ShapeSource id="rectangleSource" shape={rectangleGeoJSON}>
                    <Mapbox.FillLayer
                      id="rectangleFill"
                      style={{
                        fillColor: 'rgba(0, 150, 200, 0.5)',
                        fillOutlineColor: 'rgba(0, 150, 200, 1)',
                      }}
                    />
                  </Mapbox.ShapeSource>
                </Mapbox.MapView>
              </View>
              <View style={styles.modalActions}>
                <Pressable
                  style={[styles.modalButton, styles.cancelButton]}
                  onPress={() => {
                    setShowMap(false);
                    setSelectedMap();
                  }}
                >
                  <Text style={styles.buttonText}>Close</Text>
                </Pressable>
              </View>
            </View>
          </View>
        </KeyboardAvoidingView>
      </Modal>

      {/* Modal for Adding Offline Region */}
      <Modal
        visible={isModalVisible}
        animationType="slide"
        transparent={true}
        onRequestClose={() => setModalVisible(false)}
      >
        <KeyboardAvoidingView style={{ flex: 1 }}>
          <View style={styles.modalBackground}>
            <View style={styles.modalContent}>
              <Text style={styles.modalHeader}>Add Offline Region</Text>
              <View
                style={{
                  width: '100%',
                  flexDirection: 'row',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  marginBottom: 16,
                }}
              >
                <TextInput
                  style={[
                    styles.input,
                    {
                      width: '75%',
                      height: '100%',
                    },
                  ]}
                  placeholder="Region Name"
                  value={regionName}
                  onChangeText={setRegionName}
                />
                <View style={[styles.input, { width: '24%', height: 'auto' }]}>
                  <Picker
                    selectedValue={zoomLevel}
                    onValueChange={(itemValue) => setZoomLevel(itemValue)}
                    style={{ padding: 0 }}
                    placeholder="Zoom Level"
                  >
                    {zoomLevels.map((z) => (
                      <Picker.Item
                        key={`zoom-level-${z.value}`}
                        label={z.label}
                        value={z.value}
                      />
                    ))}
                  </Picker>
                </View>
              </View>
              <Text style={styles.label}>
                Select Map Region (Zoom and Pan to set region visible. Map area will be saved for offline use.)
              </Text>
              <View style={styles.mapContainer}>
                <TouchableOpacity
                  style={styles.mapStyle2}
                  onPress={() => {
                    if (mapStyle === MAPBOX_OUTDOOR_STYLE) {
                      setMapStyle(MAPBOX_SATELITE_STYLE);
                    } else {
                      setMapStyle(MAPBOX_OUTDOOR_STYLE);
                    }
                  }}
                >
                  {mapStyle === MAPBOX_OUTDOOR_STYLE ? (
                    <Image
                      source={require('../../assets/satellite_map_icon.png')}
                      style={styles.mapStyleIcon}
                    />
                  ) : (
                    <Image
                      source={require('../../assets/street_map_icon.png')}
                      style={styles.mapStyleIcon}
                    />
                  )}
                </TouchableOpacity>
                <Mapbox.MapView
                  logoEnabled={false}
                  attributionEnabled={false}
                  style={styles.map}
                  styleURL={mapStyle}
                  onRegionDidChange={(state) => {
                    setSelectedRegion(state.properties.visibleBounds);
                    console.log(
                      'MAP REGION CHANGED ====> ',
                      JSON.stringify(state.properties)
                    );
                  }}
                >
                  <Mapbox.Camera
                    zoomLevel={12}
                    centerCoordinate={centerCoordinates}
                  />
                </Mapbox.MapView>
              </View>
              <View style={styles.modalActions}>
                <Pressable
                  style={[styles.modalButton, styles.cancelButton]}
                  onPress={() => {
                    setModalVisible(false);
                    setRegionName('');
                    setZoomLevel(12);
                    setSelectedRegion();
                  }}
                >
                  <Text style={styles.buttonText}>Cancel</Text>
                </Pressable>
                <Pressable style={styles.modalButton} onPress={saveOfflineRegion}>
                  <Text style={styles.buttonText}>Save</Text>
                </Pressable>
              </View>
            </View>
          </View>
        </KeyboardAvoidingView>
      </Modal>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5F5F5',
  },
  regionList: {
    paddingHorizontal: 16,
    paddingBottom: 80,
  },
  regionItemContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  regionItem: {
    backgroundColor: '#fff',
    padding: 10,
    marginVertical: 8,
    borderRadius: 8,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  infoContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    flex: 1,
  },
  icon: {
    marginRight: 10,
  },
  textContainer: {
    flex: 1,
  },
  regionName: {
    fontSize: 16,
    fontWeight: 'bold',
    color: '#212121',
  },
  regionInfo: {
    fontSize: 14,
    color: '#757575',
    marginTop: 4,
  },
  actionIcons: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  iconButton: {
    marginHorizontal: 8,
  },
  label: {
    fontSize: 18,
    color: '#757575',
    marginTop: 4,
    marginBottom: 8,
    textAlign: 'center',
  },
  emptyText: {
    textAlign: 'center',
    marginTop: 20,
    fontSize: 16,
    color: '#757575',
  },
  fab: {
    position: 'absolute',
    right: 20,
    bottom: 30,
    backgroundColor: '#4CAF50',
    width: 56,
    height: 56,
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    elevation: 5,
  },
  fabText: {
    fontSize: 30,
    color: '#FFF',
    fontWeight: 'bold',
  },
  modalBackground: {
    height: Dimensions.get('window').height,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
  },
  modalContent: {
    width: '90%',
    backgroundColor: '#FFF',
    padding: 16,
    borderRadius: 8,
    elevation: 4,
  },
  modalHeader: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#212121',
    marginBottom: 16,
    textAlign: 'left',
  },
  input: {
    height: 48,
    borderWidth: 1,
    borderColor: '#BDBDBD',
    borderRadius: 4,
    paddingHorizontal: 12,
    backgroundColor: '#FAFAFA',
  },
  mapContainer: {
    height: 400,
    width: '100%',
    borderRadius: 8,
    marginBottom: 16,
    overflow: 'hidden',
    justifyContent: 'center',
    alignItems: 'center',
    position: 'relative',
  },
  map: {
    flex: 1,
    height: 400,
    width: 400,
    borderWidth: 5,
    borderColor: '#4CAF50',
    position: 'relative',
  },
  mapStyle2: {
    position: 'absolute',
    bottom: 20,
    right: 220,
    width: 70,
    height: 70,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 2,
    borderRadius: 10,
    overflow: 'hidden',
    zIndex: 1,
  },
  mapStyleIcon: {
    width: 70,
    height: 70,
  },
  modalActions: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  modalButton: {
    flex: 1,
    backgroundColor: '#4CAF50',
    paddingVertical: 12,
    borderRadius: 4,
    alignItems: 'center',
    marginHorizontal: 4,
  },
  cancelButton: {
    backgroundColor: '#757575',
  },
  buttonText: {
    color: '#FFF',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

export default MapRegionCaching;

const ProgressModal = ({
  visible,
  progress,
  onClose,
  cancelButtonTitle,
  onCancelPress,
  title,
}) => {
  return (
    <Modal
      transparent
      animationType="slide"
      visible={visible}
      onRequestClose={onClose}
    >
      <View style={styles1.modalBackground}>
        <View style={styles1.modalContainer}>
          <Text style={styles1.modalTitle}>{title}</Text>
          <View style={styles1.progressContainer}>
            <View style={styles1.progressBar}>
              <View
                style={[styles1.progressFill, { width: `${progress}%` }]}
              />
            </View>
            <Text style={styles1.progressText}>{`${progress}%`}</Text>
          </View>
          <View style={styles1.buttonContainer}>
            <TouchableOpacity
              style={[styles1.button, styles1.cancelButton]}
              onPress={onCancelPress}
            >
              <Text style={styles1.buttonText}>{cancelButtonTitle}</Text>
            </TouchableOpacity>
          </View>
        </View>
      </View>
    </Modal>
  );
};

ProgressModal.propTypes = {
  visible: PropTypes.bool.isRequired,
  progress: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
    .isRequired,
  onClose: PropTypes.func,
  cancelButtonTitle: PropTypes.string.isRequired,
  onCancelPress: PropTypes.func.isRequired,
  title: PropTypes.string.isRequired,
};

const styles1 = StyleSheet.create({
  modalBackground: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
  },
  modalContainer: {
    width: '80%',
    backgroundColor: '#FFFFFF',
    borderRadius: 8,
    padding: 16,
    alignItems: 'flex-start',
    elevation: 5,
  },
  modalTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 16,
  },
  progressContainer: {
    width: '100%',
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 20,
  },
  progressBar: {
    width: '95%',
    height: 10,
    backgroundColor: '#E0E0E0',
    borderRadius: 5,
    overflow: 'hidden',
  },
  progressFill: {
    height: '100%',
    backgroundColor: '#4CAF50',
  },
  progressText: {
    textAlign: 'center',
    fontSize: 16,
    fontWeight: 'bold',
    color: '#333',
    width: '5%',
  },
  buttonContainer: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
    width: '100%',
  },
  button: {
    flex: 1,
    padding: 12,
    backgroundColor: '#757575',
    borderRadius: 8,
    marginHorizontal: 8,
    alignItems: 'center',
  },
  cancelButton: {},
  buttonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

Image
Image

Observed behavior and steps to reproduce

we area download a area of map using createPack method and we getting that in packs by calling getPack() method but we are not able to see that area of map when there is internet connection besically we area downloading area of map at certain zoom level so that we can see that area when there is not internet connection we followed everything from dcoumentation and every issue reported nothing is working

LOGS i have recorded

Logs of Downloading offline pack.----- from zoom level 18,20

PROGRESS ====> {"_metadata": null, "pack": {"bounds": "{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[-79.378419567841,43.665287295057084]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[-79.40243501061582,43.64791235618151]}}]}", "metadata": "{"name":"Toronto sat "}"}}
(NOBRIDGE) LOG STATUS ====> {"completedResourceCount": 0, "completedResourceSize": 0, "erroredResourceCount": 0, "loadedResourceCount": 0, "loadedResourceSize": 0, "metadata": {"_rnmapbox": {"bounds": [Object], "styleURI": "mapbox://styles/mapbox/satellite-streets-v12", "zoomRange": [Array]}, "name": "Toronto sat "}, "name": "Toronto sat ", "percentage": 0, "requiredResourceCount": 1, "state": "unkown"}
(NOBRIDGE) LOG PROGRESS ====> {"_metadata": {"name": "Toronto sat "}, "pack": {"bounds": "{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[-79.378419567841,43.665287295057084]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[-79.40243501061582,43.64791235618151]}}]}", "metadata": "{"name":"Toronto sat "}"}}
(NOBRIDGE) LOG STATUS ====> {"completedResourceCount": 1, "completedResourceSize": 8648487, "erroredResourceCount": 0, "loadedResourceCount": 0, "loadedResourceSize": 0, "metadata": {"_rnmapbox": {"bounds": [Object], "styleURI": "mapbox://styles/mapbox/satellite-streets-v12", "zoomRange": [Array]}, "name": "Toronto sat "}, "name": "Toronto sat ", "percentage": 100, "requiredResourceCount": 1, "state": "complete"}
(NOBRIDGE) LOG OFFLINE_MAPS ===> [{"pack":{"expires":"Sun Mar 23 17:51:06 GMT+05:30 2025","percentage":100,"bounds":[-79.378419567841,43.66528729505709,-79.40243501061582,43.64791235618151],"completedResourceSize":8648487,"metadata":"{"name":"Toronto sat ","_rnmapbox":{"bounds":{"coordinates":[[[-79.3784196,43.6652873],[-79.402435,43.6652873],[-79.402435,43.6479124],[-79.3784196,43.6479124],[-79.3784196,43.6652873]]],"type":"Polygon"},"zoomRange":[18,20],"styleURI":"mapbox:\/\/styles\/mapbox\/satellite-streets-v12"}}","state":"complete","completedResourceCount":1,"requiredResourceCount":1},"_metadata":{"name":"Toronto sat ","_rnmapbox":{"bounds":{"coordinates":[[[-79.3784196,43.6652873],[-79.402435,43.6652873],[-79.402435,43.6479124],[-79.3784196,43.6479124],[-79.3784196,43.6652873]]],"type":"Polygon"},"zoomRange":[18,20],"styleURI":"mapbox://styles/mapbox/satellite-streets-v12"}}}]

when viewing map with no network its just cache is visible which was there when downloaded it at zoom 13 just those cache tiles are visible when i am zooming it to level 18-20 no detailed tiles are visible of that region i created pack for.

these log data which offline device trying to view offline pack in mapview

(NOBRIDGE) ERROR Mapbox [error] RNMBXMapView | Map load failed: {tile-id={x=293049, y=382662, z=20}, type=tile, message=Failed to load tile: Unable to resolve host "api.mapbox.com": No address associated with hostname, begin=86303505788, source-id=mapbox-satellite}
(NOBRIDGE) LOG CAMERA_STATE ====> {"gestures": {"isGestureActive": true}, "properties": {"bounds": {"ne": [Array], "sw": [Array]}, "center": [-79.39018702067013, 43.65789523675591], "heading": 354.00065729767084, "pitch": 0, "zoom": 19.07918573547368}, "timestamp": 1740140840016}

SCREENSHOTS when device is offline for the downloaded area at same zoom levels which we have downloaded for.

Expected behavior

Downloaded area of map should be visible when there is no internet connection to device

Notes / preliminary analysis

No response

Additional links and references

No response

@sahni01 sahni01 added the bug 🪲 Something isn't working label Feb 24, 2025
@github-actions github-actions bot reopened this Feb 25, 2025
@sahni01 sahni01 changed the title [Bug]: [Bug]: Offline pack not visible in mapview when device is offline Feb 25, 2025
@sampathkumarch
Copy link

am also facing the same issue , i was downloading the app , but it was not showing as the zoom level of 20 , i thick it was only 13 zoom level only

@sahni01
Copy link
Author

sahni01 commented Feb 28, 2025

@sampathkumarch you mean offline packs are working till zoom level 13 only?

@sampathkumarch
Copy link

sampathkumarch commented Feb 28, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants