Friday, December 6, 2019

Convert list comprehension to for loop in python

Lets see the concept of going from 'list comprehension' to 'for loop'.

Above is a nested python list of list that contains names of countries. The list comprehension returns the names of countries with less than ten characters.

Lets try to 'incomprehension' the list :)... more like trying to decompress it into for loop!

The "ten_character" list will start as an empty list then we append the filtered result to it from the for loops.

So, the arrangement is to take the first for loop, follow by the second for loop, then the if conditional statement and then append the result at the end. See the script below...

The complete source code:-

# List of countries...
countries = [['San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Georgia and the South Sandwich Islands'], 
             ['Nepal', 'Netherlands', 'Netherlands Antilles', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'North Korea', 'Northern Mariana Islands', 'Norway'], 
             ['Togo', 'Tokelau', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks and Caicos Islands', 'Tuvalu', 'U.S. Minor Outlying Islands', 'U.S. Virgin Islands', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican City', 'Venezuela', 'Vietnam', 'Wallis and Futuna', 'Western Sahara'], 
             ['Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Bouvet Island', 'Brazil', 'British Indian Ocean Territory']]

# Country name less than 10 character lenght...
ten_character = [ten for sublist in countries for ten in sublist if len(ten) < 10]


# List of countries...
countries = [['San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Georgia and the South Sandwich Islands'], 
             ['Nepal', 'Netherlands', 'Netherlands Antilles', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'North Korea', 'Northern Mariana Islands', 'Norway'], 
             ['Togo', 'Tokelau', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks and Caicos Islands', 'Tuvalu', 'U.S. Minor Outlying Islands', 'U.S. Virgin Islands', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican City', 'Venezuela', 'Vietnam', 'Wallis and Futuna', 'Western Sahara'], 
             ['Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Bouvet Island', 'Brazil', 'British Indian Ocean Territory']]

ten_character = []

for sublist in countries:
    for ten in sublist:
        if len(ten) < 10:


That is it!

Monday, December 2, 2019

JavaScript Recursive Factorial Algorithm

This blog post is about "Recursive Function in JavaScript". The ability for a function to call it self is know as 'Recursion'.

A recursive function has two parts namely: the base case (which gets called when the recursion is satisfied needs to terminate) and the recursive case (which continue to call the function they are in until the base case condition is satisfied)

Recursion is particularly useful for divide and conquer problems. A simple problem that naturally best solved by recursive solution is 'calculating factorials'.

The recursive factorial algorithm defines two cases:
~ the base case when x is zero, and
~ the recursive case when x is greater than zero.

Factorial of a number 'x' is the product of all positive integers less than or equal to the number 'x'. For example the factorial of 6 is: 1 x 2 x 3 x 4 x 5 x 6 = 720

The implementation is as follow:-

