Merged in feature/MAPG-111-calculate-map-area-when-bounds-are-modified (pull request #105)
Feature/MAPG-111 calculate map area when bounds are modified
This commit is contained in:
commit
6c8a3c6a90
24
database/migrations/data/20200612_2124_map_area.php
Normal file
24
database/migrations/data/20200612_2124_map_area.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use MapGuesser\Database\Query\Modify;
|
||||||
|
use MapGuesser\Database\Query\Select;
|
||||||
|
use MapGuesser\Interfaces\Database\IResultSet;
|
||||||
|
use MapGuesser\Util\Geo\Bounds;
|
||||||
|
|
||||||
|
$select = new Select(\Container::$dbConnection, 'maps');
|
||||||
|
$select->columns(['id', 'bound_south_lat', 'bound_west_lng', 'bound_north_lat', 'bound_east_lng']);
|
||||||
|
|
||||||
|
$result = $select->execute();
|
||||||
|
|
||||||
|
\Container::$dbConnection->startTransaction();
|
||||||
|
|
||||||
|
while ($map = $result->fetch(IResultSet::FETCH_ASSOC)) {
|
||||||
|
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
||||||
|
|
||||||
|
$modify = new Modify(\Container::$dbConnection, 'maps');
|
||||||
|
$modify->setId($map['id']);
|
||||||
|
$modify->set('area', $bounds->calculateApproximateArea());
|
||||||
|
$modify->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
\Container::$dbConnection->commit();
|
4
database/migrations/structure/20200612_2124_map_area.sql
Normal file
4
database/migrations/structure/20200612_2124_map_area.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE
|
||||||
|
`maps`
|
||||||
|
ADD
|
||||||
|
`area` decimal(13, 4) NOT NULL DEFAULT 0.0;
|
@ -44,7 +44,7 @@ class GameController
|
|||||||
if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) {
|
if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) {
|
||||||
$session->set('state', [
|
$session->set('state', [
|
||||||
'mapId' => $mapId,
|
'mapId' => $mapId,
|
||||||
'area' => $bounds->calculateApproximateArea(),
|
'area' => $map['area'],
|
||||||
'rounds' => []
|
'rounds' => []
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ class GameFlowController
|
|||||||
|
|
||||||
private function calculateScore(float $distance, float $area): int
|
private function calculateScore(float $distance, float $area): int
|
||||||
{
|
{
|
||||||
$goodness = 1.0 - ($distance / sqrt($area));
|
$goodness = 1.0 - ($distance / (sqrt($area) * 1000));
|
||||||
|
|
||||||
return (int) round(pow(static::MAX_SCORE, $goodness));
|
return (int) round(pow(static::MAX_SCORE, $goodness));
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,8 @@ class MapAdminController implements ISecured
|
|||||||
'bound_south_lat' => $mapBounds->getSouthLat(),
|
'bound_south_lat' => $mapBounds->getSouthLat(),
|
||||||
'bound_west_lng' => $mapBounds->getWestLng(),
|
'bound_west_lng' => $mapBounds->getWestLng(),
|
||||||
'bound_north_lat' => $mapBounds->getNorthLat(),
|
'bound_north_lat' => $mapBounds->getNorthLat(),
|
||||||
'bound_east_lng' => $mapBounds->getEastLng()
|
'bound_east_lng' => $mapBounds->getEastLng(),
|
||||||
|
'area' => $mapBounds->calculateApproximateArea(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (isset($_POST['name'])) {
|
if (isset($_POST['name'])) {
|
||||||
|
@ -6,7 +6,6 @@ use MapGuesser\Interfaces\Authentication\IUser;
|
|||||||
use MapGuesser\Interfaces\Database\IResultSet;
|
use MapGuesser\Interfaces\Database\IResultSet;
|
||||||
use MapGuesser\Interfaces\Request\IRequest;
|
use MapGuesser\Interfaces\Request\IRequest;
|
||||||
use MapGuesser\Interfaces\Response\IContent;
|
use MapGuesser\Interfaces\Response\IContent;
|
||||||
use MapGuesser\Util\Geo\Bounds;
|
|
||||||
use MapGuesser\Response\HtmlContent;
|
use MapGuesser\Response\HtmlContent;
|
||||||
|
|
||||||
class MapsController
|
class MapsController
|
||||||
@ -29,6 +28,7 @@ class MapsController
|
|||||||
['maps', 'bound_west_lng'],
|
['maps', 'bound_west_lng'],
|
||||||
['maps', 'bound_north_lat'],
|
['maps', 'bound_north_lat'],
|
||||||
['maps', 'bound_east_lng'],
|
['maps', 'bound_east_lng'],
|
||||||
|
['maps', 'area'],
|
||||||
new RawExpression('COUNT(places.id) AS num_places')
|
new RawExpression('COUNT(places.id) AS num_places')
|
||||||
]);
|
]);
|
||||||
$select->leftJoin('places', ['places', 'map_id'], '=', ['maps', 'id']);
|
$select->leftJoin('places', ['places', 'map_id'], '=', ['maps', 'id']);
|
||||||
@ -39,9 +39,7 @@ class MapsController
|
|||||||
|
|
||||||
$maps = [];
|
$maps = [];
|
||||||
while ($map = $result->fetch(IResultSet::FETCH_ASSOC)) {
|
while ($map = $result->fetch(IResultSet::FETCH_ASSOC)) {
|
||||||
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
$map['area'] = $this->formatMapAreaForHuman($map['area']);
|
||||||
|
|
||||||
$map['area'] = $this->formatMapAreaForHuman($bounds->calculateApproximateArea());
|
|
||||||
|
|
||||||
$maps[] = $map;
|
$maps[] = $map;
|
||||||
}
|
}
|
||||||
@ -53,29 +51,29 @@ class MapsController
|
|||||||
|
|
||||||
private function formatMapAreaForHuman(float $area): array
|
private function formatMapAreaForHuman(float $area): array
|
||||||
{
|
{
|
||||||
if ($area < 100.0) {
|
if ($area < 0.01) {
|
||||||
|
$digits = 0;
|
||||||
|
$rounded = round($area * 1000000.0, -2);
|
||||||
|
$unit = 'm';
|
||||||
|
} elseif ($area < 0.1) {
|
||||||
|
$digits = 0;
|
||||||
|
$rounded = round($area * 1000000.0, -3);
|
||||||
|
$unit = 'm';
|
||||||
|
} elseif ($area < 1.0) {
|
||||||
|
$digits = 2;
|
||||||
|
$rounded = round($area, 2);
|
||||||
|
$unit = 'km';
|
||||||
|
} elseif ($area < 100.0) {
|
||||||
$digits = 0;
|
$digits = 0;
|
||||||
$rounded = round($area, 0);
|
$rounded = round($area, 0);
|
||||||
$unit = 'm';
|
$unit = 'km';
|
||||||
} elseif ($area < 100000.0) {
|
} elseif ($area < 10000.0) {
|
||||||
$digits = 0;
|
$digits = 0;
|
||||||
$rounded = round($area, -2);
|
$rounded = round($area, -2);
|
||||||
$unit = 'm';
|
|
||||||
} elseif ($area < 1000000.0) {
|
|
||||||
$digits = 2;
|
|
||||||
$rounded = round($area / 1000000.0, 2);
|
|
||||||
$unit = 'km';
|
|
||||||
} elseif ($area < 100000000.0) {
|
|
||||||
$digits = 0;
|
|
||||||
$rounded = round($area / 1000000.0, 0);
|
|
||||||
$unit = 'km';
|
|
||||||
} elseif ($area < 10000000000.0) {
|
|
||||||
$digits = 0;
|
|
||||||
$rounded = round($area / 1000000.0, -2);
|
|
||||||
$unit = 'km';
|
$unit = 'km';
|
||||||
} else {
|
} else {
|
||||||
$digits = 0;
|
$digits = 0;
|
||||||
$rounded = round($area / 1000000.0, -4);
|
$rounded = round($area, -4);
|
||||||
$unit = 'km';
|
$unit = 'km';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ class MapRepository
|
|||||||
public function getById(int $mapId)
|
public function getById(int $mapId)
|
||||||
{
|
{
|
||||||
$select = new Select(\Container::$dbConnection, 'maps');
|
$select = new Select(\Container::$dbConnection, 'maps');
|
||||||
$select->columns(['id', 'name', 'description', 'bound_south_lat', 'bound_west_lng', 'bound_north_lat', 'bound_east_lng']);
|
$select->columns(['id', 'name', 'description', 'bound_south_lat', 'bound_west_lng', 'bound_north_lat', 'bound_east_lng', 'area']);
|
||||||
$select->whereId($mapId);
|
$select->whereId($mapId);
|
||||||
|
|
||||||
return $select->execute()->fetch(IResultSet::FETCH_ASSOC);
|
return $select->execute()->fetch(IResultSet::FETCH_ASSOC);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class Bounds
|
class Bounds
|
||||||
{
|
{
|
||||||
const ONE_DEGREE_OF_LATITUDE_IN_METER = 111132.954;
|
const ONE_DEGREE_OF_LATITUDE_IN_KM = 111.132954;
|
||||||
|
|
||||||
private float $southLat = 90.0;
|
private float $southLat = 90.0;
|
||||||
private float $westLng = 180.0;
|
private float $westLng = 180.0;
|
||||||
@ -84,9 +84,9 @@ class Bounds
|
|||||||
$dLat = $this->northLat - $this->southLat;
|
$dLat = $this->northLat - $this->southLat;
|
||||||
$dLng = $this->eastLng - $this->westLng;
|
$dLng = $this->eastLng - $this->westLng;
|
||||||
|
|
||||||
$m = $dLat * static::ONE_DEGREE_OF_LATITUDE_IN_METER;
|
$m = $dLat * static::ONE_DEGREE_OF_LATITUDE_IN_KM;
|
||||||
$a = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_METER * cos(deg2rad($this->northLat));
|
$a = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_KM * cos(deg2rad($this->northLat));
|
||||||
$c = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_METER * cos(deg2rad($this->southLat));
|
$c = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_KM * cos(deg2rad($this->southLat));
|
||||||
|
|
||||||
return $m * ($a + $c) / 2;
|
return $m * ($a + $c) / 2;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user