NEW: add support for revgeod

closes #263
This commit is contained in:
Jan-Piet Mens
2018-10-23 14:09:32 +02:00
parent 34003192ea
commit 704af81996
2 changed files with 52 additions and 3 deletions
+3 -1
View File
@@ -269,10 +269,11 @@ This section lists the most important options of the Recorder with their long na
`--precision` overrides the compiled-in default. (See "Precision" later.)
`--geokey` sets the API key for reverse geo lookups. We support Google (legacy) and OpenCage which we recommend [OpenCage](doc/OPENCAGE.md). You will require an API key for both. For backwards-compatibility the API key for Google is used "as is", whereas you prefix the OpenCage API key with the string `"opencage:"`:
`--geokey` sets the API key for reverse geo lookups. We support Google (legacy) and OpenCage which we recommend [OpenCage](doc/OPENCAGE.md). We also support [revgeod]. You will require an API key for the first two. For backwards-compatibility the API key for Google is used "as is", whereas you prefix the OpenCage API key with the string `"opencage:"`:
```
--geokey "opencage:xxxxxxxxxxxxxxxxxxxxxx" # for OpenCage
--geokey "xxxxxxxxxxxxxxxxxxxxxx" # for Google
--geokey "revgeod:localhost:8865" # for Revgeod (host:port)
```
(The rules of the game for using Google as reverse geocoder changed in May 2018; make sure to check Google's Map Project documentation before using this)
@@ -969,3 +970,4 @@ It actually is possible to gateway location publishes arriving via HTTP into MQT
If a payload is received with an element called `_geoprec` it contains an override for the Recorder's configured reverse-geo precision. So, for example, if Recorder is running with precision 7, say, and the received payload contains `"_geoprec" : 2` the 2 will be used for this particular publish. This is not used in the OwnTracks apps, but it can be used with payloads you generate otherwise. If `_geoprec` is negative, new reverse geo lookups will not be performed, but cached entries of `abs(_geoprec)` will be used.
[revgeod]: https://github.com/jpmens/revgeod
+49 -2
View File
@@ -29,13 +29,16 @@
typedef enum {
GOOGLE,
OPENCAGE
OPENCAGE,
REVGEOD
} geocoder;
#define GOOGLE_URL "https://maps.googleapis.com/maps/api/geocode/json?latlng=%lf,%lf&sensor=false&language=EN&key=%s"
#define OPENCAGE_URL "https://api.opencagedata.com/geocode/v1/json?q=%lf+%lf&key=%s&abbrv=1&no_record=1&limit=1&format=json"
#define REVGEOD_URL "http://%s/rev?lat=%lf&lon=%lf" /* "host:port", lat, lon */
static CURL *curl;
static size_t writemem(void *contents, size_t size, size_t nmemb, void *userp)
@@ -139,6 +142,43 @@ static int goog_decode(UT_string *geodata, UT_string *addr, UT_string *cc, UT_st
return (1);
}
static int revgeod_decode(UT_string *geodata, UT_string *addr, UT_string *cc, UT_string *locality)
{
JsonNode *json, *village, *j, *a;
/*
* We are parsing this data returned from revgeod(1):
*
* {"address":{"village":"La Terre Noire, 77510 Sablonnières, France","locality":"Sablonnières","cc":"FR","s":"lmdb"}}
*
*/
if ((json = json_decode(UB(geodata))) == NULL) {
return (0);
}
if ((a = json_find_member(json, "address")) != NULL) {
if ((village = json_find_member(a, "village")) != NULL) {
if (village->tag == JSON_STRING) {
utstring_printf(addr, "%s", village->string_);
}
}
if ((j = json_find_member(a, "locality")) != NULL) {
if (j->tag == JSON_STRING) {
utstring_printf(locality, "%s", j->string_);
}
}
if ((j = json_find_member(a, "cc")) != NULL) {
if (j->tag == JSON_STRING) {
utstring_printf(cc, "%s", j->string_);
}
}
}
json_delete(json);
return (1);
}
static int opencage_decode(UT_string *geodata, UT_string *addr, UT_string *cc, UT_string *locality)
{
JsonNode *json, *results, *address, *ac, *zeroth;
@@ -267,12 +307,16 @@ JsonNode *revgeo(struct udata *ud, double lat, double lon, UT_string *addr, UT_s
if (strncmp(ud->geokey, "opencage:", strlen("opencage:")) == 0) {
utstring_printf(url, OPENCAGE_URL, lat, lon, ud->geokey + strlen("opencage:"));
geocoder = OPENCAGE;
} else if (strncmp(ud->geokey, "revgeod:", strlen("revgeod:")) == 0) {
/* revgeod:localhost:8865 */
utstring_printf(url, REVGEOD_URL, ud->geokey + strlen("revgeod:"), lat, lon);
geocoder = REVGEOD;
} else {
utstring_printf(url, GOOGLE_URL, lat, lon, ud->geokey);
geocoder = GOOGLE;
}
// printf("--------------- %s\n", UB(url));
// fprintf(stderr, "--------------- %s\n", UB(url));
curl_easy_setopt(curl, CURLOPT_URL, UB(url));
curl_easy_setopt(curl, CURLOPT_USERAGENT, "OwnTracks-Recorder/1.0");
@@ -302,6 +346,9 @@ JsonNode *revgeo(struct udata *ud, double lat, double lon, UT_string *addr, UT_s
case OPENCAGE:
rc = opencage_decode(cbuf, addr, cc, locality);
break;
case REVGEOD:
rc = revgeod_decode(cbuf, addr, cc, locality);
break;
}
if (!rc) {