function myRecur_factorial(x){
    if (x == 1){
        return x; // This is the: Base Case
    } else{
        return(x * myRecur_factorial(x-1)) // This is the: Recursive Case

x = 6

console.log(`The factorial of ${x} is: ` + myRecur_factorial(x))

Here is a non-recursive approach to writing factorial of a number in JavaScript.

This make use of 'range function' and the 'for loop'. Because JavaScript has built-in range function, we will define one as follow..

function range(start, end) {
    return (new Array(end - start + 1)).fill(undefined).map((_, i) => i + start);

number = 6
factorial = 1

for (i of range(1, number)) {
    factorial = factorial * i;

console.log(`The factorial value for the ${number} is: ` + factorial);

Recursion and Iteration are somewhat similar and often confused by programmers because they both repeat a series of operations. It is mostly not clear if recursion or iteration is a better solution to a particular problem. The following table highlights some differences between recursion and iteration:

When the base case is reached, it terminates
It terminates when a defined condition is met
Space in memory is required to store each  recursive call
Iteration is not stored in memory
Stack Overflow Error occurs when a recursion is  infinite
Infinite iteration will not return error

Another example of recursion is when we used a recursive approach to generating all the possible permutations of a given string, X, of a given length Y:

Sunday, November 24, 2019

QGIS - Remove Neighboring features in Atlas map

Lets take a polygon layer as an example. As seen below, I need to make an atlas map showing only a single polygon feature from the states layer. So, I want only the polygon marked green to be displayed while others in red cross should be hidden.

The end result would be this...

The solution

Step 1: Add an 'id' field to the attribute table. If the 'id' field already exist, then skip this step.

Step 2: Set the layer symbology to 'Rule-based' and set the filter rule to '$id = @atlas_featureid'

Step 3: Click on 'Ok' to apply the settings. Now all the other polygon will remain hidden except the one in atlas preview.

Note: when working with atlas map layer control, you can also use rules such as these listed below:-
1) within($geometry, @atlas_geometry)
2) intersects($geometry , @atlas_geometry)

That is it!

Thursday, October 24, 2019

Generating Zip code map download links

For each of the US states zip code map listed on this page, we want to construct the map download link.

There several ways to get this task completed including using selenium or request/beatifulsoup modules. However, in this exercise, we are going to keep it simple and assume that we know the pattern at which the maps download links are made-up (indeed the pattern is same for all states and readily known) and we just need to generate them based on the file names.

The download link pattern is: URL + state_name + -zip-code-map.png

So, we can easily construct each state's download link from their respective names...

At the end of this tutorial, you should become familiar with:-
a) To become familiar with using string concatenation
b) To become familiar with using string split(), replace() and lower() methods
c) To become familiar with convert pandas series to list using tolist() method
d) To be able to use for loop to append string to empty list

a) Read the spreadsheet containing the file names into a list
b) Clean the names to remove unwanted characters such as ' ('
c) Concatenate the strings to form the URLs

Code Snippet

import pandas as pd

# Read the spreadsheet file...
zip_df = pd.read_csv(r"C:\Users\Yusuf_08039508010\Desktop\GIS Data Processing Scripts\US_ZipMap_Size.csv")

# Convert the column to a list...
zip_list = zip_df['Maps'].tolist()

# ----------------------
# For each item in the list, split at ' (' and keep the first part...
name_list = []
for item in zip_list:
    name_list.append(item.split(' (')[0])

# ----------------------
# Download link URL is: '' + stateName + '-zip-code-map.png'
download_link = []
for name in name_list:
    download_link.append('' + name.replace(' ', '-').lower() + '.png')



Step 1: First we import pandas module and read the spreadsheet file into a dataframe.

import pandas as pd

# Read the spreadsheet file...
zip_df = pd.read_csv(r"C:\Users\Yusuf_08039508010\Desktop\GIS Data Processing Scripts\US_ZipMap_Size.csv")

# Convert the column to a list...
zip_list = zip_df['Maps'].tolist()

Step 2: Next, we need to split the sting and keep the useful part. The part needed is that before the ' (' character. Note that the character has a space followed by the open brace/parentheses.

# ----------------------
# For each item in the list, split at ' (' and keep the first part...
name_list = []
for item in zip_list:
    name_list.append(item.split(' (')[0])

Step 3: The last step is to replace spaces within the string by '-' and concatenate the url string to the variable string. The first part of the string is: '' while the end part of the string is: '.png'

download_link = []
for name in name_list:
    download_link.append('' + name.replace(' ', '-').lower() + '.png')

Assignment Takeaway
An exercise to help you learn further is: Write a script that will extend the above script by adding the resulting list to a new column that corresponds to the file names as seen below, then save the result to spreadsheet file. The result will look like this:-

Reference Material


Monday, October 21, 2019

Building SQL Expressions in ArcGIS and QGIS

In the modern GIS industry, programming skill is an essential asset and one of the programming languages the is very popular within the industry is Structure Query Language (SQL) as you will later find out how it is been used in few moments.

