У меня есть гибридное приложение C ++ / Javascript, которое отображает карту Leaflet в представлении QtWebEngine
http://doc.qt.io/qt-5/qwebengineview.html
или внутри wxWebView
http://docs.wxwidgets.org/trunk/classwx_web_view.html
пока общение было 1 направленным
в C ++ я определяю Javascript как строку C ++ и вызываю соответствующий метод выполнения javascript (из Qt или WxWidgets),
таким образом я могу ввести, скажем, широту и долготу на стороне C ++, а сторона javascrit — это только конечная точка.
например, для Qt
void WebView::loadFinished(bool)
{
std::string str_js = get_render_javascript_leaflet();
page()->runJavaScript(QString::fromStdString(str_js));
}
std::string WebView::get_render_javascript_leaflet()
{
std::string js;
std::string str_lat;
std::string str_lon;
str_lat = std::to_string((long double)38.9250);
str_lon = std::to_string((long double)-77.0387);
js = "var map = L.map('map').setView([";
js += str_lat;
js += ",";
js += str_lon;
js += "], 14);";
js += "map.options.scrollWheelZoom = false;";
js += "map.options.minZoom = 2;";
js += "map.options.maxZoom = 20;";
js += "L.tileLayer('http://{s}.google.com/vt/lyrs=p&x={x}&y={y}&z={z}',{";
js += "maxZoom: 20,";
js += "subdomains:['mt0','mt1','mt2','mt3']";
js += "}).addTo(map);";
//mapzen geocoder
js += "L.control.geocoder('mapzen-<YOUR MAPZEN KEY>').addTo(map);";
return js;
}
но теперь я хочу добавить геокодирование на карту, используя Mapzeen,
https://github.com/mapzen/leaflet-geocoder
так что мне было интересно, как зов
//mapzen geocoder
js += "L.control.geocoder('mapzen-<YOUR MAPZEN KEY>').addTo(map);";
может вернуть результаты геокодирования на сторону C ++.
Qt имеет методы, которые позволяют
одноранговая связь между приложением C ++ и клиентом (HTML / JavaScript), но здесь возникает вопрос
что извлечь из поиска Mapzen
Есть 2 способа решить эту проблему
1) Во-первых, прочитайте документацию Mazen, всегда хорошая идея, прежде чем спрашивать.
2) Первый способ:
добавить прослушиватель событий для события «results» в геокодере
https://github.com/mapzen/leaflet-geocoder#on-results-or-error
затем получите данные результатов и передайте их как JSON через qtwebchannel.
пример события mapzen для карты листовки (замените YOUR_API_KEY на ключ, полученный на веб-сайте mapzen)
<script>
var map = L.map('map').setView([38.9250, -77.0387], 14);
map.options.scrollWheelZoom = false;
map.options.minZoom = 2;
map.options.maxZoom = 20;
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png',{
}).addTo(map);
var geocoder = L.control.geocoder('mapzen-YOUR_API_KEY');
geocoder.on('select', function (e)
{
alert(e.feature.properties.label);
});
geocoder.addTo(map);
</script>
3) более простой способ
Сделайте HTTP-запрос, используя сокеты C.
Это чистый C / C ++, поэтому нет необходимости использовать qtwebchannel для ссылки на Javascript.
результат (широта, долгота) может быть отправлен непосредственно на карту листовки
без необходимости делать запрос геокодирования внутри JavaScript.
Это просто вопрос создания HTTP-заголовка, в котором есть параметры запроса, которые нам нужны.
пример в C ++:
http_t client(host_name, port);
//open connection
if (client.open() < 0)
{
}
std::string str_header;
str_header += "GET /v1/search?api_key=mapzen-YOUR_API_KEY&text=YMCA&size=2 HTTP/1.1\r\n";
str_header += "Host: ";
str_header += "search.mapzen.com";
str_header += "\r\n";
str_header += "Accept: application/json\r\n";
str_header += "Connection: close";
str_header += "\r\n";
str_header += "\r\n";
//send request, using built in tcp_client_t socket
if (client.write(str_header.c_str(), str_header.size()) < 0)
{
}
//we sent a close() server request, so we can use the read_all function
//that checks for recv() return value of zero (connection closed)
if (client.read_all_get_close("mazen.response.txt", verbose)< 0)
{
}
client.close();
это использует lib_netsockets
https://github.com/pedro-vicente/lib_netsockets/blob/master/examples/http_client.cc
mapzen ответил этим HTTP
HTTP/1.1 200 OK
Age: 0
Via: 1.1 140.90.160.232 (McAfee Web Gateway 7.6.2.2.0.21927)
Date: Mon, 24 Apr 2017 19:13:45 GMT
etag: W/"734-KRn5K9yTLPWwZt8pN3/G4TSSTr0"Vary: Accept-Encoding
charset: utf8
X-Cache: MISS, MISS from 140.90.160.232
X-Timer: S1493061226.560908,VS0,VE95
Connection: Close
X-Served-By: cache-iad2123-IAD
Content-Type: application/json; charset=utf-8
X-Cache-Hits: 0
x-powered-by: mapzen
Cache-Control: public, max-age=120
Content-Length: 1844
X-ApiaxleProxy-Qpd-Left: 29998
X-ApiaxleProxy-Qps-Left: 5
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Authorization, Content-Type, Accept, Origin, User-Agent, Cache-Control, Keep-Alive, If-Modified-Since, If-None-Match, X-Requested-With
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Expose-Headers: Content-Type, Cache-Control, ETag, Expires, Last-Modified, Content-Length, X-ApiaxleProxy-Qpd-Left, X-ApiaxleProxy-Qpm-Left, X-ApiaxleProxy-Qps-Left, X-Cache
Access-Control-Allow-Credentials: true
{"geocoding":{"version":"0.2","attribution":"https://search.mapzen.com/v1/attribution","query":{"text":"YMCA","size":2,"private":false,"lang":{"name":"English","iso6391":"en","iso6393":"eng","defaulted":true},"querySize":4},"engine":{"name":"Pelias","author":"Mapzen","version":"1.0"},"timestamp":1493061225650},"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-71.532305,43.020898]},"properties":{"id":"polyline:8893463","gid":"openstreetmap:street:polyline:8893463","layer":"street","source":"openstreetmap","source_id":"polyline:8893463","name":"YMCA","street":"YMCA","confidence":0.6,"accuracy":"centroid","country":"United States","country_gid":"whosonfirst:country:85633793","country_a":"USA","region":"New Hampshire","region_gid":"whosonfirst:region:85688689","region_a":"NH","county":"Hillsborough County","county_gid":"whosonfirst:county:102085493","localadmin":"Goffstown","localadmin_gid":"whosonfirst:localadmin:404477175","neighbourhood":"Grasmere","neighbourhood_gid":"whosonfirst:neighbourhood:85822609","label":"YMCA, Goffstown, NH, USA"},"bbox":[-71.532563,43.020401,-71.532227,43.021076]},{"type":"Feature","geometry":{"type":"Point","coordinates":[19.143451,48.738157]},"properties":{"id":"node:388597045","gid":"openstreetmap:venue:node:388597045","layer":"venue","source":"openstreetmap","source_id":"node:388597045","name":"YMCA","confidence":0.6,"accuracy":"point","country":"Slovakia","country_gid":"whosonfirst:country:85633769","country_a":"SVK","region":"Banskobystrický kraj","region_gid":"whosonfirst:region:85688355","county":"Banská Bystrica","county_gid":"whosonfirst:county:102080531","locality":"Banská Bystrica","locality_gid":"whosonfirst:locality:101752053","label":"YMCA, Banská Bystrica, Slovakia"}}],"bbox":[-71.532563,43.020401,19.143451,48.738157]}
Других решений пока нет …