Merge branch 'geo' of https://git.xpub.nl/XPUB/XPPL into geo

geo
geoadmin 2 years ago
commit 6c7e6f0f60

@ -1,6 +1,6 @@
from flask_wtf import FlaskForm
from wtforms import StringField, FileField, validators
from wtforms.validators import InputRequired, DataRequired
from wtforms.validators import InputRequired, DataRequired, NumberRange
from wtforms import FieldList
from wtforms import Form as NoCsrfForm
from wtforms.fields import StringField, FormField, SubmitField, SelectField, RadioField
@ -14,17 +14,23 @@ from wtforms.widgets import TextArea
# # this forms is never exposed so we can use the non CSRF version
# author_name = StringField('Author Name', validators=[DataRequired()])
class UploadLocation(FlaskForm):
longitude = DecimalRangeField( 'longitude', [InputRequired(),NumberRange(min=1, message="Not valid coordinates")])
latitude = DecimalRangeField('latitude',[InputRequired(),NumberRange(min=1, message="Not valid coordinates")])
class UploadText(FlaskForm):
message = StringField('message', widget=TextArea(), default=None)
longitude = DecimalRangeField('longitude', default=0)
latitude = DecimalRangeField('latitude', default=0)
message = StringField('message', [InputRequired()], widget=TextArea(), default=None)
longitude = DecimalRangeField( 'longitude', [InputRequired(),NumberRange(min=1, message="Not valid coordinates")])
latitude = DecimalRangeField('latitude',[InputRequired(),NumberRange(min=1, message="Not valid coordinates")])
class UploadAudio(FlaskForm):
message = StringField('message', widget=TextArea(), default=None)
audio = FileField()
longitude = DecimalRangeField('longitude', default=0)
latitude = DecimalRangeField('latitude', default=0)
longitude = DecimalRangeField( 'longitude', [InputRequired(),NumberRange(min=1, message="Not valid coordinates")])
latitude = DecimalRangeField('latitude',[InputRequired(),NumberRange(min=1, message="Not valid coordinates")])