Most of the query expressions used in ArcGIS or QGIS desktop software are derived from SQL. SQL is a standard language for storing, manipulating and retrieving data in databases.

Both ArcGIS and QGIS support the following common database engines: SQLite, MySQL, SQL Server, MS Access, Oracle, Sybase, Informix, PostgreSQL, and other database systems. When connected to any of them, you can take full advantage of SQL in GIS.

For small GIS projects where database isn't required, we make use of traditional GIS files type such as "Shapefile" which allow us to use query expressions that adhere to standard SQL expressions.

What is an expressions?
An expressions is a combination of "Constants, Variables, Operators and Functions" organized in an ordered statement that returns an output value. Expressions are unique to the computer language they are created in. An example of SQL expressions is: "SELECT * FROM <Layer_name> WHERE <Field_name> <Operator> <Value or String>".

If you data resides in a shapefiles or any of these (coverages, INFO tables, and dBASE tables), this part of the SQL expression (SELECT * FROM <Layer_name> WHERE) is automatically supplied for you, so you only provide this part (<Field_name> <Operator> <Value or String>) to query your data.

Since GIS data is made up of Spatial and Attribute, it is worth noting that 'Attribute Query' is similar to the standard SQL queries found in traditional database systems and this will be our focus in this article. On the other hand, 'Spatial Query' which allow operations such as "Contains, Equals, Intersects, Is Disjoint, Overlaps, Touches, Within and Crosses" requires some extension installed on traditional database systems to make them work.

Building SQL Expressions for Attribute Query

There are many places you can build expressions within both ArcGIS and QGIS software, some of the common places are listed below:-

ArcGIS Tools:
~ Select By Attribute
~ Definition Query
~ Field Calculator
~ Label Expression Dialog Box
~ Add Query Layer

QGIS Tools:
~ Select By Expression
~ Filter Query Builder
~ Field Calculator
~ Label Expression Dialog Box
~ Layer Property Display
~ Database Manager

Wednesday, October 9, 2019

Calculating the total size of zip code maps

On this US printable zip codes maps page, there is a list of all the US states zip code maps with their respective sizes in braces like this "Alabama ZIP Code Map (3.59MB)" as seen below...

Lets calculate the total size of all the maps using python scripting!

Off course, there are several or even better ways to get this done. But here we want to test our python skills on this, let us stick to using python 😏.

Some other reasons it is good idea we use python is that we can easily use our python skill to:-
1) make HTTP request to scrape/download the map data
2) generate the download links on the fly
3) create a bot to monitor change in map size (which could indicate the map has been updated).
4) visualization of the string including map/geographic visualization.

The list can go on and on, but I will keep it simple here to just calculate the total sum the map sizes.

Step 1:
First thing is to get the string/text off the web page into our python environment. There are several ways to do this as I have mentioned above, but I will just select, copy and paste it in a CSV file as seen below.

Step 2:
Read the CSV file in python. Here I will use the pandas module to read the CSV file, could have also used the CSV module to do this.

Monday, October 7, 2019

Filtering Missing Zip codes out of master Zip codes list

Here I have a list of zip codes, I want to know the missing zip code from the given list (these are the postal code in Texas, USA).

List 'available_zipcodes' contains the master zip codes and list 'given_zipcodes' contain the provided or working zip codes. Now I want check and filter out those zipcode that are NOT in the master zip codes.

These three lines of python code below will do it. It uses the 'for' loop with and 'if' statement. Basically, we loop through the list of 'given_zipcodes' and if it is not in the 'available_zipcodes', then we print it out.

If you care to run the script and don't want to type all that out, here below is the Code is...

available_zipcodes = [77389, 77086, 77346, 77018, 77040, 77388, 77065, 77080, 77041, 77396, 77385, 77354, 77382, 77067, 77066, 77090, 77345, 77355, 77373, 77339, 77043, 77302, 77304, 77070, 77375, 77095, 77433, 77069, 77038, 77091, 77380, 77092, 77316, 77429, 77377, 77379, 77064, 77088, 77338, 77449, 77386, 77381, 77493, 77356, 77068, 77014, 77084, 77055, 77301, 77303, 77384]

