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

Icon image doesn't display at particular zoom level / initial load #7598

Closed
lapidus opened this issue Nov 18, 2018 · 3 comments
Closed

Icon image doesn't display at particular zoom level / initial load #7598

lapidus opened this issue Nov 18, 2018 · 3 comments

Comments

@lapidus
Copy link

lapidus commented Nov 18, 2018

I am adding 2 layers "P" and "G".

For unknown reason SOME of the P icons don't display on initial load. The text field displays but not the image. The image appears again at higher AND lower zoom levels. But for a specific zoom level (the initial one), the image icons are not visible:

image

this.map.addLayer({
        id: "p",
        type: "symbol",
        source: {
          type: "geojson",
          data: geoData,
        },
        layout: {
          "icon-image": "{pin}",
          "icon-size": 0.7,
          "icon-allow-overlap": true,
          "icon-ignore-placement": true,
          "icon-padding": 0,
          "text-allow-overlap": true,
          'text-field': "P"
        }
})

this.map.addLayer({
        id: "g",
        type: "symbol",
        source: {
          type: "geojson",
          data: highSchoolGeoData,
        },
        layout: {
          "icon-image": "{pin}",
          "icon-size": 0.7,
          "icon-allow-overlap": true,
          "icon-ignore-placement": true,
          "icon-padding": 0,
          "text-allow-overlap": true,
          'text-field': "G"
        }
})
@mourner
Copy link
Member

mourner commented Nov 21, 2018

Can you set up a minimal live test case (e.g. with JSFiddle) so we could try diagnosing this?

@jacknkandy
Copy link

@lapidus Are you by any chance adding the map layers before the icon images have been loaded? In that case it might be related to issue #6231

@Pictor13
Copy link

Pictor13 commented Sep 1, 2022

Seeing many are having troubles finding a good solution (myself included), I share a snippet similar to what I did to solve the issue:

[⚠️ ❗️UNTESTED CODE: DO NOT COPY PASTE❗️ ⚠️ ]

// asynchronous loading & adding of map. wait for all to be terminated.
function loadImagesFrom(features, map) {
  const promisedImages = []
  for (var feature of features) {
    const imageUrl = feature.image
    const imageId = feature.id

    const promisedImage = new Promise((resolve, reject) => {
      map.loadImage(imageUrl, (error, image) => {
        // hint: for fallback logic use 'coalesce' (https://docs.mapbox.com/mapbox-gl-js/example/fallback-image/);
        // avoid 'styleimagemissing' or you'll have the same issue with addLayer used before addImage (mapbox-gl-js/issues/6231).
        if (error) return reject(error)
        if (!map.hasImage(imageId)) {
          map.addImage(imageId, image)
          return resolve(image)
        }
      })
    })
    promisedImages.push(promisedImage)
  }

  // wait for all images to be ready (either failing and successful)
  return Promise.allSettled(promisedImages)
}

function addLayerTo(map) {
  /*
    ..... you own logic...
  */
  map.addLayer(/* layer specification */)
}

const map = new mapboxgl.Map(/* map config */)

$.getJSON(geojsonUrl)
  .done((geojson, textStatus, jqXHR) => {
    if (jqXHR.status !== 200 || !geojson)
      throw Error('no geojson')

    loadImagesFrom(geojson.features, map)
      .then(
        addedImages => addLayerTo(map)
      )
  })

Hopefully it saves some time to some one (and maybe a lot of time to a lot of ones 🙃).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants