/** * Test for the geohash::contains() and geohash_set::contains() functions. * This test constructs the test points and ranges in and around the geohash. * * @dataProvider geohashProvider * @param string $geohash */ public function testContains($geohash) { $north = geohash::neighbor($geohash, geohash::north); $south = geohash::neighbor($geohash, geohash::south); $east = geohash::neighbor($geohash, geohash::east); $west = geohash::neighbor($geohash, geohash::west); $outside_tests = array($east, $west); if ($north) { $outside_tests[] = $north; } if ($south) { $outside_tests[] = $south; } // test points outside the geohash box foreach ($outside_tests as $test) { for ($i = 0; $i < 32; $i++) { $point = geohash::decode($test . geohash::encode_digit($i)); $this->assertFalse(geohash::contains($geohash, $point)); } } // test points inside the box for ($i = 0; $i < 32; $i++) { $point = geohash::decode($geohash . geohash::encode_digit($i)); $this->assertTrue(geohash::contains($geohash, $point)); } // and the four edge cases (all corners) $box = geohash::decode_box($geohash); $this->assertTrue(geohash::contains($geohash, new geopoint($box->north, $box->west))); $this->assertTrue(geohash::contains($geohash, new geopoint($box->north, $box->east))); $this->assertTrue(geohash::contains($geohash, new geopoint($box->south, $box->west))); $this->assertTrue(geohash::contains($geohash, new geopoint($box->south, $box->east))); // make a geohash set and test points inside and out $set = new geohash_set(); $set->add_range($geohash . geohash::encode_digit(8), $geohash . geohash::encode_digit(23)); // test points outside the set foreach ($outside_tests as $test) { $point = geohash::decode($test); $this->assertFalse($set->contains($point)); } // test closer points outside the set for ($i = 0; $i < 8; $i++) { $point = geohash::decode($geohash . geohash::encode_digit($i)); $this->assertFalse($set->contains($point)); } for ($i = 24; $i < 32; $i++) { $point = geohash::decode($geohash . geohash::encode_digit($i)); $this->assertFalse($set->contains($point)); } // test points inside the set for ($i = 8; $i < 24; $i++) { $point = geohash::decode($geohash . geohash::encode_digit($i)); $this->assertTrue($set->contains($point)); } // make a compound geohash set and test points inside and out $set = new geohash_set(); $set->add($geohash); $set->add($east); // test points outside the set $outside_tests = array(geohash::neighbor($east, geohash::east), $west); if ($north) { $outside_tests[] = $north; } if ($south) { $outside_tests[] = $south; } foreach ($outside_tests as $test) { $point = geohash::decode($test); $this->assertFalse($set->contains($point)); } // test points inside the set $point = geohash::decode($geohash); $this->assertTrue($set->contains($point)); $point = geohash::decode($east); $this->assertTrue($set->contains($point)); }
/** * Reduce this geohash to a region of one quadrant. * @param string $hash * @param string $direction one of geohash::northeast, geohash::northwest, geohash::southeast, geohash::southwest * @return geohash_set */ public static function quarter($hash, $direction) { $odd = strlen($hash) % 2; switch ($direction) { case geohash::northeast: $range = array(24, 31); break; case geohash::northwest: $range = $odd ? array(16, 23) : array(8, 15); break; case geohash::southeast: $range = $odd ? array(8, 15) : array(16, 23); break; case geohash::southwest: $range = array(0, 7); break; default: trigger_error('Illegal quarter direction, "' . $direction . '"', E_USER_ERROR); break; } $set = new geohash_set(); $set->add_range($hash . geohash::encode_digit($range[0]), $hash . geohash::encode_digit($range[1])); return $set; }