0

我有一个混合 C++/Javascript 应用程序,它在 QtWebEngine 视图中显示传单地图

http://leafletjs.com/

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 搜索中检索什么

http://doc.qt.io/qt-5/qtwebchannel-index.html

4

1 回答 1

0

有2种方法可以解决这个问题

1)首先,阅读 Mazen 文档,在询问之前总是一个好主意。

2)第一种方式:

为地理编码器上的“结果”事件添加事件侦听器

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)更简单的方法

使用 C 套接字执行 HTTP 请求。

这种方式是纯 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]}
于 2017-04-24T20:13:46.733 回答