When planning a journey to a new country or a city it helps to mark down all the places you would like to visit and eventually create a travel plan for each day. I personally use Google Maps for finding places of interest including historical buildings, museums, and libraries. As an example, if I were to visit Split, Croatia I can format the query on Google Maps as “places to visit split” which will list all the attractions based on features such as reviews and popularity.

Although it is possible to use the “Save” feature in Google Maps, it does not allow customisability options including categorisation of places and marking places based on priority.

Google My Maps

Google My Maps is a tool which allows creating custom maps and is useful for making travel plans, marking hiking routes, and planning other sports activities. It also allows sharing the map with other people either publicly or privately. Some of its features include:

Updating the base map to satellite or street view

Personalising the map by styling the icons and changing their color

Importing data from a spreadsheet including CSV, XML, and KML files

Adding a new entry

The manual process for adding a new entry involves finding a location using the search bar and then adding it to the map layer which places a waypoint icon on the base map.

A layer is Google My Map’s way of categorising different topics, for example, there can be a separate layer for each city.

This, however, is a tedious and repetitive task, which can be done programmatically using Python.

Adding entries using Google Maps API

In principal, if we have a spreadsheet with a list of places, the only task left is to import these places into our custom map. Thus we require a way of automating the process of creating this spreadsheet.

The Google Maps API provides an elegant way of querying data using their Places API. For example, to get a list of places to visit in Split, the request can be formatted as:

This returns a JSON object containing a list of places. Each record contains the place’s name and its latitude, longitude, address, icon, etc.

The code block below sends a GET request to the server, and then performs four major steps including getting the result object, enumerating through the places list and then writing the appropriate entries to a CSV file.

# Fetch the data.places=requests.get(f'https://maps.googleapis.com/maps/api/place/textsearch/json?query={args.query}&language=en&key=API_KEY')# Convert the response to a JSON object.places=json.loads(places.text)['results']# Note: in this case we only keep the following three columns, however, we can further populate the CSV file with the place description, its rating, etc.columns=['names','coordinates','icon']# Write the data to a CSV file.withopen(f'places/{query}.csv','w')asout_file:writer=csv.writer(out_file,delimiter=',')writer.writerow(columns)forplaceinplaces:name=place['name']icon=place['icon']lat,lng=place['geometry']['location']['lat'],place['geometry']['location']['lng']data=[name,(lat,lng),icon]print(f'{filename} -> {data}')writer.writerow(data)

Invoking the script

To get a list of all places to visit in Split the script can be invoked as:

$ python fetch-google-maps.py "things to do split"

This will generate a CSV file called Things To Do Split.csv in the places sub-directory.

Importing the file

Google My Maps supports importing data from CSV, XML, KML, and GPL files and then populates the map using the input data. Instead of using coordinates we can also use street addresses.

To import the file, create a new layer in your custom map and use the “Import” utility. A window will pop up prompting for the file upload. Note that you will still need to do mark the appropriate columns in your CSV file which correspond to the place’s name and its coordinates.

Note: By default, if there are more than 10 items in a CSV file the tool will group them all under a single entry. To view each item separately, select the “Uniform style” option and update “group places by” dropdown to “Individual styles”.

Limitations

Although our map is now populated with the landmark icons at their correct positions, they are not styled and all have the same icon. They are also not color coded which makes it difficult to keep track of all the places to visit on a particular day and changing the icon allows quick identification, e.g. museum or library should have two distinct icons. We thus need a way to transform the map to:

I could not find a way to embed this information within the CSV file, and this step still has to be done manually. Another limitation is that it is not possible to import multiple CSV files into a single layer, thus requiring to merge the files before importing them.