@ -1,5 +1,14 @@
@font-face {
font-family: 'metaaccanthisalternaalternate';
src: url('../fonts/metaaccanthisalternate-webfont.woff2') format('woff2'),
url('../fonts/metaaccanthisalternate-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
*{
font-family: "Helvetica";
font-family: "metaaccanthisalternaalternate";
box-sizing: border-box;
}
@ -12,7 +21,7 @@ body{
}
p{
font-size: 20px;
font-size: 1.5em;
}
a{
@ -97,7 +106,9 @@ audio{
}
.content_container{
padding: 1em;
}
/* FROM */
@ -250,7 +261,7 @@ margin: 4em 0;
display: inline-block;
top: 0;
font-size: 1em;
font-family: 'Courier New', Courier, monospace;
font-family: "metaaccanthisalternaalternate";
margin: 1em;
}
@ -263,7 +274,7 @@ margin: 4em 0;
}
#distance_close{
font-family: 'Courier New', Courier, monospace;
font-family: "metaaccanthisalternaalternate";
}
@ -271,19 +282,28 @@ margin: 4em 0;
#button_group button, #button_group select{
background-color: grey;
color: white;
font-size: 1em;
font-size: 0.9em;
border: 1px solid white;
border-radius: 2em;
padding: 0.8em;
padding: 0.6em;
vertical-align: middle;
margin-top: 0.5em;
cursor: pointer;
}
#button_group select option{
padding: 0;
#button_group select{
height:2.8em;
margin: 0;
padding-top: 0;
padding-bottom: 0;
}
#button_group select option{
vertical-align: middle;
margin: 0;
padding-top: 0;
padding-bottom: 0;
}
#button_group img{
@ -292,24 +312,37 @@ margin: 4em 0;
vertical-align: middle;
}
button[type="submit"]{
background-color: grey;
color: white;
font-size: 1em;
border: 1px solid white;
border-radius: 2em;
padding: 0.8em;
vertical-align: middle;
margin-top: 0.5em;
cursor: pointer;
}
/* COMPAS */
.compass {
position: relative;
width: 320px;
height: 320px;
width: 40vw;
height: 40vw;
border-radius: 50%;
/* box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); */
margin: auto;
pointer-events: none;
/* display: none; */
}
.compass > .compass-circle,
.compass > .my-point {
.compass > .arrow,
.compass > .compass-goal {
position: absolute;
width: 90%;
height: 90%;
@ -317,11 +350,14 @@ margin: 4em 0;
left: 50%;
transform: translate(-50%, -50%);
transition: transform 0.1s ease-out;
display: none;
pointer-events: none;
}
.compass > .compass-circle svg{
width: 100%;
height: 100%;
pointer-events: none;
}

@ -1,9 +1,14 @@
{% extends "base.html" %}
{% block main %}
<h1 class="page-header">About</h1>
<div style="width: 900px;">
<p>About</p>
<div class="content_container">
<h1 class="page-header">About</h1>
<div style="max-width: 900px;">
<p>This webpage is part of the projekt Hunting Mosquitos by Angeliki Diakrousi</p>
<p>
The site is running on a flask instance, storing data in a SQLite database. The location is tracked using the geolocation API. Audio is recorded through the WebAudio API.
</p>
</div>
</div>
{% endblock %}

@ -2,7 +2,7 @@
{% block main %}
{% from "_formhelpers.html" import render_field %}
<div class="content_container">
<h1 class="page-header">Add Audio</h1>
{% with messages = get_flashed_messages() %}
{% if messages %}
@ -16,7 +16,7 @@
{% endif %}
{% endwith %}
<form method="POST" action="{{ url_for('addaudio') }}" enctype=multipart/form-data>
<form method="POST" action="{{ url_for('addaudio', lng=longitude, lat=latitude) }}" enctype=multipart/form-data>
{{ form.csrf_token }}
<input type="hidden" name="longitude" value="{{ longitude }}" />
<input type="hidden" name="latitude" value="{{ latitude }}" />
@ -32,12 +32,17 @@
<input hidden="true" type="file" name="file" id="uploadedFile" accept="audio/*"><br>
<div style="width: 100%;">
message: <br>{{ form.message(class="form-control") }}
</div>
<!-- <div style="width: 100%;">
<br>{{ form.message(class="form-control") }}
</div> -->
{% block privacy_note_submit %}
{% include "privacy_note_submit.html" %}
{% endblock %}
<button type="submit">Submit</button>
</form>
</div>
<clear>
{% endblock main %}

@ -0,0 +1,31 @@
{% extends 'base.html' %}
{% block main %}
{% from "_formhelpers.html" import render_field %}
<div class="content_container">
<h1 class="page-header">Add Hangout</h1>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="alert alert-danger">
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endwith %}
{% block privacy_note_submit %}
{% include "privacy_note_submit.html" %}
{% endblock %}
<form method="POST" action="{{ url_for('add_hangout', lng=longitude, lat=latitude) }}" enctype=multipart/form-data>
{{ form.csrf_token }}
<input type="hidden" name="longitude" value="{{ longitude }}" />
<input type="hidden" name="latitude" value="{{ latitude }}" />
<button type="submit">Submit</button>
</form>
</div>
<clear>
{% endblock main %}

@ -0,0 +1,30 @@
{% extends 'base.html' %}
{% block main %}
{% from "_formhelpers.html" import render_field %}
<div class="content_container">
<h1 class="page-header">Add Mosquito</h1>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="alert alert-danger">
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endwith %}
{% block privacy_note_submit %}
{% include "privacy_note_submit.html" %}
{% endblock %}
<form method="POST" action="{{ url_for('add_mosquito', lng=longitude, lat=latitude) }}" enctype=multipart/form-data>
{{ form.csrf_token }}
<input type="hidden" name="longitude" value="{{ longitude }}" />
<input type="hidden" name="latitude" value="{{ latitude }}" />
<button type="submit">Submit</button>
</form>
</div>
<clear>
{% endblock main %}

