Unlock the secrets of your code with our AI-powered Code Explainer. Take a look!
In this tutorial, we will use the GADM country API to generate SVG Files for each country. We will make it, so the country fits perfectly in the SVG tag. For this, we have to analyze the data. We will also use the pycountry
module to get all three letter country codes. Let us get right into it!
Installing pycountry:
$ pip install pycountry
Importing the libraries:
# Default Library
import requests
import json
import os
# Download with pip install pycountry
import pycountry
All the rest of the code is inside a for
loop because we will download every country. To do this, we convert the countries
dictionary to a list and loop over it. The country object will hold a Country
object that has the three-letter code as a property.:
for country in list(pycountry.countries):
Then we define four variables. The first one will hold all coordinates of the current country's border. The second one will hold the coordinates as they are grouped in the API. This is needed because most countries consist of multiple nonconnected parts. The last two hold the three-letter country code and the country name from the country object:
# All Points from all Groups
# used to analyze
allPoints = []
# Countries that dont consist of one body
# will have multiple groups of coordinates
pointGroups = []
# Country Code with 3 letters
countryCode = country.alpha_3
countryName = country.name
Before we get deeper into the loop, we check if we have already generated an SVG map for this country. We will store the SVG in an output
folder, and the file's name will simply be the country's name. So we concatenate a string with this information and give it to the os.path.exists()
function. If the file exists, we skip this iteration with the continue
statement.
# Check if the SVG file already Exists and skip if it does
if os.path.exists(f'output/{countryName}.svg'):
print(f'{countryName}.svg Already exists ... Skipping to next Country\n')
continue
print('Generating Map for: ', countryName)
Now we request the data. The data is just a .json
file residing on a web server. The URL for the swiss data looks like this. For other countries, we have to simply swap the CHE
with another country's code:
https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_CHE_0.json
So we insert this country code in this URL and use it in the get()
function from requests
. After that, we try to decode the returned text. If that does not work, we may have made an invalid request. If that's the case, we skip the iteration.
# Get the Data
re = requests.get(f'https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_{countryCode}_0.json')
# If the string cant be parsed an invalid country was requested
try:
data = json.loads(re.text)
except json.decoder.JSONDecodeError:
print('Could not decode ... Skipping to next Country\n')
continue
Now we need to organize the data for later usage. For this, we loop over the data until we encounter the groups; we append these to the list we defined earlier. Then we also loop through this group and append the points to the allPoints
list:
# Organise the Data
# Get the groups and all coordinates
for i in data['features'][0]['geometry']['coordinates']:
for group in i:
pointGroups.append(group)
for coord in group:
allPoints.append(coord)
print(f'\n{len(allPoints)} Points')
After that, we analyze the data. We want to find out the lowest and highest points for each axis because we want to make it so the path we later generate fits ideally into the SVG file. So we define variables for each of those four points:
# Analyse Data
# Use these Information to calculate
# offset, height and width of the Country
lowestX = 9999999999
highestX = -9999999999
lowestY = 9999999999
highestY = -9999999999
Then we loop over the allPoints
list and set each value accordingly. We do this with a ternary operator:
for x, y in allPoints:
lowestX = x if x < lowestX else lowestX
highestX = x if x > highestX else highestX
lowestY = y if y < lowestY else lowestY
highestY = y if y > highestY else highestY
We then display some debug information:
print('lowestX', lowestX)
print('highestX', highestX)
print('lowestY', lowestY)
print('highestY', highestY)
Then we can calculate the height and width of the SVG, or there I say the country with the info we just got.
svgWidth = (highestX - lowestX)
svgHeight = (highestY - lowestY)
Let us display the country with SVG. We will use the polygon
element. Some HTML knowledge would be good for the following part because SVG is just HTML.
So we define a polygon variable that will hold the polygon
element strings. Then we loop over the groups and define a coordinateString
which will keep the current coordinates. We then also loop over this group and unpack it.
We subtract the lowest of each axis, so the country sticks to the edges. Then we add the pair to the coordinate string. After we have looped over the group, we make a polygon string with the coordinate string inserted at the correct location.
# Transfrom Points to Polygon Strings
polygonString = ''
for group in pointGroups:
coordinateString = ''
for x, y in group:
x = (x - lowestX)
y = (y - lowestY)
coordinateString = coordinateString + f'{x},{y} '
polygonString += f'<polygon points="{coordinateString}"></polygon>'
Then we insert all the polygons into an SVG string with the correct settings:
svgContent = f"""
<svg width="{svgWidth}" height="{svgHeight}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="transform: scale(1, -1)">
{polygonString}
</svg>
"""
Last but not least, we write this string to a file named after the country:
# make the output folder
if not os.path.isdir("output"):
os.mkdir("output")
# write the svg file
with open(f'output/{countryName}.svg', 'w') as f:
f.write(svgContent)
# new line
print('\n')
This program will try to make country border SVG files of all world countries and will store them in the output
folder.
Note that small countries will look tiny compared to larger ones, make sure to scale them if you wish to use any of them.
Learn also: How to Get Geolocation in Python.
Happy coding ♥
Want to code smarter? Our Python Code Assistant is waiting to help you. Try it now!
View Full Code Explain The Code for Me
Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!