given_zipcodes = [77325, 77339, 77345, 77346, 77380, 77381, 77382, 77383, 77384, 77385, 77386, 77301, 77302, 77303, 77304, 77316, 77354, 77356, 77389, 77014, 77018, 77038, 77040, 77041, 77043, 77055, 77064, 77065, 77066, 77067, 77068, 77069, 77070, 77080, 77084, 77086, 77088, 77090, 77091, 77092, 77095, 77375, 77377, 77379, 77388, 77429, 77433, 77449, 77493, 77373, 77338, 77347, 77391, 77396, 77355]

for zipcode in given_zipcodes:
    if zipcode not in available_zipcodes:

In the case above, the missing zip codes are: 77325, 77383, 77347, 77391

Note: In a production job. these zip codes will probably come in a text file, just read the file into python lists and loop through as seen above.

That is it!

Tuesday, September 24, 2019

Limitations of a Shapefile

For along time, shapefile has being my primary GIS file for working with vector data. I have never had any reason to look beyond shapefile for handling my GIS vector datasets not until recently when I have a need to store some large quantity of text string in the attribute table.

Before I share my story, let make a point to what a shapefile is just in case you don't know it.

Shapefile is a file type developed by ESRI to handle vector map data in the form of points, polylines and polygons. More details can be found on the Wikipedia page as summarized in the picture below, also on the 'Shapefile Technical Description' document.

Limitations of a Shapefile
Specifically, I was trying to convert a KML file to shapefile. Then one of the columns that had alot of text/string content gets truncated when converted to shapefile. I couldn't figure out why and what caused that until I found this website (Switch from Shapefile) that listed listed some its limitations and that one that affected my situation directly was that the maximum characters is 254.

No way! My attribute table has way more than 254 characters. Then I had to look beyond a shapefile. I actually settled with a GeoJSON file type.

Once again as listed on the website Switch from Shapefile, other limitations include:-
~ No coordinate reference system definition.
~ It's a multifile format.
~ Attribute names are limited to 10 characters.
~ Only 255 attributes. The DBF file does not allow you to store more then 255 attribute fields.
~ Limited data types. Data types are limited to float, integer, date and text with a maximum 254 characters.
~ Unknown character set. There is no way to specify the character set used in the database.
~ It's limited to 2GB of file size. Although some tools are able to surpass this limit, they can never exceed 4GB of data.
~ No topology in the data. There is no way to describe topological relations in the format.
~ Single geometry type per file. There is no way to save mixed geometry features.
~ More complicated data structures are impossible to save. It's a "flat table" format.
~ There is no way to store 3D data with textures or appearances such as material definitions. There is also no way to store solids or parametric objects.
~ Projections definition. They are incompatible or missing.
~ Line and polygon geometry type, single or multipart, cannot be reliably determined at the layer level, it must be determined at the individual feature level.

Now you know some troubles you may encounter with you shapefile data are due to some of these limitations, so no need to full your hair just switch to a more advanced GIS file type.

Thursday, September 19, 2019

QGIS Calculate the Mid Coordinates of Polygons

In QGIS field calculator, you can calculate the center point of all polygons within a polygon layer.

Formula 1:
x($geometry), y($geometry)

Formula 2:
xmin(centroid($geometry)), ymin(centroid($geometry))

Formula 3:
x(centroid($geometry)), y(centroid($geometry))

Note that: 'x' standards for Longitude while 'y' standards for Latitude. $geometry represent the variable polygon geometry.

As you can see the preview result for the three formulas are the same.

Sunday, September 1, 2019

Map from GIS to CAD


No doubt, on the desktop ESRI ArcGIS is the top GIS software while AutoDesk AutoCAD is the top CAD software.

