Plot postal codes on a map

Balasaheb Molawade 136 Reputation points
2024-04-12T09:56:34.0933333+00:00

Hi,

We received a requirement to plot Canadian postal codes on a map. While we have a similar functionality for US postal codes, which we achieved using the Bing Maps public data source available at the following link https://learn.microsoft.com/en-us/bingmaps/spatial-data-services/public-data-sources/2010-us-census-data-sources, we discovered that there isn't a similar data source available for Canadian postal codes. Additionally, although we utilize features from our Bing Maps portal, we require a Canadian postal code shapefile (.shp) or .kml file, which we have been unable to find freely available.

Does anyone have any suggestions for a public data source for Canadian postal codes or know of a site from which we can download a Canadian postal code shapefile (.shp) or .kml file.

Thanks

Azure Maps
Azure Maps
An Azure service that provides geospatial APIs to add maps, spatial analytics, and mobility solutions to apps.
588 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. rbrundritt 15,311 Reputation points Microsoft Employee
    2024-04-12T16:59:36.78+00:00

    Ahhh..., Canadian Postal codes, something I have beat my head on several times in the past. Before I dive in, Postal Code boundaries for Canada are not available in Bing Maps or Azure Maps. Now, let me break this up into two parts:

    Background info and open data options

    Canada is one of the only major countries where the postal/zip code boundary data is not available as an open data set. Canada Post has a monopoly on that dataset. As a Canadian GIS person it drives me nuts as many other Candian government GIS programs have been active in the open data/open-source world for decades. Even crazier is that Statistics Canada has an open database of all addresses in the country here https://www.statcan.gc.ca/en/lode/databases/oda that has a postal code column, but it's empty for all addresses. Anyone who has tried to create their own dataset of polygons has usually ended up being chased down by Canada post. There is a company called Geocoder.ca who made a geocoder and when you passed in a street address with a postal code in it, it would keep track of that, and geocode based on the street address. Over time they built up a database of coordinates and postal codes and were able to generate their own approximate boundaries that where pretty accurate. Canada Post went after them: https://geocoder.ca/?sued=1 Their data is still free for non-profits, and relatively cheap for commercial purposes: https://geocoder.ca/?freedata=1 The only other open data related postal codes you will find easily available is Forward Sortation Code boundaries (FSA) which is the area that represents the first three characters of a Canadian Postal code. For example, postal code "N0R 1K0" would have an FSA of "N0R". For demo's and some analysis scenarios that can often be enough.

    Actual method for achieving Canadian postal code analysis

    To enable postal code analysis for Canada you would need to do the following:

    • License postal code boundary data either from Canada post, one of their resellers, or an alternative source such as geocoder.ca (this one would be lower accuracy, but postal code boundaries are generally not well-defined areas).
    • Once you have the data, load it into a spatial database such as Azure SQL or Azure PostgreSQL (with PostGIS). I recommend Azure PostgreSQL as it provides more spatial analysis capabilities and native support for vector tiles which will surely be useful in the future if you move to a newer map platform such as Azure Maps.
    • You then need to serve the data, which means creating a simple query API. How this designed would be based on your overall architecture. You may already have an API that can make queries to the backend services or have to create a simple standalone one using something like an Azure function. How you query and expose this data would depend on how your analysis works. I have a section below on different ways to serve the data.

    Methods to serve the data:

    • If you only want to query a small subset of postal codes (maybe one or two hundred at most), you can often get away with a simple query service where you call the database, get the postal boundaries you need and return those to your client-side app where you load them in a similar way to what you are doing now. Note, even if the map control is capable of rendering more polygons, you will likely find the loading time of the polygon data is long. I've seen some apps that took this approach with thousands of high-resolution polygons and the user had to wait several minutes for the data to download to the app which is not ideal.
    • If you want to show all visible postal codes within the map area, you will quickly run into performance issues if the user zooms out a bit as that will be a ton of data. To support this scenario the main method used is to tile the data. With Bing Maps you can only really use image-based tiles which means having a backend service that generates these images from the data. A tool such as GeoServer can save you some work, but image-based tiles for this type of scenario is an old method that most have moved away from. Vector based tiles are more commonly used today as it is a much more efficient data format that separates the styling from the data (you only have to create a tile once for all users). The PostGIS plugin for PostgreSQL return geospatial data as vector tiles as a response natively which means it's about the same amount of work as querying the raw polygon data and returning that to the user. When it comes to analysis two map apps, vector-based tiles provide a ton of benefits. This is part of the reason why Power BI maps moved from Bing Maps to Azure Maps (Even the Bing Maps consumer website uses Azure Maps now).
    • If you limit the zoom level and number of polygons that are loaded, you can get away with loading all polygons within the map area (mix of the first two options above), the user just needs to be zoomed in accordingly.
    1 person found this answer helpful.