Results 1 to 11 of 11

Thread: WebKit - accessing javascript results + googleMap

  1. #1
    Join Date
    May 2008
    Posts
    276
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default WebKit - accessing javascript results + googleMap

    I'am triying to get the results of a googlemap function, from the javascript code back to the c++ source code in order to process those results. But no success.
    I have an html page which I load inside a class derived from QWebView. The html page I load inside the WebView is:
    Qt Code:
    1. <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=GOOGLE_MAPS_KEY"
    2. type="text/javascript"></script>
    3. <script type="text/javascript">
    4.  
    5. var map;
    6. var geocoder;
    7. var Lat,Lng;
    8.  
    9. function initialize()
    10. {
    11. if (GBrowserIsCompatible())
    12. {
    13. map = new GMap2(document.getElementById("map"));
    14. //
    15. map.addControl(new GSmallMapControl);
    16. map.addControl(new GMapTypeControl);
    17. geocoder = new GClientGeocoder();
    18. map.setCenter( new GLatLng(0,0),1 );
    19. GEvent.addListener(map, "click", getAddress);
    20. }
    21.  
    22. }
    23.  
    24. function getAddress(overlay, latlng) {
    25.  
    26. if (latlng != null) {
    27.  
    28. address = latlng;
    29.  
    30. geocoder.getLocations(latlng, showAddress);
    31.  
    32. }
    33. }
    34. function showAddress(response) {
    35. map.clearOverlays();
    36. if (!response || response.Status.code != 200) {
    37. alert("Status Code:" + response.Status.code);
    38. } else {
    39. place = response.Placemark[0];
    40. point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
    41. marker = new GMarker(point);
    42. map.addOverlay(marker);
    43. marker.openInfoWindowHtml(
    44. '<b>orig latlng:</b>' + response.name + '<br/>' +
    45. '<b>latlng:</b>' + place.Point.coordinates[1] + "," + place.Point.coordinates[0] + '<br>' +
    46. '<b>Status Code:</b>' + response.Status.code + '<br>' +
    47. '<b>Status Request:</b>' + response.Status.request + '<br>' +
    48. '<b>Address:</b>' + place.address + '<br>' +
    49. '<b>Accuracy:</b>' + place.AddressDetails.Accuracy + '<br>' +
    50. '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
    51. Lat = place.Point.coordinates[1];
    52. Lng = place.Point.coordinates[2];
    53. Name= plcae.AddressDetails.Country.AdmninistrativeArea.Locality;
    54. Map.setValues(Lat, Lng, Name);
    55.  
    56. }
    57. }
    58. function Open(x,y)
    59. {
    60. map.setCenter( new GLatLng(x,y),13 );
    61. }
    62. </script>
    63.  
    64. </head>
    65. <body onload="initialize()" onunload="GUnload()" topmargin="0" leftmargin="0">
    66. <div id="map" style="width: 341px; height: 271px"></div>
    67. </body>
    68. </html>
    To copy to clipboard, switch view to plain text mode 

    In my c++ code I have
    Qt Code:
    1. this->page()->mainFrame()->addToJavaScriptWindowObject("Map", this);
    2. connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
    3. this, SLOT(populateJavaScriptWindowObject()));
    4. .....
    5. void Map::geoCode(QString local)
    6. {
    7. clearCoordinates();
    8. // qDebug()<<"Map finding..."<<local;
    9. QString requestStr( tr("http://maps.google.com/maps/geo?q=%1&output=%2&key=%3")
    10. .arg(local)
    11. .arg("csv")
    12. .arg("GOOGLE_MAPS_KEY") );
    13.  
    14. manager->get( QNetworkRequest(requestStr) );
    15. ++pendingRequests;
    16. }
    17. ...
    18. void Map::populateJavaScriptWindowObject()
    19. {
    20. this->page()->mainFrame()->addToJavaScriptWindowObject("Map", this);
    21.  
    22. }
    23. void Map::setValues(const QString &latitude, const QString &longitude, const QString &n)
    24. {
    25. lat = latitude.toDouble();
    26. lon = longitude.toDouble();
    27. name = n;
    28. qDebug()<<"MAP new values available";
    29. }
    To copy to clipboard, switch view to plain text mode 
    So, I am expecting that when I click on a point in the google map the javascript calls the object Map, which I exported with the addToJavaScriptWindowObject.
    But, nothing: I double click on a point, the map change but it seems that the setValues faunction is not call at all.

  2. #2
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    I had a project doing this very same thing. I was not successful doing it in the way you describe, so I ended up doing it a different way. I found out that Google Maps is sometimes kindof laggy. What happens, is that your page will load, but without the calculated information, then as google catches up, it will then put the values in the page.

    How I ended up getting it to work, was making a PHP page, which generated javascript according to variables I sent it:

    Qt Code:
    1. webView->setUrl(QUrl("http://server/page.php?street=" + street->text() + "&street2=" + street2->text() + "&city=" + city->text() + "&state=" + state->currentText() + "&zip=" + zip->text()));
    To copy to clipboard, switch view to plain text mode 

    The javascript on the page was set to it generated a hidden <div> tag in the page, which contained the variables that I wanted to pass to my Qt program.

    I created a slot to examine the page with a single shot timer in it.

    Qt Code:
    1. connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(examineWait(bool)));
    2.  
    3. void DialogDelivery::examineWait(bool ok) {
    4. QTimer::singleShot(5000, this, SLOT(examinePage()));
    5. }
    6.  
    7. void DialogDelivery::examinePage() {
    8. //checks if the page has loaded the stuff from google yet
    9. //if it has not found anything, it calls examineWait() again
    10. //so it can see if the page has loaded yet
    11. //also a good idea to keep count somewhere of how many
    12. //times you tried to examine, and if too many times then
    13. //give up because google could have timed out.
    14. }
    To copy to clipboard, switch view to plain text mode 

    webView->page()->currentFrame()->toHtml() contents change as the map and geocoding from google loads.

    I found that sometimes, google's server is bogged down and never returns results, or takes several seconds.

    So even though the loadFinished(bool) signal is fired, google's map/geocoding may not have finished yet. This is why I use the single shot timer, to give google time to catch up, and do "tries" of seeing if google is done loading, so that I can give the user results as fast as possible when google finally does return the results.

    After 10 or so tries, I make the program give up trying to examine the loaded page, as google probably will not return results at all if it hasn't within 50 seconds.

    *edit*
    Also, one other thing I thought of, was that the API key also is bound to a domain. Depending on where google thinks your page loads from, you may have trouble getting results.
    Last edited by tpf80; 16th May 2009 at 09:15.

  3. #3
    Join Date
    May 2008
    Posts
    276
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    From what you are saying, I guess that it should be better to switch to another way to get coordinates/city data worldwide.
    My application is very simple: I need to konw the coordinates of a city worldwide, and viceversa (from coordinates to city name).
    Are you aware of other methods to perform the same task?
    Bye

  4. #4
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    How is your app going to use the coordinate/city name combo?

    For example, are you expecting the user to click on the map, and then have something happen with the coordinate/city name? Or is the end result not using the map at all, and just doing something with the coordinate/city names?

  5. #5
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Angry Re: WebKit - accessing javascript results + googleMap

    Actually I played around with your code for a bit, and I was able to get the values to come into the Qt Program what I did was in the html I created a function for example:

    Qt Code:
    1. //javascript added to your web code
    2. function getlat(){
    3. return Lat;
    4. }
    To copy to clipboard, switch view to plain text mode 

    Then in the Qt Program I made a function:
    Qt Code:
    1. void someSlot() {
    2. QString javascript = QString("getlat()");
    3. QVariant latfromjavapage = webView->page()->currentFrame()->evaluateJavaScript(javascript);
    4. }
    To copy to clipboard, switch view to plain text mode 
    the variable latfromjavapage did contain the latitude.

  6. #6
    Join Date
    May 2008
    Posts
    276
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    Well, I need the coordinates of the city.
    So for example, If I type "Paris" I need back paris' coordinates.
    On the other hand, I wish to have a feature like that: if the user move a point on the map near Paris I would have back the point's coordinates.
    Without this feature, the map would be not useful.

  7. #7
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    you can for example do something like this:

    Qt Code:
    1. // here you can enter an address and your web page evaluates it:
    2. //put this in some slot connected to the button in the UI to find the city
    3. QString javascript = QString("geocoder.getLocations(\"" + street->text() + " " + street2->text() + ", " + city->text() + ", " + state->currentText() + ", " + zip->text() + "\", showAddress);");
    4. webView->page()->currentFrame()->evaluateJavaScript(javascript);
    5. }
    6.  
    7. //now your coordinates are in Lat and Lng in the page;
    8. // they also are there if you just click on the map
    9.  
    10. //so now all you have to do, is check them after they are loaded
    11. // i use a 1 second single shot timer for this (call this from the click slot
    12. // and from the button slot that inputs the address)
    13. //and you can use them:
    14.  
    15. QTimer::singleShot(1000, this, SLOT(someSlot()));
    16.  
    17. void someSlot() {
    18. QString javascript = QString("getlat()");
    19. QVariant latfromjava = webView->page()->currentFrame()->evaluateJavaScript(javascript);
    20. javascript = QString("getlng()");
    21. QVariant lngfromjava = webView->page()->currentFrame()->evaluateJavaScript(javascript);
    22. }
    To copy to clipboard, switch view to plain text mode 

    in your html you add these 2 pieces of code:
    Qt Code:
    1. //javascript added to your web code
    2. function getlat(){
    3. return Lat;
    4. }
    5.  
    6. function getlng(){
    7. return Lng;
    8. }
    To copy to clipboard, switch view to plain text mode 

    so what ends up happening, is:

    If you click on the map, then Lat and Lng are filled with data (and the popup shows the info on the map), the single shot timer triggers, and the data is gathered into your Qt program.

    If you enter an address in the GUI, then when you click the submit button, it forces the address into the getlocation function, which in turn shows the bubble of info on the map at that location, and triggers the single shot timer causing the returned lat/lng to be in your Qt program.

  8. #8
    Join Date
    May 2008
    Posts
    276
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    Thank you.
    I just did what you suggested, but do not work
    But I do not understand where and how to call singleShot.
    Qt Code:
    1. connect(this,SIGNAL(loadFinished(bool)),SLOT(waitPage(bool )));
    2.  
    3. void Map::waitPage(bool ok)
    4. {
    5. QTimer::singleShot(1000,this,SLOT(examinePage()));
    6. }
    7. void Map::examinePage()
    8. {
    9. QString javascript = QString("getlat()");
    10. QVariant latfromjava = page()->currentFrame()->evaluateJavaScript(javascript);
    11. javascript = QString("getlng()");
    12. QVariant lngfromjava = page()->currentFrame()->evaluateJavaScript(javascript);
    13. qDebug()<<latfromjava<<lngfromjava;
    14.  
    15. }
    To copy to clipboard, switch view to plain text mode 

  9. #9
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    Qt Code:
    1. class DialogMap: public QDialog, private Ui::DialogMap {
    2.  
    3. Q_OBJECT
    4.  
    5. public:
    6. //functions:
    7. DialogMap(QWidget *parent = 0);
    8.  
    9. //variables:
    10.  
    11. private slots:
    12. void calcMap();
    13. void examineWait();
    14. void examinePage();
    15.  
    16. private:
    17. bool examineSuccess;
    18. int examineTries;
    19. bool examinetimedout;
    20.  
    21. };
    22.  
    23. //setup interface of main window:
    24. DialogMap::DialogMap(QWidget *parent) : QDialog(parent) {
    25.  
    26.  
    27. examineSuccess = false;
    28. examinetimedout = false;
    29. examineTries = 10;
    30.  
    31.  
    32. setupUi(this);
    33.  
    34.  
    35. //if we click on the button in the GUI we call that slot:
    36.  
    37. connect(calcButton, SIGNAL(clicked()), this, SLOT(calcMap()));
    38.  
    39. //this is to make sure the program examines the script after the map is first loaded:
    40.  
    41. connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(examineWait()));
    42. ///////////////////////////////////////////////////////////////////
    43. //also can have other slots here, such as a "clicked" signal connecting to examinewait
    44. //for when the map is clicked by the user
    45. //or any other signal that might trigger you to examine the lat/lng in the map
    46. //////////////////////////////////////////////////////////////////////
    47.  
    48.  
    49.  
    50. //load the view with the map page:
    51. webView->setUrl(QUrl("http://domain/map.html"));
    52.  
    53.  
    54.  
    55. }
    56.  
    57.  
    58. //make the map process the GUi vars we pass to the javascript:
    59. void DialogMap::calcMap() {
    60. //reset success to false because we have not examined it yet:
    61. examineSuccess = false;
    62. examinetimedout = false;
    63. examineTries = 10;
    64.  
    65. //input the vars from our GUI into the google javascript
    66. QString javascript = QString("geocoder.getLocations(\"" + street->text() + " " + street2->text() + ", " + city->text() + ", " + state->currentText() + ", " + zip->text() + "\", showAddress);");
    67. webView->page()->currentFrame()->evaluateJavaScript(javascript);
    68. }
    69.  
    70. //examine the map now that we sent an address to it
    71. examineWait();
    72.  
    73. }
    74.  
    75.  
    76.  
    77. //single shot timer, to wait to examine the map (lets google catch up)
    78. //tune the time variable based on your load times
    79. void DialogMap::examineWait() {
    80. QTimer::singleShot(1000, this, SLOT(examinePage()));
    81. }
    82.  
    83.  
    84. void DialogMap::examinePage() {
    85.  
    86. QString javascript = QString("getlat()");
    87. QVariant lat = webView->page()->currentFrame()->evaluateJavaScript(javascript);
    88.  
    89. javascript = QString("getlng()");
    90. QVariant lng = webView->page()->currentFrame()->evaluateJavaScript(javascript);
    91.  
    92. examineTries--;
    93.  
    94. //if we got results, then we can stop trying:
    95. if ((examineSuccess == false)&&(lat.toString() != "")&&(lng.toString() != "")) {
    96.  
    97. //reset our tries for the next time the user clicks/requests an address
    98.  
    99. examineSuccess = true;
    100. examineTries = 10;
    101.  
    102. //since we grabbed the lat and lng, reset them to "", so we
    103. //don't pull them again out of the page until user selects a new
    104. //point
    105. javascript = QString("Lat = \"\";\nLng = \"\";");
    106. webView->page()->currentFrame()->evaluateJavaScript(javascript);
    107.  
    108. ////////////////////////////////////////////
    109. //do something with your lat and lng vars here
    110. ////////////////////////////////////////////
    111.  
    112. //if we found nothing then try again until examinetries has 0 left
    113. } else {
    114. //if we have tries left, then we try again:
    115. if ((examineSuccess == false)&&(examineTries > 0)) {
    116. examineWait();
    117. }
    118. if ((examineSuccess == false)&&(examineTries == 0)) {
    119. if (!examinetimedout) {
    120. //qDebug()<< "Timed out!";
    121. QMessageBox::critical(0, qApp->tr("Map Timed Out!"),
    122.  
    123. qApp->tr("Loading Google Map timed out!\n\nPlease click \"Calculate >>\" to try again."), QMessageBox::Ok,
    124.  
    125. QMessageBox::NoButton);
    126. examinetimedout = true;
    127. }
    128. }
    129. }
    130.  
    131. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    May 2008
    Posts
    276
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    Did you try your code?
    G

  11. #11
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: WebKit - accessing javascript results + googleMap

    Yes and it works. The example I posted is a good start but not totally complete. You would need to make the UI file in designer, add the code in main to exec the dialog, and of course some code to do something with the data you gathered.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.