Both are capable of making maps and in this article, I will demo how to convert existing map in ArcGIS to AutoCAD. But before I go into that, lets get to know what GIS and CAD mean.

What is GIS and CAD?

GIS = Geographic Information System
CAD = Computer Aided Design

What is the Difference between GIS and CAD?

Both GIS and CAD can be used for making maps however, they are very different technologies with different applications.

GIS: analyzing/visualizing map data
CAD: creating/editing accurate map data

GIS allows data to be attached to the points, lines, and polygons used in the map. This makes GIS the best tool for analyzing and visualizing data through the use of a map.

CAD easily allows a user to create a very accurate drawing whether it is a map, site plan, profile etc. CAD allows the drawing of maps by the use of coordinates or through distances/bearings in different types of unit.

Map displayed in ArcGIS

Map displayed in AutoCAD

How to converting map data from GIS to CAD and vice versa

In ArcGIS, you use the command at: ArcToolBox >> ConversionTools >> To CAD to concert map layer to CAD.

In AutoCAD you simply save the map as .dxf or .dwg file to have it usable in GIS.

That is it!

Wednesday, August 28, 2019

QGIS Remove Black Background Boarder from Raster Image

Often times, you are left with black boarder around an image you manipulated in QGIS as seen below. This is often cause because there is no data to display around data part of the image.

Here is how to get ride of the black background in QGIS 3.

Open the raster image layer property window and select the 'Transparency' tab. Then enter '0' under No data value >> Additional no data value.

Click 'Ok' to apply the changes. Your raster image should now have no black background color surrounding it as seen below.

That is it.

Monday, August 26, 2019

Get the row count of multiple excel spreadsheet files

Here I have many excel spreadsheet files within a folder as seen below...

The task is to return the number of rows in each of the excel files. I can go manually, open each file, scroll to the bottom and note down the row number. That will be cumbersome and time consuming given that number of files I have to cover.

So, I have to write a simple script in python that will handle this boring task accordingly as follow:-

Step 1: First things first, lets find a way to read all the .xlsx files. Here I used the glob module to handle this.

import glob

folder_xlsx = r"C:\Users\Yusuf_08039508010\Desktop\my-xlsx-folder"

# read all the individual order xlsx files
xlsx_files = glob.glob(folder_xlsx + '/*.xlsx')
what I have above is a list that contains path to all the excel files in the folder. Lets move on...

Step 2: Next step is to read each excel file into a pandas dataframe and use a function to count the number of rows in the dataframes. There are many functions to count the number of rows as seen below, but I will use this function 'len(df.index)'.

Here is the solution for the fisrt dataframe.

df = pd.read_excel(xlsx_files[0])

row_count = len(df.index)

To do for the whole excel files, we just write a for loop and save the into a list as seen below. Noticed that I used rsplit() function to get the file names to print it along its corresponding row count.

import pandas as pd
row_count_list = []
for xls_file in xlsx_files:
    df = pd.read_excel(xls_file)
    row_count = len(df.index)
    file_name = xls_file.rsplit('\\', 1)[1]
    file_details = file_name, row_count
print (row_count_list)

That is it!

P.S: You could easily extend the script above to do many other thing with the files. An example will be to merge all the files into one file using the pandas concat() method. So, instead of appending the file names and the row counts, we will simply append the dataframe as seen below.

df_list = []
for xls_file in xlsx_files:
    df = pd.read_excel(xls_file)
merge_df = pd.concat(df_list)

Thursday, August 8, 2019

Split string at the last occurrence of a string

I have a list of strings with varying length. However, the each string always end with certain same information (country in this case) as seen below.

data_list = ['Adams Smith, white, UK', 
             'Samuel Tom, Black, 29 leen st. NY, USA', 
             'Yaks Ramson, New Student, Yet to register, Romania']

As you can see, there are three items in the list and each item ends with a country name after a comma (,) sign.