@ -2,7 +2,7 @@
{% block main %}
{% from "_formhelpers.html" import render_field %}
<div class="content_container">
<h1 class="page-header">Add Message</h1>
{% with messages = get_flashed_messages() %}
{% if messages %}
@ -15,19 +15,19 @@
</div>
{% endif %}
{% endwith %}
<form method="POST" action="{{ url_for('addtext') }}" enctype=multipart/form-data>
<form method="POST" action="{{ url_for('addtext', lng=longitude, lat=latitude) }}" enctype=multipart/form-data>
{{ form.csrf_token }}
<input type="hidden" name="longitude" value="{{ longitude }}" />
<input type="hidden" name="latitude" value="{{ latitude }}" />
<div style="width: 100%;">
message: {{ form.message(class="form-control") }}
{{ form.message(class="form-control") }}
</div>
{% block privacy_note_submit %}
{% include "privacy_note_submit.html" %}
{% endblock %}
<button type="submit">Submit</button>
</form>
</form>
</div>
<clear>
{% endblock main %}

@ -1,7 +1,7 @@
<nav class="navigation">
<ul>
<li><a href="{{ url_for('home') }}">Home</a></li>
<li><a href="{{ url_for('list_locations') }}">List</a></li>
<li><a href="{{ url_for('privacy') }}">Privacy</a></li>
<li><a href="{{ url_for('about') }}">About</a></li>
</ul>
<div class="clearfix"></div>

@ -6,12 +6,11 @@
<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 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>
<button class="start-btn">Start compass</button>
<!-- <h1 class="header" id="title">GEO</h1> -->
@ -28,6 +27,9 @@
<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>
</div>
</div>
@ -63,6 +65,8 @@
var circleArray = [];
var mosquitoArray = [];
var view="closest";
var workingCompass = false;
var map_view = false;
function assign_data(data) {
locations = data;
@ -80,11 +84,24 @@
//scrollWheelZoom: false,
}).setView([48.505, 1.09], zoom_level);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
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>'
}).addTo(map);
})
function toggle_map(){
if(map_view){
map.removeLayer(backgroundLayer)
}
else{
map.addLayer(backgroundLayer)
}
map_view = !map_view
}
locations.forEach(function (item, index) {
try {
@ -235,48 +252,52 @@
}
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
}));
// 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();
// }
// }
window.location.href = "addhangout/"+ my_location.longitude +"/"+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
}));
// 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();
// }
// }
xhr.onreadystatechange=function(){
if (xhr.readyState==4 && xhr.status==200){
location.reload();
}
}
window.location.href = "addmosquito/"+my_location.longitude +"/"+my_location.latitude+"/";
}
function add_text(){
window.location.href = "addtext?longitude="+ my_location.longitude +"&latitude="+my_location.latitude;
window.location.href = "addtext/"+my_location.longitude +"/"+my_location.latitude+"/";
}
function add_audio(){
window.location.href = "addaudio?longitude="+ my_location.longitude +"&latitude="+my_location.latitude;
window.location.href = "addaudio/"+my_location.longitude +"/"+my_location.latitude+"/";
}
function updateView(){
@ -294,6 +315,7 @@
// 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));
}
@ -331,11 +353,8 @@
updateView()
}, true);
// COMPASS
const compassCircle = document.querySelector(".compass-circle");
const compassCircle = document.querySelector(".arrow");
const myPoint = document.querySelector(".my-point");
const startBtn = document.querySelector(".start-btn");
var compass;
@ -369,25 +388,15 @@
}
function handler(e) {
workingCompass = true;
if(workingCompass){
document.getElementById("arrow").style.display = "block";
}
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;
@ -396,15 +405,21 @@
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);
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";
}
}
const point = {
lat: closest.layer.getLatLng().lat,

@ -1,6 +1,7 @@
{% extends "base.html" %}
{% block main %}
<div class="content_container">
<div id="home_content">
<h2 class="header">Index</h2>
@ -23,7 +24,7 @@
{% endfor %}
</div>
</div>
</div>
{% endblock main %}
{% block js %}

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block main %}
<div class="content_container">
<h1 class="page-header">Privacy Statement</h1>
<div style="max-width: 900px;">
<p>Please note that all data submitted to this platform will be part of the exhibition.</p>
</div>
</div>
{% endblock %}

