ASP.Net MVC -- "Google’s MarkerManager" - javascript

Been chasing a rabbit, and time to ask for help before I get any further down this rabbit hole. I have been trying to implement a Google Map with multiple markers. I was trying to use the code I found on ChangSu’s Tech blog at https://csjlsolutions.wordpress.com/2013/07/11/how-to-put-multiple-markers-in-google-map-in-mvc-4/. I managed to get my google map to display, but none of the markers displayed. By using the browsers' development tool, I saw that the java script could not find Google’s MarkerManager. After looking around some more, I used the Package Manager Console to install Jmelosegui.Mvc.Googlemap (version 0.8.0.0) (see http://www.jmelosegui.com/map/).
After installing this package, I started getting a new error:
Conflicting versions of ASP.NET Web Pages detected: specified version is “1.0.0.0”, but version in bin is “3.0.0.0”. To continues remove files from application’s bin directory or remove the version specification in web.config
More looking around, and updated my web.config to version 3 (it was version 1.0.0.0)
<appSettings>
add key="webpages:Version" value="3.0.0.0" /
Now I have syntax error.
#foreach (var place in Model) {
var myLatLng = new google.maps.LatLng("#place.MonumentLocationLat", "#place.MonumentLocationLong");
Not sure which way to turn on this. Should I start from scratch?

I think when I installed Jmelosegui.Mvc.Googlemap it really messed up something somewhere. I was getting errors about version mismatches and all kinds of strange things. I have fallen back to a previous version of my code (aren't backups nice) and have managed to get my map to displays. I
My Solution
Controller
// -------------------- Display a Map of the Battlefield showing the location of all of the monuments that have been entered to the DB -------------------------------------------------
public ActionResult MapMonuments(string battleRecID)
{
var monumentMap = from s in db.Monuments
where ((s.MonumentBattleRecID == battleRecID) &&
(s.MonumentStatus == "A"))
select s;
ViewBag.avgLat = monumentMap.Average(s => s.MonumentLocationLat);
ViewBag.avgLong = monumentMap.Average(s => s.MonumentLocationLong);
return PartialView(monumentMap.ToList());
}
View
#model IEnumerable<CWBFM.Models.Monument>
// avgLat = the average of all of the latitudes
// avgLong = the average of all of the longitudes
Int_Map("#ViewBag.avgLat", "#ViewBag.avgLong");
// Where all the fun happens
function Int_Map(avgLat, avgLong) {
var latlng = new google.maps.LatLng(avgLat, avgLong);
// These are options that set initial zoom level, where the map is centered globally to start, and the type of map to show
var mapOptions = {
zoom: 15,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
panControl: true,
zoomControl: true,
streetViewControl: true,
mapTypeControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
}
}
// This makes the div with id "map_canvas" a google map
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// place a marker on the map for each monument
#foreach (var place in Model) {
<text>
var myLatLng = new google.maps.LatLng("#place.MonumentLocationLat", "#place.MonumentLocationLong");
var markerTitle = "#place.MonumentName"; // input the monuments name from the database
var URL = "http://cwbfm.org/Monument/MonumentDetails/" + "#place.MonumentID"; // create the url to link to the monuments detail page
// set the marker icon based on the Allegiance
switch ("#place.MonumentAllegiance") {
case "B":
var image = 'http://maps.google.com/mapfiles/kml/paddle/grn-circle.png';
break;
case "C":
var image = 'http://maps.google.com/mapfiles/kml/paddle/red-circle.png';
break;
case "U":
var image = 'http://maps.google.com/mapfiles/kml/paddle/blu-circle.png';
break;
default:
var image = 'http://maps.google.com/mapfiles/kml/paddle/ylw-circle.png';
}
var myMarker = new google.maps.Marker({
position: myLatLng,
icon: image,
title: markerTitle,
url: URL,
map: map
});
// on click, go to the monuments detail page
google.maps.event.addListener(myMarker, "click", function () {
window.location.href = this.url;
});
</text>
} return
}
This works fine for me.

Related

