MAPG-2 Init project MapGuesser
* add composer.json and basic environment * add basic classes * add basic map with JS and CSS (with demo functionality) * add files for docker-compose * add launch.json for Docker debug * add README
This commit is contained in:
commit
a61d2951d7
2
.env.example
Normal file
2
.env.example
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
DEV=true
|
||||||
|
GOOGLE_MAPS_JS_API_KEY=your_google_maps_js_api_key
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.env
|
||||||
|
vendor
|
14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Listen for XDebug in Docker",
|
||||||
|
"type": "php",
|
||||||
|
"request": "launch",
|
||||||
|
"port": 9000,
|
||||||
|
"pathMappings": {
|
||||||
|
"/var/www/mapguesser": "${workspaceRoot}",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# MapGuesser
|
||||||
|
|
||||||
|
This is the MapGuesser Application project.
|
||||||
|
|
||||||
|
License: GNU GPL 3.0
|
20
composer.json
Normal file
20
composer.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "esoko/mapguesser",
|
||||||
|
"type": "project",
|
||||||
|
"description": "MapGuesser Application",
|
||||||
|
"license": "GNU GPL 3.0",
|
||||||
|
"require": {
|
||||||
|
"vlucas/phpdotenv": "^4.1"
|
||||||
|
},
|
||||||
|
"require-dev": {},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MapGuesser\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-root-package-install": [
|
||||||
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
220
composer.lock
generated
Normal file
220
composer.lock
generated
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "29431cf83ee884f01ee954b1068c0ccc",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "phpoption/phpoption",
|
||||||
|
"version": "1.7.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/schmittjoh/php-option.git",
|
||||||
|
"reference": "4acfd6a4b33a509d8c88f50e5222f734b6aeebae"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/4acfd6a4b33a509d8c88f50e5222f734b6aeebae",
|
||||||
|
"reference": "4acfd6a4b33a509d8c88f50e5222f734b6aeebae",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^5.5.9 || ^7.0 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"bamarni/composer-bin-plugin": "^1.3",
|
||||||
|
"phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.7-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PhpOption\\": "src/PhpOption/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Johannes M. Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Graham Campbell",
|
||||||
|
"email": "graham@alt-three.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Option Type for PHP",
|
||||||
|
"keywords": [
|
||||||
|
"language",
|
||||||
|
"option",
|
||||||
|
"php",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"time": "2020-03-21T18:07:53+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-ctype",
|
||||||
|
"version": "v1.17.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
|
"reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
|
||||||
|
"reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-ctype": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.17-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Ctype\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gert de Pagter",
|
||||||
|
"email": "BackEndTea@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for ctype functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"ctype",
|
||||||
|
"polyfill",
|
||||||
|
"portable"
|
||||||
|
],
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2020-05-12T16:14:59+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vlucas/phpdotenv",
|
||||||
|
"version": "v4.1.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||||
|
"reference": "539bb6927c101a5605d31d11a2d17185a2ce2bf1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/539bb6927c101a5605d31d11a2d17185a2ce2bf1",
|
||||||
|
"reference": "539bb6927c101a5605d31d11a2d17185a2ce2bf1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^5.5.9 || ^7.0 || ^8.0",
|
||||||
|
"phpoption/phpoption": "^1.7.2",
|
||||||
|
"symfony/polyfill-ctype": "^1.9"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"bamarni/composer-bin-plugin": "^1.3",
|
||||||
|
"ext-filter": "*",
|
||||||
|
"ext-pcre": "*",
|
||||||
|
"phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-filter": "Required to use the boolean validator.",
|
||||||
|
"ext-pcre": "Required to use most of the library."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "4.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Dotenv\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Graham Campbell",
|
||||||
|
"email": "graham@alt-three.com",
|
||||||
|
"homepage": "https://gjcampbell.co.uk/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vance Lucas",
|
||||||
|
"email": "vance@vancelucas.com",
|
||||||
|
"homepage": "https://vancelucas.com/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
|
||||||
|
"keywords": [
|
||||||
|
"dotenv",
|
||||||
|
"env",
|
||||||
|
"environment"
|
||||||
|
],
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/GrahamCampbell",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2020-05-02T14:08:57+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": [],
|
||||||
|
"plugin-api-version": "1.1.0"
|
||||||
|
}
|
22
docker-compose.yml
Normal file
22
docker-compose.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: ./docker
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
volumes:
|
||||||
|
- .:/var/www/mapguesser
|
||||||
|
links:
|
||||||
|
- 'mariadb'
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:10.1
|
||||||
|
volumes:
|
||||||
|
- mysql:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
#TZ: Europe/Budapest
|
||||||
|
MYSQL_ROOT_PASSWORD: 'root'
|
||||||
|
MYSQL_DATABASE: 'mapguesser'
|
||||||
|
MYSQL_USER: 'mapguesser'
|
||||||
|
MYSQL_PASSWORD: 'mapguesser'
|
||||||
|
volumes:
|
||||||
|
mysql:
|
31
docker/Dockerfile
Normal file
31
docker/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
FROM ubuntu:focal
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
# Install Apache, PHP and further necessary packages
|
||||||
|
RUN apt update
|
||||||
|
RUN apt install -y curl git apache2 \
|
||||||
|
php-apcu php-xdebug php7.4-cli php7.4-fpm php7.4-mbstring php7.4-mysql php7.4-zip
|
||||||
|
|
||||||
|
# Configure tzdata
|
||||||
|
#RUN ln -fs /usr/share/zoneinfo/Europe/Budapest /etc/localtime
|
||||||
|
#RUN dpkg-reconfigure --frontend noninteractive tzdata
|
||||||
|
|
||||||
|
# Configure Apache with PHP
|
||||||
|
RUN mkdir -p /run/php
|
||||||
|
RUN a2enmod proxy_fcgi rewrite
|
||||||
|
RUN a2enconf php7.4-fpm
|
||||||
|
COPY configs/apache.conf /etc/apache2/sites-available/000-default.conf
|
||||||
|
RUN echo "xdebug.remote_enable = 1" >> /etc/php/7.4/mods-available/xdebug.ini
|
||||||
|
RUN echo "xdebug.remote_autostart = 1" >> /etc/php/7.4/mods-available/xdebug.ini
|
||||||
|
RUN echo "xdebug.remote_connect_back = 1" >> /etc/php/7.4/mods-available/xdebug.ini
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
COPY scripts/install-composer.sh install-composer.sh
|
||||||
|
RUN ./install-composer.sh
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
VOLUME /var/www/mapguesser
|
||||||
|
WORKDIR /var/www/mapguesser
|
||||||
|
|
||||||
|
ENTRYPOINT /usr/sbin/php-fpm7.4 -F & /usr/sbin/apache2ctl -DFOREGROUND
|
15
docker/configs/apache.conf
Normal file
15
docker/configs/apache.conf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName mapguesser-dev.ch
|
||||||
|
|
||||||
|
ServerAdmin webmaster@localhost
|
||||||
|
DocumentRoot /var/www/mapguesser/public
|
||||||
|
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
<Directory /var/www/mapguesser/public>
|
||||||
|
Options FollowSymLinks
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
17
docker/scripts/install-composer.sh
Executable file
17
docker/scripts/install-composer.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
EXPECTED_CHECKSUM="$(curl -s https://composer.github.io/installer.sig)"
|
||||||
|
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||||
|
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
|
||||||
|
|
||||||
|
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
|
||||||
|
then
|
||||||
|
>&2 echo 'ERROR: Invalid installer checksum'
|
||||||
|
rm composer-setup.php
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||||||
|
RESULT=$?
|
||||||
|
rm composer-setup.php
|
||||||
|
exit $RESULT
|
14
main.php
Normal file
14
main.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require 'vendor/autoload.php';
|
||||||
|
|
||||||
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
|
||||||
|
$dotenv->load();
|
||||||
|
|
||||||
|
if (!empty($_ENV['DEV'])) {
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
} else {
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
}
|
40
public/index.php
Normal file
40
public/index.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require '../main.php';
|
||||||
|
|
||||||
|
// demo position
|
||||||
|
$realPosition = new MapGuesser\Geo\Position(47.85239, 13.35101);
|
||||||
|
|
||||||
|
// demo bounds
|
||||||
|
$bounds = new MapGuesser\Geo\Bounds($realPosition);
|
||||||
|
$bounds->extend(new MapGuesser\Geo\Position(48.07683,7.35758));
|
||||||
|
$bounds->extend(new MapGuesser\Geo\Position(47.57496, 19.08077));
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>MapGuesser</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="static/css/mapguesser.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="panorama"></div>
|
||||||
|
<div id="guess">
|
||||||
|
<div id="guessMap"></div>
|
||||||
|
<div id="guessButtonContainer">
|
||||||
|
<button id="guessButton" disabled>Guess</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var realPosition = <?= $realPosition->toJson() ?>;
|
||||||
|
var guessMapBounds = <?= $bounds->toJson() ?>;
|
||||||
|
</script>
|
||||||
|
<script src="static/js/mapguesser.js" async defer></script>
|
||||||
|
<script src="https://maps.googleapis.com/maps/api/js?key=<?= $_ENV['GOOGLE_MAPS_JS_API_KEY'] ?>&callback=initialize" async defer></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
75
public/static/css/mapguesser.css
Normal file
75
public/static/css/mapguesser.css
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panorama {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guess {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 20px;
|
||||||
|
width: 250px;
|
||||||
|
height: 150px;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 2;
|
||||||
|
transition-property: width, height, opacity;
|
||||||
|
transition-duration: 0.1s;
|
||||||
|
transition-delay: 0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guess:hover {
|
||||||
|
width: 500px;
|
||||||
|
height: 350px;
|
||||||
|
opacity: 1.0;
|
||||||
|
transition-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guess #guessMap {
|
||||||
|
height: 115px;
|
||||||
|
width: 100%;
|
||||||
|
transition-property: height;
|
||||||
|
transition-duration: 0.1s;
|
||||||
|
transition-delay: 0.8s;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guess:hover #guessMap {
|
||||||
|
height: 315px;
|
||||||
|
transition-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guessButtonContainer {
|
||||||
|
margin-top: 5px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guessButton {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5e77aa;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guessButton:hover, #guessButton:focus {
|
||||||
|
background-color: #29457f;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#guessButton:disabled {
|
||||||
|
cursor: no-drop;
|
||||||
|
color: #dddddd;
|
||||||
|
background-color: #808080;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
108
public/static/js/mapguesser.js
Normal file
108
public/static/js/mapguesser.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
Math.deg2rad = function (deg) {
|
||||||
|
return deg * (this.PI / 180.0);
|
||||||
|
};
|
||||||
|
|
||||||
|
var Util = {
|
||||||
|
EARTH_RADIUS_IN_METER: 6371000,
|
||||||
|
|
||||||
|
calculateDistance: function (position1, position2) {
|
||||||
|
var lat1 = Math.deg2rad(position1.lat);
|
||||||
|
var lng1 = Math.deg2rad(position1.lng);
|
||||||
|
var lat2 = Math.deg2rad(position2.lat);
|
||||||
|
var lng2 = Math.deg2rad(position2.lng);
|
||||||
|
|
||||||
|
var latDelta = lat2 - lat1;
|
||||||
|
var lonDelta = lng2 - lng1;
|
||||||
|
|
||||||
|
var angle = 2 * Math.asin(
|
||||||
|
Math.sqrt(
|
||||||
|
Math.pow(Math.sin(latDelta / 2), 2) +
|
||||||
|
Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(lonDelta / 2), 2)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return angle * Util.EARTH_RADIUS_IN_METER;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var MapManipulator = {
|
||||||
|
rewriteGoogleLink: function () {
|
||||||
|
if (!googleLink) {
|
||||||
|
var anchors = document.getElementById('panorama').getElementsByTagName('a');
|
||||||
|
for (var i = 0; i < anchors.length; i++) {
|
||||||
|
var a = anchors[i];
|
||||||
|
if (a.href.indexOf('maps.google.com/maps') !== -1) {
|
||||||
|
googleLink = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
googleLink.title = 'Google Maps'
|
||||||
|
googleLink.href = 'https://maps.google.com/maps'
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var panorama;
|
||||||
|
var guessMap;
|
||||||
|
var guessMarker;
|
||||||
|
var googleLink;
|
||||||
|
|
||||||
|
function initialize() {
|
||||||
|
panorama = new google.maps.StreetViewPanorama(document.getElementById('panorama'), {
|
||||||
|
position: realPosition,
|
||||||
|
pov: {
|
||||||
|
heading: 34,
|
||||||
|
pitch: 10
|
||||||
|
},
|
||||||
|
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'), {
|
||||||
|
disableDefaultUI: true,
|
||||||
|
clickableIcons: false,
|
||||||
|
draggableCursor: 'crosshair'
|
||||||
|
});
|
||||||
|
|
||||||
|
guessMap.fitBounds(guessMapBounds);
|
||||||
|
|
||||||
|
guessMap.addListener('click', function (e) {
|
||||||
|
if (guessMarker) {
|
||||||
|
guessMarker.setPosition(e.latLng);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
guessMarker = new google.maps.Marker({
|
||||||
|
map: guessMap,
|
||||||
|
position: e.latLng,
|
||||||
|
draggable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('guessButton').disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('guessButton').onclick = function () {
|
||||||
|
if (!guessMarker) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var guessedPosition = guessMarker.getPosition();
|
||||||
|
var distance = Util.calculateDistance(realPosition, { lat: guessedPosition.lat(), lng: guessedPosition.lng() });
|
||||||
|
|
||||||
|
alert('You were ' + distance + 'm close!');
|
||||||
|
|
||||||
|
this.blur();
|
||||||
|
}
|
76
src/Geo/Bounds.php
Normal file
76
src/Geo/Bounds.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php namespace MapGuesser\Geo;
|
||||||
|
|
||||||
|
class Bounds
|
||||||
|
{
|
||||||
|
private float $southLat;
|
||||||
|
private float $westLng;
|
||||||
|
|
||||||
|
private float $northLat;
|
||||||
|
private float $eastLng;
|
||||||
|
|
||||||
|
private bool $initialized = false;
|
||||||
|
|
||||||
|
public function __construct(Position $position = null)
|
||||||
|
{
|
||||||
|
if ($position === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initialize($position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extend(Position $position): void
|
||||||
|
{
|
||||||
|
if (!$this->initialized) {
|
||||||
|
$this->initialize($position);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lat = $position->getLat();
|
||||||
|
$lng = $position->getLng();
|
||||||
|
|
||||||
|
if ($lat < $this->southLat) {
|
||||||
|
$this->southLat = $lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($lng < $this->westLng) {
|
||||||
|
$this->westLng = $lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($lat > $this->northLat) {
|
||||||
|
$this->northLat = $lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($lng > $this->eastLng) {
|
||||||
|
$this->eastLng = $lng;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toJson(): string
|
||||||
|
{
|
||||||
|
if (!$this->initialized) {
|
||||||
|
throw new \Exception("Bounds are not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode([
|
||||||
|
'south' => $this->southLat,
|
||||||
|
'west' => $this->westLng,
|
||||||
|
'north' => $this->northLat,
|
||||||
|
'east' => $this->eastLng,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function initialize(Position $position)
|
||||||
|
{
|
||||||
|
$lat = $position->getLat();
|
||||||
|
$lng = $position->getLng();
|
||||||
|
|
||||||
|
$this->northLat = $lat;
|
||||||
|
$this->westLng = $lng;
|
||||||
|
$this->southLat = $lat;
|
||||||
|
$this->eastLng = $lng;
|
||||||
|
|
||||||
|
$this->initialized = true;
|
||||||
|
}
|
||||||
|
}
|
31
src/Geo/Position.php
Normal file
31
src/Geo/Position.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php namespace MapGuesser\Geo;
|
||||||
|
|
||||||
|
class Position
|
||||||
|
{
|
||||||
|
private float $lat;
|
||||||
|
private float $lng;
|
||||||
|
|
||||||
|
public function __construct(float $lat, float $lng)
|
||||||
|
{
|
||||||
|
$this->lat = $lat;
|
||||||
|
$this->lng = $lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLat(): float
|
||||||
|
{
|
||||||
|
return $this->lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLng(): float
|
||||||
|
{
|
||||||
|
return $this->lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toJson(): string
|
||||||
|
{
|
||||||
|
return json_encode([
|
||||||
|
'lat' => $this->lat,
|
||||||
|
'lng' => $this->lng,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user