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:
Bence Pőcze 2020-06-12 19:57:07 +00:00
commit 6c8a3c6a90
8 changed files with 55 additions and 28 deletions

View 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();

View File

@ -0,0 +1,4 @@
ALTER TABLE
`maps`
ADD
`area` decimal(13, 4) NOT NULL DEFAULT 0.0;

View File

@ -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' => []
]); ]);
} }

View File

@ -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));
} }

View File

@ -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'])) {

View File

@ -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';
} }

View File

@ -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);

View File

@ -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;
} }