Adding search to Shade Map

I added search functionality to today. The correct term is actually Geocoding, which is the process of converting search terms into latitude and longitude coordinates. Because Google is a leader in search technology, I decided to use Google Maps API for the task.

Screenshot 2021-05-05 at 13.27.36.png

I like the way the Google Maps search bar looks, so I used Developer Tools to copy the relevant markup and styles into my project as a React component. The search bar stretches from edge-to-edge on mobile devices but has a bit of margin on larger screens. I chose not to implement an auto-complete dropdown at this point because I have no revenue and the Google Autocomplete api is an extra cost. Without autocomplete, the Google Maps free-tier allows for 40,000 geocode requests per month.

Screenshot 2021-05-05 at 13.27.10.png

Some errors I encountered. The first was the result of using the wrong NPM library.

"error_message" : "API keys with referer restrictions cannot be used with this API.",

I used @googlemaps/google-maps-services-js, but the correct package was @googlemaps/js-api-loader. You also want @types/google.maps if you are coding in Typescript.

"Google Maps JavaScript API error: ApiNotActivatedMapError\n"

Geocoding Service: This API project is not authorized to use this API.  For more information on authentication and Google Maps JavaScript API services please see:

The above error was because I restricted my credentials to only use the Maps JavaScript API. I needed to extend the restriction to also include the Geocoding API.

Using the Google Maps Javascript API with Leaflet was very easy. Here’s the basic code:

// Initialize the Geocoder
const loader = new Loader({
    apiKey: process.env.REACT_APP_GOOGLE_MAPS_KEY as string,
let Geocoder: google.maps.Geocoder;

// Lookup query
const map = useMap();
    address: query,
}, (results) => {
    if (results && results.length) {
        const lat = results[0];
        const lng = results[0].geometry.location.lng();
        const ne = results[0].geometry.viewport.getNorthEast();
        const sw = results[0].geometry.viewport.getSouthWest();
            [, ne.lng()],
            [, sw.lng()],
        setMarkerPosition({ lat, lng }); // state setter for map marker

Now read this

ShadeMap 2021 Wrap Up

Development # A big change happened this fall. Right around the one-year mark I finally succeeded in migrating Shade Map ( onto a vector based map. Up until this point I used tiled image maps which downloaded many small,... Continue →