Merged in feature/MAPG-10-check-if-place-has-panorama (pull request #3)
Feature/MAPG-10 check if place has panorama
This commit is contained in:
commit
5c9b54c881
@ -8,9 +8,16 @@ switch($url) {
|
|||||||
case '/':
|
case '/':
|
||||||
$controller = new MapGuesser\Controller\GuessController();
|
$controller = new MapGuesser\Controller\GuessController();
|
||||||
break;
|
break;
|
||||||
|
case '/getNewPosition.json':
|
||||||
|
$controller = new MapGuesser\Controller\GetNewPosition();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
echo 'Error 404';
|
echo 'Error 404';
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $controller->render();
|
$view = $controller->run();
|
||||||
|
|
||||||
|
header('Content-Type: ' . $view->getContentType() . '; charset=UTF-8');
|
||||||
|
|
||||||
|
echo $view->render();
|
||||||
|
@ -45,26 +45,14 @@ var MapManipulator = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var realPosition;
|
||||||
var panorama;
|
var panorama;
|
||||||
var guessMap;
|
var guessMap;
|
||||||
var guessMarker;
|
var guessMarker;
|
||||||
var googleLink;
|
var googleLink;
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
panorama = new google.maps.StreetViewPanorama(document.getElementById('panorama'), {
|
getNewPosition();
|
||||||
position: realPosition,
|
|
||||||
disableDefaultUI: true,
|
|
||||||
linksControl: true,
|
|
||||||
showRoadLabels: false
|
|
||||||
});
|
|
||||||
|
|
||||||
panorama.addListener('position_changed', function () {
|
|
||||||
MapManipulator.rewriteGoogleLink();
|
|
||||||
});
|
|
||||||
|
|
||||||
panorama.addListener('pov_changed', function () {
|
|
||||||
MapManipulator.rewriteGoogleLink();
|
|
||||||
});
|
|
||||||
|
|
||||||
guessMap = new google.maps.Map(document.getElementById('guessMap'), {
|
guessMap = new google.maps.Map(document.getElementById('guessMap'), {
|
||||||
disableDefaultUI: true,
|
disableDefaultUI: true,
|
||||||
@ -90,6 +78,48 @@ function initialize() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNewPosition() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
realPosition = this.response.position;
|
||||||
|
|
||||||
|
var sv = new google.maps.StreetViewService();
|
||||||
|
sv.getPanorama({ location: this.response.position, preference: google.maps.StreetViewPreference.BEST }, loadPano);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.open('GET', 'getNewPosition.json', true);
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadPano(data, status) {
|
||||||
|
if (status !== google.maps.StreetViewStatus.OK) {
|
||||||
|
getNewPosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panorama) {
|
||||||
|
panorama.setPano(data.location.pano);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
panorama = new google.maps.StreetViewPanorama(document.getElementById('panorama'), {
|
||||||
|
pano: data.location.pano,
|
||||||
|
disableDefaultUI: true,
|
||||||
|
linksControl: true,
|
||||||
|
showRoadLabels: false
|
||||||
|
});
|
||||||
|
|
||||||
|
panorama.addListener('position_changed', function () {
|
||||||
|
MapManipulator.rewriteGoogleLink();
|
||||||
|
});
|
||||||
|
|
||||||
|
panorama.addListener('pov_changed', function () {
|
||||||
|
MapManipulator.rewriteGoogleLink();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('guessButton').onclick = function () {
|
document.getElementById('guessButton').onclick = function () {
|
||||||
if (!guessMarker) {
|
if (!guessMarker) {
|
||||||
return;
|
return;
|
||||||
@ -98,7 +128,13 @@ document.getElementById('guessButton').onclick = function () {
|
|||||||
var guessedPosition = guessMarker.getPosition();
|
var guessedPosition = guessMarker.getPosition();
|
||||||
var distance = Util.calculateDistance(realPosition, { lat: guessedPosition.lat(), lng: guessedPosition.lng() });
|
var distance = Util.calculateDistance(realPosition, { lat: guessedPosition.lat(), lng: guessedPosition.lng() });
|
||||||
|
|
||||||
alert('You were ' + distance + 'm close!');
|
alert('You were ' + (Math.round(distance) / 1000) + ' km close!');
|
||||||
|
|
||||||
this.blur();
|
this.disabled = true;
|
||||||
|
guessMarker.setMap(null);
|
||||||
|
guessMarker = null;
|
||||||
|
//TODO: fit to the same size as on init
|
||||||
|
guessMap.fitBounds(guessMapBounds);
|
||||||
|
|
||||||
|
getNewPosition();
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
<?php namespace MapGuesser\Controller;
|
|
||||||
|
|
||||||
abstract class BaseController
|
|
||||||
{
|
|
||||||
protected string $view;
|
|
||||||
|
|
||||||
protected array $variables = [];
|
|
||||||
|
|
||||||
public function render() : string
|
|
||||||
{
|
|
||||||
$this->operate();
|
|
||||||
|
|
||||||
extract($this->variables);
|
|
||||||
|
|
||||||
ob_start();
|
|
||||||
require ROOT . '/views/' . $this->view . '.php';
|
|
||||||
$content = ob_get_contents();
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected function operate() : void;
|
|
||||||
}
|
|
8
src/Controller/ControllerInterface.php
Normal file
8
src/Controller/ControllerInterface.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php namespace MapGuesser\Controller;
|
||||||
|
|
||||||
|
use MapGuesser\View\ViewBase;
|
||||||
|
|
||||||
|
interface ControllerInterface
|
||||||
|
{
|
||||||
|
public function run(): ViewBase;
|
||||||
|
}
|
28
src/Controller/GetNewPosition.php
Normal file
28
src/Controller/GetNewPosition.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php namespace MapGuesser\Controller;
|
||||||
|
|
||||||
|
use MapGuesser\Util\Geo\Position;
|
||||||
|
use MapGuesser\View\JsonView;
|
||||||
|
use MapGuesser\View\ViewBase;
|
||||||
|
use mysqli;
|
||||||
|
|
||||||
|
class GetNewPosition implements ControllerInterface
|
||||||
|
{
|
||||||
|
public function run(): ViewBase
|
||||||
|
{
|
||||||
|
$mysql = new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
||||||
|
|
||||||
|
// demo map
|
||||||
|
$mapId = 1;
|
||||||
|
|
||||||
|
// using RAND() for the time being, could be changed in the future
|
||||||
|
$stmt = $mysql->prepare('SELECT lat, lng FROM places WHERE map_id=? ORDER BY RAND() LIMIT 1');
|
||||||
|
$stmt->bind_param("i", $mapId);
|
||||||
|
$stmt->execute();
|
||||||
|
$place = $stmt->get_result()->fetch_assoc();
|
||||||
|
|
||||||
|
$position = new Position($place['lat'], $place['lng']);
|
||||||
|
|
||||||
|
$data = ['position' => $position->toArray()];
|
||||||
|
return new JsonView($data);
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
use MapGuesser\Util\Geo\Bounds;
|
use MapGuesser\Util\Geo\Bounds;
|
||||||
use MapGuesser\Util\Geo\Position;
|
use MapGuesser\Util\Geo\Position;
|
||||||
|
use MapGuesser\View\HtmlView;
|
||||||
|
use MapGuesser\View\ViewBase;
|
||||||
use mysqli;
|
use mysqli;
|
||||||
|
|
||||||
class GuessController extends BaseController
|
class GuessController implements ControllerInterface
|
||||||
{
|
{
|
||||||
protected string $view = 'guess';
|
public function run(): ViewBase
|
||||||
|
|
||||||
protected function operate() : void
|
|
||||||
{
|
{
|
||||||
$mysql = new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
$mysql = new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ class GuessController extends BaseController
|
|||||||
$realPosition = new Position($place['lat'], $place['lng']);
|
$realPosition = new Position($place['lat'], $place['lng']);
|
||||||
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
||||||
|
|
||||||
$this->variables = compact('realPosition', 'bounds');
|
$data = compact('bounds');
|
||||||
|
return new HtmlView('guess', $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ class Bounds
|
|||||||
|
|
||||||
private bool $initialized = false;
|
private bool $initialized = false;
|
||||||
|
|
||||||
public static function createWithPosition(Position $position) : Bounds
|
public static function createWithPosition(Position $position): Bounds
|
||||||
{
|
{
|
||||||
$instance = new static();
|
$instance = new static();
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ class Bounds
|
|||||||
return $instance;
|
return $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function createDirectly(float $southLat, $westLng, $northLat, $eastLng) : Bounds
|
public static function createDirectly(float $southLat, $westLng, $northLat, $eastLng): Bounds
|
||||||
{
|
{
|
||||||
$instance = new static();
|
$instance = new static();
|
||||||
|
|
||||||
|
@ -21,11 +21,16 @@ class Position
|
|||||||
return $this->lng;
|
return $this->lng;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toJson(): string
|
public function toArray(): array
|
||||||
{
|
{
|
||||||
return json_encode([
|
return [
|
||||||
'lat' => $this->lat,
|
'lat' => $this->lat,
|
||||||
'lng' => $this->lng,
|
'lng' => $this->lng,
|
||||||
]);
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toJson(): string
|
||||||
|
{
|
||||||
|
return json_encode($this->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/View/HtmlView.php
Normal file
29
src/View/HtmlView.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php namespace MapGuesser\View;
|
||||||
|
|
||||||
|
class HtmlView extends ViewBase
|
||||||
|
{
|
||||||
|
private string $template;
|
||||||
|
|
||||||
|
public function __construct(string $template, array &$data = [])
|
||||||
|
{
|
||||||
|
$this->template = $template;
|
||||||
|
$this->data = &$data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function &render(): string
|
||||||
|
{
|
||||||
|
extract($this->data);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
require ROOT . '/views/' . $this->template . '.php';
|
||||||
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContentType(): string
|
||||||
|
{
|
||||||
|
return 'text/html';
|
||||||
|
}
|
||||||
|
}
|
21
src/View/JsonView.php
Normal file
21
src/View/JsonView.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace MapGuesser\View;
|
||||||
|
|
||||||
|
class JsonView extends ViewBase
|
||||||
|
{
|
||||||
|
public function __construct(array &$data = [])
|
||||||
|
{
|
||||||
|
$this->data = &$data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function &render(): string
|
||||||
|
{
|
||||||
|
$content = json_encode($this->data);
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContentType(): string
|
||||||
|
{
|
||||||
|
return 'application/json';
|
||||||
|
}
|
||||||
|
}
|
15
src/View/ViewBase.php
Normal file
15
src/View/ViewBase.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php namespace MapGuesser\View;
|
||||||
|
|
||||||
|
abstract class ViewBase
|
||||||
|
{
|
||||||
|
protected array $data;
|
||||||
|
|
||||||
|
public function &getData(): array
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function &render(): string;
|
||||||
|
|
||||||
|
abstract public function getContentType(): string;
|
||||||
|
}
|
@ -14,7 +14,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
var realPosition = <?= $realPosition->toJson() ?>;
|
|
||||||
var guessMapBounds = <?= $bounds->toJson() ?>;
|
var guessMapBounds = <?= $bounds->toJson() ?>;
|
||||||
</script>
|
</script>
|
||||||
<script src="static/js/mapguesser.js" async defer></script>
|
<script src="static/js/mapguesser.js" async defer></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user