I have a bash script, where I need to get the user's geolocation (latitude, longitude and country code). If a GPS device is present, I use gpspipe. But a lot of laptops/computers don't have GPS devices (yet). I need the location as accurate as possible, and getting the geolocation by IP address is (by far) too unreliable.
I ended up with the following bash script with the following dependencies: Python with sys, urllib and json libraries, wget and a working internet connection.
LAT=""
LNG=""
CTRY=""
IFS=$'\n'
printf "Give your location (street name, city, country, etc): "
read LOCATION
while [ -z "$LAT" ]; do
printf "Querying Google Geo API... "
LOCATION=$(echo $LOCATION | python -c "exec(\"import urllib,sys;\\nprint(urllib.quote_plus(sys.stdin.readline()))\")")
URL="https://maps.googleapis.com/maps/api/geocode/json?address=$LOCATION"
GOOGLEAPIS=$(wget -qO- $URL)
STATUS=$(echo $GOOGLEAPIS | python -c "exec(\"import json,sys;\\nobj=json.load(sys.stdin);\\nprint(obj['status'])\")")
case "$STATUS" in
*OK*)
OPTIONS=($(echo $GOOGLEAPIS | python -c "exec(\"import json,sys;\\nobj=json.load(sys.stdin);\\nfor x in obj['results'][::]:print(x['formatted_address'])\")"))
OPT=$OPTIONS
NRFOUND=${#OPTIONS[@]}
IDX="0"
if [[ $NRFOUND -ge 2 ]]; then
printf "More than one option found. Please select your location from the list:\n"
select OPT in "${OPTIONS[@]}";
do
IDX=$(($REPLY - 1))
break
done
fi
LAT=$(echo $GOOGLEAPIS | python -c "exec(\"import json,sys;\\nobj=json.load(sys.stdin);\\nprint(obj['results'][$IDX]['geometry']['location']['lat'])\")")
LNG=$(echo $GOOGLEAPIS | python -c "exec(\"import json,sys;\\nobj=json.load(sys.stdin);\\nprint(obj['results'][$IDX]['geometry']['location']['lng'])\")")
CTRY=$(echo $GOOGLEAPIS | python -c "exec(\"import json,sys;\\nobj=json.load(sys.stdin);\\nfor x in obj['results'][$IDX]['address_components']:\\n\\tif x['types'][0] == 'country':print(x['short_name'])\")")
break
;;
*)
printf "Google could not find your location based on your query. Google says: $STATUS\nPlease enter another location description.\n"
read LOCATION
;;
esac
done
unset $IFS
printf "Selected location: %s\nYour latitude/longitude location set to: (%s, %s).\nYour countycode is set to: %s\n" $OPT $LAT $LNG $CTRY
The code works (as required here on CR) and a sensible geolocation is found for a lot of queries. But, as I'm no seasoned shell writer, I'd like your review on this code. Do you see any pitfalls, corrections, improvements (on the coding), etc?