react-mapbox-gl icon indicating copy to clipboard operation
react-mapbox-gl copied to clipboard

onStyleLoad event only gets fired for the first style that is loaded

Open agusterodin opened this issue 5 years ago • 3 comments

The onStyleLoad event only gets fired after the first style loads. If I change styles, the event never fires again like it should. Applying a callback to the underlying mapbox object directly does work and fires every time a new style is done loading.

This is a temporary workaround I came up with that works:

onStyleLoad={map => { setMapStyleLoaded(true) // Temporary workaround for the mapbox wrapper onStyleLoad function only being // fired the first time a style is ever loaded map.on('style.load', () => setMapStyleLoaded(true)) }}

Thanks for your hard work Alex!!! This is a superb Mapbox wrapper.

agusterodin avatar Feb 14 '20 20:02 agusterodin

Hello there,

I face the same issue. The problem is because of the onStyleLoad callback is triggered by 'load' event instead of style.load one.

Here is the source code: https://github.com/alex3165/react-mapbox-gl/blob/master/src/map.tsx#L272-L280

I fixed that by manually attaching style.load event listener to the map object, like this:

// ...
const handleMapLoad = useCallback(map => {
	map.on('style.load', yourEventListener)
	// ...
}, []);

// ...
<Map
	onStyleLoad={handleMapLoad}
/>
// ...

Thanks

sergei-zelinsky avatar Jul 30 '20 10:07 sergei-zelinsky

Hi @sergei-zelinsky,

I am having a problem getting this functionality from the MAP GL JS API using the onStyleLoad prop to add 3d terrain to a map. I followed your prescription above with:

 export default function MyMap() {

  function handleLoadedMap(map) {
    map.addSource('mapbox-dem', {
      'type': 'raster-dem',
      'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
      'tileSize': 512,
      'maxzoom': 14
    });
    // add the DEM source as a terrain layer with exaggerated height
    map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 });

    // add a sky layer that will show when the map is highly pitched
    map.addLayer({
      'id': 'sky',
      'type': 'sky',
      'paint': {
        'sky-type': 'atmosphere',
        'sky-atmosphere-sun': [0.0, 0.0],
        'sky-atmosphere-sun-intensity': 15
      }
    });
    map.addControl(
      new MapboxGeocoder({
        accessToken: mapboxgl.accessToken,
        mapboxgl: mapboxgl,
        position: 'top-right'

      })
    );

    map.addControl(
      new mapboxgl.GeolocateControl({
        positionOptions: {
          enableHighAccuracy: true
        },
        // When active the map will receive updates to the device's location as it changes.
        trackUserLocation: true,
        // Draw an arrow next to the location dot to indicate which direction the device is heading.
        showUserHeading: true,
        showAccuracyCircle: true,
        position: 'top-left'

      })
    );
  }

  const handleMapLoad = useCallback(map => {
    map.on('style.load', handleLoadedMap(map))
  }, []);

  return (
    <>
      <Map
        style="mapbox://styles/mapbox/streets-v9"
        onStyleLoad={handleMapLoad}
      >
        <RotationControl
          className="mt-12"
          position="top-right"
        />
        <ZoomControl
          className="mt-[2.375rem]"
          position="top-left"
        />
      </Map>
    </>
  )
}

All the other functions in there work i.e. `GeolocateControl` and  `MapboxGeocoder`.

Would you have any ideas?

antonioOrtiz avatar May 06 '22 14:05 antonioOrtiz

@sergei-zelinsky Nevermind I didn't pan it!

antonioOrtiz avatar May 06 '22 14:05 antonioOrtiz