Rearrange code, add some license headers, add app download modal
This commit is contained in:
parent
1def759b43
commit
84a72426dd
288
index.html
288
index.html
@ -1,6 +1,31 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<!--
|
||||||
|
Copyright 2021 Netsyms Technologies.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer in the documentation and/or other materials provided with
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
-->
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>FixPhrase</title>
|
<title>FixPhrase</title>
|
||||||
@ -8,6 +33,7 @@
|
|||||||
<link rel=“canonical” href=“https://fixphrase.com” />
|
<link rel=“canonical” href=“https://fixphrase.com” />
|
||||||
<link rel="stylesheet" href="https://static.netsyms.net/bootstrap/5/bootstrap.quartz.min.css" />
|
<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" />
|
<link rel="stylesheet" href="js/maplibre-gl/dist/mapbox-gl.css" />
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
<meta property="og:title" content="FixPhrase">
|
<meta property="og:title" content="FixPhrase">
|
||||||
<meta property="og:description" content="Describe and locate any place on Earth with just four words.">
|
<meta property="og:description" content="Describe and locate any place on Earth with just four words.">
|
||||||
<meta property="og:image" content="https://fixphrase.com/img/socialcard.png">
|
<meta property="og:image" content="https://fixphrase.com/img/socialcard.png">
|
||||||
@ -20,92 +46,6 @@
|
|||||||
<script src="js/maplibre-gl/dist/mapbox-gl.js"></script>
|
<script src="js/maplibre-gl/dist/mapbox-gl.js"></script>
|
||||||
<script src="js/map_maplibre.js"></script>
|
<script src="js/map_maplibre.js"></script>
|
||||||
<script src="js/map.js"></script>
|
<script src="js/map.js"></script>
|
||||||
<style>
|
|
||||||
|
|
||||||
body {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
.mapboxgl-ctrl-attrib, .mapboxgl-ctrl-attrib-inner a {
|
|
||||||
color: black !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-pills .nav-link {
|
|
||||||
background-color: rgba(50,50,50,0.7);
|
|
||||||
|
|
||||||
}
|
|
||||||
.nav-pills .nav-link.active {
|
|
||||||
background-color: rgba(0,0,0,0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
#page-container {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
.copyonclick {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.clicktext {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
@media (pointer:fine) {
|
|
||||||
.taptext {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.clicktext {
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Matomo -->
|
<!-- Matomo -->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -140,6 +80,9 @@
|
|||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
<ul class="navbar-nav ms-auto">
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#" data-bs-toggle="modal" data-bs-target="#appModal">Android/iOS App</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="https://source.netsyms.com/Netsyms/fixphrase.com/wiki/How-It-Works">How it Works</a>
|
<a class="nav-link" href="https://source.netsyms.com/Netsyms/fixphrase.com/wiki/How-It-Works">How it Works</a>
|
||||||
</li>
|
</li>
|
||||||
@ -191,141 +134,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<div class="modal fade" id="appModal" tabindex="-1" aria-labelledby="appModalLabel" aria-hidden="true">
|
||||||
window.onload = function () {
|
<div class="modal-dialog modal-lg">
|
||||||
$("#mapbox").css("height", "calc(100% - " + $("#map-style-switcher").css("height") + ")");
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="appModalLabel">Get the App</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
The FixPhrase app is easier to use than the website on small screens, and
|
||||||
|
adds easy sharing options for your location. It has a dark mode and extra
|
||||||
|
map styles, and is fully open source.
|
||||||
|
Your location doesn't leave your device and all calculations are done locally.
|
||||||
|
|
||||||
createMap();
|
<div>
|
||||||
|
<a class="btn btn-info m-1" href="https://play.google.com/store/apps/details?id=com.fixphrase.app">
|
||||||
|
Android (Google Play)
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-info m-1" href="https://apps.apple.com/us/app/fixphrase/id1598775970">
|
||||||
|
iPhone/iPad (App Store)
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-info m-1 btn-sm" href="https://repo.netsyms.com/">
|
||||||
|
F-Droid repository
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-info m-1 btn-sm" href="https://build.netsyms.net/job/FixPhrase%20App/">
|
||||||
|
Android (APK)
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-info m-1 btn-sm" href="https://source.netsyms.com/Netsyms/FixPhraseApp">
|
||||||
|
Source Code
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
var bgs = [
|
<script src="js/app.js"></script>
|
||||||
"dale-nibbe-GR09HcWwP-w-unsplash.jpg",
|
|
||||||
"hide-obara-VzWx1l2LuIA-unsplash.jpg",
|
|
||||||
"john-fowler-jcbq3qWpKoo-unsplash.jpg",
|
|
||||||
"mark-harpur-K2s_YE031CA-unsplash.jpg",
|
|
||||||
"renns-art-TXhxOXHN1EE-unsplash.jpg",
|
|
||||||
"solotravelgoals-7kLufxYoqWk-unsplash.jpg"
|
|
||||||
];
|
|
||||||
var bgimg = bgs[Math.floor(Math.random() * bgs.length)];
|
|
||||||
$("body").css("background-image", "url(./img/bg/" + bgimg + ")");
|
|
||||||
|
|
||||||
map.resize();
|
|
||||||
|
|
||||||
// Load style preference from cookie
|
|
||||||
var cookies = decodeURIComponent(document.cookie).split("; ");
|
|
||||||
cookies.forEach(val => {
|
|
||||||
if (val.indexOf("mapstyle") === 0) {
|
|
||||||
var style = val.substring(9);
|
|
||||||
setMapStyle(style);
|
|
||||||
$("#map-style-switcher a.nav-link").removeClass("active");
|
|
||||||
$("#map-style-switcher a.nav-link[data-style=" + style + "]").addClass("active");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on("click", ".copyonclick", function () {
|
|
||||||
var copyitem = $(this);
|
|
||||||
var copytext = copyitem.text();
|
|
||||||
if (copytext == "Copied to clipboard!") {
|
|
||||||
// prevent copying copied text if double-clicked
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
navigator.clipboard.writeText(copytext).then(() => {
|
|
||||||
copyitem.text("Copied to clipboard!");
|
|
||||||
setTimeout(function () {
|
|
||||||
copyitem.text(copytext);
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on("keypress", "#wordbox,#wordbox-mobile", function (e) {
|
|
||||||
if (e.which == 13) {
|
|
||||||
dolookup($(this).val());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#map-style-switcher").on("click", "a.nav-link", function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
$("#map-style-switcher a.nav-link").removeClass("active");
|
|
||||||
setMapStyle($(this).data("style"));
|
|
||||||
$(this).addClass("active");
|
|
||||||
|
|
||||||
// Save style preference in cookie
|
|
||||||
var date = new Date();
|
|
||||||
date.setTime(date.getTime() + (90 * 24 * 60 * 60 * 1000));
|
|
||||||
document.cookie = "mapstyle=" + $(this).data("style") + "; expires=" + date.toUTCString();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Read URL hash and try to parse it
|
|
||||||
window.addEventListener('hashchange', function () {
|
|
||||||
parseWindowHash();
|
|
||||||
}, false);
|
|
||||||
// Don't try to read hash until map is loaded, this prevents errors
|
|
||||||
var checkIfMapLoaded = function () {
|
|
||||||
if (map.isStyleLoaded()) {
|
|
||||||
parseWindowHash();
|
|
||||||
} else {
|
|
||||||
setTimeout(checkIfMapLoaded, 200);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
checkIfMapLoaded();
|
|
||||||
};
|
|
||||||
|
|
||||||
function dolookup(words) {
|
|
||||||
try {
|
|
||||||
words = words.trim().toLowerCase().replace(/\s+/g, ' ');
|
|
||||||
|
|
||||||
if (!/^[a-z ]+?$/i.test(words)) {
|
|
||||||
// Not a FixPhrase, run a search
|
|
||||||
$.getJSON("lookup.php", {
|
|
||||||
search: words
|
|
||||||
}, function (resp) {
|
|
||||||
if (resp.status == "OK") {
|
|
||||||
lookupAndShowCoords(resp.coords[0], resp.coords[1]);
|
|
||||||
} else {
|
|
||||||
alert("Error: " + resp.msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var coords = FixPhrase.decode(words);
|
|
||||||
|
|
||||||
showLocationPopup(coords[0], coords[1], coords[3], coords[2]);
|
|
||||||
$("#wordbox").val(coords[3]);
|
|
||||||
$("#wordbox-mobile").val(coords[3]);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseWindowHash() {
|
|
||||||
var hash = window.location.hash.substr(1);
|
|
||||||
if (/^-?[0-9]{1,2}\.?[0-9]*,-?[0-9]{1,3}\.?[0-9]*$/.test(hash)) {
|
|
||||||
var lat = hash.split(",")[0];
|
|
||||||
var lon = hash.split(",")[1];
|
|
||||||
lat = (Math.round(lat * 10000) / 10000);
|
|
||||||
lon = (Math.round(lon * 10000) / 10000);
|
|
||||||
lookupAndShowCoords(lat, lon);
|
|
||||||
} else if (/^[a-z]+\-[a-z]+\-?[a-z]+?\-?[a-z]+?$/.test(hash)) {
|
|
||||||
var words = hash.replaceAll("-", " ");
|
|
||||||
dolookup(words);
|
|
||||||
$("#wordbox").val(words);
|
|
||||||
$("#wordbox-mobile").val(words);
|
|
||||||
} else if (/^[a-z]+\ [a-z]+\ ?[a-z]+?\ ?[a-z]+?$/.test(decodeURI(hash))) {
|
|
||||||
var words = decodeURI(hash);
|
|
||||||
dolookup(words);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
160
js/app.js
Normal file
160
js/app.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 Netsyms Technologies.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer in the documentation and/or other materials provided with
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
$("#mapbox").css("height", "calc(100% - " + $("#map-style-switcher").css("height") + ")");
|
||||||
|
|
||||||
|
createMap();
|
||||||
|
|
||||||
|
var bgs = [
|
||||||
|
"dale-nibbe-GR09HcWwP-w-unsplash.jpg",
|
||||||
|
"hide-obara-VzWx1l2LuIA-unsplash.jpg",
|
||||||
|
"john-fowler-jcbq3qWpKoo-unsplash.jpg",
|
||||||
|
"mark-harpur-K2s_YE031CA-unsplash.jpg",
|
||||||
|
"renns-art-TXhxOXHN1EE-unsplash.jpg",
|
||||||
|
"solotravelgoals-7kLufxYoqWk-unsplash.jpg"
|
||||||
|
];
|
||||||
|
var bgimg = bgs[Math.floor(Math.random() * bgs.length)];
|
||||||
|
$("body").css("background-image", "url(./img/bg/" + bgimg + ")");
|
||||||
|
|
||||||
|
map.resize();
|
||||||
|
|
||||||
|
// Load style preference from cookie
|
||||||
|
var cookies = decodeURIComponent(document.cookie).split("; ");
|
||||||
|
cookies.forEach(val => {
|
||||||
|
if (val.indexOf("mapstyle") === 0) {
|
||||||
|
var style = val.substring(9);
|
||||||
|
setMapStyle(style);
|
||||||
|
$("#map-style-switcher a.nav-link").removeClass("active");
|
||||||
|
$("#map-style-switcher a.nav-link[data-style=" + style + "]").addClass("active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on("click", ".copyonclick", function () {
|
||||||
|
var copyitem = $(this);
|
||||||
|
var copytext = copyitem.text();
|
||||||
|
if (copytext == "Copied to clipboard!") {
|
||||||
|
// prevent copying copied text if double-clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navigator.clipboard.writeText(copytext).then(() => {
|
||||||
|
copyitem.text("Copied to clipboard!");
|
||||||
|
setTimeout(function () {
|
||||||
|
copyitem.text(copytext);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on("keypress", "#wordbox,#wordbox-mobile", function (e) {
|
||||||
|
if (e.which == 13) {
|
||||||
|
dolookup($(this).val());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#map-style-switcher").on("click", "a.nav-link", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$("#map-style-switcher a.nav-link").removeClass("active");
|
||||||
|
setMapStyle($(this).data("style"));
|
||||||
|
$(this).addClass("active");
|
||||||
|
|
||||||
|
// Save style preference in cookie
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime() + (90 * 24 * 60 * 60 * 1000));
|
||||||
|
document.cookie = "mapstyle=" + $(this).data("style") + "; expires=" + date.toUTCString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Read URL hash and try to parse it
|
||||||
|
window.addEventListener('hashchange', function () {
|
||||||
|
parseWindowHash();
|
||||||
|
}, false);
|
||||||
|
// Don't try to read hash until map is loaded, this prevents errors
|
||||||
|
var checkIfMapLoaded = function () {
|
||||||
|
if (map.isStyleLoaded()) {
|
||||||
|
parseWindowHash();
|
||||||
|
} else {
|
||||||
|
setTimeout(checkIfMapLoaded, 200);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
checkIfMapLoaded();
|
||||||
|
};
|
||||||
|
|
||||||
|
function dolookup(words) {
|
||||||
|
try {
|
||||||
|
words = words.trim().toLowerCase().replace(/\s+/g, ' ');
|
||||||
|
|
||||||
|
if (!/^[a-z ]+?$/i.test(words)) {
|
||||||
|
// Not a FixPhrase, run a search
|
||||||
|
$.getJSON("lookup.php", {
|
||||||
|
search: words
|
||||||
|
}, function (resp) {
|
||||||
|
if (resp.status == "OK") {
|
||||||
|
lookupAndShowCoords(resp.coords[0], resp.coords[1]);
|
||||||
|
} else {
|
||||||
|
alert("Error: " + resp.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var coords = FixPhrase.decode(words);
|
||||||
|
|
||||||
|
showLocationPopup(coords[0], coords[1], coords[3], coords[2]);
|
||||||
|
$("#wordbox").val(coords[3]);
|
||||||
|
$("#wordbox-mobile").val(coords[3]);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseWindowHash() {
|
||||||
|
var hash = window.location.hash.substr(1);
|
||||||
|
if (/^-?[0-9]{1,2}\.?[0-9]*,-?[0-9]{1,3}\.?[0-9]*$/.test(hash)) {
|
||||||
|
var lat = hash.split(",")[0];
|
||||||
|
var lon = hash.split(",")[1];
|
||||||
|
lat = (Math.round(lat * 10000) / 10000);
|
||||||
|
lon = (Math.round(lon * 10000) / 10000);
|
||||||
|
lookupAndShowCoords(lat, lon);
|
||||||
|
} else if (/^[a-z]+\-[a-z]+\-?[a-z]+?\-?[a-z]+?$/.test(hash)) {
|
||||||
|
var words = hash.replaceAll("-", " ");
|
||||||
|
dolookup(words);
|
||||||
|
$("#wordbox").val(words);
|
||||||
|
$("#wordbox-mobile").val(words);
|
||||||
|
} else if (/^[a-z]+\ [a-z]+\ ?[a-z]+?\ ?[a-z]+?$/.test(decodeURI(hash))) {
|
||||||
|
var words = decodeURI(hash);
|
||||||
|
dolookup(words);
|
||||||
|
}
|
||||||
|
}
|
29
lookup.php
29
lookup.php
@ -1,5 +1,31 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2021 Netsyms Technologies.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer in the documentation and/or other materials provided with
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
require_once __DIR__ . "/FixPhrase.lib.php";
|
require_once __DIR__ . "/FixPhrase.lib.php";
|
||||||
|
|
||||||
header("Access-Control-Allow-Origin: *");
|
header("Access-Control-Allow-Origin: *");
|
||||||
@ -60,6 +86,9 @@ try {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
} else if (!empty($_GET["search"])) {
|
} else if (!empty($_GET["search"])) {
|
||||||
|
/*
|
||||||
|
* Please don't access this API endpoint if forking the code. Substitute for a different API.
|
||||||
|
*/
|
||||||
$resp = file_get_contents("https://data.netsyms.net/v1/gis/geocode/?address=" . urlencode($_GET["search"]));
|
$resp = file_get_contents("https://data.netsyms.net/v1/gis/geocode/?address=" . urlencode($_GET["search"]));
|
||||||
$data = json_decode($resp, true);
|
$data = json_decode($resp, true);
|
||||||
|
|
||||||
|
109
style.css
Normal file
109
style.css
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 Netsyms Technologies.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer in the documentation and/or other materials provided with
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
.mapboxgl-ctrl-attrib, .mapboxgl-ctrl-attrib-inner a {
|
||||||
|
color: black !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-pills .nav-link {
|
||||||
|
background-color: rgba(50,50,50,0.7);
|
||||||
|
|
||||||
|
}
|
||||||
|
.nav-pills .nav-link.active {
|
||||||
|
background-color: rgba(0,0,0,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-container {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
.copyonclick {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.clicktext {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (pointer:fine) {
|
||||||
|
.taptext {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.clicktext {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user