How to build a theme using jaredpalmer/presspack with Google Maps integration?

Introducing the problem
Building this theme using jaredpalmer/presspack for docker, I'm struggling for a few days now as I try to insert this pair of Google Maps instances within an element that will be called in every page. The maps won't load and Chrome tells me my function is not there.
Some context
Presspack is serving the DB and uses yarn to make a environment. It keeps scripts separately for general purposes and specific ones, as it has a common.js - where I code everything it should load on every page - and a .js - which loads only on specific pages. I'm working on common now, since I believe this contact section will be used on every page and blog post of this site. The calling function for this section is WP basic <?php get_template_part( 'content', 'contato-std' ); ?>
I've added a code in functions.php to load the API key script after the footer of my pages.
It's important to mention that I've tried the js code I'm using in common.js on another HTML only environment.
My files
common.js
export default {
init() {
// JavaScript to be fired on all pages
console.log('common');
},
finalize() {
// JavaScript to be fired on all pages, after page specific JS is fired
var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) { // Tudo o que for pra navegadores mobile
(...)
} else { // Tudo o que for pra navegadores padrão
(...)
// GOOGLE MAPS LOAD
var markers = [{
GPS1: -15.7954901,
GPS2: -47.8926766,
client_address: "Corpus - Fisioterapia & Pilates, Unidade Asa Sul"
}];
function initialize() {
initMap();
initMap2();
};
function initMap() {
var latlng = new google.maps.LatLng(-15.7954901, -47.8926766); // default location
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById('mapaAsaSul'), myOptions);
var infowindow = new google.maps.InfoWindow(),
marker, lat, lng;
for (i = 0; i < markers.length; i++) {
lat = (markers[i].GPS1);
lng = (markers[i].GPS2);
name = (markers[i].client_address);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
name: name,
map: map
});
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent(this.name);
infowindow.open(map, this);
}.bind(marker));
}
}
var markers2 = [{
GPS1: -15.7187167,
GPS2: -47.8867326,
client_address: "Corpus - Fisioterapia & Pilates, Unidade Lago norte"
}];
function initMap2() {
var latlng = new google.maps.LatLng(-15.7187167, -47.8867326); // default location
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById('mapaLagoNorte'), myOptions);
var infowindow = new google.maps.InfoWindow(),
marker, lat, lng;
for (i = 0; i < markers2.length; i++) {
lat = (markers2[i].GPS1);
lng = (markers2[i].GPS2);
name = (markers2[i].client_address);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
name: name,
map: map
});
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent(this.name);
infowindow.open(map, this);
}.bind(marker));
}
}
},
};
function.php
<?php
...
function add_google_maps() {
wp_enqueue_script(
'my-google-maps',
'http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize',
NULL,
NULL,
true
);
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if ( 'my-google-maps' !== $handle )
return $tag;
return str_replace( ' src', ' async defer src', $tag );
}, 10, 2 );
}
add_action('wp_enqueue_scripts', 'add_google_maps');
?>
The JS handling the routing from common.js and .js is index.js
import jQuery from 'jquery';
import './style.scss';
import Router from './util/Router';
import common from './routes/common';
import home from './routes/home';
/**
* Populate Router instance with DOM routes
* #type {Router} routes - An instance of our router
*/
const routes = new Router({
/** All pages */
common,
/** Home page */
home
/** About Us page, note the change from about-us to aboutUs. */
});
/** Load Events */
jQuery(document).ready(() => routes.loadEvents());
Bad response
It should load both instances of maps within the respective div's #mapaAsaSul and #mapaLagoNorte, but it won't and Chrome's console returns this:
(index):1
Uncaught (in promise) Xc {message: "initialize is not a function", name: "InvalidValueError", stack: "Error↵ at new Xc (http://maps.googleapis.com/ma…KEY&callback=initialize:125:107"}message: "initialize is not a function"name: "InvalidValueError"stack: "Error↵ at new Xc (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:56:227)↵ at Object._.Yc (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:56:337)↵ at Uh (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:125:221)↵ at http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:125:107"__proto__: Error
Promise.then (async)
Vh # js?key=KEY&callback=initialize:125
google.maps.Load # js?key=KEY&callback=initialize:21
(anonymous) # js?key=KEY&callback=initialize:212
(anonymous) # js?key=KEY&callback=initialize:212
This initialize is written in common.js. The file is listed in console, red by webpack (which presspack uses).
I'm running this #localhost so won't be able to provide a link for this page.
And I'm sorry if I've done any mistakes formatting this post or provide wrong info. Not really experienced at creating posts here in stack. :(
Any thoughts and ideas on this problem will be most welcome.
Edit: corrected that mistake as Evan suggested in the comments, where the calling was for maps.google.com and not maps.googleapis.com
Edit2: As Evan kept helping me on the comment section, I've made some additions to my code as follows.
The callback function that was returning a problem in console, was removed and I replaced it as a new callback for initialize function that appears on common.js.
var markers = [{(...)}];
function initialize() {(...)};
function initMap() {(...)};
var markers = [{(...)}];
function initMap2() {(...)};
google.maps.event.addDomListener(window, 'load', initialize); //This is the new callback for my maps
This did solved something, since the first map appeared. Still, there was still some error which console would point at:
"Uncaught ReferenceError: i is not defined at initMap (common.js?a395:77) at initialize (common.js?a395:56)" pointing at this line of common.js: for (i = 0; i < markers.length; i++) {.
I didn't get it. Just guessed that it had something to do with my markers code, since the first map appeared after the callback being made in common.js but with no marker.
Then, Evan pointed that if i was initialized globally, that error made sense. So he suggested changing the code to for (let i = 0; i < markers.length; i++) {, which did it for me. Adding it to both instances of markers in the code, made both maps appear properly and with markers.
Thanks for your help, Evan!
First of all, the JavaScript API should be called via https://maps.googleapis.com/, not http://maps.google.com/.
The "initialize is not a function" scope error can be worked around by loading the Maps API script synchronously on page load, e.g. by using google.maps.event.addDomListener(window, 'load', initialize), but in general the recommended approach is to load the API asynchronously via a callback:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize"></script>
Then there's an issue with both markers loops, e.g. for (i = 0; i < markers.length; i++), as they're missing i initialization. Try using for (let i = 0; i < markers.length; i++).
You can find here a working jsbin that shows both your maps and markers loading successfully after the above code changes.

Google Maps & JavaFX: Display marker on the map after clicking JavaFX button

I have been trying to display a marker on the map when I click on a Button of my JavaFX application. So what happens is when I click on that button, I write the position in a JSON file, this file will be loaded in the html file that contains the map. The problem is that it works perfectly when I open the html page in the browser, but nothing happens in the JavaFX's web view, and I don't know why !
This is the html file:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
/*#map {
height: 100%;
}*/
#map{width:100%;height:100%;margin:auto;}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map;
var marker;
// Multiple Markers
var markers = [];
var pos = {lat: 46.662388, lng: 0.3599617};
var itinerary_markers = [];
function initMap() {
var currentLat, currentLng;//Latitude et longtitude courante
$.ajax({
url: 'https://maps.googleapis.com/maps/api/geocode/json?address=My+ADDRESS&key=MY_KEY',
async: false,
dataType: 'json',
success: function (data) {
currentLat = data.results[0].geometry.location.lat;
currentLng = data.results[0].geometry.location.lng;
}
});
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: currentLat, lng: currentLng},
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
/*MARQUEUR*/
$.ajax({
async: false,
url: 'test.json',
data: "",
accepts:'application/json',
dataType: 'json',
success: function (data) {
for (var i = 0; i < data.hydrants.length; i++) {
markers.push( data.hydrants[i]);
}
}
});
var posi = new google.maps.LatLng(markers[0].Lat, markers[0].Lng);
marker = new google.maps.Marker({
position: posi,
map: map,
//title: markers[i][0]
title: markers[0].Name
});
}
</script>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous">
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap&language=fr"
async defer></script>
</body>
</html>
When I click the button, I fill the JSON file (which works perfectly) and then I execute this to refresh the webview:
this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());
As I said before, when I open the file on the browser I see the expected result, but I don't know what is the problem with the JavaFX.
If there is a better way to do this please tell me.
EDIT:
I found a solution to the problem by sending directly the data (the GPS coordinates) from JavaFX to Javascript using the executeScript() method, so I don't need a json file as bridge between the two platforms.
So this is an example of how the code looks like:
eng.executeScript("updateMarker(" + lat + ", " + lng + ")");//eng is a WebEngine instance
And here is the Javascript:
/*The initial latitude and longtitude*/
var currentLat = the latitude;
var currentLng = the longtitude;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: currentLat, lng: currentLng},
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var posi = new google.maps.LatLng(currentLat, currentLng);
marker = new google.maps.Marker({
position: posi,
map: map,
visible: false
});
}
/*The method that is I call from JavaFX*/
function updateMarker(_lat, _lng){
marker.setPosition({lat: _lat, lng: _lng});
map.setCenter(new google.maps.LatLng(_lat, _lng));
marker.setVisible(true);
}
Thank you for your comments and answers, and a special shootout to reddit.
If I had to guess - one of two things is happening:
Either A) your javaFX is not supporting cross site ajax calls or B) it is not waiting for the asynchronous ajax response/something else is going wrong.
So let's do some testing together. Firstly can we clean this up to nest the ajax calls? Then can you add in some console.log statements to find out what each is sending back? If you miss some output we know where it's going wrong and that'll help us fix things.
Note I've changed success to the 'done' additions because success is a bit out of date, and everything is nested to eliminate the question around whether any blanks are being sent in to the next calls (synchronicity issues):
$.ajax({
url: 'https://maps.googleapis.com/maps/api/geocode/json?address=My+ADDRESS&key=MY_KEY',
async: false,
dataType: 'json'
}).done(function(data) {
currentLat = data.results[0].geometry.location.lat;
currentLng = data.results[0].geometry.location.lng;
console.log(currentLat);
console.log(currentLng);
// Multiple Markers
var markers = [];
var pos = {lat: 46.662388, lng: 0.3599617};
var itinerary_markers = [];
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: currentLat, lng: currentLng},
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
console.log(map);
/*MARQUEUR*/
$.ajax({
async: false,
url: 'test.json',
data: "",
accepts:'application/json',
dataType: 'json'
}).done(function(data) {
for (var i = 0; i < data.hydrants.length; i++) {
markers.push( data.hydrants[i]);
}
console.log(markers);
var posi = new google.maps.LatLng(markers[0].Lat, markers[0].Lng);
console.log(posi);
var marker = new google.maps.Marker({
position: posi,
map: map,
//title: markers[i][0]
title: markers[0].Name
});
console.log(marker);
}).fail(function(jqXHR, testStatus){
console.log(textStatus);
});
}).fail(function(jqXHR, testStatus){
console.log(textStatus);
});
Here is a link on getting the console.log output in to System.out in Java if this is an issue:
JavaFX 8 WebEngine: How to get console.log() from javascript to System.out in java?
...Also hello from reddit.
In the line:
this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());
I would try double-checking the path to the file is correct. Reading other answers on StackOverflow, it looks like this is supposed to be relative to the package root and either with or without the leading '/'. i.e. getResource("data/index.html"). But, then again, maybe you would already be seeing errors related to getResource()...
My next go to, for debugging purposes, would be to comment out the part where you write the JSON and just manually write some good JSON and just try to get it to show up in the webView. The fewer moving parts, the better. If you can get it to work with your pre-written JSON then you can assume it is some problem with the JSON you are writing with Java and then it being loaded to the HTML.
Edit: I dug a bit deeper. This could be totally wrong again but maybe you can try manually calling the initMap() function from Java that your web browser normally calls onload. How to call a JavaScript function from a JavaFX WebView on Button click? has some more details. Try this.webView.getEngine().executeScript("initMap()"); after you edit the JSON with your button.
Edit 2 As an aside, too, it might make sense to split initMap into an initMap and updateMap function for making the map to begin with and then setting the markers on the map. Though this is hardly breaking anything.
If your mouse-wheel is used to zoom the map out or in and the marker appears, then you are experiencing the same issue that I did.
Try manually zooming the mapview to restore the markers. I also had to employ this technique when displaying a route from the Directions Service, otherwise the waypoint markers were not displaying correctly.
This is the code in my Javafx controller class to do so:
KeyFrame kf1 = new KeyFrame(Duration.seconds(0.75), e -> map.setZoom(map.getZoom() - 1));
KeyFrame kf2 = new KeyFrame(Duration.seconds(1.5), e -> map.setZoom(map.getZoom() + 1));
Timeline timeline = new Timeline(kf1, kf2);
Platform.runLater(timeline::play);
This was using GMapsFX, which is just a thin Java wrapper around javascript engine calls on a JavaFX WebView. Hopefully it helps.