When you loop through the items, you can split each item by comma like this: item.split(','). However, this isn't what I wanted, I want to split just at the last comma. In other words, I want to plit each of the string at the last occurrence of the comma (,) sign.

So, here the solution is to use a list method call rsplit(',', 1), which accept a second argument that tells how many times you want to split a string. Here I want to split the string just once, so my script will look like this...

data_list = ['Adams Smith, white, UK', 
             'Samuel Tom, Black, 29 leen st. NY, USA', 
             'Yaks Ramson, New Student, Yet to register, Romania']

item_list = []
for item in data_list:
    item_1 = item.rsplit(',', 1), # Not item.split(',')

Now, each item is split into two and you can access the individual countries as seen below:-

Sunday, July 28, 2019

Ways to create and add SVG maps to a web page

SVG stands for 'Scalable Vector Graphics' which defines vector-based graphics in XML format. It is just another format for displaying images on the web and every element and every attribute of its can be animated. It have greater advantages over other image file types such as PNG, JPG, GIF, BMP, etc.

Some of its notable advantages are:-
~ It is scalable. That is it doesn't loss quality when stretched or compressed.
~ It has interactive ability with CSS and JS
~ It can be created and edited with any text editor
~ It can be searched, indexed and scripted
~ It can be printed with high quality at any resolution

Ways to create SVG image maps

SVG maps can be created with either of the two ways namely; text editor or drawing program. The examples of each is given below:-
1) Text editor (Code): any text editor such as notepad++, sublime, atom, etc can be used.
2) Drawing tools/program: Inkscape, Adobe Illustrator, etc. While most of these tools can save SVG files directly, it is worth noting that there are some such as ArcGIS and QGIS that edit maps in other formats such as shapefile then other online such as Mapshaper,  Mapstarter, Geoconverter, etc are used to convert the shapefile to SVG file.

Creating SVGs with Code allows you to understand the different svg elements and the attributes that make up the file. This is very import when you want to manipulate and interact with the SVG using CSS and JS scripting.

If your SVG is a complex one such as a state map administrative boundaries, you are better off creating the SVGs with drawing tools.

Ways to add SVG image maps into HTML web page

1) Using inline SVG tag (<svg>...</svg>)

2) Using image tag (<img src='filename.svg' >)

3) Using CSS background-image property
background: url(filename.svg);

4) Using HTML object, iframe or embed tags

Using inline SVG tag to add SVG images are the most powerful and flexible, as it allows certain CSS and JS operations with SVG that other ways don't allow. This method also helps with very fast loading speed of the web page.

On the other hand, a major draw back for using the inline SVG tag is that it is very poor in "search engine indexing".

That is it, hope it was useful.
Thank you for reading.

Saturday, July 6, 2019

Toggle cell line numbers in Jupyter notebook

When you are switching from a text editor to jupyter notebook environment for writing python code, you will definitely wish to see line numbers on jupyter notebook cells. And one obvious reason is that it makes it easier to trace errors as seen below.

In the script pictured above, there is an 'ElementNotVisibleException' error on line 86. If the cell line number was off, it will be very difficult to count and locate the line where the error occurred. But will line number enabled, we just scroll to the line number as seen below.

How to enable cell line numbers in Jupyter notebook

To toggle cell line numbers in Jupyter notebook, you can use two keyboard shortcuts in "Command Mode" as follow:-
1) L - to toggle line numbers
2) Shift-L - to toggles line numbers in all cells, and persist the setting

Note that the Jupyter Notebook has two different keyboard input modes.
Edit mode allows you to type code or text into a cell and is indicated by a green cell border.

Command mode binds the keyboard to notebook level commands and is indicated by a grey cell border with a blue left margin.

That is it!

Tuesday, June 18, 2019

How to work with Geographical APIs

API - is the acronym for "Application Programming Interface" which basically means some sets of actions that allow interaction with some bunch of data hosted somewhere on a remote server. These interactions are commonly achieved by sending HTTP request to the server where the data resides. When such a data is related to some geographic location, then it is said you are working with a geographical API.

