mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.35k stars 1.33k forks source link

symbol-avoid-edges removes symbols where it shouldn't #16541

Open pbnsilva opened 3 years ago

pbnsilva commented 3 years ago

Platform: node

Mapbox SDK version: v5.0.2

Steps to trigger behavior See below for the code that generates 1 tile where the problem can be seen. I am using this style.

The problem: If symbol-avoid-edges is set to false then most text labels are show. If it is set to true then many that are not close to the edge are removed. See the comparison below.

Expected behavior Labels that don't cross edges are visible. false

Actual behavior Many labels are missing! true

Code

const mbgl = require('@mapbox/mapbox-gl-native')
const request = require('request')
const utils = require('./utils')
const config = require('./config')
const sharp = require('sharp')
const readline = require('readline')
const fs = require('fs')

var tile1 ={ zoom: 15.1,
  width: 2051,
  height: 2051,
  pxWidth: 280,
  pxHeight: 280,
  center: [ 6.909015, 51.072115 ],
  bearing: 0,
  pitch: 0,
  ratio: 0.1365236470014627 }

renderTile('tile1', tile1)

function mapRequest(req, callback) {
  var url = req.url
  if (url.indexOf('access_token') === -1) {
    var urlObject = utils.parseURL(url)
    url = utils.makeAPIURL(urlObject, config.ACCESS_TOKEN)
  }

  makeRequest(url, callback)
}

function makeRequest(url, callback) {
  request({
    url: url,
    encoding: null,
    gzip: true
  }, function (err, res, body) {
    if (err) {
      callback(err)
    } else if (res.statusCode == 200) {
      var response = {}

      if (res.headers.modified) { response.modified = new Date(res.headers.modified) }
      if (res.headers.expires) { response.expires = new Date(res.headers.expires) }
      if (res.headers.etag) { response.etag = res.headers.etag }

      response.data = body

      callback(null, response)
    } else {
      callback(new Error(JSON.parse(body).message))
    }
  })
}

function renderTile(name, tile) {
  var options = {
    request: mapRequest,
    ratio: tile.ratio,
    mode: 'tile'
  }
  var map = new mbgl.Map(options)

  map.load(require('./style.json'))

  map.render({
    zoom: tile.zoom,
    width: tile.width,
    height:  tile.height,
    center: tile.center,
    bearing: 0,
    pitch: 0,
  }, function(err, buffer) {
      if (err) {
        throw err
      }

      map.release()

      var image = sharp(buffer, {
          raw: {
              width: tile.pxWidth,
              height: tile.pxHeight,
              channels: 4
          }
      })

      image.toFile(name + '.png', function(err) {
          if (err) {
            throw err
          }
      })
  })
}

Am I missing some setting? This looks like a bug.

Thank you