Hunting for Postboxes (part 1)

Posted by Unknown on Tuesday, January 28, 2014




Hunting for Postboxes (part 1)




postbox-pebble.png

The new year brings new hobby projects! In this year, I am going to try to photograph as many UK postboxes as I can. For this I am going to build some apps and overview maps, but I will write more about those later. A teaser for a future post is here to the left ;-).


The first thing that I want my application(s) to do is to give a description of where a postbox is located and this post is the tale of how I went about just doing that.


As my data source, I am using an OpenStreetMap extract for the London region. I import that through my "Import OSM data into MongoDB" script that I wrote about in an earlier article. The script is available on GitHub as part of the 3angle repository. The latest version is at https://raw.github.com/derickr/3angle/master/import-data.php and it also requires https://raw.github.com/derickr/3angle/master/classes.php for some GeoJSON helper classes and https://raw.github.com/derickr/3angle/master/config.php where you can set the database name and collection name (in my case, demo and poiConcat).


My goal is to get from a longitude/latitude pair to the closest postbox's reference number (EC2 201), a description like (On Paul Street, on the corner with Epworth Street), and a direction and distance (East, 86m).


The first thing I do is to look-up the closest postbox. I can very easily do that with the following aggrgation query in MongoDB:



<?php $m = new MongoClient( 'mongodb://localhost' );
$d = $m-?>selectDb( 'demo' );
$c = $d->selectCollection( 'poiConcat' );

$center = new GeoJSONPoint( (float) $_GET['lon'], (float) $_GET['lat'] );

$res = $c->aggregate( array(
'$geoNear' => array(
'near' => $center->getGeoJson(),
'distanceField' => 'distance',
'distanceMultiplier' => 1,
'maxDistance' => 5000,
'spherical' => true,
'query' => array( TAGS => 'amenity=post_box' ),
'limit' => 1,
)
) );


I am using the aggregation framework instead of a normal query because the aggregation framework also can return the distance to the found object. The above returns $res, and our first result is located in $res['result'][0], which looks like:



array(
'_id' => 'n905143645',
'l' => array(
'type' => 'Point',
'coordinates' => array( -0.1960, 51.5376 ),
),
'm' => array(
'v' => 5,
'cs' => 14576087,
'uid' => 37137,
'ts' => 1357659884,
),
'ts' => array(
0 => 'amenity=post_box',
1 => 'operator=Royal Mail',
2 => 'ref=NW6 14',
),
'ty' => 1,
'distance' => 162.15002059040299,
),


So postbox NW6 14 is 162.15 meters away from -0.1979, 51.5385 at -0.1960, 51.5376, as you can see in this image:


postbox1.png

To find a description of where the postbox is, we first find the closest road:



$r = $res['result'][0];
$query = [
LOC => [
'$near' => $r['l']
],
TAGS => new MongoRegex(
'/^highway=(trunk|pedestrian|service|primary|secondary|tertiary|residential|unclassified)/'
)
];
$road = $c->findOne( $query );


highway is an OpenStreetMap tag that is also used for footpaths, service roads and alleys. These generally don't have names, so with the regular expression we restrict the query to only return "normal" roads. After executing this query, $road now contains:



array (
'_id' => 'w4442243',
'ty' => 2,
'l' => array (
'type' => 'LineString',
'coordinates' => array (
array



Truncated by Planet PHP, read more at the original (another 6190 bytes)




more

{ 0 comments... » Hunting for Postboxes (part 1) read them below or add one }

Post a Comment

Popular Posts