Permalink
Browse files

Adding auto-detection

  • Loading branch information...
1 parent 29fd6d9 commit e6d0c727e3a2234f7243ea8f92d44860a386f9c2 @phayes committed Aug 29, 2012
Showing with 75 additions and 0 deletions.
  1. +64 −0 geoPHP.inc
  2. +11 −0 tests/test.php
View
@@ -48,6 +48,11 @@ class geoPHP
$type_map = geoPHP::getAdapterMap();
+ // Auto-detect type if needed
+ if (!$type) {
+ $type = geoPHP::detectFormat($data);
+ }
+
$processor_type = $type_map[$type];
if (!$processor_type) {
@@ -194,4 +199,63 @@ class geoPHP
return new GeometryCollection($geometries);
}
}
+
+ // Detect a format given a value. This function is meant to be SPEEDY.
+ // It could make a mistake in XML detection if you are mixing or using namespaces in weird ways (ie, KML inside an RSS feed)
+ static function detectFormat(&$input) {
+ $mem = fopen('php://memory', 'r+');
+ fwrite($mem, $input, 8); // Write 8 bytes - we can detect the vast majority of formats in the first 8 bytes
+ fseek($mem, 0);
+
+ $first_byte = array_pop(unpack("c", fread($mem, 1)));
+
+ // Detect WKB or EWKB -- first byte is 1 (little endian indicator)
+ if ($first_byte == 1) {
+ $wkb_info = unpack("ctype/cz/cm/cs", fread($mem, 4));
+ if ($wkb_info['s']) return 'ewkb';
+ else return 'wkb';
+ }
+
+ // Detect GeoJSON - first char starts with {
+ if ($first_byte == 123) {
+ return 'json';
+ }
+
+ // Detect EWKT - first char is S
+ if ($first_byte == 83) {
+ return 'ewkt';
+ }
+
+ // Detect WKT - first char starts with P (80), L (76), M (77), or G (71)
+ $wkt_chars = array(80, 76, 77, 71);
+ if (in_array($first_byte, $wkt_chars)) {
+ return 'wkt';
+ }
+
+ // Detect XML -- first char is <
+ if ($first_byte == 60) {
+ // grab the first 256 characters
+ $string = substr($input, 0, 256);
+ if (strpos($string, '<kml') !== FALSE) return 'kml';
+ if (strpos($string, '<gpx') !== FALSE) return 'gpx';
+ if (strpos($string, '<georss') !== FALSE) return 'georss';
+ if (strpos($string, '<rss') !== FALSE) return 'georss';
+ if (strpos($string, '<feed') !== FALSE) return 'georss';
+ }
+
+ // We need an 8 byte string for geohash and EWKT
+ fseek($mem, 0);
+ $string = trim(fread($mem, 8));
+
+ // Detect geohash - geohash ONLY contains lowercase chars and numerics
+ preg_match('/[a-z0-9]+/', $string, $matches);
+ if ($matches[0] == $string) {
+ return 'geohash';
+ }
+
+ // What do you get when you cross an elephant with a rhino?
+ // http://youtu.be/RCBn5J83Poc
+ return FALSE;
+ }
+
}
View
@@ -27,6 +27,7 @@ function run_test() {
test_adapters($geometry, $format, $value);
test_methods($geometry);
test_geometry($geometry);
+ test_detection($value, $format, $file);
}
}
print "Testing Done!";
@@ -232,3 +233,13 @@ function test_methods($geometry) {
//@@TODO: centroid function is non-compliant for collections and strings
}
}
+
+function test_detection($value, $format, $file) {
+ $detected = geoPHP::detectFormat($value);
+ if ($detected != $format) {
+ if ($detected) print 'detected as ' . $detected . "\n";
+ else print "not detected\n";
+ }
+ // Make sure it loads using auto-detect
+ geoPHP::load($value);
+}

0 comments on commit e6d0c72

Please sign in to comment.