Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 441ce94

Browse files
committedFeb 12, 2013
initial Commit
* implementations of Coordinate, Ellipsoid, Bounds, and Vincenty-Distance-Calculation
0 parents  commit 441ce94

File tree

14 files changed

+964
-0
lines changed

14 files changed

+964
-0
lines changed
 

‎.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
.idea/

‎README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# phpgeo - A Simple Geo Library for PHP
2+
3+
phpgeo provides abstractions to geographical coordinates (including support for different ellipsoids) and allows you to calculate geographical distances between coordinates with high precision.
4+
5+
## Installation
6+
7+
Using Composer, just add the following configuration to your `composer.json`:
8+
9+
{
10+
"require": {
11+
"mjaschen/phpgeo": "*"
12+
}
13+
}
14+
15+
## Usage
16+
17+
### Distance between two coordinates
18+
19+
use Location\Coordinate;
20+
use Location\Distance\Vincenty;
21+
22+
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
23+
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
24+
25+
$calculator = new Vincenty();
26+
$distance = $calculator->getDistance($coordinate1, $coordinate2); // returns 128130.850 (meters; ≈128 kilometers)
27+
28+
## Credits
29+
30+
* Marcus T. Jaschen <mjaschen@gmail.com>
31+
* [Chris Veness](http://www.movable-type.co.uk/scripts/latlong-vincenty.html) - JavaScript implementation of the [Vincenty formula](http://en.wikipedia.org/wiki/Vincenty%27s_formulae) for distance calculation

‎composer.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "mjaschen/location",
3+
"description": "Simple Geo Library",
4+
"keywords": ["distance", "coordinate", "geo", "gis", "bounds", "ellipsoid", "calculation"],
5+
"homepage": "https://mj.gs/",
6+
"type": "library",
7+
"license": "MIT",
8+
"authors": [
9+
{
10+
"name": "Marcus T. Jaschen",
11+
"email": "mjaschen@gmail.com",
12+
"homepage": "https://mj.gs/"
13+
}
14+
],
15+
"support" : {
16+
"email" : "mjaschen@gmail.com"
17+
},
18+
"require": {
19+
"php": ">=5.3.0"
20+
},
21+
"autoload": {
22+
"psr-0": {
23+
"Location": "src/"
24+
}
25+
}
26+
}

‎phpunit.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit bootstrap="tests/bootstrap.php" colors="true">
4+
<testsuites>
5+
<testsuite name="Location Test Suite">
6+
<directory>tests/Location/</directory>
7+
</testsuite>
8+
</testsuites>
9+
</phpunit>

‎src/Location/Bounds.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
/**
3+
* Coordinate Bounds Class
4+
*
5+
* PHP version 5.3
6+
*
7+
* @category Location
8+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
9+
* @copyright 2013 r03.org
10+
* @license http://www.opensource.org/licenses/mit-license MIT License
11+
* @link http://r03.org/
12+
*/
13+
14+
namespace Location;
15+
16+
use Location\Coordinate;
17+
18+
/**
19+
* Coordinate Bounds Class
20+
*
21+
* @category R03
22+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
23+
* @license http://www.opensource.org/licenses/mit-license MIT License
24+
* @link http://r03.org/
25+
*/
26+
class Bounds
27+
{
28+
/**
29+
* @var Coordinate
30+
*/
31+
protected $northWest;
32+
33+
/**
34+
* @var Coordinate
35+
*/
36+
protected $southEast;
37+
38+
/**
39+
* @param Coordinate $northWest
40+
* @param Coordinate $southEast
41+
*/
42+
public function __construct(Coordinate $northWest, Coordinate $southEast)
43+
{
44+
$this->northWest = $northWest;
45+
$this->southEast = $southEast;
46+
}
47+
48+
/**
49+
* Getter
50+
*
51+
* @return Coordinate
52+
*/
53+
public function getNorthWest()
54+
{
55+
return $this->northWest;
56+
}
57+
58+
/**
59+
* Getter
60+
*
61+
* @return Coordinate
62+
*/
63+
public function getSouthEast()
64+
{
65+
return $this->southEast;
66+
}
67+
68+
/**
69+
* @return float
70+
*/
71+
public function getNorth()
72+
{
73+
return $this->northWest->getLat();
74+
}
75+
76+
/**
77+
* @return float
78+
*/
79+
public function getSouth()
80+
{
81+
return $this->southEast->getLat();
82+
}
83+
84+
/**
85+
* @return float
86+
*/
87+
public function getWest()
88+
{
89+
return $this->northWest->getLng();
90+
}
91+
92+
/**
93+
* @return float
94+
*/
95+
public function getEast()
96+
{
97+
return $this->southEast->getLng();
98+
}
99+
100+
/**
101+
* Calculates the center of this bounds object and returns it as a
102+
* Coordinate instance.
103+
*
104+
* @return Coordinate
105+
*/
106+
public function getCenter()
107+
{
108+
$centerLat = ($this->getNorth() + $this->getSouth()) / 2;
109+
$centerLng = ($this->getEast() + $this->getWest()) / 2;
110+
111+
$overlap = $this->getWest() > 0 && $this->getEast() < 0;
112+
113+
if ($overlap && $centerLng > 0) {
114+
$centerLng = -180 + $centerLng;
115+
} elseif ($overlap && $centerLng < 0) {
116+
$centerLng = 180 + $centerLng;
117+
} elseif ($overlap && $centerLng == 0) {
118+
$centerLng = 180;
119+
}
120+
121+
return new Coordinate($centerLat, $centerLng);
122+
}
123+
}

