You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

415 lines
12 KiB
HTML

7 years ago
{% extends "base.html" %}
{% block main %}
7 years ago
<div id="home_content">
2 years ago
<p id="position"></p>
2 years ago
2 years ago
<div class="compass">
<div id="arrow" class="arrow"><svg viewBox="0 0 25 25" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd"
clip-rule="evenodd">
<path class="st0" d="M13,2.6l6.2,7.5L20,9.5l-7.5-9L5,9.5l0.8,0.6L12,2.6v21.9h1C13,24.5,13,2.6,13,2.6z" /></svg>
</div>
<div id="goal" class="compass-goal"><svg id="Layer_2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.94 21.94">
<defs>
<style>
.cls-1 {
fill: #3fb800;
opacity: .3;
}
</style>
</defs>
<g id="Layer_1-2">
<circle class="cls-1" cx="10.97" cy="10.97" r="10.97" />
</g>
</svg></div>
<div class="my-point"></div>
</div>
2 years ago
2 years ago
<!-- <h1 class="header" id="title">GEO</h1> -->
2 years ago
<div id="button_group">
2 years ago
<div id="distance_close">(distance to mosquito)</div>
2 years ago
<button id="store_location" onclick="store_location()"><img src="/static/img/hangout.png" alt="">add
hangout</button>
<button id="store_location_mosquito" onclick="store_location_mosquito()"><img src="/static/img/mosquito.png"
alt="">add mosquito</button>
2 years ago
<button id="add_text" onclick="add_text()"><img src="/static/img/text.png" alt="">add message</button>
<button id="add_audio" onclick="add_audio()"><img src="/static/img/audio.png" alt=""> add audio</button>
2 years ago
2 years ago
<select id="viewSelector" onchange="changeViewSelect()">
<option>Choose view</option>
<option value="all">show all entries</option>
<option value="closest">show closest mosquito</option>
<option value="me">my position</option>
</select>
<button class="start-btn">compass</button>
<button id="map_view" onclick="toggle_map()">map</button>
2 years ago
</div>
</div>
2 years ago
<!-- HEADING DIRECTION https://stackoverflow.com/questions/46033649/heading-javascript-geolocation -->
<!-- COMPASS CROSS DEVICE https://stackoverflow.com/questions/16048514/can-i-use-javascript-to-get-the-compass-heading-for-ios-and-android-->
2 years ago
2 years ago
<div class="locations_popup">
{% for location in locations %}
2 years ago
<div class="row" id={{location.id}}>
<div onclick="closeLocation()" class="close">×</div>
<div>{{location.longitude}}, {{location.latitude}}</div>
<div>{{location.message if location.loc_type == "message"}}</div>
<div>
{% if location.loc_type == "audio" %}
<audio id="audio-player" controls="" src="uploads/{{location.audio}}"></audio>
{% endif %}
2 years ago
</div>
2 years ago
</div>
2 years ago
{% endfor %}
</div>
{% endblock main %}
{% block js %}
<script>
2 years ago
var locations;
var zoom_level = 18;
var markerArray = [];
var circleArray = [];
var mosquitoArray = [];
var view = "me";
var workingCompass = false;
var map_view = false;
function assign_data(data) {
locations = data;
}
assign_data({
{
data_locations | tojson
}
2 years ago
});
var map = L.map('map', {
attributionControl: false,
zoomControl: false,
zoom: 2000,
zoomSnap: 0.5,
animate: true,
maxZoom: 19,
//dragging: false,
//scrollWheelZoom: false,
}).setView([48.505, 1.09], zoom_level);
var backgroundLayer = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
zoom: 2,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
})
function toggle_map() {
if (map_view) {
map.removeLayer(backgroundLayer)
} else {
map.addLayer(backgroundLayer)
}
2 years ago
map_view = !map_view
}
2 years ago
var myIcon = L.icon({
2 years ago
iconUrl: '/static/img/me.png',
2 years ago
iconSize: [30, 30],
iconAnchor: [15, 15],
2 years ago
popupAnchor: [-3, -76],
2 years ago
});
var myPositionCircle = L.marker([50.505, 30.57], {
icon: myIcon
}).addTo(map);
circleArray.push(myPositionCircle);
locations.forEach(function (item, index) {
try {
var icon;
if (item.loc_type == "message") {
icon = L.icon({
iconUrl: '/static/img/text.png',
iconSize: [50, 50],
iconAnchor: [25, 25],
popupAnchor: [-3, -76],
});
} else if (item.loc_type == "audio") {
icon = L.icon({
iconUrl: '/static/img/audio.png',
iconSize: [50, 50],
iconAnchor: [25, 25],
popupAnchor: [-3, -76],
});
} else if (item.loc_type == "mosquito") {
icon = L.icon({
iconUrl: '/static/img/mosquito.png',
iconSize: [50, 50],
iconAnchor: [25, 25],
popupAnchor: [-3, -76],
});
} else if (item.loc_type == "hangout") {
icon = L.icon({
iconUrl: '/static/img/hangout.png',
iconSize: [50, 50],
iconAnchor: [25, 25],
popupAnchor: [-3, -76],
});
2 years ago
}
2 years ago
var circle = L.marker([item.latitude, item.longitude], {
icon: icon
}).addTo(map).on("click", e => circleClick(e));
circle.id = item.id;
circleArray.push(circle);
2 years ago
markerArray.push(L.marker([item.latitude, item.longitude]));
2 years ago
if (item.loc_type == "mosquito") mosquitoArray.push(L.marker([item.latitude, item.longitude]));
} catch (error) {
console.error(error);
2 years ago
}
2 years ago
});
var x = document.getElementById("position");
let id;
let target;
let options;
//first: latitude, second: longitude 51.915528423609125, 4.477065873620031
target = {
latitude: 51.915528423609125,
longitude: 4.477065873620031
};
2 years ago
2 years ago
var my_location = {
latitude: 0,
longitude: 0
};
2 years ago
function success(pos) {
const crd = pos.coords;
my_location.longitude = crd.longitude;
my_location.latitude = crd.latitude;
updateView()
x.innerHTML = "Latitude: " + crd.latitude +
"<br>Longitude: " + crd.longitude +
"<br>Distance to TENT: " + distance(target.longitude, target.latitude, crd.longitude, crd.latitude);
locationHandler(pos);
// if we want to clear the watch
// if (target.latitude === crd.latitude && target.longitude === crd.longitude) {
// console.log('Congratulations, you reached the target');
// navigator.geolocation.clearWatch(id);
// }
}
function error(err) {
console.error(`ERROR(${err.code}): ${err.message}`);
console.log("trying again")
// id = navigator.geolocation.watchPosition(success, error, options);
}
options = {
enableHighAccuracy: true,
timeout: 1000,
maximumAge: 1000
};
id = navigator.geolocation.watchPosition(success, error, options);
function distance(lon1, lat1, lon2, lat2) {
var R = 6371; // Radius of the earth in km
var dLat = (lat2 - lat1).toRad(); // Javascript functions in radians
var dLon = (lon2 - lon1).toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
var text;
if (d < 1) {
text = Math.round(d * 100) / 100 * 1000 + " m";
} else {
text = Math.round(d * 100) / 100 + " km"
}
2 years ago
return text;
}
2 years ago
/** Converts numeric degrees to radians */
if (typeof (Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function () {
return this * Math.PI / 180;
}
2 years ago
}
2 years ago
2 years ago
function store_location() {
window.location.href = "addhangout/" + my_location.longitude + "/" + my_location.latitude + "/";
2 years ago
2 years ago
}
2 years ago
2 years ago
function store_location_mosquito() {
window.location.href = "addmosquito/" + my_location.longitude + "/" + my_location.latitude + "/";
}
function add_text() {
window.location.href = "addtext/" + my_location.longitude + "/" + my_location.latitude + "/";
}
function add_audio() {
window.location.href = "addaudio/" + my_location.longitude + "/" + my_location.latitude + "/";
}
function updateView() {
//update position on map
// map.setView([my_location.latitude, my_location.longitude], zoom_level);
myPositionCircle.setLatLng([my_location.latitude, my_location.longitude]);
if (view == "all") {
var group = new L.featureGroup(circleArray);
map.fitBounds(group.getBounds().pad(0.4));
} else if (view == "closest") {
var closest = L.GeometryUtil.closestLayer(map, mosquitoArray, myPositionCircle.getLatLng());
document.getElementById("distance_close").innerHTML = "closest mosquito: " + distance(closest.layer.getLatLng()
.lng, closest.layer.getLatLng().lat, myPositionCircle.getLatLng().lng, myPositionCircle.getLatLng().lat)
var group = new L.featureGroup([closest.layer, myPositionCircle]);
map.fitBounds(group.getBounds().pad(0.4));
} else if (view == "me") {
map.setView([my_location.latitude, my_location.longitude], zoom_level);
} else if (view == "free") {
}
}
function changeViewSelect() {
var mylist = document.getElementById("viewSelector");
view = mylist.options[mylist.selectedIndex].value;
updateView();
}
function circleClick(e) {
var id = e.target.id
var divsToHide = document.getElementsByClassName("row"); //divsToHide is an array
for (var i = 0; i < divsToHide.length; i++) {
divsToHide[i].style.display = "none"; // depending on what you're doing
2 years ago
}
2 years ago
document.getElementById(id).style.display = "block";
}
2 years ago
2 years ago
function closeLocation() {
var divsToHide = document.getElementsByClassName("row"); //divsToHide is an array
for (var i = 0; i < divsToHide.length; i++) {
divsToHide[i].style.display = "none"; // depending on what you're doing
}
}
window.addEventListener('resize', function (event) {
updateView()
}, true);
// COMPASS
const compassCircle = document.querySelector(".arrow");
const myPoint = document.querySelector(".my-point");
const startBtn = document.querySelector(".start-btn");
var compass;
var pointDegree;
const isIOS =
navigator.userAgent.match(/(iPod|iPhone|iPad)/) &&
navigator.userAgent.match(/AppleWebKit/);
function init() {
startBtn.addEventListener("click", startCompass);
// navigator.geolocation.getCurrentPosition(locationHandler);
if (!isIOS) {
window.addEventListener("deviceorientationabsolute", handler, true);
2 years ago
}
2 years ago
}
2 years ago
2 years ago
function startCompass() {
if (isIOS) {
DeviceOrientationEvent.requestPermission()
.then((response) => {
if (response === "granted") {
window.addEventListener("deviceorientation", handler, true);
} else {
alert("has to be allowed!");
}
})
.catch(() => alert("not supported"));
2 years ago
}
2 years ago
}
2 years ago
2 years ago
function handler(e) {
workingCompass = true;
if (workingCompass) {
document.getElementById("arrow").style.display = "block";
2 years ago
}
2 years ago
compass = e.webkitCompassHeading || Math.abs(e.alpha - 360);
compassCircle.style.transform = `translate(-50%, -50%) rotate(${pointDegree-compass}deg)`;
2 years ago
2 years ago
}
2 years ago
2 years ago
function locationHandler(position) {
2 years ago
2 years ago
const {
latitude,
longitude
} = position.coords;
pointDegree = calcDegreeToPoint(latitude, longitude);
2 years ago
2 years ago
if (pointDegree < 0) {
pointDegree = pointDegree + 360;
2 years ago
}
2 years ago
}
function calcDegreeToPoint(latitude, longitude) {
// Qibla geolocation
var closest = L.GeometryUtil.closestLayer(map, mosquitoArray, myPositionCircle.getLatLng());
if (workingCompass == true) {
if (parseFloat(distance(closest.layer.getLatLng().lat, closest.layer.getLatLng().lng, myPositionCircle.getLatLng()
.lat, myPositionCircle.getLatLng().lng).split(" ")) < 20) {
document.getElementById("arrow").style.display = "none";
document.getElementById("goal").style.display = "block";
} else {
document.getElementById("arrow").style.display = "block";
document.getElementById("goal").style.display = "none";
}
2 years ago
}
2 years ago
const point = {
lat: closest.layer.getLatLng().lat,
lng: closest.layer.getLatLng().lng
};
const phiK = (point.lat * Math.PI) / 180.0;
const lambdaK = (point.lng * Math.PI) / 180.0;
const phi = (latitude * Math.PI) / 180.0;
const lambda = (longitude * Math.PI) / 180.0;
const psi =
(180.0 / Math.PI) *
Math.atan2(
Math.sin(lambdaK - lambda),
Math.cos(phi) * Math.tan(phiK) -
Math.sin(phi) * Math.cos(lambdaK - lambda)
);
return Math.round(psi);
}
init();
//
</script>
{% endblock js %}