-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathLeafletMapMarker.php
115 lines (93 loc) · 3.46 KB
/
LeafletMapMarker.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?php namespace ProcessWire;
/**
* Class to hold an address and geocode it to latitude/longitude
*
*/
class LeafletMapMarker extends WireData {
const statusNoGeocode = -100;
protected $geocodeStatuses = array(
0 => 'N/A',
1 => 'OK',
2 => 'OK_ROOFTOP',
3 => 'OK_RANGE_INTERPOLATED',
4 => 'OK_GEOMETRIC_CENTER',
5 => 'OK_APPROXIMATE',
-1 => 'UNKNOWN',
-2 => 'ZERO_RESULTS',
-3 => 'OVER_QUERY_LIMIT',
-4 => 'REQUEST_DENIED',
-5 => 'INVALID_REQUEST',
-100 => 'Geocode OFF', // RCD
);
protected $geocodedAddress = '';
public function __construct() {
$this->set('lat', '');
$this->set('lng', '');
$this->set('address', '');
$this->set('status', 0);
$this->set('zoom', 0);
$this->set('provider', '');
$this->set('raw', '');
// temporary runtime property to indicate the geocode should be skipped
$this->set('skipGeocode', false);
}
public function set($key, $value) {
if($key == 'lat' || $key == 'lng') {
// if value isn't numeric, then it's not valid: make it blank
if(strpos($value, ',') !== false) $value = str_replace(',', '.', $value); // convert 123,456 to 123.456
if(!is_numeric($value)) $value = '';
} else if($key == 'address') {
$value = wire('sanitizer')->text($value);
} else if($key == 'status') {
$value = (int) $value;
if(!isset($this->geocodeStatuses[$value])) $value = -1; // -1 = unknown
} else if($key == 'zoom') {
$value = (int) $value;
} else if($key == 'provider') {
$value = $value;
}
return parent::set($key, $value);
}
public function get($key) {
if($key == 'statusString') return str_replace('_', ' ', $this->geocodeStatuses[$this->status]);
return parent::get($key);
}
public function geocode() {
if($this->skipGeocode) return -100;
// check if address was already geocoded
if($this->geocodedAddress == $this->address) return $this->status;
$this->geocodedAddress = $this->address;
if(!ini_get('allow_url_fopen')) {
$this->error("Geocode is not supported because 'allow_url_fopen' is disabled in PHP");
return 0;
}
// use openstreetmap api for get geocode
$url = 'https://nominatim.openstreetmap.org/search?limit=1&format=json&q=' . urlencode($this->address);
$http = new WireHttp();
$response = $http->get($url);
if ($response !== false) {
$result = json_decode($response, true);
} else {
$this->error("Error geocoding address");
if(isset($json['status'])) $this->status = (int) array_search($json['status'], $this->geocodeStatuses);
else $this->status = -1;
$this->lat = 0;
$this->lng = 0;
$this->raw = '';
return $this->status;
}
$this->lat = $result[0]['lat'];
$this->lng = $result[0]['lon'];
$this->raw = $response;
$this->message("Geocode OK: '{$this->address}'");
$this->status = 1;
return $this->status;
}
/**
* If accessed as a string, then just output the lat, lng coordinates
*
*/
public function __toString() {
return "$this->address ($this->lat, $this->lng, $this->zoom) [$this->statusString]";
}
}