Geocoding Distance

maXbox Starter 142 – Get a GEO distance. “Natura abhorret vacuum1 – Spinoza. Source: 1390_Sphenic_Numbers2TIO_12_py_uc.txt 1397_Geolocation_distance12_uc.txt Nominatim can power the search box on your website, allowing your users to type free-form queries (“Cafe Paris, Cologne”) in any language. It also offers a structured query mode (“postcode=12345”, “city=London”, “type=cafe”) that helps you to automate geocoding of extensive address lists. https://sourceforge.net/projects/maxbox5/files/examples/1274_GoogleMapsAPI_General1.pas/download Sometimes life is like playing with us: You write some useful code that solves a problem, and then someone comes along and makes the problem much harder. Here’s how to continuously integrate new solutions without having to rewrite your old solutions (as much). Means you don’t have to change the language, you change the environment. Let’s start with a simple problem: Get the distance between two earth-coordinates. Calculating the geographical distance between two points on the Earth’s surface can be done using the Haversine formula. This formula accounts for the spherical shape of the Earth. Below is a Delphi and Python function that performs this calculation: type TipGeolocation = record Latitude: Double; //read Coordinates[0] write SetLatitude; Longitude: Double; //read Coordinates[1] write SetLongitude; end; For the purposes of this task we make the problem harder, a geocoding function with a record pair of coordinates: const EARTHS_RADIUS_IN_METERS = 6378137; function TipGeolocationDistanceInMetersTo( const AGeolocation: TipGeolocation; Latitude, Longitude: Double): Double; var LDeltaLat, LDeltaLong, LA: Double; begin LDeltaLat:= DegToRad(AGeolocation.Latitude - Latitude); LDeltaLong:= DegToRad(AGeolocation.Longitude - Longitude); LA:= Sin(LDeltaLat / 2) * Sin(LDeltaLat / 2) + Cos(DegToRad(Latitude)) * Cos(DegToRad(AGeolocation.Latitude)) * Sin(LDeltaLong / 2) * Sin(LDeltaLong / 2); Result:= Abs(EARTHS_RADIUS_IN_METERS * 2 * ArcTan2(Sqrt(LA), Sqrt(1 - LA))); end; This function calculates the distance between two points given their latitude and longitude in degrees. The example usage calculates the distance between Bern and Paris. Feel free to adapt the coordinates to your specific needs! Geoloc_setup; //reference data2 writeln('Distance Bern,CH - Paris,F: '+ format('%2.4f m ',[TipGeolocationDistanceInMetersTo(tipgeoloc1,lat2,lon2)])); And in Python: import math def haversine_distance(lat1, lon1, lat2, lon2): # Radius of the Earth in kilometers R = 6371.0 # Convert latitude and longitude from degrees to radians lat1_rad = math.radians(lat1) lon1_rad = math.radians(lon1) lat2_rad = math.radians(lat2) lon2_rad = math.radians(lon2) # Differences in coordinates dlat = lat2_rad - lat1_rad dlon = lon2_rad - lon1_rad # Haversine formula a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) *math.cos(lat2_rad) * math.sin(dlon / 2)**2 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) # Distance in kilometers distance = R * c return distance # Example usage lat1 = 46.94809 # Latitude of Bern lon1 = 7.44744 # Longitude of Bern lat2 = 48.8566 # Latitude of Paris lon2 = 2.3522 # Longitude of Paris distance = haversine_distance(lat1, lon1, lat2, lon2) print(f"The distance between Bern and Paris is {distance:.2f} kilometers.") The distance between Bern and Paris is 434.96 kilometers. Often, we calculate the great-circle distance of given two points in geophysics, for example, the distance from the seismic station to the epicenter. Supposing that we have two geographical points, and let’s say P1:(ϕ1,λ1)and P2:(ϕ2,λ2), where,ϕ and λ represent the latitude and longitude, respectively. Using Haversine formula, we can calculate the great-circle distance. The great-circle distance, orthodromic distance, or spherical distance is the distance between two points on a sphere, measured along the great-circle arc between them. Paris Place Madeleine Place de la Madeleine Next we need a geocoding API. Geocoding is the process of transformation of any location name into geographical coordinates, and the other way around (reverse geocoding). OpenWeather’s Geocoding API and OpenStreetMap supports both the direct and reverse methods, working at the level of city names, areas and districts, countries and states: https://nominatim.openstreetmap.org/search?format=json&q=madeleine,paris Test the link above then you get: Its not a unique place, different results as JSON possible Take the result with the most importance after place_rank like 0.50962: const URL_GEOLOCURL9 = 'https://nominatim.openstreetmap.org/search?format=json&q=%s'; URL_APILAY_GEO = 'https://api.apilayer.com/geo/country/capital/%s'; var fromgeo, togeo: Tlat

Apr 23, 2025 - 19:33
 0
Geocoding Distance

maXbox Starter 142 – Get a GEO distance.

“Natura abhorret vacuum1 – Spinoza.

Source: 1390_Sphenic_Numbers2TIO_12_py_uc.txt
1397_Geolocation_distance12_uc.txt