Imagine there is database of all elevation/heights of points around the world which you can access by providing the location's latitude and longitude. If you want to obtain an elevation of a point, you don't need to travel to that location just to get the elevation value. You will simply send a request to the API of the organization that has the database to retrieve the value.

Or on another hand, there is a database of latitude and longitude values of places around the world. If you need the latitude and longitude of a place you just send a request to with the name of that place to retrieve the latitude and longitude value. This is what the Google Geocode API does, we will see more of other APIs in the coming sections.

Who maintains Geographical API?
An API can be developed and maintained by any individual or organization. The bottom line is that you have access to some data legally and you want users to have access to them by sending HyperText Transfer Protocol (HTTP) requests. Then you will host the data on a server and define some instructions for accessing the data.

To make further clarifications, many organizations such as NASA, Google, ESRI, Mapbox, Government Organisations, etc who have access to large geographic data often have API for accessing and interacting with the data. At the time of writing, the above list are major providers of geo-data API.

There are several method available for the HTTP request, however the most commonly used once are the GET and POST methods. Others are described in the table below:-

SNMethod and Description
The GET method is used to retrieve information from the given server using a given URI. Requests using GET should only retrieve data and should have no other effect on the data.
Same as GET, but transfers the status line and header section only.
A POST request is used to send data to the server, for example, customer information, file upload, etc. using HTML forms.
Replaces all current representations of the target resource with the uploaded content.
Removes all current representations of the target resource given by a URI.
Establishes a tunnel to the server identified by a given URI.
Describes the communication options for the target resource.
Performs a message loop-back test along the path to the target resource.

Where to fine Geographical API?
Just about any individual or organisation that maintains a large volume of geographical data would probably has an API where such data is exposed to developer. However, there are few places to look when searching for geographical API services as listed below:-

1) Rapid API

2) ProgrammableWeb Mashup & API Directory

3) Any API

Above are few places where various APIs are listed and you can use the keywords "Geography", "Location" or "Mapping" to narrow down the search list. In few minutes, I will get some APIs from the directories for demonstration in the section below.

As you can see from each API description, there are literally hundreds of geographical API from different organizations that you can use for different kind of data exploration. You just need to know what the API can do and use it according to there terms of usage as I will explain in the next section.

How to work with Geographical API
1) The first thing is to know what kind of data you want, then head over to the API directories above and search for it availability.

2) If it is available, read and study the documentation provided for the API and use it accordingly.

3) Use any programming language to send/make the HTTP requests.

Example: Lets say we want to work with "Elevation" data across the globe in our project. Obviously we can travel all the globe to collect elevations of points locations, then what do we do? The solution lies in a API, we need an API the provide accurate elevations of places on the globe.

Let's search for such a API...

There are many API providers the can provide "Elevations", some are: Google Elevation API, Open-Elevation API, ElevationAPI.ioBing Maps Elevations etc.

Now, we have several options to choose from. Here I am going to work with Lets read and study its documentation.

From the doc, you will see that to retrieve the elevation of a point you need to provied the point's latitude and longitude pair in this HTTP GET request format: ',-106.17188),(62.52417,10.02487)&key=YOUR-API-KEY-HERE'.

Further study of the API doc reveals that the API_Key is an optional parameter in the GET url. So, it means we can obtain an elevation of a point at 5km resolution like this:,-106.17188)'

The output result is in JSON format and you can parse this easily in python or similar programming language or use an online tool like 'JSON Editor Online' to view the result in a friendly form.

The above concept is the same for any other type of API data you want to work with begin it: Geocode API, Distance API, Satelite Image API, IPGeolocation API, Drone UAV API, etc just to name a few.

That is it!

Saturday, June 8, 2019

Documenting a python script and REST API with 'PyDoc' and 'Swagger OpenAPI Specification' respectively

