Skip to content

Commit 3622d9f

Browse files
committed
starting GPS clustering algorithm implementation
1 parent 5cfae37 commit 3622d9f

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

src/Gps/Algorithm.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Kmeans\Gps;
4+
5+
use Kmeans\Algorithm as BaseAlgorithm;
6+
use Kmeans\Interfaces\PointCollectionInterface;
7+
use Kmeans\Interfaces\PointInterface;
8+
use Kmeans\Math;
9+
10+
class Algorithm extends BaseAlgorithm
11+
{
12+
protected function getDistanceBetween(PointInterface $pointA, PointInterface $pointB): float
13+
{
14+
if (! $pointA instanceof Point || ! $pointB instanceof Point) {
15+
throw new \InvalidArgumentException(
16+
"Expecting \\Kmeans\\GPS\\Point"
17+
);
18+
}
19+
20+
return Math::haversine($pointA->getCoordinates(), $pointB->getCoordinates());
21+
}
22+
23+
protected function findCentroid(PointCollectionInterface $points): PointInterface
24+
{
25+
if (! $points->getSpace() instanceof Space) {
26+
throw new \InvalidArgumentException(
27+
"Point collection should consist of GPS coordinates"
28+
);
29+
}
30+
31+
/** @var array<Point> $points */
32+
$points = iterator_to_array($points);
33+
34+
return new Point(Math::gpsCentroid(
35+
array_map(fn (Point $point) => $point->getCoordinates(), $points)
36+
));
37+
}
38+
}

src/Gps/Point.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Kmeans\Gps;
4+
5+
use Kmeans\Point as BasePoint;
6+
7+
/**
8+
* @method array{0: float, 1: float} getCoordinates()
9+
*/
10+
class Point extends BasePoint
11+
{
12+
/**
13+
* @param array<float> $coordinates
14+
*/
15+
public function __construct(array $coordinates)
16+
{
17+
$this->validateCoordinates($coordinates);
18+
19+
parent::__construct(new Space(), $coordinates);
20+
}
21+
22+
/**
23+
* @param array<float> $coordinates
24+
*/
25+
private function validateCoordinates(array $coordinates): void
26+
{
27+
if (count($coordinates) != 2) {
28+
throw new \InvalidArgumentException(
29+
"Invalid GPS coordinates"
30+
);
31+
}
32+
33+
list($lat, $long) = $coordinates;
34+
35+
if ($lat < -90 || $lat > 90 || $long < -180 || $long > 180) {
36+
throw new \InvalidArgumentException(
37+
"Invalid GPS coordinates"
38+
);
39+
}
40+
}
41+
}

src/Gps/Space.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Kmeans\Gps;
4+
5+
use Kmeans\Space as BaseSpace;
6+
7+
class Space extends BaseSpace
8+
{
9+
public function __construct()
10+
{
11+
parent::__construct(2);
12+
}
13+
}

0 commit comments

Comments
 (0)