test.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. // Uncomment to test
  3. # run_test();
  4. function run_test() {
  5. set_time_limit(0);
  6. header("Content-type: text");
  7. include_once('../geoPHP.inc');
  8. if (geoPHP::geosInstalled()) {
  9. print "GEOS is installed.\n";
  10. }
  11. else {
  12. print "GEOS is not installed.\n";
  13. }
  14. foreach (scandir('./input') as $file) {
  15. $parts = explode('.',$file);
  16. if ($parts[0]) {
  17. $format = $parts[1];
  18. $value = file_get_contents('./input/'.$file);
  19. print '---- Testing '.$file."\n";
  20. $geometry = geoPHP::load($value, $format);
  21. test_adapters($geometry, $format, $value);
  22. test_methods($geometry);
  23. test_geometry($geometry);
  24. test_detection($value, $format, $file);
  25. }
  26. }
  27. print "Testing Done!";
  28. }
  29. function test_geometry($geometry) {
  30. // Test common functions
  31. $geometry->area();
  32. $geometry->boundary();
  33. $geometry->envelope();
  34. $geometry->getBBox();
  35. $geometry->centroid();
  36. $geometry->length();
  37. $geometry->greatCircleLength();
  38. $geometry->haversineLength();
  39. $geometry->y();
  40. $geometry->x();
  41. $geometry->numGeometries();
  42. $geometry->geometryN(1);
  43. $geometry->startPoint();
  44. $geometry->endPoint();
  45. $geometry->isRing();
  46. $geometry->isClosed();
  47. $geometry->numPoints();
  48. $geometry->pointN(1);
  49. $geometry->exteriorRing();
  50. $geometry->numInteriorRings();
  51. $geometry->interiorRingN(1);
  52. $geometry->dimension();
  53. $geometry->geometryType();
  54. $geometry->SRID();
  55. $geometry->setSRID(4326);
  56. // Aliases
  57. $geometry->getCentroid();
  58. $geometry->getArea();
  59. $geometry->getX();
  60. $geometry->getY();
  61. $geometry->getGeos();
  62. $geometry->getGeomType();
  63. $geometry->getSRID();
  64. $geometry->asText();
  65. $geometry->asBinary();
  66. // GEOS only functions
  67. $geometry->geos();
  68. $geometry->setGeos($geometry->geos());
  69. $geometry->pointOnSurface();
  70. $geometry->equals($geometry);
  71. $geometry->equalsExact($geometry);
  72. $geometry->relate($geometry);
  73. $geometry->checkValidity();
  74. $geometry->isSimple();
  75. $geometry->buffer(10);
  76. $geometry->intersection($geometry);
  77. $geometry->convexHull();
  78. $geometry->difference($geometry);
  79. $geometry->symDifference($geometry);
  80. $geometry->union($geometry);
  81. $geometry->simplify(0);// @@TODO: Adjust this once we can deal with empty geometries
  82. $geometry->disjoint($geometry);
  83. $geometry->touches($geometry);
  84. $geometry->intersects($geometry);
  85. $geometry->crosses($geometry);
  86. $geometry->within($geometry);
  87. $geometry->contains($geometry);
  88. $geometry->overlaps($geometry);
  89. $geometry->covers($geometry);
  90. $geometry->coveredBy($geometry);
  91. $geometry->distance($geometry);
  92. $geometry->hausdorffDistance($geometry);
  93. // Place holders
  94. $geometry->hasZ();
  95. $geometry->is3D();
  96. $geometry->isMeasured();
  97. $geometry->isEmpty();
  98. $geometry->coordinateDimension();
  99. $geometry->z();
  100. $geometry->m();
  101. }
  102. function test_adapters($geometry, $format, $input) {
  103. // Test adapter output and input. Do a round-trip and re-test
  104. foreach (geoPHP::getAdapterMap() as $adapter_key => $adapter_class) {
  105. if ($adapter_key != 'google_geocode') { //Don't test google geocoder regularily. Uncomment to test
  106. $output = $geometry->out($adapter_key);
  107. if ($output) {
  108. $adapter_loader = new $adapter_class();
  109. $test_geom_1 = $adapter_loader->read($output);
  110. $test_geom_2 = $adapter_loader->read($test_geom_1->out($adapter_key));
  111. if ($test_geom_1->out('wkt') != $test_geom_2->out('wkt')) {
  112. print "Mismatched adapter output in ".$adapter_class."\n";
  113. }
  114. }
  115. else {
  116. print "Empty output on " . $adapter_key . "\n";
  117. }
  118. }
  119. }
  120. // Test to make sure adapter work the same wether GEOS is ON or OFF
  121. // Cannot test methods if GEOS is not intstalled
  122. if (!geoPHP::geosInstalled()) return;
  123. foreach (geoPHP::getAdapterMap() as $adapter_key => $adapter_class) {
  124. if ($adapter_key != 'google_geocode') { //Don't test google geocoder regularily. Uncomment to test
  125. // Turn GEOS on
  126. geoPHP::geosInstalled(TRUE);
  127. $output = $geometry->out($adapter_key);
  128. if ($output) {
  129. $adapter_loader = new $adapter_class();
  130. $test_geom_1 = $adapter_loader->read($output);
  131. // Turn GEOS off
  132. geoPHP::geosInstalled(FALSE);
  133. $test_geom_2 = $adapter_loader->read($output);
  134. // Turn GEOS back On
  135. geoPHP::geosInstalled(TRUE);
  136. // Check to make sure a both are the same with geos and without
  137. if ($test_geom_1->out('wkt') != $test_geom_2->out('wkt')) {
  138. print "Mismatched adapter output between GEOS and NORM in ".$adapter_class."\n";
  139. }
  140. }
  141. }
  142. }
  143. }
  144. function test_methods($geometry) {
  145. // Cannot test methods if GEOS is not intstalled
  146. if (!geoPHP::geosInstalled()) return;
  147. $methods = array(
  148. //'boundary', //@@TODO: Uncomment this and fix errors
  149. 'envelope', //@@TODO: Testing reveales errors in this method -- POINT vs. POLYGON
  150. 'getBBox',
  151. 'x',
  152. 'y',
  153. 'startPoint',
  154. 'endPoint',
  155. 'isRing',
  156. 'isClosed',
  157. 'numPoints',
  158. );
  159. foreach ($methods as $method) {
  160. // Turn GEOS on
  161. geoPHP::geosInstalled(TRUE);
  162. $geos_result = $geometry->$method();
  163. // Turn GEOS off
  164. geoPHP::geosInstalled(FALSE);
  165. $norm_result = $geometry->$method();
  166. // Turn GEOS back On
  167. geoPHP::geosInstalled(TRUE);
  168. $geos_type = gettype($geos_result);
  169. $norm_type = gettype($norm_result);
  170. if ($geos_type != $norm_type) {
  171. print 'Type mismatch on '.$method."\n";
  172. continue;
  173. }
  174. // Now check base on type
  175. if ($geos_type == 'object') {
  176. $haus_dist = $geos_result->hausdorffDistance(geoPHP::load($norm_result->out('wkt'),'wkt'));
  177. // Get the length of the diagonal of the bbox - this is used to scale the haustorff distance
  178. // Using Pythagorean theorem
  179. $bb = $geos_result->getBBox();
  180. $scale = sqrt((($bb['maxy'] - $bb['miny'])^2) + (($bb['maxx'] - $bb['minx'])^2));
  181. // The difference in the output of GEOS and native-PHP methods should be less than 0.5 scaled haustorff units
  182. if ($haus_dist / $scale > 0.5) {
  183. print 'Output mismatch on '.$method.":\n";
  184. print 'GEOS : '.$geos_result->out('wkt')."\n";
  185. print 'NORM : '.$norm_result->out('wkt')."\n";
  186. continue;
  187. }
  188. }
  189. if ($geos_type == 'boolean' || $geos_type == 'string') {
  190. if ($geos_result !== $norm_result) {
  191. print 'Output mismatch on '.$method.":\n";
  192. print 'GEOS : '.(string) $geos_result."\n";
  193. print 'NORM : '.(string) $norm_result."\n";
  194. continue;
  195. }
  196. }
  197. //@@TODO: Run tests for output of types arrays and float
  198. //@@TODO: centroid function is non-compliant for collections and strings
  199. }
  200. }
  201. function test_detection($value, $format, $file) {
  202. $detected = geoPHP::detectFormat($value);
  203. if ($detected != $format) {
  204. if ($detected) print 'detected as ' . $detected . "\n";
  205. else print "not detected\n";
  206. }
  207. // Make sure it loads using auto-detect
  208. geoPHP::load($value);
  209. }