Nominatim can power the search box on your website, allowing your users to type free-form queries (“Cafe Paris, Cologne”) in any language. It also offers a structured query mode (“postcode=12345”, “city=London”, “type=cafe”) that helps you to automate geocoding of extensive address lists.

https://sourceforge.net/projects/maxbox5/files/examples/1274_GoogleMapsAPI_General1.pas/download

Sometimes life is like playing with us: You write some useful code that solves a problem, and then someone comes along and makes the problem much harder. Here’s how to continuously integrate new solutions without having to rewrite your old solutions (as much). Means you don’t have to change the language, you change the environment.

Let’s start with a simple problem: Get the distance between two earth-coordinates. Calculating the geographical distance between two points on the Earth’s surface can be done using the Haversine formula. This formula accounts for the spherical shape of the Earth. Below is a Delphi and Python function that performs this calculation:

type
 TipGeolocation = record
     Latitude: Double; //read Coordinates[0] write SetLatitude;
     Longitude: Double; //read Coordinates[1] write SetLongitude;
  end;

For the purposes of this task we make the problem harder, a geocoding function with a record pair of coordinates:

const
    EARTHS_RADIUS_IN_METERS = 6378137;  


function TipGeolocationDistanceInMetersTo(
                     const AGeolocation: TipGeolocation;
                           Latitude, Longitude: Double): Double;
var LDeltaLat, LDeltaLong, LA: Double;
begin
  LDeltaLat:= DegToRad(AGeolocation.Latitude - Latitude);
  LDeltaLong:= DegToRad(AGeolocation.Longitude - Longitude);
  LA:= Sin(LDeltaLat / 2) * Sin(LDeltaLat / 2) + Cos(DegToRad(Latitude)) * 
       Cos(DegToRad(AGeolocation.Latitude)) * Sin(LDeltaLong / 2) * Sin(LDeltaLong / 2);
  Result:= Abs(EARTHS_RADIUS_IN_METERS * 2 * ArcTan2(Sqrt(LA), Sqrt(1 - LA)));
end;

This function calculates the distance between two points given their latitude and longitude in degrees. The example usage calculates the distance between Bern and Paris. Feel free to adapt the coordinates to your specific needs!

Geoloc_setup;    //reference data2
writeln('Distance Bern,CH - Paris,F: '+
         format('%2.4f m ',[TipGeolocationDistanceInMetersTo(tipgeoloc1,lat2,lon2)]));

And in Python: import math

def haversine_distance(lat1, lon1, lat2, lon2):
    # Radius of the Earth in kilometers
    R = 6371.0
    # Convert latitude and longitude from degrees to radians
    lat1_rad = math.radians(lat1)
    lon1_rad = math.radians(lon1)
    lat2_rad = math.radians(lat2)
    lon2_rad = math.radians(lon2)

    # Differences in coordinates
    dlat = lat2_rad - lat1_rad
    dlon = lon2_rad - lon1_rad

    # Haversine formula
    a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) *math.cos(lat2_rad) * math.sin(dlon / 2)**2                                                 
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    # Distance in kilometers
    distance = R * c
    return distance

# Example usage
lat1 = 46.94809  # Latitude of Bern
lon1 = 7.44744   # Longitude of Bern
lat2 = 48.8566   # Latitude of Paris
lon2 = 2.3522    # Longitude of Paris

distance = haversine_distance(lat1, lon1, lat2, lon2)
print(f"The distance between Bern and Paris is {distance:.2f} kilometers.")

The distance between Bern and Paris is 434.96 kilometers.
Often, we calculate the great-circle distance of given two points in geophysics, for example, the distance from the seismic station to the epicenter. Supposing that we have two geographical points, and let’s say P1:(ϕ1,λ1)and P2:(ϕ2,λ2), where,ϕ and λ represent the latitude and longitude, respectively. Using Haversine formula, we can calculate the great-circle distance.
The great-circle distance, orthodromic distance, or spherical distance is the distance between two points on a sphere, measured along the great-circle arc between them.


Image description

Paris Place Madeleine Place de la Madeleine
Next we need a geocoding API. Geocoding is the process of transformation of any location name into geographical coordinates, and the other way around (reverse geocoding). OpenWeather’s Geocoding API and OpenStreetMap supports both the direct and reverse methods, working at the level of city names, areas and districts, countries and states:

https://nominatim.openstreetmap.org/search?format=json&q=madeleine,paris
Test the link above then you get:

Image description

Its not a unique place, different results as JSON possible
Take the result with the most importance after place_rank like 0.50962:

Image description

const URL_GEOLOCURL9 = 'https://nominatim.openstreetmap.org/search?format=json&q=%s';
      URL_APILAY_GEO = 'https://api.apilayer.com/geo/country/capital/%s';  

var fromgeo, togeo: Tlatlong;      

function API_GEOLocation_OSM9(AURL, aloc, aApikey: string;
                                             verbose: boolean): Tlatlong;
var Httpreq: THttpRequestC; httpres: string;
    jsn: TMcJsonItem;
