Geocoding IV

Max Kleiner
Nerd For Tech
Published in
4 min readMar 6, 2024
XN Resource Editor

Just like every actual house has its address (which includes the number, the name of the street, city), every single point on the surface of earth can be specified by the latitude and longitude coordinates (lat & long).

So how we did this? With the OpenStreetMap API Nominatim and maXbox5.

The OSM Nominatim is a search engine for OpenStreetMap data. From this site you may search for a name or address (like Bahnhof, Graz, Austria), or look up place names by geographic coordinates. Each result will link to details page where you can inspect what data about the object is saved in the database and investigate how the address of the object has been computed (URI and JSON for example):

type Tlatlong = record lat, long: double; descript: string; end; function TAddressGeoCodeOSM5(faddress: string): Tlatlong; var url, res, display: string; jo: TJSONObject; urlid: TIduri; winapi: TWinApiDownload; begin urlid:= TIdURI.create(''); url:= urlid.URLEncode('https://nominatim.openstreetmap.org/search?format=json&q='+ fAddress); winapi:= TWinApiDownload.create; winapi.useragent:= 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1'; winapi.url:= url; writeln('check url: '+itoa(winapi.CheckURL(url))); winapi.download1(res); if (res <> '') and (res <> '[]') then begin //windown.OnWorkStart StrReplace(res, '[{', '{'); jo:= TJSONObject.create4(res); try if jo.getString('place_id') <> ' ' then display:= jo.getstring('display_name'); result.descript:= Format('Coords: lat %2.5f lng %2.5f %s place_id: %d', [jo.getdouble('lat'),jo.getdouble('lon'),display, jo.getint('place_id')]); result.lat:= jo.getdouble('lat'); result.long:= jo.getdouble('lon'); except writeln('Geo E: '+ExceptiontoString(exceptiontype, exceptionparam)); finally jo.Free; urlid.free; winapi.free; end; end else showmessagebig('OSM geo location not found! '); end;
type Tlatlong = record
lat, long: double;
descript: string;
end;

function TAddressGeoCodeOSM5(faddress: string): Tlatlong;
var url, res, display: string;
jo: TJSONObject; urlid: TIduri; winapi: TWinApiDownload;
begin
urlid:= TIdURI.create('');
url:= urlid.URLEncode('https://nominatim.openstreetmap.org/search?format=json&q='+
fAddress);
winapi:= TWinApiDownload.create;
winapi.useragent:= 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1';
winapi.url:= url;
writeln('check url: '+itoa(winapi.CheckURL(url)));
winapi.download1(res);
if (res <> '') and (res <> '[]') then begin
//windown.OnWorkStart
StrReplace(res, '[{', '{');
jo:= TJSONObject.create4(res);
try
if jo.getString('place_id') <> ' ' then
display:= jo.getstring('display_name');
result.descript:= Format('Coords: lat %2.5f lng %2.5f %s place_id: %d',
[jo.getdouble('lat'),jo.getdouble('lon'),display,
jo.getint('place_id')]);
result.lat:= jo.getdouble('lat');
result.long:= jo.getdouble('lon');
except
writeln('Geo E: '+ExceptiontoString(exceptiontype, exceptionparam));
finally
jo.Free;
urlid.free;
winapi.free;
end;
end else showmessagebig('OSM geo location not found! ');
end;
1274_Screenshot2024–03–06_mX5GUI.png

I use an URI, a struct Tlatlong, a JSON and a HTTPGet object and call the function from the main:

writeln(‘res back_: ‘+TAddressGeoCodeOSM5(‘Bonnaud, France’));

latlong:= TAddressGeoCodeOSM5('Hauptbahnhof, Graz, Austria'); writeln('OSM5 res back_: '+latlong.descript); >>> OSM5 res back_: Coords: lat 47.07391 lng 15.41681 Hauptbahnhof, Europaplatz, Smart City, Lend, Graz, Steiermark, 8020, Österreich place_id: 56301250 writeln('get geoCoords: '+format(' lat: %.4f - lon: %.4f',[latlong.lat,latlong.long])); OpenWeb('https://www.latlong.net/c/?lat='+flots(latlong.lat)+'&long='+flots(latlong.long));
latlong:=  TAddressGeoCodeOSM5('Hauptbahnhof, Graz, Austria');
writeln('OSM5 res back_: '+latlong.descript);
>>> OSM5 res back_: Coords: lat 47.07391 lng 15.41681 Hauptbahnhof, Europaplatz, Smart City, Lend, Graz, Steiermark, 8020, Österreich place_id: 56301250

writeln('get geoCoords: '+format(' lat: %.4f - lon: %.4f',[latlong.lat,latlong.long]));
>>> get geocoords: lat: 47.0739 - lon: 15.4168
OpenWeb('https://www.latlong.net/c/?lat='+flots(latlong.lat)+'&long='+flots(latlong.long));

You should in particular verify that you have set a custom HTTP referrer or HTTP user agent ( windown.useragent:=) that identifies your application, and that you are not overusing the service with massive bulk requests. Otherwise you get following message:

<p>You have been blocked because you have violated the<a href=”https://operations.osmfoundation.org/policies/nominatim/">usage policy</a>of OSM’s Nominatim geocoding service. Please be aware that OSM’s resources are limited and shared between many users. The usage policy is there to ensure that the service remains usable for everybody.</p>

Fusion of OpenStreetMap with Google Maps Directions (OSM&GMD)

You can get directions for driving, public transit, walking, ride sharing, cycling, flight, or motorcycle on Google Maps. If there are multiple routes, the best route to your destination is blue, all other routes are gray. Some directions in Google Maps are in development and may have limited availability.

Now we pass the coordinates of two locations , for example Cologne to Graz, in a automated script and call the computed link in a browser.

Script Ref: http://www.softwareschule.ch/examples/directions3.htm

Testunit From Cologne to Graz
get geocoords: lat: 50.9473 — lon: 6.9503 Cologne
get geocoords: lat: 47.0739 — lon: 15.4168 Graz

latlong:= TAddressGeoCodeOSM(‘Gereonswall 66, Cologne, Germany’);
latlong:= TAddressGeoCodeOSM(‘Hauptbahnhof, Graz, Austria’);

UnitTest GeoCode

1274_Screenshot2024–03–06mX5Browser.png

Important: Stay alert when you use directions on Google Maps. Always be aware of your surroundings to ensure the safety of yourself and others. When in doubt, follow actual traffic regulations and confirm signage from the road or path that you’re on (we call them PathMath).

Bern — St. Ingbert

// — — — — — — — — — — — Input From To — — — — — — — — — — — — — — -//

fromlat:= ‘46.9479’; fromlong:= ‘7.44744’;
tolat:= ‘49.27092’; tolong:= ‘7.1116’;

“https://www.google.com/maps/dir/046.94790,007.44744/049.27092,007.11160/@046.94790,007.44744,9z

// — — —

This could be an updated map of night-trains with pathmath from and to over europe:

TEN over TEE

Max Kleiner, 06/03/2024

Originally published at http://maxbox4.wordpress.com on March 6, 2024.

--

--

Max Kleiner
Nerd For Tech

Max Kleiner's professional environment is in the areas of OOP, UML and coding - among other things as a trainer, developer and consultant.