From 4d7c86fd1b00e8c6e3344bc4de1b61574ca29eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=91cze=20Bence?= Date: Fri, 12 Jun 2020 21:54:05 +0200 Subject: [PATCH 1/2] MAPG-111 store map area in table 'maps' --- .../data/20200612_2124_map_area.php | 24 +++++++++++++++++++ .../structure/20200612_2124_map_area.sql | 4 ++++ 2 files changed, 28 insertions(+) create mode 100644 database/migrations/data/20200612_2124_map_area.php create mode 100644 database/migrations/structure/20200612_2124_map_area.sql diff --git a/database/migrations/data/20200612_2124_map_area.php b/database/migrations/data/20200612_2124_map_area.php new file mode 100644 index 0000000..d6460ef --- /dev/null +++ b/database/migrations/data/20200612_2124_map_area.php @@ -0,0 +1,24 @@ +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(); diff --git a/database/migrations/structure/20200612_2124_map_area.sql b/database/migrations/structure/20200612_2124_map_area.sql new file mode 100644 index 0000000..04970d1 --- /dev/null +++ b/database/migrations/structure/20200612_2124_map_area.sql @@ -0,0 +1,4 @@ +ALTER TABLE + `maps` +ADD + `area` decimal(13, 4) NOT NULL DEFAULT 0.0; From 7159867db074e54361f12c06d9ac63b37501632b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=91cze=20Bence?= Date: Fri, 12 Jun 2020 21:55:04 +0200 Subject: [PATCH 2/2] MAPG-111 query map area from DB modify calculations to be in square km (instead of m) --- src/Controller/GameController.php | 2 +- src/Controller/GameFlowController.php | 2 +- src/Controller/MapAdminController.php | 3 ++- src/Controller/MapsController.php | 38 +++++++++++++-------------- src/Repository/MapRepository.php | 2 +- src/Util/Geo/Bounds.php | 8 +++--- 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/Controller/GameController.php b/src/Controller/GameController.php index e2f9146..c9472d9 100644 --- a/src/Controller/GameController.php +++ b/src/Controller/GameController.php @@ -44,7 +44,7 @@ class GameController if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) { $session->set('state', [ 'mapId' => $mapId, - 'area' => $bounds->calculateApproximateArea(), + 'area' => $map['area'], 'rounds' => [] ]); } diff --git a/src/Controller/GameFlowController.php b/src/Controller/GameFlowController.php index 3b44efa..913cfa6 100644 --- a/src/Controller/GameFlowController.php +++ b/src/Controller/GameFlowController.php @@ -123,7 +123,7 @@ class GameFlowController 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)); } diff --git a/src/Controller/MapAdminController.php b/src/Controller/MapAdminController.php index 2cf280f..7a49d41 100644 --- a/src/Controller/MapAdminController.php +++ b/src/Controller/MapAdminController.php @@ -118,7 +118,8 @@ class MapAdminController implements ISecured 'bound_south_lat' => $mapBounds->getSouthLat(), 'bound_west_lng' => $mapBounds->getWestLng(), 'bound_north_lat' => $mapBounds->getNorthLat(), - 'bound_east_lng' => $mapBounds->getEastLng() + 'bound_east_lng' => $mapBounds->getEastLng(), + 'area' => $mapBounds->calculateApproximateArea(), ]; if (isset($_POST['name'])) { diff --git a/src/Controller/MapsController.php b/src/Controller/MapsController.php index 33da754..0546ec7 100644 --- a/src/Controller/MapsController.php +++ b/src/Controller/MapsController.php @@ -6,7 +6,6 @@ use MapGuesser\Interfaces\Authentication\IUser; use MapGuesser\Interfaces\Database\IResultSet; use MapGuesser\Interfaces\Request\IRequest; use MapGuesser\Interfaces\Response\IContent; -use MapGuesser\Util\Geo\Bounds; use MapGuesser\Response\HtmlContent; class MapsController @@ -29,6 +28,7 @@ class MapsController ['maps', 'bound_west_lng'], ['maps', 'bound_north_lat'], ['maps', 'bound_east_lng'], + ['maps', 'area'], new RawExpression('COUNT(places.id) AS num_places') ]); $select->leftJoin('places', ['places', 'map_id'], '=', ['maps', 'id']); @@ -39,9 +39,7 @@ class MapsController $maps = []; 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($bounds->calculateApproximateArea()); + $map['area'] = $this->formatMapAreaForHuman($map['area']); $maps[] = $map; } @@ -53,29 +51,29 @@ class MapsController 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; $rounded = round($area, 0); - $unit = 'm'; - } elseif ($area < 100000.0) { + $unit = 'km'; + } elseif ($area < 10000.0) { $digits = 0; $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'; } else { $digits = 0; - $rounded = round($area / 1000000.0, -4); + $rounded = round($area, -4); $unit = 'km'; } diff --git a/src/Repository/MapRepository.php b/src/Repository/MapRepository.php index 7fef975..ba9e11a 100644 --- a/src/Repository/MapRepository.php +++ b/src/Repository/MapRepository.php @@ -8,7 +8,7 @@ class MapRepository public function getById(int $mapId) { $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); return $select->execute()->fetch(IResultSet::FETCH_ASSOC); diff --git a/src/Util/Geo/Bounds.php b/src/Util/Geo/Bounds.php index 47d4a1f..72501c1 100644 --- a/src/Util/Geo/Bounds.php +++ b/src/Util/Geo/Bounds.php @@ -2,7 +2,7 @@ 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 $westLng = 180.0; @@ -84,9 +84,9 @@ class Bounds $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)); + $m = $dLat * static::ONE_DEGREE_OF_LATITUDE_IN_KM; + $a = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_KM * cos(deg2rad($this->northLat)); + $c = $dLng * static::ONE_DEGREE_OF_LATITUDE_IN_KM * cos(deg2rad($this->southLat)); return $m * ($a + $c) / 2; }