mapbox / mapbox-maps-ios

Interactive, thoroughly customizable maps for iOS powered by vector tiles and Metal
https://www.mapbox.com/mapbox-mobile-sdk
Other
462 stars 150 forks source link

GeoJSON Source Loads Data Even When Layer is Hidden #2216

Open p-lizak opened 1 month ago

p-lizak commented 1 month ago

Environment

Observed behavior and steps to reproduce

When starting the app, all layers should be hidden by default, which they are. However, the geoJSON source loads even though the layer is hidden. This behavior results in unnecessary data being loaded. For other endpoints where tiles are used, the data is not loaded if the layer is hidden.

Steps to reproduce:

  1. Define a map style with the following structure:
    {
    "version": 8,
    "sources": {
    "geojson_source": {
      "type": "geojson",
      "data": "https://example.com/data.geojson"
    },
    "tile_source": {
      "type": "vector",
      "tiles": ["https://example.com/tiles/{z}/{x}/{y}.pbf"]
    }
    },
    "layers": [
    {
      "id": "geojson_layer",
      "type": "symbol",
      "source": "geojson_source",
      "layout": {
        "visibility": "none"
      }
    },
    {
      "id": "tile_layer",
      "type": "symbol",
      "source": "tile_source",
      "layout": {
        "visibility": "none"
      }
    }
    ]
    }
  2. Start the app and observe the network requests

    Expected behavior

    The expected behavior is that no data should be loaded for hidden layers, including both geoJSON and tile sources. The app should not load the geoJSON data if the corresponding layer's visibility is set to "none".

Notes / preliminary analysis

Initial analysis suggests that the geoJSON source is being loaded even when its layer is hidden. This does not occur with tile sources, indicating a discrepancy in how different source types are handled regarding layer visibility.

pjleonard37 commented 1 month ago

Hi @p-lizak --

The data from GeoJSON sources is loaded like this by design so that it is ready when styling layers need it. If you'd like to wait to load GeoJSON data until some event in your application (user input, a state change, etc.), then you can load the GeoJSON source at runtime after that event.

func addGeoJSONSource() {
      var geoJSONSource = GeoJSONSource(id: "sourceID")
      geoJSONSource.data = .url(URL(string: "https://example.com/data.geojson")

      do {
          try mapView.mapboxMap.addSource(geoJSONSource)
      } catch {
          print("Ran into an error adding a source: \(error)")
      }
}

There's more information about working with sources and layers here: https://docs.mapbox.com/ios/maps/guides/styles/work-with-layers/#geojson