‎src/Location/Coordinate.php

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
/**
3+
* Coordinate Implementation
4+
*
5+
* PHP version 5.3
6+
*
7+
* @category Location
8+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
9+
* @copyright 2013 r03.org
10+
* @license http://www.opensource.org/licenses/mit-license MIT License
11+
* @link http://r03.org/
12+
*/
13+
14+
namespace Location;
15+
16+
use Location\Ellipsoid;
17+
use Location\Distance;
18+
use Location\Distance\AbstractDistance;
19+
20+
/**
21+
* Coordinate Implementation
22+
*
23+
* @category Location
24+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
25+
* @license http://www.opensource.org/licenses/mit-license MIT License
26+
* @link http://r03.org/
27+
*/
28+
class Coordinate
29+
{
30+
/**
31+
* @var float
32+
*/
33+
protected $lat;
34+
35+
/**
36+
* @var float
37+
*/
38+
protected $lng;
39+
40+
/**
41+
* @var Ellipsoid
42+
*/
43+
protected $ellipsoid;
44+
45+
/**
46+
* @param float $lat -90.0 .. +90.0
47+
* @param float $lng -180.0 .. +180.0
48+
* @param Ellipsoid $ellipsoid if omitted, WGS-84 is used
49+
*
50+
* @throws \InvalidArgumentException
51+
*/
52+
public function __construct($lat, $lng, Ellipsoid $ellipsoid = null)
53+
{
54+
if (! $this->isValidLatitude($lat)) {
55+
throw new \InvalidArgumentException("Latitude value must be numeric -90.0 .. +90.0");
56+
}
57+
58+
if (! $this->isValidLongitude($lng)) {
59+
throw new \InvalidArgumentException("Latitude value must be numeric -180.0 .. +180.0");
60+
}
61+
62+
$this->lat = doubleval($lat);
63+
$this->lng = doubleval($lng);
64+
65+
if ($ellipsoid !== null) {
66+
$this->ellipsoid = $ellipsoid;
67+
} else {
68+
$this->ellipsoid = Ellipsoid::createDefault();
69+
}
70+
}
71+
72+
/**
73+
* @return float
74+
*/
75+
public function getLat()
76+
{
77+
return $this->lat;
78+
}
79+
80+
/**
81+
* @return float
82+
*/
83+
public function getLng()
84+
{
85+
return $this->lng;
86+
}
87+
88+
/**
89+
* @return Ellipsoid
90+
*/
91+
public function getEllipsoid()
92+
{
93+
return $this->ellipsoid;
94+
}
95+
96+
/**
97+
* Calculates the distance between the given coordinate
98+
* and this coordinate.
99+
*
100+
* @param Coordinate $coordinate
101+
* @param AbstractDistance $calculator instance of distance calculation class
102+
*
103+
* @return float
104+
*/
105+
public function getDistance(Coordinate $coordinate, AbstractDistance $calculator)
106+
{
107+
return $calculator->getDistance($this, $coordinate);
108+
}
109+
110+
/**
111+
* Validates latitude
112+
*
113+
* @param mixed $latitude
114+
*
115+
* @return bool
116+
*/
117+
protected function isValidLatitude($latitude)
118+
{
119+
if (! is_numeric($latitude)) {
120+
return false;
121+
}
122+
123+
if ($latitude < - 90.0 || $latitude > 90.0) {
124+
return false;
125+
}
126+
127+
return true;
128+
}
129+
130+
/**
131+
* Validates longitude
132+
*
133+
* @param mixed $longitude
134+
*
135+
* @return bool
136+
*/
137+
protected function isValidLongitude($longitude)
138+
{
139+
if (! is_numeric($longitude)) {
140+
return false;
141+
}
142+
143+
if ($longitude < - 180.0 || $longitude > 180.0) {
144+
return false;
145+
}
146+
147+
return true;
148+
}
149+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Abstract Distance Class
4+
*
5+
* PHP version 5.3
6+
*
7+
* @category Location
8+
* @package Distance
9+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
10+
* @copyright 2013 r03.org
11+
* @license http://www.opensource.org/licenses/mit-license MIT License
12+
* @link http://r03.org/
13+
*/
14+
15+
namespace Location\Distance;
16+
17+
use Location\Coordinate;
18+
19+
/**
20+
* Abstract Distance Class
21+
*
22+
* @category Location
23+
* @package Distance
24+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
25+
* @license http://www.opensource.org/licenses/mit-license MIT License
26+
* @link http://r03.org/
27+
*/
28+
abstract class AbstractDistance
29+
{
30+
/**
31+
* @param Coordinate $point1
32+
* @param Coordinate $point2
33+
*
34+
* @return float distance between the two coordinates in meters
35+
*/
36+
abstract public function getDistance(Coordinate $point1, Coordinate $point2);
37+
}

‎src/Location/Distance/Vincenty.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
/**
3+
* Implementation of distance calculation with Vincenty Method
4+
*
5+
* PHP version 5.3
6+
*
7+
* @category Location
8+
* @package Distance
9+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
10+
* @copyright 2013 r03.org
11+
* @license http://www.opensource.org/licenses/mit-license MIT License
12+
* @link http://r03.org/
13+
*/
14+
15+
namespace Location\Distance;
16+
17+
use Location\Coordinate;
18+
use Location\Exception\NotConvergingException;
19+
20+
/**
21+
* Implementation of distance calculation with Vincenty Method
22+
*
23+
* @see http://www.movable-type.co.uk/scripts/latlong-vincenty.html
24+
*
25+
* @category Location
26+
* @package Distance
27+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
28+
* @license http://www.opensource.org/licenses/mit-license MIT License
29+
* @link http://r03.org/
30+
*/
31+
class Vincenty extends AbstractDistance
32+
{
33+
/**
34+
* @param Coordinate $point1
35+
* @param Coordinate $point2
36+
*
37+
* @throws NotConvergingException
38+
* @throws \InvalidArgumentException
39+
*
40+
* @return float
41+
*/
42+
public function getDistance(Coordinate $point1, Coordinate $point2)
43+
{
44+
if ($point1->getEllipsoid() != $point2->getEllipsoid()) {
45+
throw new \InvalidArgumentException("The ellipsoids for both coordinates must match");
46+
}
47+
48+
$lat1 = deg2rad($point1->getLat());
49+
$lat2 = deg2rad($point2->getLat());
50+
$lng1 = deg2rad($point1->getLng());
51+
$lng2 = deg2rad($point2->getLng());
52+
53+
$a = $point1->getEllipsoid()->getA();
54+
$b = $point1->getEllipsoid()->getB();
55+
$f = 1 / $point1->getEllipsoid()->getF();
56+
57+
$L = $lng2 - $lng1;
58+
$U1 = atan((1 - $f) * tan($lat1));
59+
$U2 = atan((1 - $f) * tan($lat2));
60+
61+
$iterationLimit = 100;
62+
$lambda = $L;
63+
64+
$sinU1 = sin($U1);
65+
$sinU2 = sin($U2);
66+
$cosU1 = cos($U1);
67+
$cosU2 = cos($U2);
68+
69+
do {
70+
71+
$sinLambda = sin($lambda);
72+
$cosLambda = cos($lambda);
73+
74+
$sinSigma = sqrt(
75+
($cosU2 * $sinLambda) * ($cosU2 * $sinLambda) +
76+
($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda) * ($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda)
77+
);
78+
79+
if ($sinSigma == 0) {
80+
return 0.0;
81+
}
82+
83+
$cosSigma = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosLambda;
84+
85+
$sigma = atan2($sinSigma, $cosSigma);
86+
87+
$sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma;
88+
89+
$cosSqAlpha = 1 - $sinAlpha * $sinAlpha;
90+
91+
if ($cosSqAlpha == 0) {
92+
$cos2SigmaM = 0;
93+
} else {
94+
$cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha;
95+
}
96+
97+
$C = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha));
98+
99+
$lambdaP = $lambda;
100+
101+
$lambda = $L + (1 - $C) * $f * $sinAlpha * ($sigma + $C * $sinSigma * ($cos2SigmaM + $C * $cosSigma * (- 1 + 2 * $cos2SigmaM * $cos2SigmaM)));
102+
103+
} while (abs($lambda - $lambdaP) > 1e-12 && --$iterationLimit > 0);
104+
105+
if ($iterationLimit == 0) {
106+
throw new NotConvergingException();
107+
}
108+
109+
$uSq = $cosSqAlpha * ($a * $a - $b * $b) / ($b * $b);
110+
$A = 1 + $uSq / 16384 * (4096 + $uSq * (- 768 + $uSq * (320 - 175 * $uSq)));
111+
$B = $uSq / 1024 * (256 + $uSq * (- 128 + $uSq * (74 - 47 * $uSq)));
112+
$deltaSigma = $B * $sinSigma * ($cos2SigmaM + $B / 4 * ($cosSigma * (- 1 + 2 * $cos2SigmaM * $cos2SigmaM) - $B / 6 * $cos2SigmaM * (- 3 + 4 * $sinSigma * $sinSigma) * (- 3 + 4 * $cos2SigmaM * $cos2SigmaM)));
113+
$s = $b * $A * ($sigma - $deltaSigma);
114+
115+
return (round($s, 3));
116+
}
117+
}

