Make new algorithm that allows using three words, draw accuracy on map
This commit is contained in:
parent
4614f9fbac
commit
348f62a5c3
@ -7661,11 +7661,16 @@ class FixPhrase {
|
||||
$lon = str_pad($lon, 7, "0", STR_PAD_LEFT);
|
||||
|
||||
// Split up coordinates into chunks, add offsets so no two words will be the same and order won't matter
|
||||
$lat1dec = (int) substr($lat, 0, 4);
|
||||
$lon1dec = (int) substr($lon, 0, 4);
|
||||
$latlon2dec = (int) (substr($lat, 4, 2) . substr($lon, 4, 1));
|
||||
$latlon4dec = (int) (substr($lat, 6, 1) . substr($lon, 5, 2));
|
||||
|
||||
$groups = [
|
||||
(int) substr($lat, 0, 4) + 0,
|
||||
((int) substr($lon, 0, 4)) + 2000,
|
||||
((int) substr($lat, 4, 3)) + 5610,
|
||||
((int) substr($lon, 4, 3)) + 6610
|
||||
$lat1dec + 0,
|
||||
$lon1dec + 2000,
|
||||
$latlon2dec + 5610,
|
||||
$latlon4dec + 6610
|
||||
];
|
||||
|
||||
return implode(" ", [self::WORDLIST[$groups[0]], self::WORDLIST[$groups[1]], self::WORDLIST[$groups[2]], self::WORDLIST[$groups[3]]]);
|
||||
@ -7707,18 +7712,43 @@ class FixPhrase {
|
||||
$lat = str_pad((string) $indexes[0], 4, "0", STR_PAD_LEFT);
|
||||
$lon = str_pad((string) $indexes[1], 4, "0", STR_PAD_LEFT);
|
||||
|
||||
// Get the last three digits of each coordinate
|
||||
// Get second decimal for latitude and longitude
|
||||
if ($indexes[2] != -1) {
|
||||
$divby = 100.0;
|
||||
$latlon2dec = str_pad((string) $indexes[2], 3, "0", STR_PAD_LEFT);
|
||||
$lat .= substr($latlon2dec, 0, 1);
|
||||
$lon .= substr($latlon2dec, 2, 1);
|
||||
}
|
||||
|
||||
// Get third and fourth latitude and fourth longitude
|
||||
if ($indexes[2] != -1 && $indexes[3] != -1) {
|
||||
$divby = 10000.0;
|
||||
$lat .= str_pad((string) $indexes[2], 3, "0", STR_PAD_LEFT);
|
||||
$lon .= str_pad((string) $indexes[3], 3, "0", STR_PAD_LEFT);
|
||||
$latlon4dec = str_pad((string) $indexes[3], 3, "0", STR_PAD_LEFT);
|
||||
$lat .= substr($latlon2dec, 1, 1) . substr($latlon4dec, 0, 1);
|
||||
$lon .= substr($latlon4dec, 1, 2);
|
||||
}
|
||||
|
||||
// Make them normal coordinates again with +/- and 0-90 or 0-180
|
||||
$latitude = round((((int) $lat) / $divby) - 90.0, 4);
|
||||
$longitude = round((((int) $lon) / $divby) - 180.0, 4);
|
||||
|
||||
return [$latitude, $longitude];
|
||||
switch ($divby) {
|
||||
case 10.0:
|
||||
$latitude += 0.05;
|
||||
$longitude += 0.05;
|
||||
$accuracy = 0.1;
|
||||
break;
|
||||
case 100.0:
|
||||
$latitude += 0.005;
|
||||
$longitude += 0.005;
|
||||
$accuracy = 0.01;
|
||||
break;
|
||||
case 10000.0:
|
||||
$accuracy = 0.0001;
|
||||
break;
|
||||
}
|
||||
|
||||
return [round($latitude, 4), round($longitude, 4), $accuracy];
|
||||
}
|
||||
|
||||
}
|
||||
|
55
index.html
55
index.html
@ -196,12 +196,30 @@
|
||||
words = words.trim().toLowerCase().replace(/\s+/g, ' ');
|
||||
var coords = FixPhrase.decode(words);
|
||||
|
||||
drawRectangle(
|
||||
coords[0] - (coords[2] / 2),
|
||||
coords[1] - (coords[2] / 2),
|
||||
coords[0] + (coords[2] / 2),
|
||||
coords[1] + (coords[2] / 2)
|
||||
);
|
||||
|
||||
location.hash = "#map";
|
||||
new mapboxgl.Popup()
|
||||
.setLngLat({lat: coords[0], lng: coords[1]})
|
||||
.setHTML("<b>" + words + "</b><br>" + coords[0] + ", " + coords[1])
|
||||
.addTo(map);
|
||||
map.animateMapIn(coords[0], coords[1], 18);
|
||||
$('.mapboxgl-popup').remove();
|
||||
var popup = new mapboxgl.Popup()
|
||||
popup.on('close', clearRectangle);
|
||||
popup.setLngLat({lat: coords[0], lng: coords[1]});
|
||||
popup.setHTML("<b>" + words + "</b><br>" + coords[0] + ", " + coords[1]);
|
||||
popup.addTo(map);
|
||||
var zoomlevel = 18;
|
||||
switch (coords[2]) {
|
||||
case 0.1:
|
||||
zoomlevel = 10;
|
||||
break;
|
||||
case 0.01:
|
||||
zoomlevel = 13;
|
||||
break;
|
||||
}
|
||||
map.animateMapIn(coords[0], coords[1], zoomlevel);
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
@ -214,11 +232,28 @@
|
||||
}, function (resp) {
|
||||
if (resp.status == "OK") {
|
||||
location.hash = "#map";
|
||||
new mapboxgl.Popup()
|
||||
.setLngLat({lat: resp.coords[0], lng: resp.coords[1]})
|
||||
.setHTML("<b>" + resp.words + "</b><br>" + resp.coords[0] + ", " + resp.coords[1])
|
||||
.addTo(map);
|
||||
map.animateMapIn(resp.coords[0], resp.coords[1], 18);
|
||||
drawRectangle(
|
||||
resp.coords[0] - (resp.coords[2] / 2),
|
||||
resp.coords[1] - (resp.coords[2] / 2),
|
||||
resp.coords[0] + (resp.coords[2] / 2),
|
||||
resp.coords[1] + (resp.coords[2] / 2)
|
||||
);
|
||||
$('.mapboxgl-popup').remove();
|
||||
var popup = new mapboxgl.Popup()
|
||||
popup.on('close', clearRectangle);
|
||||
popup.setLngLat({lat: resp.coords[0], lng: resp.coords[1]});
|
||||
popup.setHTML("<b>" + resp.words + "</b><br>" + resp.coords[0] + ", " + resp.coords[1]);
|
||||
popup.addTo(map);
|
||||
var zoomlevel = 18;
|
||||
switch (resp.coords[2]) {
|
||||
case 0.1:
|
||||
zoomlevel = 10;
|
||||
break;
|
||||
case 0.01:
|
||||
zoomlevel = 13;
|
||||
break;
|
||||
}
|
||||
map.animateMapIn(resp.coords[0], resp.coords[1], zoomlevel);
|
||||
} else {
|
||||
alert(resp.msg);
|
||||
}
|
||||
|
180
index.html.php
Normal file
180
index.html.php
Normal file
@ -0,0 +1,180 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FixPhrase</title>
|
||||
<link rel="stylesheet" href="https://static.netsyms.net/bootstrap/5/bootstrap.quartz.min.css" />
|
||||
<link rel="stylesheet" href="js/maplibre-gl/dist/mapbox-gl.css" />
|
||||
<script src="https://static.netsyms.net/jquery/jquery.min.js"></script>
|
||||
<script src="https://static.netsyms.net/bootstrap/5/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/map.js"></script>
|
||||
<script src="js/maplibre-gl/dist/mapbox-gl.js"></script>
|
||||
<script src="js/map_maplibre.js"></script>
|
||||
<script src="js/map.js"></script>
|
||||
<style>
|
||||
|
||||
body {
|
||||
background-image: url(<?php
|
||||
$bgs = glob("img/bg/*.jpg");
|
||||
echo $bgs[array_rand($bgs, 1)];
|
||||
?>);
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) and (max-width: 1499px) {
|
||||
#page-container {
|
||||
padding-left: 10rem;
|
||||
padding-right: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1500px) {
|
||||
#page-container {
|
||||
padding-left: 15rem;
|
||||
padding-right: 15rem;
|
||||
}
|
||||
}
|
||||
|
||||
#mapcard {
|
||||
flex-grow: 9999;
|
||||
max-height: 90vh;
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
#mapbox .mapboxgl-user-location-dot, #mapbox .mapboxgl-user-location-accuracy-circle {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
padding: 1em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
|
||||
border-top-color: rgba(255, 255, 255, 0.4);
|
||||
border-width: 0.5rem 0.5rem 0;
|
||||
}
|
||||
.mapboxgl-popup-content {
|
||||
background-image: linear-gradient(125deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.3) 70%);
|
||||
box-shadow: inset 1px 1px rgba(255, 255, 255, 0.2), inset -1px -1px rgba(255, 255, 255, 0.1), 1px 3px 24px -1px rgba(0, 0, 0, 0.15);
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
background-clip: border-box;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#page-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.clicktext {
|
||||
display: none;
|
||||
}
|
||||
@media (pointer:fine) {
|
||||
.taptext {
|
||||
display: none;
|
||||
}
|
||||
.clicktext {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<!-- Matomo -->
|
||||
<script type="text/javascript">
|
||||
var _paq = window._paq = window._paq || [];
|
||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function () {
|
||||
var u = "https://analytics.netsyms.net/";
|
||||
_paq.push(['setTrackerUrl', u + 'matomo.php']);
|
||||
_paq.push(['setSiteId', '35']);
|
||||
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||
g.type = 'text/javascript';
|
||||
g.async = true;
|
||||
g.src = u + 'matomo.js';
|
||||
s.parentNode.insertBefore(g, s);
|
||||
})();
|
||||
</script>
|
||||
<!-- End Matomo Code -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href=".">FixPhrase</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://source.netsyms.com/Netsyms/fixphrase.com/src/branch/master/FixPhrase.lib.php">Open Source</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mw-100" id="page-container">
|
||||
<div class="card mb-2 mt-2 border-secondary">
|
||||
<div class="card-header text-dark">
|
||||
Locate any place on Earth with just four words.
|
||||
<span class="taptext">Tap</span><span class="clicktext">Click</span> the map to
|
||||
get the unique phrase for that spot. Type a phrase into the search box to
|
||||
pinpoint it on the map.
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="input-group d-none d-md-flex">
|
||||
<input class="form-control" type="text" placeholder="FixPhrase Words" id="wordbox"/>
|
||||
<button class="btn btn-secondary" onclick="dolookup($('#wordbox').val());">Find on Map</button>
|
||||
</div>
|
||||
<div class="d-grid d-md-none gap-2">
|
||||
<input class="form-control" type="text" placeholder="FixPhrase Words" id="wordbox-mobile"/>
|
||||
<button class="btn btn-secondary btn-block" onclick="dolookup($('#wordbox-mobile').val());">Find on Map</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 border-secondary" id="mapcard">
|
||||
<a name="map"></a>
|
||||
<div class="card-body p-2">
|
||||
<div id="mapbox" class="w-100 h-100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function () {
|
||||
createMap();
|
||||
};
|
||||
|
||||
function dolookup(words) {
|
||||
$.getJSON("lookup.php", {
|
||||
words: words
|
||||
}, function (resp) {
|
||||
if (resp.status == "OK") {
|
||||
location.hash = "#map";
|
||||
new mapboxgl.Popup()
|
||||
.setLngLat({lat: resp.coords[0], lng: resp.coords[1]})
|
||||
.setHTML("<b>" + resp.words + "</b><br>" + resp.coords[0] + ", " + resp.coords[1])
|
||||
.addTo(map);
|
||||
map.animateMapIn(resp.coords[0], resp.coords[1], 18);
|
||||
} else {
|
||||
alert(resp.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -45,12 +45,16 @@ var FixPhrase = {
|
||||
lon = ("0000000" + lon).slice(-7);
|
||||
|
||||
// Split up coordinates into chunks, add offsets so no two words will be the same and order won't matter
|
||||
var lat1dec = Number(lat.substring(0, 4));
|
||||
var lon1dec = Number(lon.substring(0, 4));
|
||||
var latlon2dec = Number(lat.substring(4, 6) + lon.substring(4, 5));
|
||||
var latlon4dec = Number(lat.substring(6, 7) + lon.substring(5, 7));
|
||||
|
||||
var groups = [
|
||||
Number(lat.substring(0, 4)),
|
||||
(Number(lon.substring(0, 4)) + 2000),
|
||||
(Number(lat.substring(4, 7)) + 5610),
|
||||
(Number(lon.substring(4, 7)) + 6610),
|
||||
lat1dec + 0,
|
||||
lon1dec + 2000,
|
||||
latlon2dec + 5610,
|
||||
latlon4dec + 6610
|
||||
];
|
||||
|
||||
return this.wordlist[groups[0]] + " " + this.wordlist[groups[1]] + " " + this.wordlist[groups[2]] + " " + this.wordlist[groups[3]];
|
||||
@ -91,16 +95,40 @@ var FixPhrase = {
|
||||
var lat = ("0000" + indexes[0]).slice(-4);
|
||||
var lon = ("0000" + indexes[1]).slice(-4);
|
||||
|
||||
// Get second decimal for latitude and longitude
|
||||
if (indexes[2] != -1) {
|
||||
divby = 100.0;
|
||||
var latlon2dec = ("000" + indexes[2]).slice(-3);
|
||||
lat += "" + latlon2dec.substring(0, 1);
|
||||
lon += "" + latlon2dec.substring(2, 3);
|
||||
}
|
||||
|
||||
// Get the last three digits of each coordinate
|
||||
if (indexes[2] != -1 && indexes[3] != -1) {
|
||||
divby = 10000.0;
|
||||
lat += ("000" + indexes[2]).slice(-3);
|
||||
lon += ("000" + indexes[3]).slice(-3);
|
||||
var latlon4dec = ("000" + indexes[3]).slice(-3);
|
||||
lat += "" + latlon2dec.substring(1, 2) + latlon4dec.substring(0, 1);
|
||||
lon += "" + latlon4dec.substring(1, 3);
|
||||
}
|
||||
|
||||
var latitude = Math.round(((Number(lat) / divby) - 90.0) * 10000) / 10000.0;
|
||||
var longitude = Math.round(((Number(lon) / divby) - 180.0) * 10000) / 10000.0;
|
||||
|
||||
return [latitude, longitude];
|
||||
var accuracy = 0.0001;
|
||||
switch (divby) {
|
||||
case 10.0:
|
||||
latitude += 0.05;
|
||||
longitude += 0.05;
|
||||
accuracy = 0.1;
|
||||
break;
|
||||
case 100.0:
|
||||
latitude += 0.005;
|
||||
longitude += 0.005;
|
||||
accuracy = 0.01;
|
||||
break;
|
||||
}
|
||||
|
||||
return [latitude, longitude, accuracy];
|
||||
},
|
||||
wordlist: [
|
||||
"abacus",
|
||||
|
47
js/map.js
47
js/map.js
@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
var map = null;
|
||||
|
||||
function createMap() {
|
||||
if (mapboxgl.supported()) {
|
||||
$("#mapbox").css("display", "");
|
||||
@ -32,13 +31,12 @@ function reloadMap() {
|
||||
map.off();
|
||||
map.remove();
|
||||
map = null;
|
||||
|
||||
createMap();
|
||||
} else {
|
||||
createMap();
|
||||
}
|
||||
} catch (ex) {
|
||||
// oh well ¯\(°_o)/¯
|
||||
// oh well ¯\(°_o)/¯
|
||||
console.log(ex);
|
||||
$("#mapbox").css("display", "none");
|
||||
}
|
||||
@ -62,4 +60,47 @@ function animateMapIn(latitude, longitude, zoom, heading) {
|
||||
heading = 0;
|
||||
}
|
||||
map.animateMapIn(latitude, longitude, zoom, heading);
|
||||
}
|
||||
|
||||
function drawRectangle(fromlat, fromlng, tolat, tolng) {
|
||||
var geojson = {
|
||||
'type': 'Feature',
|
||||
'geometry': {
|
||||
'type': 'Polygon',
|
||||
'coordinates': [
|
||||
[
|
||||
[fromlng, fromlat],
|
||||
[fromlng, tolat],
|
||||
[tolng, tolat],
|
||||
[tolng, fromlat],
|
||||
[fromlng, fromlat]
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
if (typeof map.getSource("rectangle") == "undefined") {
|
||||
map.addSource('rectangle', {
|
||||
'type': 'geojson',
|
||||
data: geojson
|
||||
});
|
||||
}
|
||||
if (typeof map.getLayer('rectangle') == "undefined") {
|
||||
map.addLayer({
|
||||
'id': 'rectangle',
|
||||
'type': 'fill',
|
||||
'source': 'rectangle',
|
||||
'layout': {},
|
||||
'paint': {
|
||||
'fill-color': '#088',
|
||||
'fill-opacity': 0.5
|
||||
}
|
||||
});
|
||||
}
|
||||
map.getSource("rectangle").setData(geojson);
|
||||
}
|
||||
|
||||
function clearRectangle() {
|
||||
if (typeof map.getLayer("rectangle") != "undefined") {
|
||||
map.removeLayer('rectangle');
|
||||
}
|
||||
}
|
@ -25,19 +25,20 @@ function maplibreMap() {
|
||||
|
||||
map.on('click', function (e) {
|
||||
var coordinates = e.lngLat;
|
||||
// Fix coordinates if map wrapped around
|
||||
while (coordinates.lng < -180) {
|
||||
coordinates.lng += 180;
|
||||
}
|
||||
while (coordinates.lng > 180) {
|
||||
coordinates.lng -= 180;
|
||||
}
|
||||
try {
|
||||
$('.mapboxgl-popup').remove();
|
||||
var words = FixPhrase.encode(coordinates.lat, coordinates.lng);
|
||||
var popup = new mapboxgl.Popup();
|
||||
popup.setLngLat(e.lngLat);
|
||||
popup.on('close', clearRectangle);
|
||||
popup.setHTML("<b><span class='copyonclick'>" + words + "</span></b><br>" + (Math.round(coordinates.lat * 10000) / 10000) + ", " + (Math.round(coordinates.lng * 10000) / 10000));
|
||||
popup.addTo(map);
|
||||
drawRectangle(
|
||||
coordinates.lat - (0.0001 / 2),
|
||||
coordinates.lng - (0.0001 / 2),
|
||||
coordinates.lat + (0.0001 / 2),
|
||||
coordinates.lng + (0.0001 / 2)
|
||||
);
|
||||
map.flyTo({
|
||||
center: e.lngLat,
|
||||
zoom: Math.max(map.getZoom(), 14)
|
||||
@ -52,10 +53,15 @@ function maplibreMap() {
|
||||
latitude: coordinates.lat,
|
||||
longitude: coordinates.lng
|
||||
}, function (resp) {
|
||||
$('.mapboxgl-popup').remove();
|
||||
var popup = new mapboxgl.Popup();
|
||||
popup.setLngLat(coordinates);
|
||||
popup.setHTML("<b>" + resp.words + "</b><br>" + resp.coords[0] + ", " + resp.coords[1]);
|
||||
popup.setLngLat(e.lngLat);
|
||||
popup.setHTML("<b><span class='copyonclick'>" + resp.words + "</span></b><br>" + (Math.round(resp.coords[0] * 10000) / 10000) + ", " + (Math.round(resp.coords[1] * 10000) / 10000));
|
||||
popup.addTo(map);
|
||||
map.flyTo({
|
||||
center: e.lngLat,
|
||||
zoom: Math.max(map.getZoom(), 14)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user