@ -0,0 +1,2 @@
<p>Are you sure you want to add <strong>{{ longitude }}, {{ latitude }}</strong> to the map?</p>
<p>Please note that all data submitted need to conform to the privacy statement. By submitting you agree that you have read and understood the statement. </p>

@ -14,7 +14,7 @@ from sqlalchemy.sql.expression import func, select
from sqlalchemy.sql import except_
from sqlalchemy.ext.serializer import loads, dumps
# from app.forms import UploadForm, EditForm, SearchForm, ChatForm, StackForm, AddtoStackForm, EditStackForm
from app.forms import UploadText, UploadAudio
from app.forms import UploadText, UploadAudio, UploadLocation
from app.models import Location, LocationSchema
from app.cover import get_cover
from app.getannot import get_annotations, get_annot_results, get_annot_book
@ -69,37 +69,54 @@ def list_locations():
def hello(name):
return "Hello " + name
@app.route('/test/<lng>/<lat>/', methods=['POST', 'GET'])
def test(lng, lat):
return lng +" " +lat
@app.route('/addlocation', methods=['POST', 'GET'])
def add_location():
@app.route('/addhangout/<float:lng>/<float:lat>/', methods=['POST', 'GET'])
def add_hangout(lng, lat):
upload_form = UploadLocation()
longitude =lng
latitude = lat
if request.method == 'POST':
data = request.get_json()
print("UPDATING DATA")
print(data['longitude'])
location = Location(data['longitude'],data['latitude'], "hangout", "", "")
if upload_form.validate_on_submit():
longitude = upload_form.longitude.data
latitude = upload_form.latitude.data
location = Location(longitude,latitude, "hangout", "", "");
db.session.add(location)
db.session.commit()
return redirect(url_for('home'))
@app.route('/addlocationmosquito', methods=['POST', 'GET'])
def add_location_mosquito():
flash_errors(upload_form)
return render_template('addhangout.html', form=upload_form, longitude=longitude, latitude=latitude)
@app.route('/addmosquito/<float:lng>/<float:lat>/', methods=['POST', 'GET'])
def add_mosquito(lng, lat):
upload_form = UploadLocation()
longitude =lng
latitude = lat
if request.method == 'POST':
data = request.get_json()
print("UPDATING DATA")
print(data['longitude'])
location = Location(data['longitude'],data['latitude'], "mosquito", "", "")
if upload_form.validate_on_submit():
longitude = upload_form.longitude.data
latitude = upload_form.latitude.data
location = Location(longitude,latitude, "mosquito", "", "");
db.session.add(location)
db.session.commit()
return redirect(url_for('home'))
flash_errors(upload_form)
return render_template('addmosquito.html', form=upload_form, longitude=longitude, latitude=latitude)
@app.route('/addtext', methods=['POST', 'GET'])
def addtext():
@app.route('/addtext/<float:lng>/<float:lat>/', methods=['POST', 'GET'])
def addtext(lng, lat):
upload_form = UploadText()
longitude = request.args.get('longitude')
latitude = request.args.get('latitude')
longitude = lng
latitude = lat
print(longitude)
print(latitude)
@ -113,14 +130,15 @@ def addtext():
db.session.add(location)
db.session.commit()
return redirect(url_for('home'))
flash_errors(upload_form)
return render_template('addtext.html', form=upload_form, longitude=longitude, latitude=latitude)
@app.route('/addaudio', methods=['POST', 'GET'])
def addaudio():
@app.route('/addaudio/<float:lng>/<float:lat>/', methods=['POST', 'GET'])
def addaudio(lng, lat):
upload_form = UploadAudio()
if request.method == 'GET':
longitude = request.args.get('longitude')
latitude = request.args.get('latitude')
longitude = lng
latitude = lat
if request.method == 'POST':
if upload_form.validate_on_submit():
@ -144,9 +162,15 @@ def addaudio():
db.session.add(location)
db.session.commit()
return redirect(url_for('home'))
flash_errors(upload_form)
return render_template('addaudio.html', form=upload_form, longitude=longitude, latitude=latitude)
@app.route('/privacy/')
def privacy():
"""Render the website's about page."""
return render_template('privacy.html')
@app.route('/about/')
def about():
"""Render the website's about page."""

Loading…
Cancel
Save