GeoLocation
Ik had weleens eerder gevraagd over GeoLocation hoe dat precies werkt. Toch ben ik benieuwd of dit niet anders kan dmv een PHP $_GET request. Ik wil het in een Sessie zetten.
Groet Donny
Het kan op grofweg twee manieren: passief met een IP-adres via IP-geolocatie en actief met de GeoLocation API van HTML5. Via een IP-adres merkt de bezoeker er niets van (passief) en via de HTML5-API moet de gebruiker toestemming verlenen voor het doorgeven van zijn locatie (actief).
Wat nou als ik de geolocation van HTML5 wil gebruiken? Kan ik dan die JavaScript variabele linken aan een PHP variabele op een eenvoudige manier?
Je kan ook van de WebStorage van HTML5 gebruik maken:
http://www.w3schools.com/html/html5_webstorage.asp
Gewijzigd op 11/06/2013 12:02:05 door - Ariën -
Het kan echter ook anders, bijvoorbeeld door de gevonden coördinaten toe te voegen aan een single-pixel GIF of door ze in een verborgen formulierveld te plaatsen (bij zoekopdrachten, nieuwbriefaanmeldingen, inlogsystemen, enzovoort, en vooral natuurlijk bij alles waarbij locatie-informatie van pas kan komen).
Of als je al over adres gegevens van een gebruiker hebt locatie op haalen via de Google map-api.
Werkt de GEOlocation met GPS telefoons?
Maar mensen accepteren niet zo snel ik trouwens ook niet.
Ja... geolocation werkt wel, maar is niet altijd accuraat merk ik?
- Aar - op 11/06/2013 18:10:33:
Ja... geolocation werkt wel, maar is niet altijd accuraat merk ik?
Klopt, dat hangt vooral af van de bekende locatie van WiFi-hotspots. Het kan er enkele meters tot enkele tientallen meters naast zitten. Vandaar dat je geolocatie van Google Maps ook uitdrukkelijk niet mag gebruiken voor navigatie: voordat je het weet, ligt je auto in de plomp.
Toevoeging op 12/06/2013 10:42:53:
Als kleine “proof of concept” van geolocatie met HTML5 heb ik even een Ajax-applet in elkaar gestoken.
Webpagina in HTML5
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Geolocatie met HTML5 en Ajax</title>
<meta name="author" content="Ward van der Put">
</head>
<body>
<script>
// Voor versies van Microsoft Internet Explorer die XMLHttpRequest
// niet ondersteunen, kunnen we een ActiveX-object gebruiken.
if (typeof XMLHttpRequest == 'undefined') XMLHttpRequest = function() {
try {return new ActiveXObject('Msxml2.XMLHTTP.6.0')} catch(e) {}
try {return new ActiveXObject('Msxml2.XMLHTTP.3.0')} catch(e) {}
try {return new ActiveXObject('Msxml2.XMLHTTP')} catch(e) {}
try {return new ActiveXObject('Microsoft.XMLHTTP')} catch(e) {}
};
// Opties voor geolocatie met getCurrentPosition().
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(position)
{
// URL samenstellen met de twee GET-variabelen
// latitude (breedtegraad) en longitude (lengtegraad)
// in decimale graden.
var url = "http://localhost/geolocatie.php"
+ "?latitude=" + position.coords.latitude
+ "&longitude=" + position.coords.longitude;
// Nauwkeurigheid in meters (m)
url += "&accuracy=" + position.coords.accuracy;
// Hoogte in meters (m) en nauwkeurigheid van de hoogte
if (position.coords.altitude) {
url += "&altitude=" + position.coords.altitude;
if (position.coords.altitudeAccuracy) {
url += "&altitudeAccuracy=" + position.coords.altitudeAccuracy;
}
}
// Richting in graden, waarbij 0 ? heading < 360
if (position.coords.heading) {
url += "&heading=" + position.coords.heading;
}
// Snelheid in meters per seconde (m/s)
if (position.coords.speed) {
url += "&speed=" + position.coords.speed;
}
// URL verzenden in een Ajax-verzoek
verzoek = new XMLHttpRequest();
verzoek.open("GET", url, true);
verzoek.send(null);
}
// Functie voor foutafhandeling
function error(err) {
console.warn('Fout ' + err.code + ': ' + err.message);
};
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error, options);
}
</script>
</body>
</html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Geolocatie met HTML5 en Ajax</title>
<meta name="author" content="Ward van der Put">
</head>
<body>
<script>
// Voor versies van Microsoft Internet Explorer die XMLHttpRequest
// niet ondersteunen, kunnen we een ActiveX-object gebruiken.
if (typeof XMLHttpRequest == 'undefined') XMLHttpRequest = function() {
try {return new ActiveXObject('Msxml2.XMLHTTP.6.0')} catch(e) {}
try {return new ActiveXObject('Msxml2.XMLHTTP.3.0')} catch(e) {}
try {return new ActiveXObject('Msxml2.XMLHTTP')} catch(e) {}
try {return new ActiveXObject('Microsoft.XMLHTTP')} catch(e) {}
};
// Opties voor geolocatie met getCurrentPosition().
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(position)
{
// URL samenstellen met de twee GET-variabelen
// latitude (breedtegraad) en longitude (lengtegraad)
// in decimale graden.
var url = "http://localhost/geolocatie.php"
+ "?latitude=" + position.coords.latitude
+ "&longitude=" + position.coords.longitude;
// Nauwkeurigheid in meters (m)
url += "&accuracy=" + position.coords.accuracy;
// Hoogte in meters (m) en nauwkeurigheid van de hoogte
if (position.coords.altitude) {
url += "&altitude=" + position.coords.altitude;
if (position.coords.altitudeAccuracy) {
url += "&altitudeAccuracy=" + position.coords.altitudeAccuracy;
}
}
// Richting in graden, waarbij 0 ? heading < 360
if (position.coords.heading) {
url += "&heading=" + position.coords.heading;
}
// Snelheid in meters per seconde (m/s)
if (position.coords.speed) {
url += "&speed=" + position.coords.speed;
}
// URL verzenden in een Ajax-verzoek
verzoek = new XMLHttpRequest();
verzoek.open("GET", url, true);
verzoek.send(null);
}
// Functie voor foutafhandeling
function error(err) {
console.warn('Fout ' + err.code + ': ' + err.message);
};
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error, options);
}
</script>
</body>
</html>
Afhandeling in PHP
De callback wordt hier in een sessie geladen, maar je kunt hiervoor in de plaats een database gebruiken.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
// Caching op de client of een proxyserver voorkomen
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
// Breedtegraad en lengtegraad verwerken
if (isset($_GET['latitude'], $_GET['longitude'])) {
session_start();
$_SESSION['latitude'] = strip_tags($_GET['latitude']);
$_SESSION['longitude'] = strip_tags($_GET['longitude']);
if (isset($_GET['accuracy'])) {
$_SESSION['accuracy'] = strip_tags($_GET['accuracy']);
}
}
// Deze PHP-applet hoeft geen content terug te sturen
header('HTTP/1.1 204 No Content', true, 204);
?>
// Caching op de client of een proxyserver voorkomen
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
// Breedtegraad en lengtegraad verwerken
if (isset($_GET['latitude'], $_GET['longitude'])) {
session_start();
$_SESSION['latitude'] = strip_tags($_GET['latitude']);
$_SESSION['longitude'] = strip_tags($_GET['longitude']);
if (isset($_GET['accuracy'])) {
$_SESSION['accuracy'] = strip_tags($_GET['accuracy']);
}
}
// Deze PHP-applet hoeft geen content terug te sturen
header('HTTP/1.1 204 No Content', true, 204);
?>
Testen
De geografische coördinaten moeten na het voorgaande zijn terug te vinden in de sessie.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
// Sessie hervatten
session_start();
// Inhoud van de superglobal array $_SESSION tonen
echo '<pre>';
print_r($_SESSION);
?>
// Sessie hervatten
session_start();
// Inhoud van de superglobal array $_SESSION tonen
echo '<pre>';
print_r($_SESSION);
?>
Gewijzigd op 12/06/2013 10:53:54 door Ward van der Put
Er staat in je HTML5 voorbeeld een php openings teken. Dit gooit de hele markering om ;-)
Gewijzigd op 12/06/2013 10:49:41 door Chris PHP
Chris NVT op 12/06/2013 10:49:01:
Dat was voor de syntax highlighting, maar toch maar even aangepast.@Ward,
Er staat in je HTML5 voorbeeld een php openings teken. Dit gooit de hele markering om ;-)
Er staat in je HTML5 voorbeeld een php openings teken. Dit gooit de hele markering om ;-)
Maar nou wil ik bijvoorbeeld afstanden berekenen tussen 2 long en lats, hoe bereken ik die? Is er daarvoor een formule?
Donny Wie weet op 12/06/2013 12:40:39:
Maar nou wil ik bijvoorbeeld afstanden berekenen tussen 2 long en lats, hoe bereken ik die? Is er daarvoor een formule?
Ja, dat kan met de ‘haversine’-formule. Een hinderlijke beperking is echter dat deze rekent met de gemiddelde straal van de aarde en de aarde geen perfecte bol is. Afhankelijk van de coördinaten kun je er dus enkele meters tot vele tientallen meters naast zitten.
Ik wil het het liefste zelf berekenen. Ik wil bijvoorbeeld een radius aan kunnen geven van 5 km.
Donny Wie weet op 12/06/2013 12:49:06:
Ik wil het het liefste zelf berekenen. Ik wil bijvoorbeeld een radius aan kunnen geven van 5 km.
Voila, naar recept 131 uit het PHP Kookboek. Eet smakelijk :)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
function getAfstandInMeters($lengtegraad1, $breedtegraad1, $lengtegraad2, $breedtegraad2)
{
// Gemiddelde straal (r) van de aarde in meters
$r = 6367000;
// Hoogste nauwkeurigheid voor de functie pi() en de constante M_PI
ini_set('precision', 49);
// Graden omzetten in radialen
$lengtegraad1 = ($lengtegraad1 * M_PI) / 180;
$breedtegraad1 = ($breedtegraad1 * M_PI) / 180;
$lengtegraad2 = ($lengtegraad2 * M_PI) / 180;
$breedtegraad2 = ($breedtegraad2 * M_PI) / 180;
/**
* Haversine-formule
*
* dlat = lat2 - lat1
* dlon = lon2 - lon1
* a = sin^2(dlat/2) + cos(lat1) * cos(lat2) * sin^2(dlon/2)
* c = 2 * arcsin(min(1, sqrt(a)))
* d = r * c
*
* @link http://en.wikipedia.org/wiki/Haversine_formula
* @link http://www.movable-type.co.uk/scripts/gis-faq-5.1.html
*/
$dlat = $lengtegraad2 - $lengtegraad1;
$dlon = $breedtegraad2 - $breedtegraad1;
$a = pow(sin($dlat/2), 2) + cos($lengtegraad1) * cos($lengtegraad2) * pow(sin($dlon/2), 2);
$c = 2 * asin(min(1, sqrt($a)));
$d = $r * $c;
$d = (int) round($d, 0);
return $d;
}
/**
* Afstand in kilometers berekenen tussen de Martinitoren in Groningen
* (breedtegraad 53.218777, lengtegraad 6.566921) en het Vrijthof in
* Maastricht (breedtegraad 50.848434, lengtegraad 5.688955).
*/
$puntABreedtegraad = 53.218777;
$puntALengtegraad = 6.566921;
$puntBBreedtegraad = 50.848434;
$puntBLengtegraad = 5.688955;
$afstandInKilometers = getAfstandInMeters($puntALengtegraad, $puntABreedtegraad, $puntBLengtegraad, $puntBBreedtegraad);
$afstandInKilometers = $afstandInKilometers / 1000;
$afstandInKilometers = round($afstandInKilometers, 1);
echo $afstandInKilometers, ' km';
?>
function getAfstandInMeters($lengtegraad1, $breedtegraad1, $lengtegraad2, $breedtegraad2)
{
// Gemiddelde straal (r) van de aarde in meters
$r = 6367000;
// Hoogste nauwkeurigheid voor de functie pi() en de constante M_PI
ini_set('precision', 49);
// Graden omzetten in radialen
$lengtegraad1 = ($lengtegraad1 * M_PI) / 180;
$breedtegraad1 = ($breedtegraad1 * M_PI) / 180;
$lengtegraad2 = ($lengtegraad2 * M_PI) / 180;
$breedtegraad2 = ($breedtegraad2 * M_PI) / 180;
/**
* Haversine-formule
*
* dlat = lat2 - lat1
* dlon = lon2 - lon1
* a = sin^2(dlat/2) + cos(lat1) * cos(lat2) * sin^2(dlon/2)
* c = 2 * arcsin(min(1, sqrt(a)))
* d = r * c
*
* @link http://en.wikipedia.org/wiki/Haversine_formula
* @link http://www.movable-type.co.uk/scripts/gis-faq-5.1.html
*/
$dlat = $lengtegraad2 - $lengtegraad1;
$dlon = $breedtegraad2 - $breedtegraad1;
$a = pow(sin($dlat/2), 2) + cos($lengtegraad1) * cos($lengtegraad2) * pow(sin($dlon/2), 2);
$c = 2 * asin(min(1, sqrt($a)));
$d = $r * $c;
$d = (int) round($d, 0);
return $d;
}
/**
* Afstand in kilometers berekenen tussen de Martinitoren in Groningen
* (breedtegraad 53.218777, lengtegraad 6.566921) en het Vrijthof in
* Maastricht (breedtegraad 50.848434, lengtegraad 5.688955).
*/
$puntABreedtegraad = 53.218777;
$puntALengtegraad = 6.566921;
$puntBBreedtegraad = 50.848434;
$puntBLengtegraad = 5.688955;
$afstandInKilometers = getAfstandInMeters($puntALengtegraad, $puntABreedtegraad, $puntBLengtegraad, $puntBBreedtegraad);
$afstandInKilometers = $afstandInKilometers / 1000;
$afstandInKilometers = round($afstandInKilometers, 1);
echo $afstandInKilometers, ' km';
?>
Ik herinnerde mezelf dat hier al eens iets over GeoLocation gezegd was... Echter werkt dit voorbeeld niet. ZOu iemand mij meer uitleg erover kunnen geven?
Kan je wat duidelijker zijn dan: "Werkt niet"?