Documenting a python app appropriately goes along way in communicating what the app does and what is expected of it.

In this post, I will introduce you to two tools you can easily use to create and keep appropriate documentation of your python app.

The first is the PyDoc module which is a standard documentation module in python programming language similar to PerlDoc and JavaDoc for Perl and Java programming languages respectively. With PyDoc, we can generate text and HTML pages with documentation specifics.

The second tool is the Swagger (aka OpenAPI ) which is an open-source software framework backed by a large ecosystem of tools that helps developers design, build, document, and consume RESTful Web services.

PyDoc: Documenting a python script

Pydoc is a Python documentation tool. On cmd enter this: python -m pydoc
You will see that all that the pydoc module is capable of doing as explained below....

1) pydoc <name> ...
    Show text documentation on something.  <name> may be the name of a
    Python keyword, topic, function, module, or package, or a dotted
    reference to a class or function within a module or module in a
    package.  If <name> contains a '\', it is used as the path to a
    Python source file to document. If name is 'keywords', 'topics',
    or 'modules', a listing of these things is displayed.

As an example enter: python -m pydoc pandas to see the documentation on the pandas module (note you should have already install "pandas" for you to see its documentation).

2) pydoc -k <keyword>
    Search for a keyword in the synopsis lines of all available modules.

An example to search for the keyword 'sql' is: python -m pydoc -k sql
All the keywords related to 'sql' on your python environment will be returned as seen below.

3) pydoc -p <port>
    Start an HTTP server on the given port on the local machine.  Port
    number 0 can be used to get an arbitrary unused port.

For example, python -m pydoc -p 0 started an arbitrary unused port '61281' http://localhost:61281 in my case. Yours will definitely be on a different port.

On the cmd use letter 'b' to browse and 'q' to quit/stop the HTTP server.

4) pydoc -b
    Start an HTTP server on an arbitrary unused port and open a Web browser
    to interactively browse documentation.  The -p option can be used with
    the -b option to explicitly specify the server port.

Example is: python -m pydoc -b will start the server doc automatically, it is just a handy shortcut for the above.

5) pydoc -w <name> ...
    Write out the HTML documentation for a module to a file in the current
    directory.  If <name> contains a '\', it is treated as a filename; if
    it names a directory, documentation is written for all the contents.

This enable you generate a HTML doc for a module or a script you have written. Example is: python -m pydoc -w XXX where XXX can be a module or a script file name.

This is useful if you want to share or host the doc, you simply share the resulting html file with others. Below is a written sample script I did like to document. Save it as '' and run the command from the folder that contains the script: python -m pydoc -w testScript

This will generate a html doc for the script that you can share with other developers as seen below. The script contains classes, methods and function with multi line comments (doc strings) in them, the html doc is generated based on those multi line comments (doc strings).

Author: Umar Yusuf
Date: 2019/04/01
This python script, demonstrates how a module is documented for easy future reference.
Hope you like it!

class ClassA(object):
    """Here is the docstring for ClassA"""
    def __init__(self, arg):
        super(ClassA, self).__init__()
        self.arg = arg

    def myMethod(self):
        '''A function in a class is a know as a METHOD'''

class ClassB(ClassA):
    """Here is the docstring for second ClassB. It inherits from ClassA"""
    def __init__(self, arg):
        super(ClassB, self).__init__()
        self.arg = arg

# --------------------
# These are functions since they are outside the class definition
# Python program to multiply two numbers

def multiply(a, b):
    This function takes two numbers in the form of input and multiplies them.
    It displays the multiplication as the result.
    print("Result= ", (a * b))

# functions calling
multiply(5, 2)

a) Show module's doc: python -m pydoc XXX 
b) Search for keyword: python -m pydoc -k XXX
c) Start python doc on http port: python -m pydoc -p 0
d) Shortcut for http server doc: python -m pydoc -b
e) Generates HTML file for modules or written scripts: python -m pydoc -w XXX