MAPG-6 introduce and unify geo calculations

This commit is contained in:
Bence Pőcze 2020-05-19 19:01:35 +02:00
parent 1d4bfd75d8
commit e15421af8b
3 changed files with 42 additions and 9 deletions

View File

@ -11,15 +11,14 @@ var Util = {
var lat2 = Math.deg2rad(position2.lat); var lat2 = Math.deg2rad(position2.lat);
var lng2 = Math.deg2rad(position2.lng); var lng2 = Math.deg2rad(position2.lng);
var latDelta = lat2 - lat1; var angleCos = Math.cos(lat1) * Math.cos(lat2) * Math.cos(lng2 - lng1) +
var lonDelta = lng2 - lng1; Math.sin(lat1) * Math.sin(lat2);
var angle = 2 * Math.asin( if (angleCos > 1.0) {
Math.sqrt( angleCos = 1.0;
Math.pow(Math.sin(latDelta / 2), 2) + }
Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(lonDelta / 2), 2)
) var angle = Math.acos(angleCos);
);
return angle * Util.EARTH_RADIUS_IN_METER; return angle * Util.EARTH_RADIUS_IN_METER;
}, },

View File

@ -2,6 +2,8 @@
class Bounds class Bounds
{ {
const ONE_DEGREE_OF_LATITUDE_IN_METER = 111132.954;
private float $southLat; private float $southLat;
private float $westLng; private float $westLng;
@ -19,7 +21,7 @@ class Bounds
return $instance; return $instance;
} }
public static function createDirectly(float $southLat, $westLng, $northLat, $eastLng): Bounds public static function createDirectly(float $southLat, float $westLng, float $northLat, float $eastLng): Bounds
{ {
$instance = new static(); $instance = new static();
@ -61,6 +63,18 @@ class Bounds
} }
} }
public function calculateApproximateArea(): float
{
$dLat = $this->northLat - $this->southLat;
$dLng = $this->eastLng - $this->westLng;
$m = $dLat * static::ONE_DEGREE_OF_LATITUDE_IN_METER;
$a = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_METER * cos(deg2rad($this->northLat));
$c = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_METER * cos(deg2rad($this->southLat));
return $m * ($a + $c) / 2;
}
public function toJson(): string public function toJson(): string
{ {
if (!$this->initialized) { if (!$this->initialized) {

View File

@ -2,6 +2,8 @@
class Position class Position
{ {
const EARTH_RADIUS_IN_METER = 6371000;
private float $lat; private float $lat;
private float $lng; private float $lng;
@ -21,6 +23,24 @@ class Position
return $this->lng; return $this->lng;
} }
public function calculateDistanceTo(Position $otherPosition): float
{
$lat1 = deg2rad($this->lat);
$lng1 = deg2rad($this->lng);
$lat2 = deg2rad($otherPosition->lat);
$lng2 = deg2rad($otherPosition->lng);
$angleCos = cos($lat1) * cos($lat2) * cos($lng2 - $lng1) + sin($lat1) * sin($lat2);
if ($angleCos > 1.0) {
$angleCos = 1.0;
}
$angle = acos($angleCos);
return $angle * static::EARTH_RADIUS_IN_METER;
}
public function toArray(): array public function toArray(): array
{ {
return [ return [