‎src/Location/Ellipsoid.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
/**
3+
* Ellipsoid
4+
*
5+
* PHP version 5.3
6+
*
7+
* @category Location
8+
* @package Location
9+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
10+
* @copyright 2013 r03.org
11+
* @license http://www.opensource.org/licenses/mit-license MIT License
12+
* @link http://www.mtb-news.de/
13+
*/
14+
15+
namespace Location;
16+
17+
/**
18+
* Ellipsoid
19+
*
20+
* @category Location
21+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
22+
* @license http://www.opensource.org/licenses/mit-license MIT License
23+
* @link http://www.mtb-news.de/
24+
*/
25+
class Ellipsoid
26+
{
27+
/**
28+
* @var string
29+
*/
30+
protected $name;
31+
32+
/**
33+
* @var float
34+
*/
35+
protected $a;
36+
37+
/**
38+
* @var float
39+
*/
40+
protected $b;
41+
42+
/**
43+
* the 1/f value (not f!)
44+
*
45+
* @var float
46+
*/
47+
protected $f;
48+
49+
/**
50+
* Some often used ellipsoids
51+
*
52+
* @var array
53+
*/
54+
protected static $configs = array(
55+
'WGS-84' => array(
56+
'name' => 'WGS-84',
57+
'a' => 6378137.0,
58+
'b' => 6356752.3142,
59+
'f' => 298.257223563,
60+
),
61+
);
62+
63+
/**
64+
* @param $name
65+
* @param $a
66+
* @param $b
67+
* @param $f
68+
*/
69+
public function __construct($name, $a, $b, $f)
70+
{
71+
$this->name = $name;
72+
$this->a = $a;
73+
$this->b = $b;
74+
$this->f = $f;
75+
}
76+
77+
/**
78+
* @param string $name
79+
*
80+
* @return Ellipsoid
81+
*/
82+
public static function createDefault($name = 'WGS-84')
83+
{
84+
return self::createFromArray(self::$configs[$name]);
85+
}
86+
87+
/**
88+
* @param $config
89+
*
90+
* @return Ellipsoid
91+
*/
92+
public static function createFromArray($config)
93+
{
94+
return new self($config['name'], $config['a'], $config['b'], $config['f']);
95+
}
96+
97+
/**
98+
* @return string
99+
*/
100+
public function getName()
101+
{
102+
return $this->name;
103+
}
104+
105+
/**
106+
* @return float
107+
*/
108+
public function getA()
109+
{
110+
return $this->a;
111+
}
112+
113+
/**
114+
* @return float
115+
*/
116+
public function getB()
117+
{
118+
return $this->b;
119+
}
120+
121+
/**
122+
* @return float
123+
*/
124+
public function getF()
125+
{
126+
return $this->f;
127+
}
128+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Location\Exception;
4+
5+
class NotConvergingException extends \RuntimeException
6+
{
7+
}

‎tests/Location/BoundsTest.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace Location;
4+
5+
use Location\Coordinate;
6+
use Location\Bounds;
7+
8+
class BoundsTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var Bounds
12+
*/
13+
protected $object;
14+
15+
/**
16+
* Sets up the fixture, for example, opens a network connection.
17+
* This method is called before a test is executed.
18+
*/
19+
protected function setUp()
20+
{
21+
$this->object = new Bounds(
22+
new Coordinate(50, 10),
23+
new Coordinate(30, 30)
24+
);
25+
}
26+
27+
/**
28+
* Tears down the fixture, for example, closes a network connection.
29+
* This method is called after a test is executed.
30+
*/
31+
protected function tearDown()
32+
{
33+
unset($this->object);
34+
}
35+
36+
/**
37+
* @covers Location\Bounds::getNorthWest
38+
*/
39+
public function testGetNortWest()
40+
{
41+
$c = new Coordinate(50, 10);
42+
43+
$this->assertEquals($c, $this->object->getNorthWest());
44+
}
45+
46+
/**
47+
* @covers Location\Bounds::getSouthEast
48+
*/
49+
public function testGetSouthEast()
50+
{
51+
$c = new Coordinate(30, 30);
52+
53+
$this->assertEquals($c, $this->object->getSouthEast());
54+
}
55+
56+
/**
57+
* @covers Location\Bounds::getNorth
58+
*/
59+
public function testGetNorth()
60+
{
61+
$this->assertEquals(50, $this->object->getNorth());
62+
}
63+
64+
/**
65+
* @covers Location\Bounds::getSouth
66+
*/
67+
public function testGetSouth()
68+
{
69+
$this->assertEquals(30, $this->object->getSouth());
70+
}
71+
72+
/**
73+
* @covers Location\Bounds::getWest
74+
*/
75+
public function testGetWest()
76+
{
77+
$this->assertEquals(10, $this->object->getWest());
78+
}
79+
80+
/**
81+
* @covers Location\Bounds::getEast
82+
*/
83+
public function testGetEast()
84+
{
85+
$this->assertEquals(30, $this->object->getEast());
86+
}
87+
88+
/**
89+
* @covers Location\Bounds::getCenter
90+
*/
91+
public function testGetCenter()
92+
{
93+
$testBounds = [
94+
['nw' => new Coordinate(50, 10), 'se' => new Coordinate(30, 30), 'c' => new Coordinate(40, 20)],
95+
['nw' => new Coordinate(50, - 130), 'se' => new Coordinate(30, - 110), 'c' => new Coordinate(40, - 120)],
96+
['nw' => new Coordinate(10, - 10), 'se' => new Coordinate(- 10, 10), 'c' => new Coordinate(0, 0)],
97+
['nw' => new Coordinate(-80, - 130), 'se' => new Coordinate(- 90, -110), 'c' => new Coordinate(-85, -120)],
98+
['nw' => new Coordinate(80, - 130), 'se' => new Coordinate(90, -110), 'c' => new Coordinate(85, -120)],
99+
['nw' => new Coordinate(80, 110), 'se' => new Coordinate(90, 130), 'c' => new Coordinate(85, 120)],
100+
['nw' => new Coordinate(50, 170), 'se' => new Coordinate(30, -160), 'c' => new Coordinate(40, -175)],
101+
['nw' => new Coordinate(-50, 150), 'se' => new Coordinate(-70, -170), 'c' => new Coordinate(-60, 170)],
102+
];
103+
104+
foreach ($testBounds as $bounds) {
105+
106+
$b = new Bounds($bounds['nw'], $bounds['se']);
107+
108+
$this->assertEquals($bounds['c'], $b->getCenter());
109+
110+
}
111+
}
112+
}

