Skip to content

Instantly share code, notes, and snippets.

@adactio
Created December 16, 2024 15:04
Show Gist options
  • Save adactio/9e2be381bbcd1fe82e7a8add1bdec782 to your computer and use it in GitHub Desktop.
Save adactio/9e2be381bbcd1fe82e7a8add1bdec782 to your computer and use it in GitHub Desktop.
A PHP script that uses a third-party provider to get latitude, longitude, and zoom level (for use in embedded maps).
<?php
/*
Pass in a string: geocode("The Jolly Brewer, Brighton, East Sussex England")
The output is an array with keys for "latitude", "longitude", and "zoom".
*/
function geocode($location, $provider = "mapquest") {
$return = array();
$_CONFIG['api_key'] = array(
"google" => "YOUR_API_KEY_FOR_GOOGLE",
"mapquest" => "YOUR_API_KEY_FOR_MAPQUEST",
"geoapify" => "YOUR_API_KEY_FOR_GEOAPIFY",
"here" => "YOUR_API_KEY_FOR_HERE.COM",
"mapbox" => "YOUR_API_KEY_FOR_MAPBOX",
"bing" => "YOUR_API_KEY_FOR_BING",
"nominatim" => "YOUR_API_KEY_FOR_NOMINATIM",
"opencage" => "YOUR_API_KEY_FOR_OPENCAGE",
"positionstack" => "YOUR_API_KEY_FOR_POSITIONSTACK",
"tomtom" => "YOUR_API_KEY_FOR_TOMTOM",
"locationiq" => "YOUR_API_KEY_FOR_LOCATIONIQ",
"mapmaker" => "YOUR_API_KEY_FOR_MAPMAKER"
);
/* In order of accuracy */
switch ($provider) {
case 'google':
$url = "https://maps.googleapis.com/maps/api/geocode/json?address=".urlencode($location)."&key=".$_CONFIG['apikey']['google'];
break;
case 'mapquest':
$url = "https://www.mapquestapi.com/geocoding/v1/address?location=".urlencode($location)."&key=".$_CONFIG['apikey']['mapquest'];
break;
case 'geoapify':
$url = "https://api.geoapify.com/v1/geocode/search?text=".urlencode($location)."&format=json&apiKey=".$_CONFIG['apikey']['geoapify'];
break;
case 'here':
$url = "https://geocode.search.hereapi.com/v1/geocode?q=".urlencode($location)."&apiKey=".$_CONFIG['apikey']['here'];
break;
case 'mapbox':
$url = "https://api.mapbox.com/geocoding/v5/mapbox.places/".urlencode($location).".json?proximity=ip&access_token=".$_CONFIG['apikey']['mapbox'];
break;
case 'bing':
$url = "http://dev.virtualearth.net/REST/v1/Locations?query=".urlencode($location)."&key=".$_CONFIG['apikey']['bing'];
break;
case 'nominatim':
$url = "https://nominatim.openstreetmap.org/search?q=".urlencode($location)."&format=json&addressdetails=1";
break;
case 'opencage':
$url = "https://api.opencagedata.com/geocode/v1/json?q=".urlencode($location)."&key=".$_CONFIG['apikey']['opencage'];
break;
case 'positionstack':
$url = "https://api.positionstack.com/v1/forward?query=".urlencode($location)."&access_key=".$_CONFIG['apikey']['positionstack'];
break;
case 'tomtom':
$url = "https://api.tomtom.com/search/2/geocode/".urlencode($location).".json?key=".$_CONFIG['apikey']['tomtom'];
break;
case 'locationiq':
$url = "https://eu1.locationiq.com/v1/search?q=".urlencode($location)."&format=json&key=".$_CONFIG['apikey']['locationiq'];
break;
case 'mapmaker':
$url = "https://geocode.maps.co/search?q=".urlencode($location)."&api_key=".$_CONFIG['apikey']['mapmaker'];
break;
}
$context = stream_context_create(
array(
'http' => array(
'method' => "GET",
'user_agent' => "Your user agent string",
)
)
);
$json = file_get_contents($url, false, $context);
$result = json_decode($json,true);
switch ($provider) {
case 'google':
$accuracy = array(
"ROOFTOP" => 16,
"RANGE_INTERPOLATED" => 14,
"GEOMETRIC_CENTER" => 14,
"APPROXIMATE" => 12
);
if (isset($result['results'][0]['geometry']['location'])) {
$return['latitude'] = $result['results'][0]['geometry']['location']['lat'];
$return['longitude'] = $result['results'][0]['geometry']['location']['lng'];
$return['zoom'] = $accuracy[$result['results'][0]['geometry']['location_type']];
}
break;
case 'mapquest':
if (isset($result['results'][0])) {
$return['latitude'] = $result['results'][0]['locations'][0]['latLng']['lat'];
$return['longitude'] = $result['results'][0]['locations'][0]['latLng']['lng'];
$return['zoom'] = 12;
switch ($result['results'][0]['locations'][0]['geocodeQuality']) {
case 'ADDRESS':
case 'INTERSECTION':
$return['zoom'] = 16;
break;
case 'STREET':
case 'NEIGHBORHOOD':
$return['zoom'] = 14;
break;
}
}
break;
case 'geoapify':
if (isset($result['results'][0])) {
$return['latitude'] = $result['results'][0]['lat'];
$return['longitude'] = $result['results'][0]['lon'];
$return['zoom'] = 12;
if ($result['results'][0]['rank']['confidence'] > 0.4) {
$return['zoom'] = 14;
}
if ($result['results'][0]['rank']['confidence'] > 0.7) {
$return['zoom'] = 16;
}
}
break;
case 'here':
if (isset($result['items'])) {
$return['latitude'] = $result['items'][0]['position']['lat'];
$return['longitude'] = $result['items'][0]['position']['lng'];
$return['zoom'] = 12;
if ($result['items'][0]['scoring']['queryScore'] > 0.6) {
$return['zoom'] = 14;
}
if ($result['items'][0]['scoring']['queryScore'] > 0.9) {
$return['zoom'] = 16;
}
}
case 'mapbox':
if (isset($result['features'][0])) {
$return['latitude'] = $result['features'][0]['center'][1];
$return['longitude'] = $result['features'][0]['center'][0];
$accuracy = array(
"poi" => 16,
"address" => 16,
"neighbourhood" => 16,
"locality" => 14,
"place" => 12,
"district" => 12,
"postcode" => 12,
"region" => 12,
"country" => 12
);
$return['zoom'] = $accuracy[$result['features'][0]['place_type']['0']];
}
break;
case 'bing':
$accuracy = array(
"High" => 16,
"Medium" => 14,
"Low" => 12
);
if (isset($result['resourceSets'][0]['resources'][0])) {
$return['latitude'] = $result['resourceSets'][0]['resources'][0]['point']['coordinates'][0];
$return['longitude'] = $result['resourceSets'][0]['resources'][0]['point']['coordinates'][1];
$return['zoom'] = $accuracy[$result['resourceSets'][0]['resources'][0]['confidence']];
}
break;
case 'nominatim':
if (isset($result[0])) {
$return['latitude'] = $result[0]['lat'];
$return['longitude'] = $result[0]['lon'];
$return['zoom'] = 12;
if (isset($return[0]['address']['road'])) {
$return['zoom'] = 14;
}
if (isset($return[0]['address']['house_number'])) {
$return['zoom'] = 16;
}
}
break;
case 'opencage':
if (isset($result['results'][0])) {
$return['latitude'] = $result['results'][0]['geometry']['lat'];
$return['longitude'] = $result['results'][0]['geometry']['lng'];
$return['zoom'] = 12;
if ($result['results'][0]['confidence'] > 4) {
$return['zoom'] = 14;
}
if ($result['results'][0]['confidence'] > 7) {
$return['zoom'] = 16;
}
}
break;
case 'positionstack':
if (isset($result['data'][0])) {
$return['latitude'] = $result['data'][0]['latitude'];
$return['longitude'] = $result['data'][0]['longitude'];
$return['zoom'] = 12;
if ($result['data'][0]['confidence'] > 0.5) {
$return['zoom'] = 14;
}
if ($result['data'][0]['confidence'] > 0.8) {
$return['zoom'] = 16;
}
}
break;
case 'tomtom';
if (isset($result['results'][0])) {
$return['latitude'] = $result['results'][0]['position']['lat'];
$return['longitude'] = $result['results'][0]['position']['lon'];
$return['zoom'] = 12;
if ($result['results'][0]['matchConfidence']['score'] > 0.5) {
$return['zoom'] = 14;
}
if ($result['results'][0]['matchConfidence']['score'] > 0.8) {
$return['zoom'] = 16;
}
}
break;
case 'locationiq':
if (isset($result[0])) {
$return['latitude'] = $result[0]['lat'];
$return['longitude'] = $result[0]['lon'];
$return['zoom'] = 12;
}
break;
case 'mapmaker':
if (isset($result[0])) {
$return['latitude'] = $result[0]['lat'];
$return['longitude'] = $result[0]['lon'];
$return['zoom'] = 16;
$accuracy = ($result[0]['boundingbox'][1] - $result[0]['boundingbox'][0]) * 1000;
if ($accuracy < 50) {
$return['zoom'] = 14;
}
if ($accuracy < 20) {
$return['zoom'] = 12;
}
}
break;
}
return $return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment