6

From Mapbox's documentation, I should get a GeoJson feature object when I call queryRenderedFeatures method.

I run it from a click event without any filter:

this.map.on("click",
    function(e) {
        var clickedCluster
        this.map.queryRenderedFeatures(e.point).forEach(function(element) {
            console.log(elem)
        })
    })

On my console (see screenshot below), I got feature's properties of the point I click on the map, I got layer's information, but I don't get its geometry. How can I get it?

As far as I understand Mapbox's example, I should obtain it
https://www.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures/

enter image description here

2 Answers 2

7

You're right that queryRenderedFeatures returns a GeoJSON Feature Object. You may access it's Geometry Object like in the following example (for the first feature in features):

map.on('click', function (e) {
    var features = map.queryRenderedFeatures(e.point);
    console.log(features[0].geometry) 
});

https://jsbin.com/jixiferoya/edit?html,output

Please note (from the docs):

Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature geometries may be split or duplicated across tile boundaries [...]

1
  • Oh I test it and it works, I shouldn't trust the javascript console, I thought it content was exhaustive. Thanks ! Jun 4, 2018 at 10:48
1

A few additional notes of caution when using queryRenderedFeatures().

Here's the object returned, which contains a bunch of non-standard "GeoJSON Feature Object" properties:

{
  _geometry:{type: 'Point', coordinates: Array(2)}
  _vectorTileFeature:Au {properties: {…}, extent: 8192, type: 1, _pbf: xc, 
  _geometry: 164, …}
  id:undefined
  layer:{id: 'markers-layer-public', 
    type: 'symbol', source: 'markers- 
    source-public', layout: {…}, paint: {…}}
    properties:{isMarker: true, name: 'Point Wilson', icon: 'coastpilot', 
    access: 'public', id: 'GNIS1507543'}
  source:'markers-source-public'
  state:{}
  type:'Feature'
  geometry (get):ƒ geometry(){return void 0===this._geometry&&(this._geometry=this._vectorTileFeature.toGeoJSON(this._vectorTileFeature._x,this._vectorTileFeature._y,this._vectorTileFeature._z).geometry),this._geometry}
  geometry (set):ƒ geometry(t){this._geometry=t;}
}

Note the get/set methods for .geometry. This means a simple copy will fail, ie. you can't use:

const featureCopy = {...feature} // this won't copy the geometry!

Instead use:

const featureCopy = {
  type: feature.type, 
  layer: {...feature.layer}, // if you need this
  properties: {...feature.properties}, 
  geometry: {...feature.geometry}
};

Also, note that the .id property is undefined. I'm not sure if this is related to using mapboxgl Draw, but the .id property isn't correctly returned even if it was set when the feature was added to the map.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.