diff --git a/FixPhrase.lib.php b/FixPhrase.lib.php index 71724e4..f208c7d 100644 --- a/FixPhrase.lib.php +++ b/FixPhrase.lib.php @@ -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]; } } diff --git a/index.html b/index.html index 7dc03a2..9afd0aa 100644 --- a/index.html +++ b/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("" + words + "
" + 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("" + words + "
" + 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("" + resp.words + "
" + 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("" + resp.words + "
" + 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); } diff --git a/index.html.php b/index.html.php new file mode 100644 index 0000000..d84e5c2 --- /dev/null +++ b/index.html.php @@ -0,0 +1,180 @@ + + + + + + FixPhrase + + + + + + + + + + + + + + + + + +
+
+
+ Locate any place on Earth with just four words. + TapClick the map to + get the unique phrase for that spot. Type a phrase into the search box to + pinpoint it on the map. +
+
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
+
+ + + + diff --git a/js/fixphrase.js b/js/fixphrase.js index cd5efe6..c530729 100644 --- a/js/fixphrase.js +++ b/js/fixphrase.js @@ -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", diff --git a/js/map.js b/js/map.js index d0e1cd0..85c92c0 100644 --- a/js/map.js +++ b/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'); + } } \ No newline at end of file diff --git a/js/map_maplibre.js b/js/map_maplibre.js index 5e5c7b8..1695d99 100644 --- a/js/map_maplibre.js +++ b/js/map_maplibre.js @@ -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("" + words + "
" + (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("" + resp.words + "
" + resp.coords[0] + ", " + resp.coords[1]); + popup.setLngLat(e.lngLat); + popup.setHTML("" + resp.words + "
" + (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) + }); }); });