Where in the World?Geo-data in PHP
80% of data has a geo-component
Some  background
Mercator - 1569
51 28’ 38”N0 0’ 0” EMunich, 11EParis, 2EMadrid, 3WPrime meridianKnow your datum!
PointsParis52°20'28N, 04°53'25E12 Grimmauld Place, LondonWhat makes up geo-data?
LinesM4Sunset BoulevardDover TSSWhat makes up geo-data?
PolygonsLondonSomersetContourWhat makes up geo-data?
Is point x within y?Questions, questions…
Does line x pass through y?Questions, questions…
How far is point x from point y?Questions, questions…
Which region is point x within?Regions can overlap:District:     ClaphamBorough:  WandswothCity:         	 LondonCountry:    UKQuestions, questions…
80% of data has a geo-componentSo how do I find it?
Geo-data from web visitors
Every web visitor offers 2 sources of geo-data: IP address
 Ask the browser!Where is my visitor?
home51 26’ 55.2” N0 0’ 0.1” WexchangeAccurate?IP gives you the location of the Serving area interface (telco exchange).Some exchanges can be 5 miles away!homeofficeReliable?ProxiesVPNsNetwork distributions (ever tried geo-locating an AOL IP?)exchangeThe problem with IP
include("geoip.inc"); $gi = geoip_open("/usr/local/share/GeoIP/GeoIP.dat",GEOIP_STANDARD);$country_code = geoip_country_code_by_addr($gi, "24.24.24.24");$country_name = geoip_country_name_by_addr($gi, "24.24.24.24”); Free data library from MaxMind….Pure PHP
Pear extension
Apache moduleUse the code…
function myCallback(position) {  // called if the browser reports its location}if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(myCallback);}W3C spec:http://dev.w3.org/geo/api/spec-source.htmlMozilla, where art thou?
Geo-data from content
“Journey’s End”by nathanhayag“MacRitchie Reservoir, Singapore”Geo-data encoded in the image file:1°22'18”N103°49'27"EA picture says a thousand words
$exif = exif_read_data('file.jpg');$long[‘deg’] = $exif['GPSLongitude'][0];$long[‘min’] = $exif['GPSLongitude'][1] / 60;$long[‘sec’] = $exif['GPSLongitude'][2] / 3600;$lat[‘deg’] = $exif['GPSLatitude'][0];$lat[‘min’] = $exif['GPSLatitude'][1] / 60;$lat[‘sec’] = $exif['GPSLatitude'][2] / 3600;Reading EXIF
“Journey’s End”by nathanhayag“MacRitchie Reservoir, Singapore”Parse text for location data….Usual PHP information retrieval techniques applyhttp://phpir.com/ to learn moreA picture says a thousand words
“Journey’s End”by nathanhayag“MacRitchie Reservoir, Singapore”Feeling brave?Image recognition and associationA picture says a thousand words
External sources
Don’t forget…
Primitive data-types$long = 51.5723$lat = -0.0179Class structures$point = new GISPoint;$point->setLatitude(51,21,35,'N');$point->setLongitude(0,1,21, 'W');Geo-data in PHP variables
MySQL storageCREATE TABLE tweet(  id BIGINT,  user VARCHAR(15),  message VARCHAR(140),  location VARCHAR(16)  );INSERT INTO tweet VALUES (  15924144610,  'manarth',  'hello!',  '0512732N0000319W'  );  Persistent storage
MySQL Spatial extensionsCREATE TABLE tweet(  id BIGINT,  user VARCHAR(15),  message VARCHAR(140),location POINT  );INSERT INTO tweet VALUES (  15924144610,  'manarth',  'hello!',PointFromWKT(Point(51.1,-0.2))  );  Spatial extensions
MySQLMS SQLOraclePostgres – PostGISGeo-data in the DB
WKT: Well Known TextPOINT(6 10) LINESTRING(3 4,10 50,20 25)WKB: Well Known Binary1010010001001010GeoJSON{  "geometry":  {     "type" : "Point",     "coordinates" : [97.03125, 39.7265625]  }}Write to disk?
Binary TerrainCoverage (ArcGIS)DEM Spatial Data File (Autodesk)…More (obscure) formats
DiscoveryStorageAnalysis
Geo-centric:Cartesianhttp://trac.osgeo.org/proj/wiki/man_cs2csCoordinate conversion
Cartesian geometrya(x1, y1)√(y1 – y2)2 + (x2 – x1)2y1 – y2bx2 – x1(x2, y2)Distance from a to b
Geo-centric geometryGreater circle routea(λs, Φs)Haversine formulab(λf, Φf)Distance from a to b
function haversine($a) {  return (sin($a/2) * sin($a/2));}function ahaversine($a) {  return 2 * asin(sqrt($a));}function haversine_separation($a, $b) {  // assume a radius of 3956 miles.  define ('RADIUS', 3956);  // convert degree inputs to radians  $a = array(deg2rad($a['long']), deg2rad($a['lat']));  $b = array(deg2rad($b['long']), deg2rad($b['lat']));  $x = haversine($a['long'] - $b['long']) + (cos($a['long']) * cos($b['long']) * haversine(abs($a['lat'] - $b['lat'])));  // $d (distance) is therefore R * inverse haversine($x)  $d = RADIUS * ihaversine($x);  return $d;}Haversine calculations
SELECT DISTANCE(a, b);SELECT INTERSECTS (a, b);SELECT DISJOINT (a, b);SELECT OVERLAPS (a, b);SELECT CONTAINS (a, b);SELECT WITHIN (a, b);Some limitations – currently measures against MBR – Minimum Bounding RectangleSpatial analysis in MySQL
DiscoveryStorageAnalysisVisualisation
Map APIs
Simple overlays
Heatmaps
Custom visualisation
Image generation
Upcoming conferencesBristol Indiemedia  Bristol – June

Where in the world

Editor's Notes

  • #6 - Different datums: WGS84, NAD27, NAD83…
  • #10 Simple as yes or no…
  • #12 Distance between 2 points…(don't mention solutions)
  • #13 Regions can overlap…
  • #14 Remember this?So, if 80%...DISCOVERY
  • #17 Accuracy: to nearest exchangeReliability: proxies, VPNs, Networks structure
  • #18 Other IP geo-databases availableAPI options
  • #19 Single positionContinously updating positionPermit stale data
  • #21 EXIF – used by some camerasGives latitude, longitude, and lat-reg (N/S), long-ref (E/W)
  • #25 Twitter4 squareGowallaSocial graphSearch by hash-tags; user-configured integration…endless choiceCustom file input
  • #26 Having gone to all this effort to find this data, you’re going to throw it away.
  • #30 Also get analysis tools
  • #31  OGC - Open Geospatial Consortium - standards
  • #32 Please document the format…for your colleague's sanity!
  • #34 Co-ordinate conversion is complicatedUse a library
  • #35 Cartesian geometry for a grid based system
  • #36 Haversine corrects for projection distortion over long distancesSpheroid geometrySuffers from antipodal errors – use Vincenty insteadNote the Greek
  • #40 JS
  • #41 Most overlays require cartesian geometry – need to convert.
  • #44 Go see Mike's uncon talk at 2pm