How to create and bind a context menu with array of markers on the Google map?

I am working on a treasure hunting project using JSP, Postgres and Tomcat. After logging in, it should allow the admin to specify the map location, add various objects (like treasure and NPCs that are already saved in my database) to the map and be able to copy, paste and delete any objects.
Everything like login, and insert objects of various types, is working but now I want to enable a right-click context menu for each marker that will give the admin 3-4 options; copy, paste, delete, edit.
To achieve this, I have found the link very useful where the source code for the context menu is provided: http://code.martinpearman.co.uk/googlemapsapi/contextmenu/1.0/src/ContextMenu.js
I created a ContextMenu.js file and copied the above code and then have the following function in my jsp file. Please note that I'm retrieving a list of markers from my database as JSON object and looping through it to create and place the markers on the map.
function drawMap(){
var markers = {};
var contextMenu;
var contextMenuOptions={};
contextMenuOptions.classNames={menu:'context_menu',
menuSeparator:'context_menu_separator'};
// create an array of ContextMenuItem objects
var menuItems=[];
menuItems.push({id: "copy", className:'context_menu_item',
eventName:'copy_click', label:'Copy'});
menuItems.push({id: "paste", className:'context_menu_item',
eventName:'paste_click', label:'Paste'});
menuItems.push({id: "delete", className:'context_menu_item',
eventName:'delete_click', label:'Delete'});
contextMenuOptions.menuItems=menuItems;
lat='43.56873147104461';
lng='-79.76628009520937';
map = new google.maps.Map(
document.getElementById("map_container"), {
center: new google.maps.LatLng(lat,lng),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
json ='<%=request.getSession().getAttribute("data")%>'
json = JSON.parse(json);
for (i = 0; i <= json.length; i++) {
var lt,ln;
lat = json[i].latstr;
lng = json[i].lngstr;
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map
});
contextMenu = new ContextMenu(map, contextMenuOptions); //stops at this point
google.maps.event.addListener(marker, 'rightclick',function(e) {
contextMenu.show(e.latLng);
});
} //end for loop
google.maps.event.addListener(contextMenu, 'menu_item_selected',
function(object, latLng, eventName){
// latLng is the position of the ContextMenu
// eventName is the eventName defined for the clicked
ContextMenuItem in the ContextMenuOptions
switch(eventName){
case 'copy_click':
copyObject(object);
break;
case 'paste_click':
pasteObject(object, latLng);
break;
case 'delete_click':
deleteObject(object);
break;
}
});
} //end function drawMap();
I am not sure where the problem is. When I run the program, it just displays the first marker on the map and the right-click does nothing and I have tried alert("hi"); to check the problem. It stops at
contextMenu = new ContextMenu(map, contextMenuOptions);
I also tried to put an alert inside the ContextMenu function and it stops at the second line
this.setMap(map);
when I comment it out, it goes beyond this point, displays all the markers in the loop but the right-click does nothing. which means that the contextMenu.show(e.latLng); is not working. It may have something to do with the for loop.