‎tests/Location/CoordinateTest.php

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
namespace Location;
4+
5+
use Location\Coordinate;
6+
use Location\Ellipsoid;
7+
8+
class CoordinateTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var Ellipsoid
12+
*/
13+
protected $ellipsoid;
14+
15+
/**
16+
* @var Coordinate
17+
*/
18+
protected $coordinate;
19+
20+
/**
21+
* Sets up the fixture, for example, opens a network connection.
22+
* This method is called before a test is executed.
23+
*/
24+
protected function setUp()
25+
{
26+
$ellipsoidConfig = array(
27+
'name' => 'WGS-84',
28+
'a' => 6378137.0,
29+
'b' => 6356752.3142,
30+
'f' => 298.257223563,
31+
);
32+
33+
$this->ellipsoid = Ellipsoid::createFromArray($ellipsoidConfig);
34+
35+
$this->coordinate = new Coordinate(52.5, 13.5, $this->ellipsoid);
36+
}
37+
38+
/**
39+
* Tears down the fixture, for example, closes a network connection.
40+
* This method is called after a test is executed.
41+
*/
42+
protected function tearDown()
43+
{
44+
unset($this->ellipsoid);
45+
unset($this->coordinate);
46+
}
47+
48+
/**
49+
* @covers Location\Coordinate::__construct
50+
* @expectedException \InvalidArgumentException
51+
*/
52+
public function testConstructorInvalidLatitude()
53+
{
54+
$c = new Coordinate('foo', 13.5, $this->ellipsoid);
55+
}
56+
57+
/**
58+
* @covers Location\Coordinate::__construct
59+
* @expectedException \InvalidArgumentException
60+
*/
61+
public function testConstructorInvalidLongitude()
62+
{
63+
$c = new Coordinate(52.5, 'foo', $this->ellipsoid);
64+
}
65+
66+
/**
67+
* @covers Location\Coordinate::__construct
68+
*/
69+
public function testConstructorDefaultEllipsoid()
70+
{
71+
$c = new Coordinate(52.5, 13.5);
72+
}
73+
74+
/**
75+
* @covers Location\Coordinate::getLat
76+
*/
77+
public function testGetLat()
78+
{
79+
$this->assertEquals(52.5, $this->coordinate->getLat());
80+
}
81+
82+
/**
83+
* @covers Location\Coordinate::getLng
84+
*/
85+
public function testGetLng()
86+
{
87+
$this->assertEquals(13.5, $this->coordinate->getLng());
88+
}
89+
90+
/**
91+
* @covers Location\Coordinate::getEllipsoid
92+
*/
93+
public function testGetEllipsoid()
94+
{
95+
$this->assertEquals($this->ellipsoid, $this->coordinate->getEllipsoid());
96+
}
97+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
namespace Location\Distance;
4+
5+
use Location\Distance\Vincenty;
6+
use Location\Ellipsoid;
7+
use Location\Coordinate;
8+
9+
/**
10+
* Generated by PHPUnit_SkeletonGenerator on 2012-09-28 at 11:02:18.
11+
*/
12+
class VincentyTest extends \PHPUnit_Framework_TestCase
13+
{
14+
protected $ellipsoid;
15+
16+
/**
17+
* Sets up the fixture, for example, opens a network connection.
18+
* This method is called before a test is executed.
19+
*/
20+
protected function setUp()
21+
{
22+
$ellipsoidConfig = array(
23+
'name' => 'WGS-84',
24+
'a' => 6378137.0,
25+
'b' => 6356752.3142,
26+
'f' => 298.257223563,
27+
);
28+
29+
$this->ellipsoid = Ellipsoid::createFromArray($ellipsoidConfig);
30+
}
31+
32+
/**
33+
* Tears down the fixture, for example, closes a network connection.
34+
* This method is called after a test is executed.
35+
*/
36+
protected function tearDown()
37+
{
38+
unset($this->ellipsoid);
39+
}
40+
41+
/**
42+
* @covers Location\Distance\Vincenty::getDistance
43+
*/
44+
public function testGetDistanceZero()
45+
{
46+
$coordinate1 = new Coordinate(52.5, 13.5, $this->ellipsoid);
47+
$coordinate2 = new Coordinate(52.5, 13.5, $this->ellipsoid);
48+
49+
$calculator = new Vincenty();
50+
$distance = $calculator->getDistance($coordinate1, $coordinate2);
51+
52+
$this->assertEquals(0.0, $distance);
53+
}
54+
55+
/**
56+
* @covers Location\Distance\Vincenty::getDistance
57+
*/
58+
public function testGetDistanceSameLatitude()
59+
{
60+
$coordinate1 = new Coordinate(52.5, 13.5, $this->ellipsoid);
61+
$coordinate2 = new Coordinate(52.5, 13.1, $this->ellipsoid);
62+
63+
$calculator = new Vincenty();
64+
$distance = $calculator->getDistance($coordinate1, $coordinate2);
65+
66+
$this->assertEquals(27164.059, $distance);
67+
}
68+
69+
/**
70+
* @covers Location\Distance\Vincenty::getDistance
71+
*/
72+
public function testGetDistanceSameLongitude()
73+
{
74+
$coordinate1 = new Coordinate(52.5, 13.5, $this->ellipsoid);
75+
$coordinate2 = new Coordinate(52.1, 13.5, $this->ellipsoid);
76+
77+
$calculator = new Vincenty();
78+
$distance = $calculator->getDistance($coordinate1, $coordinate2);
79+
80+
$this->assertEquals(44509.218, $distance);
81+
}
82+
83+
/**
84+
* @covers Location\Distance\Vincenty::getDistance
85+
*/
86+
public function testGetDistance()
87+
{
88+
$coordinate1 = new Coordinate(19.820664, -155.468066, $this->ellipsoid);
89+
$coordinate2 = new Coordinate(20.709722, -156.253333, $this->ellipsoid);
90+
91+
$calculator = new Vincenty();
92+
$distance = $calculator->getDistance($coordinate1, $coordinate2);
93+
94+
$this->assertEquals(128130.850, $distance);
95+
}
96+
97+
/**
98+
* @covers Location\Distance\Vincenty::getDistance
99+
*/
100+
public function testGetDistanceInternationalDateLine()
101+
{
102+
$coordinate1 = new Coordinate(20.0, 170.0, $this->ellipsoid);
103+
$coordinate2 = new Coordinate(-20.0, -170.0, $this->ellipsoid);
104+
105+
$calculator = new Vincenty();
106+
$distance = $calculator->getDistance($coordinate1, $coordinate2);
107+
108+
$this->assertEquals(4932842.135, $distance);
109+
}
110+
}

‎tests/bootstrap.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Simple PSR-0 Autoloader
4+
*
5+
* @category Location
6+
* @author Marcus T. Jaschen <mjaschen@gmail.com>
7+
*/
8+
spl_autoload_register(
9+
function ($class) {
10+
$file = __DIR__ . '/../src/' . strtr($class, '\\', '/') . '.php';
11+
if (file_exists($file)) {
12+
require_once $file;
13+
return true;
14+
}
15+
}
16+
);

0 commit comments

Comments
 (0)
Please sign in to comment.