{"id":11667,"date":"2023-12-01T16:51:40","date_gmt":"2023-12-01T14:51:40","guid":{"rendered":"https:\/\/www.geopostcodes.com\/en-GB\/?p=11667"},"modified":"2026-04-01T07:01:01","modified_gmt":"2026-04-01T07:01:01","slug":"how-to-calculate-distance-between-two-zip-codes-in-python","status":"publish","type":"post","link":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/","title":{"rendered":"How to Calculate Distance Between Two Postcodes in Python"},"content":{"rendered":"\n<div style=\"height:24px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To calculate the distance between postal codes, use Python to match each postal code to latitude and longitude coordinates from GeoPostcodes, then compute straight-line distance using geodesic methods such as GeoPy or region-specific projections with PyProj.<\/p>\n\n\n\n<div style=\"height:24px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-wide\" style=\"background-color:#e9eaeb;color:#e9eaeb\"\/>\n\n\n\n<div style=\"height:28px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Key Takeaways<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Postal code distance is calculated by first matching each postal code to <strong>latitude and longitude coordinates<\/strong>, using data sources such as <strong>GeoPostcodes\u2019 standardized postcode files<\/strong>.<\/li>\n\n\n\n<li>In Python, libraries like <strong>GeoPy<\/strong> calculate accurate geodesic (\u201cas-the-crow-flies\u201d) distances, while <strong>PyProj<\/strong> enables region-specific distance calculations using local map projections.<\/li>\n\n\n\n<li>Geodesic methods work best for <strong>cross-country or global distances<\/strong>, while local projections are more accurate <strong>within a single country or region<\/strong>.<\/li>\n\n\n\n<li>Distances calculated in this article are <strong>straight-line distances<\/strong>, not driving or routing distances.<\/li>\n\n\n\n<li>Accurate, up-to-date postal code coordinate data is essential, which is why the article relies on <strong>GeoPostcodes\u2019 regularly updated worldwide datasets<\/strong>, with Nominatim used only as a fallback.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-wide\" style=\"background-color:#e9eaeb;color:#e9eaeb\"\/>\n\n\n\n<div style=\"height:48px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Introduction<\/strong><\/h2>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Have you ever wondered how far apart two <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/what-is-a-postcode\/\" target=\"_blank\" rel=\"noreferrer noopener\">postcodes<\/a> are? Knowing the distance between two postcodes can be very useful whether ordering something online or analyzing data. But how can you calculate it quickly and accurately?<\/p>\n\n\n\n<p>In this article, we will explain the basics of postcodes and geospatial data, introduce some Python libraries that can help you with distance calculation, and guide you through a step-by-step example of how to use a postcode distance formula. By the end of this article, you will be able to use Python code to calculate the distance between two points like a pro.<\/p>\n\n\n\n<p>To follow this tutorial, you will need a computer with a Python development environment; I use Spyder, which comes with the <a href=\"https:\/\/www.anaconda.com\/download\" target=\"_blank\" rel=\"noreferrer noopener\">Anaconda Python<\/a> distribution, but other editors like JupyterLab will also work (<a href=\"https:\/\/github.com\/GeoPostcodes\/blogs\/blob\/main\/calculate-distance-between-2-zip-codes\/distance_between_2_zips.ipynb\" target=\"_blank\" rel=\"noreferrer noopener\">use the following script<\/a>). You will also need the provided postcode sample CSVs downloaded to your computer. Check our portal to <a href=\"https:\/\/public.geopostcodes.com\/portal-signup\" target=\"_blank\" rel=\"noreferrer noopener\">download free samples<\/a>.<\/p>\n\n\n\n<p class=\"has-background\" style=\"background-color:#d7efff\">\ud83d\udca1 For over 15 years, we have created the most comprehensive&nbsp;<a href=\"https:\/\/www.geopostcodes.com\/en-GB\/postal-zip-code-database\/\" target=\"_blank\" rel=\"noreferrer noopener\">worldwide postcode database<\/a>. Our location data is updated weekly, relying on more than 1,500 sources. Browse GeoPostcodes datasets and&nbsp;<strong><a href=\"https:\/\/public.geopostcodes.com\/portal-signup\" target=\"_blank\" rel=\"noreferrer noopener\">download a free sample here<\/a>.<\/strong><\/p>\n\n\n\n<div style=\"height:1px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">The data you\u2019ll need<\/h2>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Before beginning, make sure to download Postcode CSV Files containing zip\/postal codes along with their latitude and longitude:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Required columns: <code>postcode<\/code>, <code>latitude<\/code>, <code>longitude<\/code><\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Download free samples from <a href=\"https:\/\/public.geopostcodes.com\/portal-signup\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>GeoPostcodes portal<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Understanding Zip\/Post Codes and Geospatial Data<\/strong><\/h2>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Postcodes in the United States and postcodes worldwide are alphanumeric systems employed by postal services to enhance mail sorting and delivery efficiency. In the U.S., postcodes, consisting of five digits, signify regions, sectional center facilities, and specific post offices. Internationally, postcodes vary in format but share the purpose of facilitating effective mail distribution.<\/p>\n\n\n\n<p>These codes are essential for geospatial data, providing geographic attributes crucial for various applications. By utilizing postcode or postal codes and knowing the <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/geocoding-building-a-postcode-to-coordinates-converter\/\" target=\"_blank\" rel=\"noreferrer noopener\">latitude and longitude<\/a> of an address, we can perform calculations like the distance between two locations. However, it&#8217;s crucial to acknowledge their limitations and range of methods suited to different cases.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>The Role of Postcodes in Distance Calculation<\/strong><\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Before using Python code to calculate the distance between two points or two postcodes, we need information about their geographic <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/postcode-to-coordinates-converter\/\" target=\"_blank\" rel=\"noreferrer noopener\">coordinates<\/a>, specifically latitude (lat) and longitude (long).<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Latitude<\/strong> is the angle between the equator and a point on the earth&#8217;s surface, measured in degrees north or south. <\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Longitude<\/strong> is the angle between the prime meridian and a point on the earth&#8217;s surface, measured in degrees east or west. <\/li>\n<\/ul>\n\n\n\n<p>Together, latitude and longitude form a unique pair of numbers that can pinpoint any location on the globe.<\/p>\n\n\n\n<p>Once we have the lat and long coordinates of two postcodes, we can use various methods to compute the distance between them.<\/p>\n\n\n\n<p>It&#8217;s important to note that the distances calculated in this tutorial represent &#8216;as the crow flies&#8217; measurements. This means we&#8217;re computing the shortest direct distance between two points on the Earth&#8217;s surface, not accounting for any physical barriers or specific travel routes.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"444\" src=\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2023\/12\/Zip-code-breakdown-1024x444.webp\" alt=\"GeoPostcodes-Zip-code-breakdown\" class=\"wp-image-16752\" style=\"width:637px;height:auto\" srcset=\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2023\/12\/Zip-code-breakdown-1024x444.webp 1024w, https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2023\/12\/Zip-code-breakdown-300x130.webp 300w, https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2023\/12\/Zip-code-breakdown-768x333.webp 768w, https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2023\/12\/Zip-code-breakdown-1536x667.webp 1536w, https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2023\/12\/Zip-code-breakdown-2048x889.webp 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Geospatial Data Sources for Postcodes<\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>There are many sources where we can obtain geospatial data for postcodes in the form of APIs and open-source <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/boundaries-database\/\" target=\"_blank\" rel=\"noreferrer noopener\">boundary<\/a> files, but the most straightforward are CSVs and pre-existing Python packages.<\/p>\n\n\n\n<p>In my Python script, I&#8217;ll utilize <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/\" target=\"_blank\" rel=\"noreferrer noopener\">GeoPostcodes<\/a>&#8216; standardized postcode files for Great Britain and Mexico and Nominatim from the GeoPy package, allowing me to calculate postcodes not included in the CSV files. <\/p>\n\n\n\n<p>Our GeoPostcodes postcode files have the advantage of being regularly updated to ensure accuracy and up-to-date data. Download a <a href=\"https:\/\/public.geopostcodes.com\/portal-signup\" target=\"_blank\" rel=\"noreferrer noopener\">free sample<\/a> on our website. <\/p>\n\n\n\n<p>I&#8217;ve deliberately selected postcode data from two countries, Great Britain and Mexico, to showcase how various Python methods may excel in specific scenarios. Further elaboration on this topic will be provided in subsequent blog sections.<\/p>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Using Python Libraries for Distance Calculation<\/strong><\/h2>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Python is a powerful and versatile programming language with many libraries and modules for geospatial data and distance calculation. This section will introduce two of the most popular and useful ones: GeoPy and PyProj.<\/p>\n\n\n\n<p>GeoPy emerges as a powerful tool in the realm of geospatial calculations. Leveraging sophisticated algorithms, GeoPy converts addresses or postcodes into accurate geographic coordinates. The library&#8217;s standout feature lies in its geodesic distance calculations, where it employs Vincenty formula in Python to calculate the shortest path between two sets of coordinates.<\/p>\n\n\n\n<p>With user-friendly integration into Python scripts, GeoPy empowers users to effortlessly make precise and reliable distance measurements, making it a go-to solution for tasks that demand accuracy, such as <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/supply-chain-network-design-what-is-it-and-how-does-it-work\/\" target=\"_blank\" rel=\"noreferrer noopener\">supply chain<\/a> and data analytics.<\/p>\n\n\n\n<p>PyProj is a Python library specializing in coordinate projections and transformations. Particularly valuable when geographic coordinates need translation into projected space, PyProj supports a wide range of projections, allowing users to tailor their approach to specific regional contexts. <\/p>\n\n\n\n<p>In our demonstration, PyProj allows us to use specific projections tailored to countries and regions (in my example, Great Britain and Mexico), showcasing its adaptability in diverse scenarios. This flexibility positions PyProj as a robust tool for users requiring nuanced control over coordinate systems, making it a strategic choice in geospatial applications.<\/p>\n\n\n\n<p>While GeoPy and PyProj play integral roles in geospatial calculations, their strengths lie in distinct domains. GeoPy stands out for its accuracy in global geodesic calculations, ensuring accuracy across the Earth&#8217;s varied landscapes. On the other hand, PyProj&#8217;s forte lies in its ability to create and manipulate region-specific projections, offering users a calculation tailored to their region of interest. <\/p>\n\n\n\n<p>In our upcoming demonstration, we will utilize both libraries, combining GeoPy&#8217;s geodesic calculations with PyProj&#8217;s custom projections to showcase a comprehensive approach to distance measurement. <\/p>\n\n\n\n<p>The two libraries showcase the Python tools for tackling diverse geospatial challenges, ensuring optimal accuracy and context-awareness in distance calculations.<\/p>\n\n\n\n<p>We will now break down the different blocks of code that allow us to calculate the distance between two postcodes.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1. Reading CSV files with Python<\/strong><\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Before diving into calculation methods, we must write code to read the coordinates associated with the postcodes from our CSV file. Let&#8217;s begin by importing the relevant packages and defining a function to read the CSV and store the information.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import csv\u00a0 # For reading and writing CSV files\n\n\n# Paths to CSV files on your local machine\n\ncsv_file_1 = r\"C:\\PATH\\TO\\CSV1\"\n\ncsv_fileh_2 = r\"C:\\PATH\\TO\\CSV2\"\n\n\n# Open CSV and store lat and lon associated to the postcodes in the file for a first CSV\n\nwith open(csv_file_1, 'r', encoding='utf-8') as file_1:\n\n\u00a0\u00a0\u00a0\u00a0reader_1 = csv.DictReader(file_1, delimiter=';')\n\n\u00a0\u00a0\u00a0\u00a0for row_1 in reader_1:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0zip_code_1 = row_1['postcode']\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0latitude_1 = float(row_1['latitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0longitude_1 = float(row_1['longitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code_1] = (longitude_1, latitude_1)\n\n\nwith open(csv_file_2, 'r', encoding='utf-8') as file_2:\n\n\u00a0\u00a0\u00a0\u00a0reader_2 = csv.DictReader(file_2, delimiter=';')\n\n\u00a0\u00a0\u00a0\u00a0for row_2 in reader_2:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0zip_code_2 = row_2['postcode']\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0latitude_2 = float(row_2['latitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0longitude_2 = float(row_2['longitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code_2] = (longitude_2, latitude_2)\n\n\n# Enter the postcodes you want to calculate the distance between\n\nzip_code1 = 'ZIP1'\n\nzip_code2 = 'ZIP2'\n\n\n# Retrieve coordinates for the specified postcodes\n\ncoord1 = coordinates_dict.get(zip_code1)\n\ncoord2 = coordinates_dict.get(zip_code2)\n\n<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We can easily adapt the function to read coordinates from various locations on our local machine by providing the path to the desired CSV file as an argument. Note that the row variables to read the CSV are tailored to the GeoPostcodes CSV file structure, but this may need to be altered to correspond to different file structures.<\/p>\n\n\n\n<p> This is simple to do, and the names of the columns used in the example above should be altered to match the dataset you are using.<\/p>\n\n\n\n<p>The function reads postcodes and coordinates, generating a dictionary that links each postcode to its corresponding latitude and longitude. After executing the functions for each CSV file, the resulting dictionaries are merged into a comprehensive `coordinates_dict`, facilitating seamless distance calculations between them.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. Nominatim<\/strong><\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The geopy.geocoders.nominatim class is a part of the Geopy library and Geocodes from popular open source data OpenStreetMap (OSM). This package converts addresses or place names into latitude and longitude for areas of the globe where OSM has good coverage.<\/p>\n\n\n\n<p>We will need to import the relevant package in our script to use this. To use GeoPy, we need to install it using pip or conda (<strong>pip install geopy;<\/strong> in your command line), and we then import them in our script as shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from geopy.geocoders import Nominatim<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The next step is to define a function to get coordinates from an input:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def get_coordinates_from_nominatim(postal_code):\ngeolocator = Nominatim(user_agent=\"your_app_name\")\n\n\u00a0\u00a0\u00a0\u00a0location = geolocator.geocode(postal_code)\n\n\u00a0\u00a0\u00a0\u00a0if location:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return location.longitude, location.latitude\n\n\u00a0\u00a0\u00a0\u00a0else:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(f\"Coordinates not found for postal code: {postal_code}\")\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return None<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>&nbsp;We can then add some code after the <strong>coord2 = coordinates_dict.get(zip_code2)<\/strong> line so that if the postcode is not found in your local CSV files (we will merge all of this into a single code block at the end of the article), it will attempt to retrieve the lat lon from OSM using nominatim:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">if coord1 is None:\n\n\u00a0\u00a0\u00a0\u00a0if zip_code1 in coordinates_dict:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord1 = coordinates_dict[zip_code1]\n\n\u00a0\u00a0\u00a0\u00a0else:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord1 = get_coordinates_from_nominatim(zip_code1)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if coord1:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code1] = coord1\n\n\nif coord2 is None:\n\n\u00a0\u00a0\u00a0\u00a0if zip_code2 in coordinates_dict:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord2 = coordinates_dict[zip_code2]\n\n\u00a0\u00a0\u00a0\u00a0else:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord2 = get_coordinates_from_nominatim(zip_code2)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if coord2:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code2] = coord2<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Note that when using the Nominatim to fetch data, it is important to include the name of the country in the <strong>zip_code1<\/strong> and <strong>2<\/strong> input (e.g. <strong>\u201875011, France\u2019<\/strong> for the 11th arrondissement in Paris ) as postcodes are reused across different countries.<\/p>\n\n\n\n<p>For those interested in further details, the reference link to Nominatime in the GeoPy library can be found <a href=\"https:\/\/geopy.readthedocs.io\/en\/stable\/#nominatim\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3. GeoPy<\/strong><\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>GeoPy is a Python library that provides geocoding and distance measurement services. Geocoding converts addresses or postcodes into geographic coordinates, such as lat and long. Distance measurement calculates the distance between two or more locations using various formulas and methods.<\/p>\n\n\n\n<p>As we downloaded the GeoPy library in the Nominatim section above, we can import further relevant packages in our Python code as shown in the code block below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from geopy.distance import geodesic\u00a0 # For geodesic distance calculations<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The next step is to define a function to calculate the distance between the two postcodes using GeoPy:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def calculate_distance_geopy(coord1, coord2):\u00a0 \u00a0 distance_miles = geodesic(coord1, coord2).miles\ndistance_km = geodesic(coord1, coord2).kilometers\n\n\u00a0\u00a0\u00a0\u00a0return distance_miles, distance_km\n\n<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>GeoPy takes parameters representing lat and long for both coordinate sets. Upon execution, it returns the distance between the two postcodes in miles and kilometers (km), taking into account the Earth&#8217;s spherical shape. It utilizes the Vincenty formula in Python, which accounts for Earth&#8217;s flattening and curvature, and spherical trigonometry&#8217;s incorporation to accurately determine the shortest path between two points. This method is particularly good at providing precise results, especially when dealing with long distances and global measurements. It effectively solves the inverse problem of geodesy, pinpointing the shortest path between coordinates.<\/p>\n\n\n\n<p>For those interested in further details, the reference link to the Vincenty formula in Python and geodesic calculations in the GeoPy library can be found <a href=\"https:\/\/geopy.readthedocs.io\/en\/stable\/#geopy.distance.geodesic\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4. PyProj<\/strong><\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>PyProj is a Python library that offers functionality for different coordinate projections. Coordinate projections involve converting geographic coordinates into projected space tailored to specific countries or regions of the globe. Like Geopy, PyProj provides a versatile toolset for handling spatial data with precision.<\/p>\n\n\n\n<p>We are going to need to use the following package (if not installed, execute <strong>pip install pyproj;<\/strong> in your console):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from pyproj import Proj\u00a0 # For coordinate projections<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now, let&#8217;s define a function to calculate distances between two sets of coordinates using a country-specified projection with PyProj:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def calculate_distance_projection(coord1, coord2, projection):\n\n\u00a0\u00a0\u00a0\u00a0# Convert coordinates to projected space using the specified projection\n\n\u00a0\u00a0\u00a0\u00a0lon1, lat1 = coord1\n\n\u00a0\u00a0\u00a0\u00a0lon2, lat2 = coord2\n\n\u00a0\u00a0\u00a0\u00a0x1, y1 = projection(lon1, lat1)\n\n\u00a0\u00a0\u00a0\u00a0x2, y2 = projection(lon2, lat2)\n\n# Calculate distance in meters and convert to miles and kilometers\n\n\u00a0\u00a0\u00a0\u00a0distance_meters = ((x2 - x1)  2 + (y2 - y1)  2) ** 0.5\n\n\u00a0\u00a0\u00a0\u00a0distance_km = distance_meters \/ 1000\n\n\u00a0\u00a0\u00a0\u00a0distance_miles = distance_km \/ 1.60934\u00a0 # Conversion factor\n\n\u00a0\u00a0\u00a0\u00a0return distance_miles, distance_km<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This function accepts lat and long coordinates and a projection function, returning distances in both miles and kilometers. It caters to the specific needs of coordinate projections, making it a valuable addition to your exploration of distance calculation methods in Python. For more in-depth information on PyProj and coordinate projections, refer to the <a href=\"https:\/\/pyproj4.github.io\/pyproj\/stable\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">official documentation<\/a>.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5. Plotting the results<\/strong><\/h3>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/K5JqZCz-7IUMVEk3mTckvUPojr8_DsCxoVgMbkPHcuMJCvcsgZuSzXfaTZX1B5HRGZS8u8Do_J9WlLxa7HY87qYl_UB3w6XfUzlCJhk4BAzJ6G98ENqRolYhIEn_oox6I8Bs9ew5uzpHrBcbXbHEsDA\" alt=\"\"\/><\/figure>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To visualize our results, let&#8217;s create a function for plotting the results. This function will create the <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/postcode-map-power-bi\/\">map<\/a>, plot the distances, and display relevant information for our different methods. Here&#8217;s the modified code (if not installed, execute <strong>pip install cartopy;<\/strong> in your console):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import matplotlib.pyplot as plt\n\nimport cartopy.crs as ccrs\n\nimport cartopy.feature as cfeature\n\nfrom cartopy.io import img_tiles<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We are now going to code the function to call the functions to calculate the distances between the different methods as well as plot the results:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def plot_map(ax, coord1, coord2, zip_code1, zip_code2, distances):\n\n\u00a0\u00a0\u00a0\u00a0osm_tiles = img_tiles.OSM()\n\n\u00a0\u00a0\u00a0\u00a0ax.add_image(osm_tiles, 8)\u00a0 # Adjust the zoom level (here, 8) as needed\n\n\u00a0\u00a0\u00a0\u00a0ax.set_extent([coord1[0] - 1, coord2[0] + 1, coord1[1] - 1, coord2[1] + 1])\n\n\u00a0\u00a0\u00a0\u00a0ax.add_feature(cfeature.COASTLINE, edgecolor='#01295F', linewidth=0.75)\n\n\u00a0\u00a0\u00a0\u00a0ax.plot([coord1[0], coord2[0]], [coord1[1], coord2[1]], 'k-', linewidth=0.75)\n\n\u00a0\u00a0\u00a0\u00a0point1 = ax.plot(coord1[0], coord1[1], 'o', color='#e63946', markersize=3, label=f'{zip_code1}')\n\n\u00a0\u00a0\u00a0\u00a0point2 = ax.plot(coord2[0], coord2[1], 'o', color='#00a77d', markersize=3, label=f'{zip_code2}')\n\n\u00a0\u00a0\u00a0\u00a0ax.set_title(f'Distance between {zip_code1} and {zip_code2}')\n\n\u00a0\u00a0\u00a0\u00a0return point1, point2\n\n\nfig, ax = plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()}, dpi=900)\n\n\nif zip_code1 in coordinates_dict and zip_code2 in coordinates_dict:\n\n\u00a0\u00a0\u00a0\u00a0coord1 = coordinates_dict[zip_code1]\n\n\u00a0\u00a0\u00a0\u00a0coord2 = coordinates_dict[zip_code2]\n\n\n\u00a0\u00a0\u00a0\u00a0distance_geopy = calculate_distance_geopy(coord1[::-1], coord2[::-1])\n\n\u00a0\u00a0\u00a0\u00a0distance_geopy_miles, distance_geopy_km = distance_geopy\n\n\n\u00a0\u00a0\u00a0\u00a0projection_1 = Proj('EPSG:27700')\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_1 = calculate_distance_projection(coord1, coord2, projection_1)\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_1_miles, distance_projection_1_km = distance_projection_1\n\n\u00a0\u00a0\u00a0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0projection_2 = Proj('EPSG:6362')\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_2 = calculate_distance_projection(coord1, coord2, projection_2)\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_2_miles, distance_projection_2_km = distance_projection_2\n\n\n\u00a0\u00a0\u00a0\u00a0point1, point2 = plot_map(ax, coord1, coord2, zip_code1, zip_code2, None)\n\n\n\u00a0\u00a0\u00a0\u00a0# Set the title of the plot as the method name\n\n\u00a0\u00a0\u00a0\u00a0ax.set_title(f'Distance between {zip_code1} and {zip_code2}')\n\n\n\u00a0\u00a0\u00a0\u00a0# Add legend\n\n\u00a0\u00a0\u00a0\u00a0ax.legend()\n\n\u00a0\u00a0\u00a0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0# Your existing code for legend_distances_text\n\n\u00a0\u00a0\u00a0\u00a0legend_distances_text = f'Distances\\n\\nGeopy (miles): {distance_geopy_miles:.2f}\\nGeopy (km): {distance_geopy_km:.2f}\\n\\nProjection (GB) (miles): {distance_projection_1_miles:.2f}\\nProjection (GB) (km): {distance_projection_1_km:.2f}\\n\\nProjection (MX) (miles): {distance_projection_2_miles:.2f}\\nProjection (MX) (km): {distance_projection_2_km:.2f}'\n\n\u00a0\u00a0\u00a0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0fig.text(1.1, 0.5, legend_distances_text, transform=ax.transAxes, fontsize='small', va='center', ha='left', bbox=dict(facecolor='white', alpha=0.8, edgecolor='black', boxstyle='round,pad=0.3'))\n\n\u00a0\u00a0\u00a0\u00a0\n\nplt.tight_layout()\n\nplt.show()<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Note that this is also where you specify the projection systems you want to use for the PyProj method in the lines <strong>projection_1 = Proj(&#8216;EPSG:27700&#8217;)<\/strong> and the same for <strong>projection_2<\/strong>. For my case, I have used the projection for Great Britain (EPSG:27700) and Mexico (EPSG:6362). You can find projection systems best suited to your region on the following PDF where the WKID fits into the Proj line as such:<a href=\"https:\/\/pro.arcgis.com\/en\/pro-app\/latest\/help\/mapping\/properties\/pdf\/projected_coordinate_systems.pdf\" target=\"_blank\" rel=\"noreferrer noopener\"> <strong>Proj(\u2018EPSG:WKID\u2019)<\/strong><\/a>. <\/p>\n\n\n\n<p>Also, note that I am using an Open Street Map (OSM) base map for aesthetic purposes; it greatly increases the time of computation for the plot, especially for longer distances; comment on these lines for faster computation of the plot.<\/p>\n\n\n\n<p> This script block accepts the necessary data and displays the distances on a map with points, lines, and informative legends. I have tailored this part of the script to return a plot that I find clear and aesthetically pleasing, but all the parameters can be altered to your liking. For more in-depth information on <a href=\"https:\/\/matplotlib.org\/stable\/contents.html\" target=\"_blank\" rel=\"noreferrer noopener\">Matplotlib <\/a>and <a href=\"https:\/\/scitools.org.uk\/cartopy\/docs\/latest\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cartopy<\/a>, refer to the official documentation.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>6. Comparing Distance Calculation Methods: A Comprehensive Script<\/strong><\/h3>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now that we&#8217;ve explored various methods for calculating distances between postcodes using Python let&#8217;s combine these methods into a comprehensive script. In this example, the script allows us to compare the results for different distance calculation techniques for various postcodes from Great Britain and Mexico.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Integrating into a single script<\/strong><\/h4>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Let&#8217;s take a closer look at how we can bring all these components we have discussed into a single script:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># -*- coding: utf-8 -*-\n\n\nimport csv\n\nfrom geopy.distance import geodesic\n\nfrom geopy.geocoders import Nominatim\n\nfrom pyproj import Proj\n\nimport matplotlib.pyplot as plt\n\nimport cartopy.crs as ccrs\n\nimport cartopy.feature as cfeature\n\n\ndef calculate_distance_geopy(coord1, coord2):\n\n\u00a0\u00a0\u00a0\u00a0distance_miles = geodesic(coord1, coord2).miles\n\n\u00a0\u00a0\u00a0\u00a0distance_km = geodesic(coord1, coord2).kilometers\n\n\u00a0\u00a0\u00a0\u00a0return distance_miles, distance_km\n\n\ndef calculate_distance_projection(coord1, coord2, projection):\n\n\u00a0\u00a0\u00a0\u00a0lon1, lat1 = coord1\n\n\u00a0\u00a0\u00a0\u00a0lon2, lat2 = coord2\n\n\u00a0\u00a0\u00a0\u00a0x1, y1 = projection(lon1, lat1)\n\n\u00a0\u00a0\u00a0\u00a0x2, y2 = projection(lon2, lat2)\n\n\u00a0\u00a0\u00a0\u00a0distance_meters = ((x2 - x1)  2 + (y2 - y1)  2) ** 0.5\n\n\u00a0\u00a0\u00a0\u00a0distance_km = distance_meters \/ 1000\n\n\u00a0\u00a0\u00a0\u00a0distance_miles = distance_km \/ 1.60934\n\n\u00a0\u00a0\u00a0\u00a0return distance_miles, distance_km\n\n\ndef get_coordinates_from_nominatim(postal_code):\n\n\u00a0\u00a0\u00a0\u00a0geolocator = Nominatim(user_agent=\"your_app_name\")\n\n\u00a0\u00a0\u00a0\u00a0location = geolocator.geocode(postal_code)\n\n\u00a0\u00a0\u00a0\u00a0if location:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return location.longitude, location.latitude\n\n\u00a0\u00a0\u00a0\u00a0else:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(f\"Coordinates not found for postal code: {postal_code}\")\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return None\n\n\ncsv_file_1 = r\"C:\\Users\\Colin\\Desktop\\blog\\zip_code_distance\\GPC-POST-GEO-NORM-GB_CSV\\GPC-POSTCODES-GEO-NORM-GB.csv\"\n\ncsv_file_2 = r\"C:\\Users\\Colin\\Desktop\\blog\\zip_code_distance\\GPC-POST-GEO-NORM-MX_CSV\\GPC-POSTCODES-GEO-NORM-MX.csv\"\n\n\ncoordinates_dict = {}\n\n\nwith open(csv_file_1, 'r', encoding='utf-8') as file_1:\n\n\u00a0\u00a0\u00a0\u00a0reader_1 = csv.DictReader(file_1, delimiter=';')\n\n\u00a0\u00a0\u00a0\u00a0for row_1 in reader_1:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0zip_code_1 = row_1['postcode']\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0latitude_1 = float(row_1['latitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0longitude_1 = float(row_1['longitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code_1] = (longitude_1, latitude_1)\n\n\nwith open(csv_file_2, 'r', encoding='utf-8') as file_2:\n\n\u00a0\u00a0\u00a0\u00a0reader_2 = csv.DictReader(file_2, delimiter=';')\n\n\u00a0\u00a0\u00a0\u00a0for row_2 in reader_2:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0zip_code_2 = row_2['postcode']\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0latitude_2 = float(row_2['latitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0longitude_2 = float(row_2['longitude'])\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code_2] = (longitude_2, latitude_2)\n\n\nzip_code1 = 'ZIP1'\n\nzip_code2 = 'ZIP2'\n\n\ncoord1 = coordinates_dict.get(zip_code1)\n\ncoord2 = coordinates_dict.get(zip_code2)\n\n\nif coord1 is None:\n\n\u00a0\u00a0\u00a0\u00a0if zip_code1 in coordinates_dict:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord1 = coordinates_dict[zip_code1]\n\n\u00a0\u00a0\u00a0\u00a0else:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord1 = get_coordinates_from_nominatim(zip_code1)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if coord1:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code1] = coord1\n\n\nif coord2 is None:\n\n\u00a0\u00a0\u00a0\u00a0if zip_code2 in coordinates_dict:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord2 = coordinates_dict[zip_code2]\n\n\u00a0\u00a0\u00a0\u00a0else:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coord2 = get_coordinates_from_nominatim(zip_code2)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if coord2:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0coordinates_dict[zip_code2] = coord2\n\n\ndef plot_map(ax, coord1, coord2, zip_code1, zip_code2, distances):\n\n\u00a0\u00a0\u00a0\u00a0ax.add_feature(cfeature.COASTLINE, edgecolor='#01295F', linewidth=0.75)\n\n\u00a0\u00a0\u00a0\u00a0ax.plot([coord1[0], coord2[0]], [coord1[1], coord2[1]], 'k-', linewidth=0.75)\n\n\u00a0\u00a0\u00a0\u00a0point1 = ax.plot(coord1[0], coord1[1], 'o', color='#e63946', markersize=3, label=f'{zip_code1}')\n\n\u00a0\u00a0\u00a0\u00a0point2 = ax.plot(coord2[0], coord2[1], 'o', color='#00a77d', markersize=3, label=f'{zip_code2}')\n\n\u00a0\u00a0\u00a0\u00a0ax.set_title(f'Distance between {zip_code1} and {zip_code2}')\n\n\u00a0\u00a0\u00a0\u00a0return point1, point2\n\n\nfig, ax = plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()}, dpi=900)\n\n\nif zip_code1 in coordinates_dict and zip_code2 in coordinates_dict:\n\n\u00a0\u00a0\u00a0\u00a0coord1 = coordinates_dict[zip_code1]\n\n\u00a0\u00a0\u00a0\u00a0coord2 = coordinates_dict[zip_code2]\n\n\n\u00a0\u00a0\u00a0\u00a0distance_geopy = calculate_distance_geopy(coord1[::-1], coord2[::-1])\n\n\u00a0\u00a0\u00a0\u00a0distance_geopy_miles, distance_geopy_km = distance_geopy\n\n\n\u00a0\u00a0\u00a0\u00a0projection_1 = Proj('EPSG:27700')\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_1 = calculate_distance_projection(coord1, coord2, projection_1)\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_1_miles, distance_projection_1_km = distance_projection_1\n\n\u00a0\u00a0\u00a0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0projection_2 = Proj('EPSG:6362')\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_2 = calculate_distance_projection(coord1, coord2, projection_2)\n\n\u00a0\u00a0\u00a0\u00a0distance_projection_2_miles, distance_projection_2_km = distance_projection_2\n\n\n\u00a0\u00a0\u00a0\u00a0point1, point2 = plot_map(ax, coord1, coord2, zip_code1, zip_code2, None)\n\n\n\u00a0\u00a0\u00a0\u00a0# Set the title of the plot as the method name\n\n\u00a0\u00a0\u00a0\u00a0ax.set_title(f'Distance between {zip_code1} and {zip_code2}')\n\n\n\u00a0\u00a0\u00a0\u00a0# Add legend\n\n\u00a0\u00a0\u00a0\u00a0ax.legend()\n\n\u00a0\u00a0\u00a0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0# Your existing code for legend_distances_text\n\n\u00a0\u00a0\u00a0\u00a0legend_distances_text = f'Distances\\n\\nGeopy (miles): {distance_geopy_miles:.2f}\\nGeopy (km): {distance_geopy_km:.2f}\\n\\nProjection (GB) (miles): {distance_projection_1_miles:.2f}\\nProjection (GB) (km): {distance_projection_1_km:.2f}\\n\\nProjection (MX) (miles): {distance_projection_2_miles:.2f}\\nProjection (MX) (km): {distance_projection_2_km:.2f}'\n\n\u00a0\u00a0\u00a0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0fig.text(1.1, 0.5, legend_distances_text, transform=ax.transAxes, fontsize='small', va='center', ha='left', bbox=dict(facecolor='white', alpha=0.8, edgecolor='black', boxstyle='round,pad=0.3'))\n\n\u00a0\u00a0\u00a0\u00a0\n\nplt.tight_layout()\n\nplt.show()<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>By running this script, you&#8217;ll obtain not only the distances but also a visual representation of the geographical locations and the variations between different calculation methods. Note that in this example the PyProj is calculated for a Great Britain and Mexico projection, you may want to alter this to suit your case.<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Comparing methods<\/strong><\/h4>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This section delves into the script&#8217;s results, examining the distances obtained using GeoPy&#8217;s geodesic calculations and PyProj&#8217;s custom projections for both Great Britain and Mexico. This comparative analysis will provide insights into when each method excels and how it performs in different geographic contexts.<\/p>\n\n\n\n<p>Orthodromy, a basic method for calculating geographical distances, employs a straightforward formula to determine the direct path between two points on the Earth&#8217;s surface. In this method, the distance (kilometers) between two locations, denoted as A and B, is computed using the equation.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Distance(A, B) = 6371  ACos(Cos(LatA)  Cos(LatB)  Cos(LngB - LngA) + Sin(LatA)  Sin(LatB)).\u00a0<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This method involves basic trigonometric calculations and requires latitude and longitude inputs in radians. While orthodromy is an introductory approach to distance measurement, its simplicity and lack of sophistication may limit its suitability for tasks demanding greater precision or advanced geodetic considerations.<\/p>\n\n\n\n<p>While many online resources often focus on the haversine method for calculating distances, this article takes a different approach. Recognizing the wealth of information already available on the haversine method, we aim to explore other efficient and innovative Python-based techniques. <\/p>\n\n\n\n<p>This exploration allows us to provide fresh insights and alternative methods, broadening the scope of tools available to our readers for calculating distances between postcodes.<\/p>\n\n\n\n<p>Let\u2019s begin by comparing the distance between two Great Britain postcodes. Feel free to download samples for other countries from the GeoPostcode portal. Note that if the postcodes you want to use are not in the files your code is fetching from, it will attempt to find the data from OSM using Nominatim where more specifications (country name) may need to be used.<br><br><strong>NE1 1AD<\/strong> in Newcastle and <strong>TR1 1UH<\/strong> in Truro. The Python script gives us the following results:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/3B_YQg2JCPgvQupWX8g2rz8ie7RLjItIEIr_61ZZmDVPdv45CHZ304Ig3hhzi3ltk-KYiueqFfKE2C1wu5qLuoO70kUZG1voBCm2l-EjZbuELiaQU3OF_zuLKAkscazqY8ye0WVFI-WdJ6UjMzHjcrU\" alt=\"\"\/><\/figure>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We observed a remarkable similarity between the Geopy and Projection (GB) results. The two methods yielded distances differing by only 0.12 miles, indicating consistent and reliable calculations by these two methods.<\/p>\n\n\n\n<p>For this specific case, the slight superiority of the Projection (GB) method becomes apparent; the method employs a custom projection tailored specifically for Great Britain, optimizing the accuracy of distance calculations within the region. The example underscores the importance of selecting a method aligned with the specific geography of interest to ensure reliable outcomes.<\/p>\n\n\n\n<p>However, the results take a noticeable turn when using Projection (MX), resulting in a distance measurement of 410.27 miles. This significant discrepancy can be attributed to the choice of a projection optimized for Mexico rather than Great Britain. <\/p>\n\n\n\n<p>When employing a projection tailored for a different geographical region, especially one with distinct characteristics, the accuracy of distance calculations will be compromised.<\/p>\n\n\n\n<p>In conclusion, the choice between Geopy and different projections hinges on the geographic context of the analysis. While Projection (GB) proves effective for distances within Great Britain, using Projection (MX) for these postcodes leads to less accurate results. <\/p>\n\n\n\n<p>This example emphasizes the necessity of aligning the chosen method with the geographic scope of the analysis to ensure optimal accuracy and reliable outcomes.<\/p>\n\n\n\n<p>Now, let&#8217;s look at what happens if we take a postcode from Great Britain and one from Mexico. We will do the distance between <strong>E14 3PW<\/strong> in London and <strong>01490<\/strong> in Mexico City. <\/p>\n\n\n\n<p>The Python script gives us the following results:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/y4F71Gx87t1L7j2SkvuxUs7ZpLShfAtbJUJm-bWueuDuTYYIsG8rHBEB2fmHDfk3c3h78IgtpBe3iORCNBIEhf5sCg_xnyy9g8j9GFUCz-nrrN9Fozv1_cNhwZIA4vs4UjlXCmmPAYIAbfnu34f_Rz0\" alt=\"\"\/><\/figure>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This comparison underscores a significant discrepancy in the results obtained using local projections. While Projection (GB) demonstrated accuracy within Great Britain in the previous example, its performance falters when applied to locations spanning different continents. The distance measured using both country-specific projections indicates substantial inaccuracies when dealing with an intercontinental distance calculation.<\/p>\n\n\n\n<p>In contrast, Geopy delivers a more reliable result of 5567.41 miles for the same pair of coordinates. This outcome highlights the versatility and robustness of Geopy&#8217;s geodesic distance calculations on the ellipsoidal model of the Earth. <\/p>\n\n\n\n<p>Operating independently of localized projections, Geopy is a more suitable choice for scenarios involving locations across diverse regions, showcasing its adaptability and accuracy in global comparisons.<\/p>\n\n\n\n<p>In summary, when assessing distances between Great Britain and Mexico, both local projection methods, namely Projection (GB) and Projection (MX), demonstrate limitations when calculating distances between countries, leading to less accurate results compared to the geodesic calculations offered by Geopy.<\/p>\n\n\n\n<p>This example underscores the critical consideration of geographic context and the necessity of choosing appropriate methods to ensure precise and reliable distance measurements, particularly when dealing with locations spanning different countries.<\/p>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Bonus: Distance Between Postcodes Excel<\/h2>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><span style=\"margin: 0px;padding: 0px\">The formula used to calculate the distance between two geographical points is called&nbsp;<strong>orthodromy<\/strong>, as mentioned above<\/span>.<\/p>\n\n\n\n<p>This same formula can be used in Excel to calculate the distance between two postcodes:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Distance(A,B) = 6371 * ACos( Cos(LatA) * Cos(LatB) * Cos(LngB - LngA) + Sin(LatA) * Sin(LatB) )<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Convert the postcodes to latitude and longitude coordinates. Alternatively, use the <a href=\"https:\/\/public.geopostcodes.com\/portal-signup\" target=\"_blank\" rel=\"noreferrer noopener\">GeoPostcodes database<\/a>, which includes pre-geocoded postcodes.<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Once you have the coordinates for both postcodes, apply the orthodromy formula to calculate the distance.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Latitude and longitude values must be input in radians:&nbsp;<em>radians = degrees * PI\/180<\/em>.<\/li>\n<\/ul>\n\n\n\n<p>The resulting number is the distance in <strong>kilometers<\/strong> between point A and point B. If you wish to return a result in <strong>miles<\/strong> (or any other unit), you must substitute the value 6371, which stands for the approximate radius of the Earth in km, by its equivalent in miles (or any other unit), that is, 3959 miles.<\/p>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In this guide, we explored the art of calculating distances between postcodes using Python, a valuable skill for logistics planning, online shopping, and data analysis, to name a few.<\/p>\n\n\n\n<p>We delved into the role of postcodes as a system for efficient mail delivery, recognizing their significance in geospatial data despite inherent limitations in representing geographic areas.<\/p>\n\n\n\n<p>Leveraging Python libraries like Geopy and PyProj, we demonstrated how to read coordinates from CSV files and crafted a script for comparing distance calculation techniques. The script highlighted the synergy between Geopy and local projections for precise results within specific regions, emphasizing the critical role of geographic alignment.<\/p>\n\n\n\n<p>In a global context, the limitations of local projections were exposed, showcasing GeoPy&#8217;s adaptability and precision. Our exploration underlines the importance of context-aware distance measurements and the need to select methods tailored to specific regions. <\/p>\n\n\n\n<p>Python&#8217;s versatility and powerful libraries empower users to navigate geospatial complexities with finesse, ensuring accurate and reliable distance calculations across diverse scenarios.<\/p>\n\n\n\n<p>Data sources are key to this process. <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/postal-zip-code-database\/\" target=\"_blank\" rel=\"noreferrer noopener\">GeoPostcodes<\/a> maintains a <a href=\"https:\/\/www.geopostcodes.com\/en-GB\/postal-zip-code-database\/\" target=\"_blank\" rel=\"noreferrer noopener\">worldwide database of postcodes<\/a> allowing you to do distance calculations between locations anywhere in the world. Our files have the advantage of being regularly updated to ensure accuracy and up-to-date data. <\/p>\n\n\n\n<p><a href=\"https:\/\/public.geopostcodes.com\/portal-signup\" target=\"_blank\" rel=\"noreferrer noopener\">Browse the data yourself<\/a>, download a free sample, and reach out to us if you want to know more!<\/p>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<div id=\"wp-block-themeisle-blocks-accordion-aa5641a4\" class=\"wp-block-themeisle-blocks-accordion exclusive has-light-content-bg is-style-default\">\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>What is a Postcode distance calculator?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>A Postcode distance calculator estimates the distance between two postal codes using their geographic coordinates.<\/p>\n\n\n\n<p>In practice, it converts Postcodes into latitude and longitude values and measures the straight-line distance between them.<\/p>\n\n\n\n<p>This approach supports large-scale analysis without relying on routing data.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>How do you calculate the distance between Postcodes in Python?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In Python, Postcode distance is calculated by matching each Postcode to latitude and longitude coordinates and applying a distance formula.<\/p>\n\n\n\n<p>Libraries such as GeoPy compute geodesic distance, while PyProj supports region-specific projections.<\/p>\n\n\n\n<p>GeoPostcodes provides standardized coordinate data to support these calculations.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>What is the difference between Postcode distance and Postcode mileage?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Postcode distance typically refers to straight-line distance between coordinates, while Postcode mileage expresses that same distance in miles.<\/p>\n\n\n\n<p>In other words, mileage is a unit choice, not a different calculation method.<\/p>\n\n\n\n<p>Both rely on the same coordinate-based approach.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>How accurate are distances calculated between Postcodes?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Postcode distances are approximate because they are based on centroid coordinates rather than exact addresses.<\/p>\n\n\n\n<p>Accuracy depends on the quality and freshness of the underlying Postcode data.<\/p>\n\n\n\n<p>Using updated reference data from GeoPostcodes improves consistency and reliability.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>Can Postcode distance be calculated in miles or kilometers?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Yes, Postcode distance can be calculated in either miles or kilometers.<\/p>\n\n\n\n<p>The unit depends on the distance formula and Earth radius value used in the calculation.<\/p>\n\n\n\n<p>GeoPy, for example, returns both miles and kilometers by default.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>What is the best Python distance formula for Postcodes?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The best Python distance formula depends on geographic scope.<\/p>\n\n\n\n<p>GeoPy&#8217;s geodesic distance works best for global and cross-country calculations.<\/p>\n\n\n\n<p>PyProj projections provide higher precision for distances within a specific country or region.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>When should you use GeoPy instead of projection-based distance methods?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>GeoPy should be used when calculating distances between Postcodes across different countries or continents.<\/p>\n\n\n\n<p>Projection-based methods are optimized for local regions and lose accuracy outside their intended area.<\/p>\n\n\n\n<p>GeoPy avoids this limitation by using global geodesic calculations.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>Where does Postcode coordinate data come from?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Postcode coordinate data comes from postal authorities, administrative sources, and curated geographic datasets.<\/p>\n\n\n\n<p>GeoPostcodes aggregates more than 1,500 authoritative sources into standardized postcode files.<\/p>\n\n\n\n<p>This ensures consistent coordinates across countries and updates over time.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>How do organizations calculate Postcode distances at scale?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Organizations calculate Postcode distances at scale by combining centralized postcode databases with automated scripts.<\/p>\n\n\n\n<p>Python libraries handle bulk distance calculations efficiently when paired with standardized reference data.<\/p>\n\n\n\n<p>This approach scales beyond spreadsheets and manual methods.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n\n\n\n<details class=\"wp-block-themeisle-blocks-accordion-item\"><summary class=\"wp-block-themeisle-blocks-accordion-item__title\"><div><strong>How does GeoPostcodes compare to other worldwide postal code database providers?<\/strong><\/div><\/summary><div class=\"wp-block-themeisle-blocks-accordion-item__content\">\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Compared with providers such as GeoNames, OpenStreetMap, Google Maps Platform, HERE, TomTom, Melissa, and Smarty, GeoPostcodes is positioned as an enterprise reference data provider rather than a mapping, API, or crowdsourced data service.<\/p>\n\n\n\n<p>Many alternatives focus on lookup, routing, or enrichment use cases, often relying on aggregated or community-maintained data that can vary in structure and update stability.<\/p>\n\n\n\n<p>In contrast, GeoPostcodes emphasizes standardized postal code data, stable identifiers, and frequent updates designed to support long-term master data management, analytics, and operational consistency across countries.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/details>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to use Python to calculate distances between postcodes accurately. A must-read for developers and data analysts in logistics and planning.<\/p>\n","protected":false},"author":31,"featured_media":11671,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[29],"tags":[61,62],"class_list":["post-11667","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-processing","tag-distance-calculation","tag-sticky-banner-blog-post"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to Calculate Distance Between Two Postcodes in Python<\/title>\n<meta name=\"description\" content=\"Learn how to use Python to calculate distances between zip codes accurately. A complete step-by-step guide for developers and data analysts.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Calculate Distance Between Two Zip Codes in Python\" \/>\n<meta property=\"og:description\" content=\"Learn how to use Python to calculate distances between zip codes accurately. A must-read for developers and data analysts in logistics and planning.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\" \/>\n<meta property=\"og:site_name\" content=\"GeoPostcodes\" \/>\n<meta property=\"article:published_time\" content=\"2023-12-01T14:51:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-01T07:01:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.geopostcodes.com\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"330\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Colin Bouqueniaux\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"How to Calculate Distance Between Two Zip Codes in Python\" \/>\n<meta name=\"twitter:description\" content=\"Learn how to use Python to calculate distances between zip codes accurately. A must-read for developers and data analysts in logistics and planning.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Colin Bouqueniaux\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\"},\"author\":{\"name\":\"Colin Bouqueniaux\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/person\/e7b8e6c9661afdf8df3f82e3a8b89de2\"},\"headline\":\"How to Calculate Distance Between Two Postcodes in Python\",\"datePublished\":\"2023-12-01T14:51:40+00:00\",\"dateModified\":\"2026-04-01T07:01:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\"},\"wordCount\":3826,\"publisher\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp\",\"keywords\":[\"Distance calculation\",\"Sticky Banner Blog Post\"],\"articleSection\":[\"Data Processing\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\",\"url\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\",\"name\":\"How to Calculate Distance Between Two Postcodes in Python\",\"isPartOf\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp\",\"datePublished\":\"2023-12-01T14:51:40+00:00\",\"dateModified\":\"2026-04-01T07:01:01+00:00\",\"description\":\"Learn how to use Python to calculate distances between zip codes accurately. A complete step-by-step guide for developers and data analysts.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage\",\"url\":\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp\",\"contentUrl\":\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp\",\"width\":800,\"height\":330,\"caption\":\"GeoPostcodes-How to Calculate Distance Between Two Zip Codes in Python\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.geopostcodes.be\/en-GB\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Calculate Distance Between Two Zip Codes in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#website\",\"url\":\"https:\/\/www.geopostcodes.com\/en-GB\/\",\"name\":\"GeoPostcodes\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.geopostcodes.com\/en-GB\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#organization\",\"name\":\"GeoPostcodes\",\"url\":\"https:\/\/www.geopostcodes.com\/en-GB\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2021\/04\/cropped-GeoPostcodes-color@2x-png.webp\",\"contentUrl\":\"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2021\/04\/cropped-GeoPostcodes-color@2x-png.webp\",\"width\":1331,\"height\":207,\"caption\":\"GeoPostcodes\"},\"image\":{\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/person\/e7b8e6c9661afdf8df3f82e3a8b89de2\",\"name\":\"Colin Bouqueniaux\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.geopostcodes.com\/wp-content\/uploads\/2025\/03\/cropped-IMG_6580-scaled-e1741618924637-512x512.webp\",\"contentUrl\":\"https:\/\/www.geopostcodes.com\/wp-content\/uploads\/2025\/03\/cropped-IMG_6580-scaled-e1741618924637-512x512.webp\",\"caption\":\"Colin Bouqueniaux\"},\"description\":\"My name is Colin Bouqueniaux. I\u2019m a Geodata Analyst at GeoPostcodes. I have developed expertise in researching and analyzing location data. I am researching the different levels of global administrative divisions at GeoPostcodes. My job consists of cleaning up location data to make sure all boundary geometries fit together perfectly and connect to the surrounding countries. I hold a Master's in Geology, planetary science, and space exploration from Sorbonne University. Before joining GeoPostcodes, I had been a research analyst at the Observatory of Paris and the Southwest Research Institute in the US.\",\"url\":\"https:\/\/www.geopostcodes.com\/en-GB\/blog\/author\/colin-bouqueniaux\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Calculate Distance Between Two Postcodes in Python","description":"Learn how to use Python to calculate distances between zip codes accurately. A complete step-by-step guide for developers and data analysts.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/","og_locale":"en_US","og_type":"article","og_title":"How to Calculate Distance Between Two Zip Codes in Python","og_description":"Learn how to use Python to calculate distances between zip codes accurately. A must-read for developers and data analysts in logistics and planning.","og_url":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/","og_site_name":"GeoPostcodes","article_published_time":"2023-12-01T14:51:40+00:00","article_modified_time":"2026-04-01T07:01:01+00:00","og_image":[{"width":800,"height":330,"url":"https:\/\/www.geopostcodes.com\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","type":"image\/webp"}],"author":"Colin Bouqueniaux","twitter_card":"summary_large_image","twitter_title":"How to Calculate Distance Between Two Zip Codes in Python","twitter_description":"Learn how to use Python to calculate distances between zip codes accurately. A must-read for developers and data analysts in logistics and planning.","twitter_image":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","twitter_misc":{"Written by":"Colin Bouqueniaux","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#article","isPartOf":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/"},"author":{"name":"Colin Bouqueniaux","@id":"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/person\/e7b8e6c9661afdf8df3f82e3a8b89de2"},"headline":"How to Calculate Distance Between Two Postcodes in Python","datePublished":"2023-12-01T14:51:40+00:00","dateModified":"2026-04-01T07:01:01+00:00","mainEntityOfPage":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/"},"wordCount":3826,"publisher":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/#organization"},"image":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","keywords":["Distance calculation","Sticky Banner Blog Post"],"articleSection":["Data Processing"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/","url":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/","name":"How to Calculate Distance Between Two Postcodes in Python","isPartOf":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage"},"image":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","datePublished":"2023-12-01T14:51:40+00:00","dateModified":"2026-04-01T07:01:01+00:00","description":"Learn how to use Python to calculate distances between zip codes accurately. A complete step-by-step guide for developers and data analysts.","breadcrumb":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#primaryimage","url":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","contentUrl":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","width":800,"height":330,"caption":"GeoPostcodes-How to Calculate Distance Between Two Zip Codes in Python"},{"@type":"BreadcrumbList","@id":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/how-to-calculate-distance-between-two-postcodes-in-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.geopostcodes.be\/en-GB\/"},{"@type":"ListItem","position":2,"name":"How to Calculate Distance Between Two Zip Codes in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.geopostcodes.com\/en-GB\/#website","url":"https:\/\/www.geopostcodes.com\/en-GB\/","name":"GeoPostcodes","description":"","publisher":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.geopostcodes.com\/en-GB\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.geopostcodes.com\/en-GB\/#organization","name":"GeoPostcodes","url":"https:\/\/www.geopostcodes.com\/en-GB\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/logo\/image\/","url":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2021\/04\/cropped-GeoPostcodes-color@2x-png.webp","contentUrl":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2021\/04\/cropped-GeoPostcodes-color@2x-png.webp","width":1331,"height":207,"caption":"GeoPostcodes"},"image":{"@id":"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/person\/e7b8e6c9661afdf8df3f82e3a8b89de2","name":"Colin Bouqueniaux","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.geopostcodes.com\/en-GB\/#\/schema\/person\/image\/","url":"https:\/\/www.geopostcodes.com\/wp-content\/uploads\/2025\/03\/cropped-IMG_6580-scaled-e1741618924637-512x512.webp","contentUrl":"https:\/\/www.geopostcodes.com\/wp-content\/uploads\/2025\/03\/cropped-IMG_6580-scaled-e1741618924637-512x512.webp","caption":"Colin Bouqueniaux"},"description":"My name is Colin Bouqueniaux. I\u2019m a Geodata Analyst at GeoPostcodes. I have developed expertise in researching and analyzing location data. I am researching the different levels of global administrative divisions at GeoPostcodes. My job consists of cleaning up location data to make sure all boundary geometries fit together perfectly and connect to the surrounding countries. I hold a Master's in Geology, planetary science, and space exploration from Sorbonne University. Before joining GeoPostcodes, I had been a research analyst at the Observatory of Paris and the Southwest Research Institute in the US.","url":"https:\/\/www.geopostcodes.com\/en-GB\/blog\/author\/colin-bouqueniaux\/"}]}},"jetpack_featured_media_url":"https:\/\/www.geopostcodes.com\/en-GB\/wp-content\/uploads\/2024\/02\/How-to-Calculate-Distance-Between-Two-Zip-Codes-in-Python.webp","_links":{"self":[{"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/posts\/11667","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/comments?post=11667"}],"version-history":[{"count":3,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/posts\/11667\/revisions"}],"predecessor-version":[{"id":43569,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/posts\/11667\/revisions\/43569"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/media\/11671"}],"wp:attachment":[{"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/media?parent=11667"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/categories?post=11667"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.geopostcodes.com\/en-GB\/wp-json\/wp\/v2\/tags?post=11667"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}