begin
  httpreq:= THttpRequestC.create(self);
  httpreq.headers.add('Accept: application/json; charset=utf-8');
  //httpreq.headers.add('X-Api-Key:'+aAPIkey);
  httpreq.useragent:= USERAGENT5;
  httpreq.SecurityOptions:= [soSsl3, soPct, soIgnoreCertCNInvalid];
  try
    if httpreq.get(Format(AURL,[aloc])) then begin
       httpres:= (httpreq.Response.ContentAsUTF8String)
       writeln('conttype '+httpreq.Response.ContentType);
       if verbose then writ('debug back '+formatJson(httpres));
       jsn:= TMcJsonItem.Create;
       jsn.AsJSON:= httpres;
       result.lat:= jsn.at(0,'lat').asnumber;
       result.long:= jsn.at(0,'lon').asnumber;
       result.descript:= Format('Coords: lat %2.5f lng %2.5f %s osm_id: %s ',
                                [result.lat,result.long,jsn.at(0,'name').asstring,
                                                        jsn.at(0,'osm_id').asstring]); 
    end else Writeln('APIError '+inttostr(Httpreq.Response.StatusCode2));
  except
    writeln('EWI_APIHTTP: '+ExceptiontoString(exceptiontype,exceptionparam));  
  finally
    writeln('Status3: '+gethttpcod(httpreq.Response.statuscode2))
    httpreq.Free;  
    sleep(200);
    jsn.Free;
  end; 
end;
const

URL_GEOLOCURL9 = https://nominatim.openstreetmap.org/search?format=json&q=%s‘;

URL_APILAY_GEO = https://api.apilayer.com/geo/country/capital/%s‘;

Test it by calling the const URL below, for example:

https://nominatim.openstreetmap.org/search?format=json&q=paris
https://softwareschule.code.blog/wp-content/uploads/2025/04/image-4.png?w=1024

Image description

Nominatim uses OpenStreetMap data to find locations on Earth by name and address (geocoding) as you can see in the const URL_GEOLOCURL9. It can also do the reverse, find an address for any location on the planet. The Geocoding API relies on a redundant infrastructure of geocoder nodes powered by the Nominatim software with edge servers for fast delivery of results.
Note that when you get an

APIError 403
Status3: SC_FORBIDDEN
Status3: SC_FORBIDDEN
Exception: Invalid pointer operation at 875.1746

or an

EWI_HTTP: Exception: The request has timed out.
Status3:
Null Pointer Exception at 929.1876

then you are not following the Nominatim Usage policy, see here: https://operations.osmfoundation.org/policies/nominatim/

You’ll have to be esp. careful about including a unique user agent for your application and change from time to time;

It sounds like you’re encountering a “403 Forbidden” error when trying to use the Nominatim API. This error typically indicates that your request is being blocked, possibly due to rate limiting, incorrect usage, or IP blocking. Here are a few steps you can take to troubleshoot and resolve this issue:

Check API Usage Limits: Ensure that you are not exceeding the usage limits set by Nominatim. They have strict policies to prevent abuse. Review their usage policy to make sure you’re compliant.

User-Agent Header: Nominatim requires a valid User-Agent header in your requests. Make sure you include a descriptive User-Agent string that identifies your application. Best is do rotate useragents:

const
  USERAGENT5 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
                                                                              Gecko)'+
                   ' Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0 '; 
  USERAGENT2 = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1';  
  USERAGENT3 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
                Gecko)'+' Chrome/125.0.0.0 Safari/537.3';                // chrome + win   
  USERAGENT4 = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15'+
                   ' (KHTML, like Gecko) Version/17.4.1 Safari/605.1.1'; // safari + mac
  USERAGENT1 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '+    
                   '(KHTML, like Gecko) Chrome/126.0.0.0 Edg/126.0.0.';  // edge + win
const useragents

Image description

softwareschule.ch/examples/geodistance1.htm

Most of the time, ~ 75% in this case, it is spent with API IP-connection. So we put in maXbox processmessagesOFF; and processmessagesON; between start and stop-time for time measure.

The interesting point is to know where the code is running and how it is stored in an executable or script itself. Solution 1 and 2 can running on the web or on premise all others run locally or on a server.

3 Solutions Overview of GEO Distance Math Solver

Image description

Conclusion

When it comes to problem-solving, there are often multiple solutions that can be used to solve the same problem. The choice of solution depends on various factors such as performance, storage, implementation, simplicity, and also scaleability and security in different environments. The code is more or less the same but the choice of the environment (script, executable, container, hosting, web or cloud API) could be a response of different requirements.

Great Circle Mapper is a tool that shows the shortest route between two or more locations on a globe. You can enter airports, cities, or coordinates and get a distance back with a geocode API.

Script:

https://sourceforge.net/projects/maxbox5/files/examples/1397_Geolocation_distance12_uc.txt/download

References:
Home – Geocoding API Documentation

Image description

Doc and Tool: maXbox5 – Manage Files at SourceForge.net

As PDF: http://www.softwareschule.ch/download/maxbox_starter142.pdf

Max Kleiner 23/04/2025

1 Nature recoils from emptiness –

Image description

Garmin GPS Distance Tracking