I am using this code to draw and google map. It works but I'd like to add a tweak where instead of getting a popup to get the geolocation I want to pass it in the url.
Here is the html page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>HTML5 Geo Location API</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=myApiKeyHere&sensor=true"></script>
<style>
div.location {
width: 100%;
height: 400px;
}
</style>
</head>
<body>
<div id="page">
<div class="location"></div>
</div>
<!-- [/page] -->
<script>
(function ( $ ) {
$.fn.GeoLocation = function( options ) {
var settings = $.extend({
home: { latitude: 52.89770, longitude: -1.15596 },
}, options );
var home = new google.maps.LatLng(settings.home.latitude, settings.home.longitude);
return this.each(function() {
var element = $(this);
element.text('Attempting to find your location');
function displayCurrentPosition(data) {
element.html('<div class="map-canvas"></div>');
var current = new google.maps.LatLng(data.coords.latitude, data.coords.longitude);
var options = {
center: current,
mapTypeId: google.maps.MapTypeId.HYBRID,
zoom: 10,
};
var map = new google.maps.Map(element[0], options);
var directions = {
origin: current,
destination: home,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
display = new google.maps.DirectionsRenderer({ map: map });
service = new google.maps.DirectionsService();
service.route(directions, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
display.setDirections(response);
}
else
alert ('failed to get directions');
});
}
function onError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
element.text('Access to location API denied by user');
break;
case error.POSITION_UNAVAILABLE:
element.text('Unable to determine location');
break;
case error.TIMEOUT:
element.text('Unable to determine location, the request timed out');
break;
case error.UNKNOWN_ERROR:
element.text('An unknown error occurred!');
break;
}
}
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayCurrentPosition, onError);
} else {
element.text('Geolocation is not supported by this browser, please upgrade to a more recent version');
}
});
};
}( jQuery ));
jQuery(document).ready(function() {
jQuery('div.location').GeoLocation();
});
</script>
</body>
</html>
And here's how I am calling it:
<iframe src="mywebsiteurlhere/map.html" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
How can I do this?
If I understand you question correctly, you can simply pass the parameters into the iframe as described here: How to pass parameters through iframe from parent html?
<iframe src="mywebsiteurlhere/map.html?param=geolocation" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
Related
I have the following full-code working.. the script retrieves the Latitude and Longitude every 3 seconds for a Car in movement, and save the data into a mysql table.
Even with the GPS running on the phone the accuracy is not so good.
I add the Options Var so the i can enableHighAccuracy: true .
but the accuracy still very bad when i draw the map:
is there a way to improve this?
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title></title>
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js?ver=3.3.1'></script>
</head>
<body style="text-align: center">
<button style="font-size:30px" id="find_btn">Find Me</button>
<div id="result"></div>
<br>
<div id="resp"></div>
<br>
<button style="font-size:30px" id="stop_btn">STOP</button>
<script type="text/javascript">
function SaveLatLng(lat,lng) {
var url = "saveLatLng.php";
$.ajax({
type: "POST",
url: url,
data: {latitude:lat,longitude:lng},
success: function(data) {
$('#resp').html(data);
}
});
};
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
}
function randomQuote() { //user clicks button
if ("geolocation" in navigator) { //check geolocation available
//try to get user current location using getCurrentPosition() method
navigator.geolocation.getCurrentPosition(function(position){
$("#result").html("Found your location <br />Lat : "+position.coords.latitude+" </br>Lang :"+ position.coords.longitude);
SaveLatLng(position.coords.latitude,position.coords.longitude);
}, error, options);
} else {
console.log("Browser doesn't support geolocation!");
}
};
var interval = null;
$("#find_btn").click(function () {
interval = setInterval(randomQuote, 3000);
});
$("#stop_btn").click(function () {
clearInterval(interval);
});
</script>
</body>
</html>
Use watchPosition instead of getCurrentPosition every 3 secs. The later is optimized to return quickly at the possible expense of accuracy. Also you can check the accuracy (in meters) of the returned value and decide it is too inaccurate and ignore it.
You may also want to consider other position-filtering detailed here Min-distance, min-time etc
First of all, please apologize my English.
Hi! I need to print with PHP the current user´s address, i have this small script:
<?
function getaddress($lat,$lng)
{
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.trim($lat).','.trim($lng).'&sensor=false';
$json = #file_get_contents($url);
$data=json_decode($json);
$status = $data->status;
if($status=="OK")
{
return $data->results[0]->formatted_address;
}
else
{
return false;
}
}
?>
<?php
$lat= 21.884766199999998; //latitude
$lng= -102.2996459; //longitude
$address= getaddress($lat,$lng);
if($address)
{
echo $address;
}
else
{
echo "Not found";
}
?>
of course it works, but I don't know how to change the $lat and $long variables to the current users location.
In few words; how I can pass the current user lat and long location to the PHP variables to let this script works?
<html>
<body>
<p id="demo">Click the button to get your coordinates:</p>
<button onclick="getLocation()">Try It</button>
<script>
var x=document.getElementById("demo");
function getLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(showPosition);
}
else{x.innerHTML="Geolocation is not supported by this browser.";}
}
function showPosition(position)
{
x.innerHTML="Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
</body>
</html>
this is an javascript based search. you can try it in html browser and pass the lat long to the php scripts.
if it helps you its ok or you can tell , i have other ways too.
You need to get this using JavaScript or other google api. Which you can place lat & lang in an separate hidden field and then assign to your php variables from that hidden fields.
Here is an example script to get this using html 5 and java-script
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
This is another script using google Geo-location API
<!DOCTYPE html>
<html>
<head>
<title>Geolocation</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<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%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// Note: This example requires that you consent to location sharing when
// prompted by your browser. If you see the error "The Geolocation service
// failed.", it means you probably did not give permission for the browser to
// locate you.
var map, infoWindow;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 6
});
infoWindow = new google.maps.InfoWindow;
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
</body>
</html>
I am using Google Maps API to load a map with draggable directions. It works fine and great when I have the javascript written out in the html file, but I am still adding functions and for readability's sake. Therefore, I decided to separate the two. What I got was this:
HTML:
<!doctype html>
<html>
<head>
<link href="../CSS/main.css" rel="stylesheet" type="text/css">
<meta name="viewport" content="initial-scale=1.0">
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Create Route</title>
<script src="https://maps.googleapis.com/maps/api/js?key=XXXX" defer></script>
<script src="../JavaScript/create_route_map.js" defer></script>
</head>
<body>
<table>
<td>
<div id="map_canvas" name="map_canvas"></div>
</td>
<td>
<input size="25" id="hometown" type="text">
<input type = "button" value="Get Directions" onclick="calcRoute();">
</td>
</table>
</body>
</html>
JavaScript:
var rendererOptions = {
draggable: true
};
var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);;
var directionsService = new google.maps.DirectionsService();
var map;
function initMap() {
var town = new google.maps.LatLng(46.8133,-100.7790);
var mapOptions = {
center: town,
zoom: 7
};
map = new google.maps.Map(document.GetElementByID('map_canvas'), mapOptions);
directionsDisplay.setMap(map);
google.maps.event.addListener(directionsDisplay, 'directions_changed', function(){
computeTotalDistance(directionsDisplay.getDirections());
});
calcRoute();
}
function calcRoute() {
var start = "Town"
var end = document.getElementById('hometown').value;
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
google.maps.event.addDomListener(window, 'load', initmap);
I've tried using the function loadscript() but that didn't work.
function loadScript() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?key=XXXX' +
'callback=initMap';
document.body.appendChild(script);
}
I've also tried removing the api key since it is no longer needed for v3, but that didn't work either.
Thoughts? Suggestions? What am I missing?
(I think an important side note is that the .css file includes the height and width for the map-canvas div.)
UPDATE
After retyping getElementById and placing the scripts above , the errors I'm getting from the browser console are:
ReferenceError: google is not defined
NetworkError: A network error occurred
How would I go about fixing the Reference Error?
So; I am developing this web application that works based on the location of the user.
The part that finds the coordinates and the part that converts those coordinates into an address both work individually. However the variable from the first function doesn't seem to transfer over to do the second function and I can't figure out why.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script type="text/javascript">
var coordinates;
function getCoordinates(){
var options = {
enableHighAccuracy: true,
timeout: 4500,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
console.log('Enlem : ' + crd.latitude);
console.log('Boylam: ' + crd.longitude);
console.log('Hata Payı ' + crd.accuracy + ' metre.');
coordinates = new google.maps.LatLng(crd.latitude, crd.longitude);
alert(coordinates);
return coordinates;
};
function error(err) {
console.warn('HATA(' + err.code + '): ' + err.message);
};
navigator.geolocation.getCurrentPosition(success, error, options);
}
var ReverseGeocode = function () {
//This is declaring the Global variables
var geocoder, map, marker;
//This is declaring the 'Geocoder' variable
geocoder = new google.maps.Geocoder();
function GeoCode(latlng) {
// This is making the Geocode request
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if(status !== google.maps.GeocoderStatus.OK)
{
alert(status);
}
// This is checking to see if the Geoeode Status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
var address = (results[0].formatted_address);
//This is placing the returned address in the 'Address' field on the HTML form
document.getElementById('Address').value = results[0].formatted_address;
}
});
}
return {
Init: function () {
var latlng = getCoordinates();
alert(latlng);
GeoCode(latlng);
},
};
} ();
</script>
</head>
<body>
<div>
<input name="Address" type="text" id="Address" size="55" />
</div>
<div>
<input type="button" value="Adres Bul" onclick="ReverseGeocode.Init()">
</div>
<div id="map_canvas" style="height: 90%; top: 60px; border: 1px solid black;">
</div>
</body>
</html>
Your main problem: getCoordinates() does not return coordinates. So you cannot use it like this:
var latlng = getCoordinates();
Javascript has asyncronous stuff. That means it takes javascript some time to do it.
The way javascript handles this: You send a request, and you provide a callback (a function). Whenever javascript is ready, your callback will be executed. Positioning is one of those asynchronic things.
Here is a short example:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script type="text/javascript">
// this function is triggered when geolocation has found coordinates
function geolocationReturnedCoordinates(coordinates) {
document.getElementById('log').innerHTML =
'lat: ' + coordinates.coords.latitude +
'<br>lng: ' + coordinates.coords.longitude +
'<br>accuracy: ' + coordinates.coords.accuracy;
// Here would be a good place to call Reverse geocoding, since you have the coordinates here.
GeoCode(new google.maps.LatLng(coordinates.coords.latitude, coordinates.coords.longitude));
}
// geocoder
geocoder = new google.maps.Geocoder();
function GeoCode(latlng) {
// This is making the Geocode request
geocoder.geocode({'location': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var address = (results[0].formatted_address);
//This is placing the returned address in the 'Address' field on the HTML form
document.getElementById('Address').value = results[0].formatted_address;
}
});
}
function search_position_and_address() {
// we start the request, to ask the position of the client
// we will pass geolocationReturnedCoordinates as the success callback
navigator.geolocation.getCurrentPosition(geolocationReturnedCoordinates, null, null);
}
</script>
</head>
<body>
<input type="button" value="GO" onclick="search_position_and_address()"> Get position (coordinates) of the client. -- Then look for the address
<div id="log"></div>
<input id="Address" placeholder="Address">
</body>
</html>
It's up to you to put it back in your structure.
I just compiled the shortest code that permitted me to make my point.
Also the names of the functions ... I'm trying to make a point. In real life you would pick a shorter name.
I'm trying to write a piece of code which reads the longitude and latitude from a database and passes that into a JavaScript function which then places a marker in correspondence to the longitude and latitude of the coordinates which have been read from the database.
After the HTML has been set to the QWebView I then use: evaluateJavaScript to attempt to run the function in the JavaScript MarkersFromDatabase.
As you can see I have modified the QWebPage class to display the console error message and when I run the program I get this error:
ReferenceError: Can't find variable: MarkersFromDatabase 0 undefined
I don't understand why it's trying to find a variable when I'm running a function.
I don't understand why this isn't running the function.
Any help would be appreciated. Sorry for the messy JavaScript formatting!
Full Code:
from PyQt4.QtWebKit import *
import sqlite3
from PyQt4.QtSql import *
class CustomQWebPage(QWebPage):
def __init__(self):
super().__init__()
def javaScriptConsoleMessage(self,message,lineNumber,sourceID):
print(message,lineNumber,sourceID)
print("javascript console message^")
class ViewOnlyMap(QWebView):
def __init__(self, parent=None):
super().__init__()
self.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
self.settings().setAttribute(QWebSettings.JavascriptCanOpenWindows, True)
self.settings().setAttribute(QWebSettings.JavascriptCanAccessClipboard, True)
self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
self.CustomPage=CustomQWebPage()
self.Coordinates=None
self.set_code()
self.get_marker_coordinates()
def get_marker_coordinates(self):
with sqlite3.connect("skateboard_progress_tracker.db") as db:
cursor=db.cursor()
sql="select SkateparkLongitude, SkateparkLatitude from Skatepark"
cursor.execute(sql)
self.Coordinates=cursor.fetchall()
for coordinate in self.Coordinates:
self.CustomPage.mainFrame().evaluateJavaScript('MarkersFromDatabase({0},{1})'.format(coordinate[0],coordinate[1]))
print("Marker added")
print(coordinate[0])
print(coordinate[1])
def set_code(self):
self.html='''<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple markers</title>
<style>
html, body, #map-canvas {
height: 100%;
width: 100%
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var map;
var markers = [];
var results = [];
var coords = [];
var highestLevel;
function initialize() {
var Centre = new google.maps.LatLng(52.20255705185695,0.1373291015625);
var mapOptions = {
zoom: 8,
minZoom: 3,
center: Centre,
}
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
AddMarker(event.latLng);
});
}
function MarkersFromDatabase(SkateparkLat,SkateparkLng) {
var Skatepark = new google.maps.LatLng(SkateparkLat,SkateparkLng);
//return Skatepark;
AddMarker(Skatepark); }
function AddMarker(location) {
var marker = new google.maps.Marker({
title: 'Test',
position: location,
animation: google.maps.Animation.DROP,
map: map
});
//markers.push(marker);
var lat = marker.getPosition().lat();
var lng = marker.getPosition().lng();
markers.push({"Object":marker,"Lat":lat,"Lng":lng});
var contentString = '<div id="content">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">Skatepark</h1>'+
'<div id="bodyContent">'+
'<p>A skatepark description </p>'+
'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, 'rightclick', function(event) {
marker.setMap(null);
});
google.maps.event.addListener(marker, 'mouseover', function(event) {
infowindow.open(map,marker);
});
}
function GetMarkers(){
return markers;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html> '''
self.setHtml(self.html)
You need to give the web-page a chance to load before attempting to call javascript functions. So add a handler for the loadFinished signal:
class ViewOnlyMap(QWebView):
def __init__(self, parent=None):
super().__init__()
...
self.setPage(self.CustomPage)
self.loadFinished.connect(self.handleLoadFinished)
self.set_code()
def handleLoadFinished(self, ok):
if ok:
print("Page loaded successfully")
self.get_marker_coordinates()
else:
print("Could not load page")