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.

430 lines
13 KiB
HTML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{% extends "base.html" %}
{% block main %}
<div id="home_content">
<p id="position"></p>
<div class="compass">
<div class="arrow"></div>
<div class="compass-circle"><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 class="my-point"></div>
</div>
<!-- <h1 class="header" id="title">GEO</h1> -->
<div id="button_group">
<div id="distance_close">(distance to mosquito)</div>
<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>
<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>
<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>
</div>
</div>
<!-- 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-->
<div class="locations_popup">
{% for location in locations %}
<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 %}
</div>
</div>
{% endfor %}
</div>
{% endblock main %}
{% block js %}
<script>
var locations;
var zoom_level = 18;
var markerArray = [];
var circleArray = [];
var mosquitoArray = [];
var view="closest";
function assign_data(data) {
locations = data;
}
assign_data({{ data_locations|tojson }});
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);
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>'
}).addTo(map);
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],
});
}
var circle = L.marker([item.latitude, item.longitude], {icon: icon}).addTo(map).on("click", e => circleClick(e));
circle.id = item.id;
circleArray.push(circle);
markerArray.push(L.marker([item.latitude, item.longitude]));
if(item.loc_type=="mosquito") mosquitoArray.push(L.marker([item.latitude, item.longitude]));
} catch (error) {
console.error(error);
}
});
// var myPositionCircle = L.circle([48.172934, 9.01236], {
// color: 'red',
// stroke:false,
// fillColor: 'red',
// fillOpacity: 0.5,
// radius: 10
// }).addTo(map);
var myIcon = L.icon({
iconUrl: '/static/img/me.png',
iconSize: [50, 50],
iconAnchor: [25, 25],
popupAnchor: [-3, -76],
});
var myPositionCircle = L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
circleArray.push(myPositionCircle);
var x = document.getElementById("position");
let id;
let target;
let options;
//first: latitude, second: longitude
target = {
latitude : 48.172934,
longitude: 9.01236
};
var my_location = {
latitude : 0,
longitude: 0
};
function success(pos) {
const crd = pos.coords;
my_location.longitude = crd.longitude;
my_location.latitude = crd.latitude;
if(view == "closest") updateView()
console.log("updated")
x.innerHTML = "Latitude: " + crd.latitude +
"<br>Longitude: " + crd.longitude +
"<br>Distance to TENT: " + distance(target.longitude, target.latitude, crd.longitude, crd.latitude);
// 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"
}
return text;
}
/** Converts numeric degrees to radians */
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
function store_location(){
console.log("storing location");
console.log(my_location)
var xhr = new XMLHttpRequest();
xhr.open("POST", "./addlocation", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
longitude: my_location.longitude,
latitude: my_location.latitude
}));
xhr.onreadystatechange=function(){
if (xhr.readyState==4 && xhr.status==200){
location.reload();
}
}
}
function store_location_mosquito(){
console.log("storing location");
console.log(my_location)
var xhr = new XMLHttpRequest();
xhr.open("POST", "./addlocationmosquito", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
longitude: my_location.longitude,
latitude: my_location.latitude
}));
xhr.onreadystatechange=function(){
if (xhr.readyState==4 && xhr.status==200){
location.reload();
}
}
}
function add_text(){
window.location.href = "addtext?longitude="+ my_location.longitude +"&latitude="+my_location.latitude;
}
function add_audio(){
window.location.href = "addaudio?longitude="+ my_location.longitude +"&latitude="+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());
// L.polyline([closest.layer.getLatLng(), myPositionCircle.getLatLng()], {
// color: 'black',
// weight: 1,
// }).addTo(map)
document.getElementById("distance_close").innerHTML = "closest mosquito: " + distance(closest.layer.getLatLng().lat,closest.layer.getLatLng().lng,myPositionCircle.getLatLng().lat, myPositionCircle.getLatLng().lng)
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
}
document.getElementById(id).style.display = "block";
}
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(".compass-circle");
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);
}
}
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"));
}
}
function handler(e) {
compass = e.webkitCompassHeading || Math.abs(e.alpha - 360);
compassCircle.style.transform = `translate(-50%, -50%) rotate(${pointDegree-compass}deg)`;
// ±15 degree
// if (
// (pointDegree < Math.abs(compass) &&
// pointDegree + 15 > Math.abs(compass)) ||
// pointDegree > Math.abs(compass + 15) ||
// pointDegree < Math.abs(compass)
// ) {
// myPoint.style.opacity = 0;
// } else if (pointDegree) {
// myPoint.style.opacity = 1;
// }
}
function locationHandler(position) {
const { latitude, longitude } = position.coords;
pointDegree = calcDegreeToPoint(latitude, longitude);
if (pointDegree < 0) {
pointDegree = pointDegree + 360;
}
// compassCircle.style.transform = `translate(-50%, -50%) rotate(${-compass}deg)`;
}
function calcDegreeToPoint(latitude, longitude) {
// Qibla geolocation
var closest = L.GeometryUtil.closestLayer(map, mosquitoArray, myPositionCircle.getLatLng());
console.log(closest);
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();
startCompass();
</script>
{% endblock js %}