Geocoding with MapLibre

Adding an autocomplete search box to your MapLibre powered map is easy with Geocode Earth.

<!DOCTYPE html>
<html lang="en">
  <head>
      <title>Geocode Earth MapLibre autocomplete demo</title>
      <meta charset='utf-8'>
      <meta name="viewport" content="width=device-width, initial-scale=1">

      <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@5.5.0/dist/maplibre-gl.css">
      <script src="https://unpkg.com/maplibre-gl@5.5.0/dist/maplibre-gl.js"></script>

      <link rel="stylesheet" href="https://unpkg.com/@maplibre/maplibre-gl-geocoder@1.8.0/dist/maplibre-gl-geocoder.css">
      <script src="https://unpkg.com/@maplibre/maplibre-gl-geocoder@1.8.0/dist/maplibre-gl-geocoder.js"></script>

      <script src="https://unpkg.com/protomaps-leaflet@4.0.1/dist/protomaps-leaflet.js"></script>
  </head>
  <body>
      <div id="map"></div>
      <script>
          // configuration
          const API_KEY = '<YOUR API KEY>';
          const PROTOMAPS_KEY = '<YOUR PROTOMAPS KEY>';
          const NUM_RESULTS = 5;

          // init maplibre map
          const map = new maplibregl.Map({
              container: 'map',
              style: 'https://api.protomaps.com/styles/v5/light/en.json?key=' + PROTOMAPS_KEY,
              center: [0, 0],
              zoom: 1
          });

          // query Geocode Earth APIs
          const geocodeEarthResults = async (config, endpoint) => {
              const { lat, lng } = map.getCenter();
              const url = "https://api.geocode.earth/v1/" + endpoint +
                          "?api_key=" + API_KEY +
                          "&text=" + encodeURIComponent(config.query) +
                          "&focus.point.lat=" + lat +
                          "&focus.point.lon=" + lng +
                          "&size=" + NUM_RESULTS;
              const result = await fetch(url);
              json = await result.json();
              json.features.forEach(f => {
                  const props = f.properties;
                  f.place_name = props.label;
              });
              return json;
          };

          // set geocoder options
          const geocoder = new MaplibreGeocoder(
              {
                  getSuggestions: config => geocodeEarthResults(config, "autocomplete"),
                  forwardGeocode: config => geocodeEarthResults(config, "search")
              },
              {
                  maplibregl,
                  showResultsWhileTyping: true,
                  placeholder: "Search a city or address",
                  limit: NUM_RESULTS,
                  proximityMinZoom: 9 // only prioritize the viewport when zoomed in to z9
              }
          );

          map.addControl(geocoder);
      </script>
  </body>
</html>

Be sure to replace <YOUR API KEY> with your Geocode Earth API key.

Customizing #

The geocoder plugin can be customized, see the documentation on GitHub for more details.