Google maps js api. Many maps on page

I have accordion (twitter-bootstrap), and on each I have a map.
Accordion blocks generates in foreach. Maps generates as partial view, that takes model with latitude and longitude and block id.
It calls in foreach:
#if (item.Latitude != null)
{
<p>Map:</p>
<div class="map-margin">
#{Html.RenderAction("Map", "Default", new {model = item});}
</div>
}
And action returns this partial view:
#model MPS.Administration.Models.ReportModel
<div id="map-canvas-#Model.Id.ToString()" style="width: 470px; height: 270px;"></div>
<script type="text/javascript">
$('#map-canvas-#Model.Id').ready(function() {
initialize();
});
function initialize() {
var lat = #Model.Latitude;
var lng = #Model.Longitude;
var latlng = new google.maps.LatLng(#Model.Latitude, #Model.Longitude);
debugger;
var mapOptions = {
center: latlng,
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var name = 'map-canvas-' + #Model.Id.ToString();
var map = new google.maps.Map(document.getElementById(name),mapOptions);
debugger;
// create a marker
var image = '../Content/Images/map_icon.png';
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: image
});
}
</script>
On layout I included script for js api.
Now I have 4 blocks, but only the last have map block (and it have only google logo and gray background without the map :( ). In debugger I see that lat and lng is same all 4 times. I think the problem is how I call initialize() map. Please help me to solve this issue.
The map si show only in the visible div. For the other you shuuld see only a grey background and in some case a small portion of the map in the upper left corner.
For see the map in every block you should use map.resize() or better use a genaration function for each time you show a new map. Initialize tipcally is call only when the windows is created and this this case the maps not visible fails

Retrieve position of a google maps v3 marker to Qt in a desktop app with QtWebKit

I'm building a Qt app with Python where you can point and click at a (google) map and get the coordinates of the location. The map is shown through a QWebView loading a simple HTML page and the user can create markers by clicking. Screenshot of the widget after clicking on the map.
However, I'm having trouble to retrieve the just-clicked location coordinates back to Qt (so that I can use them as variables -- and, for example, show them in the QLineEdits on the topleft corner above, as current location of the marker).
This is the relevant part of the HTML file:
<script type="text/javascript">
var map;
function initialize() {
var local = new google.maps.LatLng(-23.4,-40.3);
var myOptions = {
zoom: 5,
center: local,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'rightclick', function(event) {
placeMarker(event.latLng);
});
}
function placeMarker(location) {
var clickedLocation = new google.maps.LatLng(location);
var marker = new google.maps.Marker({
position: location,
map: map
});
map.setCenter(location);
}
function dummyTxt() {
return 'This works.';
}
</script>
I've been trying with evaluateJavaScript, but was not able to retrieve the coordinates. I tried to created a function to access the position with marker.getPosition(), but with no luck. The dummy below works though..
newplace = QWebView.page().mainFrame().evaluateJavaScript(QString('dummyTxt()'))
>>> print newplace.toString()
This works.
Any suggestions on how to get the coordinates back to Qt?
Edit:
Here is the code that worked for me:
def update_geo(self):
# Capture coordinates of the last marker on the map.
mark = self.map.page().mainFrame().evaluateJavaScript('document.getElementById("markerlocation").value').toString()
# Convert string to list of floats, stripping parentheses.
marker = str(mark).strip('()').split(', ')
decimals = [float(c) for c in marker]
Full source in https://github.com/nelas/veliger/blob/master/veliger.py#L2374
I found a work around to make it work but I'm not pretty sure that it will be the right approach. Anyway, this is what I did:
Create a hidden input in the body section of your html document to save the position data of the marker:
<body>
(...)
<input id="locationData" type="hidden">
(...)
</body>
In the javascript code, save the position of the marker in the hidden input every time it's created:
function placeMarker(location) {
(...)
document.getElementById("locationData").value = marker.position;
(...)
}
In your Qt code, read the value of the hidden input with the instruction:
webView->page()->mainFrame()->findFirstElement("#locationData").evaluateJavaScript("this.value").toString();
I hope it helps!
Source: http://opendocs.net/qt/4.6/webkit-formextractor.html

Categories

Resources