From: Marc Tobias Metten Date: Tue, 23 Sep 2014 20:53:20 +0000 (+0200) Subject: move looksLikeLatLonPair into lib.php, basic PHP test suite using phpunit X-Git-Tag: v2.3.0~4 X-Git-Url: https://git.openstreetmap.org./nominatim.git/commitdiff_plain/d6f298f0336f69d0f89157a42fa546337f4d80e5?hp=aae90ea5cb079b0c36ebadecdccad9b868193597 move looksLikeLatLonPair into lib.php, basic PHP test suite using phpunit --- diff --git a/.gitignore b/.gitignore index 0c54ce76..54af2ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.log +*.pyc nominatim/*.d nominatim/*.o @@ -27,3 +28,4 @@ compile data/wiki_import.sql data/wiki_specialphrases.sql data/osmosischange.osc + diff --git a/lib/Geocode.php b/lib/Geocode.php index c8cc4c4a..2955b94f 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -542,35 +542,9 @@ } // Do we have anything that looks like a lat/lon pair? - if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[ ]+([0-9.]+)?[, ]+([EW])[ ]+([0-9]+)[ ]+([0-9]+[0-9.]*)?\\b/', $sQuery, $aData)) - { - $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60); - $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60); - if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1) - { - $this->setNearPoint(array($fQueryLat, $fQueryLon)); - $sQuery = trim(str_replace($aData[0], ' ', $sQuery)); - } - } - elseif (preg_match('/\\b([0-9]+)[ ]+([0-9]+[0-9.]*)?[ ]+([NS])[, ]+([0-9]+)[ ]+([0-9]+[0-9.]*)?[ ]+([EW])\\b/', $sQuery, $aData)) - { - $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60); - $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60); - if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1) - { - $this->setNearPoint(array($fQueryLat, $fQueryLon)); - $sQuery = trim(str_replace($aData[0], ' ', $sQuery)); - } - } - elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData)) - { - $fQueryLat = $aData[2]; - $fQueryLon = $aData[3]; - if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1) - { - $this->setNearPoint(array($fQueryLat, $fQueryLon)); - $sQuery = trim(str_replace($aData[0], ' ', $sQuery)); - } + if ( $aLooksLike = looksLikeLatLonPair($sQuery) ){ + $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon'])); + $sQuery = $aLooksLike['query']; } $aSearchResults = array(); diff --git a/lib/lib.php b/lib/lib.php index 74e971b4..e200202b 100644 --- a/lib/lib.php +++ b/lib/lib.php @@ -905,3 +905,93 @@ { return "'".$s."'"; } + + // returns boolean + function validLatLon($fLat,$fLon) + { + return ($fLat <= 90.1 && $fLat >= -90.1 && $fLon <= 180.1 && $fLon >= -180.1); + } + + // Do we have anything that looks like a lat/lon pair? + // returns array(lat,lon,query_with_lat_lon_removed) + // or null + function looksLikeLatLonPair($sQuery) + { + $sFound = null; + $fQueryLat = null; + $fQueryLon = null; + + // degrees decimal minutes + // N 40 26.767, W 79 58.933 + // N 40°26.767′, W 79°58.933′ + // 1 2 3 4 5 6 + if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[° ]+([0-9.]+)?[′\']*[, ]+([EW])[ ]+([0-9]+)[° ]+([0-9]+[0-9.]*)[′\']*?\\b/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60); + $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60); + } + // degrees decimal minutes + // 40 26.767 N, 79 58.933 W + // 40° 26.767′ N 79° 58.933′ W + // 1 2 3 4 5 6 + elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\']*[ ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\' ]+([EW])\\b/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60); + $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60); + } + // degrees decimal seconds + // N 40 26 46 W 79 58 56 + // N 40° 26′ 46″ W, 79° 58′ 56″ + // 1 2 3 4 5 6 7 8 + elseif (preg_match('/\\b([NS])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*[, ]+([EW])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*\\b/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60 + $aData[4]/3600); + $fQueryLon = ($aData[5]=='E'?1:-1) * ($aData[6] + $aData[7]/60 + $aData[8]/3600); + } + // degrees decimal seconds + // 40 26 46 N 79 58 56 W + // 40° 26′ 46″ N, 79° 58′ 56″ W + // 1 2 3 4 5 6 7 8 + elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([EW])\\b/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = ($aData[4]=='N'?1:-1) * ($aData[1] + $aData[2]/60 + $aData[3]/3600); + $fQueryLon = ($aData[8]=='E'?1:-1) * ($aData[5] + $aData[6]/60 + $aData[7]/3600); + } + // degrees decimal + // N 40.446° W 79.982° + // 1 2 3 4 + elseif (preg_match('/\\b([NS])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*[, ]+([EW])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*\\b/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2]); + $fQueryLon = ($aData[3]=='E'?1:-1) * ($aData[4]); + } + // degrees decimal + // 40.446° N 79.982° W + // 1 2 3 4 + elseif (preg_match('/\\b([0-9]+[0-9]*\\.[0-9]+)[° ]+([NS])[, ]+([0-9]+[0-9]*\\.[0-9]+)[° ]+([EW])\\b/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = ($aData[2]=='N'?1:-1) * ($aData[1]); + $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[3]); + } + // degrees decimal + // 12.34, 56.78 + // [12.456,-78.90] + // 1 2 3 4 + elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData)) + { + $sFound = $aData[0]; + $fQueryLat = $aData[2]; + $fQueryLon = $aData[3]; + } + + if (!validLatLon($fQueryLat, $fQueryLon)) return; + $sQuery = trim(str_replace($sFound, ' ', $sQuery)); + + return array('lat' => $fQueryLat, 'lon' => $fQueryLon, 'query' => $sQuery); + } \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 00000000..bea876d5 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,26 @@ + + + + + + + ./tests-php/Nominatim + + + + + ./lib/ + + + + diff --git a/tests-php/Nominatim/NominatimTest.php b/tests-php/Nominatim/NominatimTest.php new file mode 100644 index 00000000..68519e48 --- /dev/null +++ b/tests-php/Nominatim/NominatimTest.php @@ -0,0 +1,77 @@ +assertSame("'St. John's'", addQuotes("St. John's")); + $this->assertSame("''", addQuotes('')); + } + + public function test_looksLikeLatLonPair() + { + // no coordinates expected + $this->assertNull(looksLikeLatLonPair('')); + $this->assertNull(looksLikeLatLonPair('abc')); + $this->assertNull(looksLikeLatLonPair('12 34')); + $this->assertNull(looksLikeLatLonPair('200.1 89.9')); // because latitude > 180 + + // coordinates expected + $this->assertNotNull(looksLikeLatLonPair('0.0 -0.0')); + + $this->assertEquals( + array( 'lat' => 12.456, 'lon' => -78.90, 'query' => 'abc def'), + looksLikeLatLonPair(' abc 12.456 -78.90 def ') + ); + + $this->assertEquals( + array( 'lat' => 12.456, 'lon' => -78.90, 'query' => ''), + looksLikeLatLonPair(' [12.456,-78.90] ') + ); + + // http://en.wikipedia.org/wiki/Geographic_coordinate_conversion + // these all represent the same location + $aQueries = array( + '40 26.767 N 79 58.933 W', + '40° 26.767′ N 79° 58.933′ W', + "40° 26.767' N 79° 58.933' W", + 'N 40 26.767, W 79 58.933', + 'N 40°26.767′, W 79°58.933′', + "N 40°26.767', W 79°58.933'", + + '40 26 46 N 79 58 56 W', + '40° 26′ 46″ N 79° 58′ 56″ W', + 'N 40 26 46 W 79 58 56', + 'N 40° 26′ 46″, W 79° 58′ 56″', + 'N 40° 26\' 46", W 79° 58\' 56"', + + '40.446 -79.982', + '40.446,-79.982', + '40.446° N 79.982° W', + 'N 40.446° W 79.982°', + + '[40.446 -79.982]', + ' 40.446 , -79.982 ', + ); + + + foreach($aQueries as $sQuery){ + $aRes = looksLikeLatLonPair($sQuery); + $this->assertEquals( 40.446, $aRes['lat'], 'degrees decimal ' . $sQuery, 0.01); + $this->assertEquals(-79.982, $aRes['lon'], 'degrees decimal ' . $sQuery, 0.01); + } + + } + +} diff --git a/tests-php/README.txt b/tests-php/README.txt new file mode 100644 index 00000000..31fd21ed --- /dev/null +++ b/tests-php/README.txt @@ -0,0 +1,13 @@ +Basic unit tests of PHP code. Very low coverage. Doesn't cover interaction +with the webserver/HTTP or database (yet). + +You need to have +https://phpunit.de/manual/4.2/en/ +installed. + +To execute the test suite run +$ phpunit + +It will read phpunit.xml which points to the library, test path, bootstrap +strip and set other parameters. + diff --git a/tests-php/bootstrap.php b/tests-php/bootstrap.php new file mode 100644 index 00000000..a4abe2da --- /dev/null +++ b/tests-php/bootstrap.php @@ -0,0 +1,2 @@ +