-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME
267 lines (193 loc) · 9.34 KB
/
README
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
FindMyNearest
FindMyNearest is a PHP class for working with UK postcodes, and
in particular for calculating the distance between two postcodes.
FindMyNearest supports several alternative data sources through
drivers. Currently data can be got from a delimited text file, a
mysql database or through the web API at www.uk-postcodes.com
FindMyNearest is generally not too fussy about the formatting of
postcodes. It accepts any case, spaces between parts or not and
partial postcodes. It even corrects the letter O at the beginning
of an inward part, changing it to the nubmer 0.
If the backend datasource contains location data for
partial postcodes these are used if an exact match can't be found.
Synopsis
========
require 'FindMyNearest.php';
$fmn = FindMyNearest::factory('textfile', array('datafile' => 'postcodes.txt'));
if (! $fmn->loaddata()) {
echo "Error loading data: " . $fmn->lasterror() . "\n";
exit;
}
$goodcode = $fmn->validcode('SW1A 1AA'); // Check if we know about a code
$distance = $fmn->calc_distance('SW1A 1AA', 'CV32 5HZ'); // calculate distance
if ($distance === false) {
echo "The was an error " . $fmn->lasterror();
}
Methods
=======
factory(string $driver, array $params)
Create a new instance. $driver is currently one of 'textfile', 'mysql',
'uk_postcodes', 'ukgeocode', 'geopostcode' or 'openlylocal'. Valid values
for $params depend on the driver chosen.
loaddata()
Initialise the connection to the back end. This must always be called
before any functions needing to look up postcodes can be called.
set_inoutsep(string $sep)
Sets the value of the separator between outward (SW1A) and inward (1AA)
parts of the postcode data. The default depends on the driver. It is a
single space usually, but an empty string for uk_postcodes. The use of
an empty string is not recommended if your data also includes means or
midpoints for districts and sectors, because this can be ambiguous. Eg
'B11' could be either the district B11 or the sector B1 1.
use_wgs84()
Indicates that the geo data is in wgs84 (latitude and longitude) format
Note that when using the mysql driver if you do not specify the sql
parameter in the paramaters passed to factory() and you are using wgs84 you
must call use_wgs84() *before* calling loaddata. This is because the default
SQL is dependent on the co-ordinate scheme being used.
use_osgb36()
Indicates that the geo data is in osgb36 (British national grid) format.
This is the default.
Note that the uk_postcodes driver (which uses http://www.uk-postcodes.com)
can provide data in either wgs84 or osgb36. The latter makes distance
calculations less demanding
validcode(string $postcode [, bool $exactmatch])
Tests if a postcode is valid and known in the database. Returns the found
code on success, false on failure.
If the full code is not found, checks will be made for matches by sector
(SW1A 1), district (SW1A) and area (SW1). The return value is the best
match.
If $exactmatch is true (defaults to false), matches only if the $postcode
is known (after normalising $postcode).
set_grain(int $grain)
Sets the smallest unit that will be checked for by validcode()
1: Area only: SW
2: District: SW1A
3: Sector: SW1A 1
4: Unit: SW1A 1AA
getgeodata(string $postcode)
Returns an array containing the location of the postcode. The elements are
(eastings, northings) for osgb36 or (latitude, longitude) for wgs84
splitpostcode(string $postcode)
Takes a postcode or partial postcode and attempts to split it into
component parts. Returns an array:
[0] => Area,
[1] => District
[2] => Sector
[3] => Unit
eg, for SW1A 1AA
[0] => SW
[1] => 1A
[2] => 1
[3] => AA
Returns false on failure
samepostcode(string $postcode1, string $postcode2)
Checks if $postcode1 is the same postcode as $postcode2
Returns true if the same, false otherwise
normalise ($postcode)
Returns a normalised version of $postcode, taking account of the current
setting of $inoutsep
calc_distance (string $fromcode, string $tocode[, array $options])
calculate the distance between $fromcode and $tocode.
$options is an optional array:
unit => 'miles'|'km' The unit to return the distance in (default miles)
decimal => int The number of decimal places (defalt 0)
Like validcode(), if an exact match isn't available calc_distance will
match on sector, district or area.
Returns false on failure.
***********************************************************************
*NB* 0 is a valid, good response indicating a distance of 0km or 0miles
Be sure to test for false (eg if($d === false)
************************************************************************
lasterror()
returns the last error message generated
Drivers
=======
textfile
========
The textfile driver stores postcode data in a simple text file. The following
parameters are available:
datafile: location of the datafile
fieldsep: field separator used in the datafile. Default is "\t" (tab)
Data files should contain three fields, either
postcode latitude longitude
or
postcode eastings northings
The textfile driver is useful for simple installations requiring data
only down to sector level. It is not recommended if you have unit level
data, unless it is for a small area only, as there are 17 million postcodes
in Great Britain
mysql
=====
The mysql driver stores data in a mysql database. Valid parameters are
host: mysql host to connect to
user: user name for mysql connection
pass: password for mysql connection
db: database to use
sql: the SQL statement to execute. This should take a single substitution,
%s, which is replaced by the postcode being searched. It should return
two fields, eastings and northings or latitude and logtitude. Defaults are
"SELECT lat,long FROM postcodes WHERE postcode = '%s'" for wgs84 and
"SELECT east,north FROM postcodes WHERE postcode = '%s' for osgb36
uk_postcodes
============
The uk_postcodes driver uses the API at http://www.uk-postcodes.com to retrieve
data. It caches data in a local file to minimize the load on the remote server.
Valid parameters are:
cachefile: path to file for cache. Must be readable and writeable by server
cachettl: time to live in seconds for cache entries (default 604800, 1 week)
The uk_postcodes driver only handles full postcodes. Consequently the behaviour of
validcode() is slightly different, in that it will not check for matches at sector
level or below.
ukgeocode
=========
The ukgeocode driver uses the API at http://maxmanders.co.uk/ukgeocode/ to retrieve
data. It caches data in a local file to minimize the load on the remote server.
Valid parameters are:
cachefile: path to file for cache. Must be readable and writeable by server
cachettl: time to live in seconds for cache entries (default 604800, 1 week)
The ukgeocode driver only handles full postcodes. Consequently the behaviour of
validcode() is slightly different, in that it will not check for matches at sector
level or below.
ukgeocode uses wgs84. The driver will set this - there is no need to call use_wgs84
openlylocal
===========
The openlylocal driver uses the API at http://www.openlylocal.com/ to retrieve
data. It caches data in a local file to minimize the load on the remote server.
Valid parameters are:
cachefile: path to file for cache. Must be readable and writeable by server
cachettl: time to live in seconds for cache entries (default 604800, 1 week)
The openlylocal driver only handles full postcodes. Consequently the behaviour of
validcode() is slightly different, in that it will not check for matches at sector
level or below.
openlylocal uses wgs84. The driver will set this - there is no need to call use_wgs84
geopostcode
===========
The geopostcode driver uses the API at http://www.geopostcode.org.uk to retrieve
data. It caches data in a local file to minimize the load on the remote server.
Valid parameters are:
cachefile: path to file for cache. Must be readable and writeable by server
cachettl: time to live in seconds for cache entries (default 604800, 1 week)
Writing drivers
===============
Drivers are classes that extend FindMyNearest. A driver provides a class named
FindMyNearest_<driver> and is stored in the file drivers/<driver>.php, where <driver>
is the driver's name.
A driver should provide a method named FindMyNearest_<driver>, which takes as an
argument an associative array of options. It should return true, or on error return
false.
Drivers should provide the following override methods:
loaddata()
Takes no paramaters. Return true on success. On failure, returns false and sets
$this->lasterr. Does whatever needs to be done to initialise the backend connection
getgeodata($postcode)
Return an array of either (lat, long) or (east, north) coordinates for the supplied
postcode
_postcodeknown($postcode)
Return true if $postcode exists in the backend, false otherwise
dumpdata()
Does something useful for debugging. Exactly what is useful is likely to depend
on the driver
When writing drivers to access web services, it may be useful to include WebServices.php
and then write your class to extend FindMyNearest_WebServices. This provides a number of
useful functions for accessing web services and maintaining a cache of data.