From a5e4bb94f09e50e8e857e5322785b44a3fac7dc6 Mon Sep 17 00:00:00 2001 From: sjanzou Date: Sat, 9 Mar 2019 06:14:51 -0700 Subject: [PATCH] Updated geocoding from developer.nrel.gov --- include/wex/easycurl.h | 6 ++-- src/easycurl.cpp | 70 ++++++++++++++++++++++++++++++++++++--- src/lkscript.cpp | 13 +++++--- tools/sandbox/sandbox.cpp | 14 ++++++++ 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/include/wex/easycurl.h b/include/wex/easycurl.h index 3bc75556..d3d60d8d 100644 --- a/include/wex/easycurl.h +++ b/include/wex/easycurl.h @@ -84,7 +84,7 @@ class wxEasyCurl : public wxObject // app-wide init and shutdown calls for underlying libcurl initialization static void Initialize(); static void Shutdown(); - static void SetApiKeys(const wxString &google_key, const wxString &bing_key); + static void SetApiKeys(const wxString &google_key, const wxString &bing_key, const wxString &developer); static void SetUrlEscape(const wxString &key, const wxString &value); static void SetProxyAddress(const wxString &proxy); static wxString GetProxyForURL(const wxString &url); @@ -93,7 +93,9 @@ class wxEasyCurl : public wxObject // geocoding function using google APIs. // call is synchronous. Optionally determine time // zone from lat/lon using second service call - static bool GeoCode(const wxString &address, + static bool GeoCodeGoogle(const wxString &address, + double *lat, double *lon, double *tz = 0, bool showprogress = true); + static bool GeoCodeDeveloper(const wxString &address, double *lat, double *lon, double *tz = 0, bool showprogress = true); enum MapProvider { GOOGLE_MAPS, BING_MAPS }; static wxBitmap StaticMap(double lat, double lon, int zoom, MapProvider service = BING_MAPS); diff --git a/src/easycurl.cpp b/src/easycurl.cpp index af84a549..f592c948 100644 --- a/src/easycurl.cpp +++ b/src/easycurl.cpp @@ -44,7 +44,7 @@ #include #include #include - +#include #include #include @@ -581,15 +581,16 @@ void wxEasyCurl::SetUrlEscape(const wxString &key, const wxString &value) gs_urlEscapes[key] = value; } -static wxString GOOGLE_API_KEY, BING_API_KEY; +static wxString GOOGLE_API_KEY, BING_API_KEY, DEVELOPER_API_KEY; -void wxEasyCurl::SetApiKeys(const wxString &google, const wxString &bing) +void wxEasyCurl::SetApiKeys(const wxString &google, const wxString &bing, const wxString &developer) { if (!google.IsEmpty()) GOOGLE_API_KEY = google; if (!bing.IsEmpty()) BING_API_KEY = bing; + if (!developer.IsEmpty()) DEVELOPER_API_KEY = developer; } -bool wxEasyCurl::GeoCode(const wxString &address, double *lat, double *lon, double *tz, bool showprogress) +bool wxEasyCurl::GeoCodeGoogle(const wxString &address, double *lat, double *lon, double *tz, bool showprogress) { wxBusyCursor _curs; @@ -654,6 +655,67 @@ bool wxEasyCurl::GeoCode(const wxString &address, double *lat, double *lon, doub else return true; } +bool wxEasyCurl::GeoCodeDeveloper(const wxString &address, double *lat, double *lon, double *tz, bool showprogress) +{ + wxBusyCursor _curs; + + wxString plusaddr = address; + plusaddr.Replace(" ", " "); + plusaddr.Replace(" ", " "); + plusaddr.Replace(" ", "+"); + + + wxString url("https://developer.nrel.gov/api/mapquest/geocoding/v1/address?location=" + plusaddr + "&_app_id=sam&outFormat=csv&api_key=" + DEVELOPER_API_KEY); + + wxEasyCurl curl; + wxBusyCursor curs; + if (showprogress) + { + if (!curl.Get(url, "Geocoding address '" + address + "'...")) + return false; + } + else + { + if (!curl.Get(url)) + return false; + } + + wxCSVData csv; + if (csv.ReadString(curl.GetDataAsString())) + { + wxString slat = csv.Get(1, 14); + wxString slng = csv.Get(1, 15); + if (!slat.ToDouble(lat)) + return false; + if (!slng.ToDouble(lon)) + return false; + } + else + return false; + + /* JSON reader fails with UTF-8 issues + wxJSONReader reader; + wxJSONValue root; + if (reader.Parse(curl.GetDataAsString(), &root) == 0) + { + wxJSONValue loc = root.Item("results").Item(0).Item("locations").Item(0).Item("displayLatLng"); + if (!loc.IsValid()) return false; + *lat = loc.Item("lat").AsDouble(); + *lon = loc.Item("lng").AsDouble(); + + if (root.Item("status").AsString() != "OK") + return false; + } + else + return false; + */ + if (tz != 0) + { + *tz = 0; // no current TZ API + } + return true; +} + wxBitmap wxEasyCurl::StaticMap(double lat, double lon, int zoom, MapProvider service) { if (zoom > 21) zoom = 21; diff --git a/src/lkscript.cpp b/src/lkscript.cpp index 770e0484..3c56ef52 100644 --- a/src/lkscript.cpp +++ b/src/lkscript.cpp @@ -1383,24 +1383,27 @@ void fcall_rand(lk::invoke_t &cxt) static void fcall_apikeys(lk::invoke_t &cxt) { - LK_DOC("apikeys", "Set API keys for Google and Bing web services. Table can have 'google' and 'bing' keys.", "(table:keys):none"); + LK_DOC("apikeys", "Set API keys for Google and Bing and Developer web services. Table can have 'google' and 'bing' and 'developer' keys.", "(table:keys):none"); - wxString google, bing; + wxString google, bing, developer; if (lk::vardata_t *x = cxt.arg(0).lookup("google")) google = x->as_string(); if (lk::vardata_t *x = cxt.arg(0).lookup("bing")) bing = x->as_string(); - wxEasyCurl::SetApiKeys(google, bing); + if (lk::vardata_t *x = cxt.arg(0).lookup("developer")) + developer = x->as_string(); + + wxEasyCurl::SetApiKeys(google, bing, developer); } static void fcall_geocode(lk::invoke_t &cxt) { - LK_DOC("geocode", "Given a street address, location name, or latitude-longitude pair ('lat,lon') string, returns the latitude, longitude, and time zone of an address using Google API. Returned table fields are 'lat', 'lon', 'tz', 'ok'.", "(string:address):table"); + LK_DOC("geocode", "Given a street address, location name, or latitude-longitude pair ('lat,lon') string, returns the latitude, longitude, and time zone of an address using Developer API. Returned table fields are 'lat', 'lon', 'tz', 'ok'.", "(string:address):table"); double lat = 0, lon = 0, tz=0; - bool ok = wxEasyCurl::GeoCode(cxt.arg(0).as_string(), &lat, &lon, &tz); + bool ok = wxEasyCurl::GeoCodeDeveloper(cxt.arg(0).as_string(), &lat, &lon, &tz); cxt.result().empty_hash(); cxt.result().hash_item("lat").assign(lat); cxt.result().hash_item("lon").assign(lon); diff --git a/tools/sandbox/sandbox.cpp b/tools/sandbox/sandbox.cpp index b3aa0b68..c1c51474 100644 --- a/tools/sandbox/sandbox.cpp +++ b/tools/sandbox/sandbox.cpp @@ -40,6 +40,8 @@ #include "wex/icons/scatter.cpng" #include "wex/pdf/pdfdoc.h" #include "wex/radiochoice.h" +//#include "wex/easycurl.h" + class PngTestApp : public wxApp { @@ -84,6 +86,15 @@ class PngTestApp : public wxApp #include "wex/uiform.h" #include "wex/snaplay.h" +/* +void TestGeoCode(wxString address) +{ +// wxEasyCurl curl; + double lat, lon, tz = 0; + wxEasyCurl::GeoCodeDeveloper(address, &lat, &lon, &tz); + wxMessageBox(wxString::Format("address %s : lat %g, lon %g", (const char*)address.c_str(), lat, lon)); +} +*/ void TestDVSelectionCtrl() { wxFrame *frame = new wxFrame(0, wxID_ANY, wxT("wxDVSelectionCtrl in \x01dc\x03AE\x03AA\x00C7\x00D6\x018C\x01dd"), wxDefaultPosition, wxSize(250, 510)); @@ -838,6 +849,9 @@ class MyApp : public wxApp if (!wxApp::OnInit()) return false; + +// return true; + #ifdef __WXMSW__ typedef BOOL(WINAPI *SetProcessDPIAware_t)(void); wxDynamicLibrary dllUser32(wxT("user32.dll"));