TransWikia.com

Supplement Mapbox geocoder results with external geocoder API

Geographic Information Systems Asked by jnucc on October 4, 2021

I am still learning JS so please bear with me.

I have built a Mapbox GL JS map and would like to supplement Mapbox geocoding results with those from an external geocoding API as many POIs I need are not returned with the standard Mapbox geocoder (such as campsites and national parks).

I have followed the tutorial to supplement results by querying local data here: Supplement forward geocoding search results from another data source

I have got this to work with local a geojson source however I cant get it to work when querying an external geocoder. I am testing with OpenCage.

My code for the geocoder instance on the map is:

// Load geojson source data                
var myjson;
$.getJSON("<github hosted file>", function(json){
  myjson = json;
});    

// Local geocoder function
function forwardGeocoder(query) {

      var matchingFeatures = [];
      for (var i = 0; i < myjson.features.length; i++) {
      var feature = myjson.features[i];
      if (feature.properties.road_name.toLowerCase().search(query.toLowerCase()) !== -1) {
           feature['place_name'] = '? ' + feature.properties.road_name;
           feature['center'] = feature.geometry.coordinates;
           matchingFeatures.push(feature);
          }
       }

    return matchingFeatures;
}

//Add geocoder/search box
var geocoder = new MapboxGeocoder({
      accessToken: mapboxgl.accessToken,
      localGeocoder: forwardGeocoder,
      country: 'au'
});

This works fine for local data pulled in from a geojson source (i.e. already loaded in the client side). When I try to add an external geocoder into the forwardGeocoder() function, the query returns the correct geocoded results and I can get them to appear in the console but they dont appear in the standard mapbox geocoder results list. Code for the external geocoder (using OpenCage to test).

function forwardGeocoder(query){
    var matchingFeatures = [];
    $.ajax({
        url: 'https://api.opencagedata.com/geocode/v1/geojson',
        method: 'GET',
        data: {
          'key': 'ab6ad6e3ad3043e2aeb897322ab038f0',
          'q': query,
          'pretty': 1
        },
        dataType: 'json',
        statusCode: {
           200: function(response){  // success
                  var listings = response.features;
                  //console.log(listings);
                  for (var i = 0; i < listings.length; i++) {
                    var feature = listings[i];
                    if (feature.properties.formatted.toLowerCase().search(query.toLowerCase()) !== -1) {
                      feature['place_name'] = '? ' + feature.properties.formatted;
                      feature['center'] = feature.geometry.coordinates;
                      matchingFeatures.push(feature);
                    }
                  }
                console.log(matchingFeatures);
                return matchingFeatures;
              },
              402: function(){
                console.log('hit free-trial daily limit');
                console.log('become a customer: https://opencagedata.com/pricing');
              }
            }
          });
        }

Console output from this function:

0:
center: (2) [145.516244, -37.4666249]
geometry: {coordinates: Array(2), type: "Point"}
place_name: "? Aeroplane Track, Toolangi VIC, Australia"
properties:
annotations: {DMS: {…}, MGRS: "55HCU6878852327", Maidenhead: "QF22sm18wa", Mercator: {…}, OSM: {…}, …}
bounds: {northeast: {…}, southwest: {…}}
components: {ISO_3166-1_alpha-2: "AU", ISO_3166-1_alpha-3: "AUS", _type: "road", continent: "Oceania", country: "Australia", …}
confidence: 7
formatted: "Aeroplane Track, Toolangi VIC, Australia"
__proto__: Object
type: "Feature"
__proto__: Object
length: 1
__proto__: Array(0)

I am able to get results of the geocode to appear correctly (in the same format as the local data version) in the console (console.log(matchingFeatures)) but the subsequent return matchingFeatures doesnt seem to work to add them to the mapbox geocoder results.

Been searching around for days with no luck. Annoyingly I feel like this is a common problem as the Mapbox geocoder results are lacking in many ways.

One Answer

What you're trying to do won't work since the localGeocoder option to mapbox-gl-geocoder is synchronous, so it can't be used to supplement results from a 3rd party API without https://github.com/mapbox/mapbox-gl-geocoder/issues/157

Your best option is to either write the code to extend mapbox-gl-geocoder to do this, or write your own replacement of mapbox-gl-geocoder which can call two external services.

Answered by AndrewHarvey on October 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP