Changes based on user feedback

This commit is contained in:
Pieter Vander Vennet 2020-07-01 21:21:29 +02:00
parent 118a60c805
commit 1738fc4252
16 changed files with 342 additions and 64 deletions

View file

@ -26,7 +26,7 @@ export class Bos extends LayerDefinition {
];
this.maxAllowedOverlapPercentage = 10;
this.minzoom = 14;
this.minzoom = 13;
this.questions = [Quests.nameOf(this.name), Quests.accessNatureReserve, Quests.operator];
this.style = this.generateStyleFunction();
this.elementsToShow = [

View file

@ -22,6 +22,7 @@ export class KnownSet {
public startLat: number;
static allSets : any = {};
public welcomeTail: string;
constructor(
name: string,
@ -32,7 +33,8 @@ export class KnownSet {
startLon: number,
welcomeMessage: string,
gettingStartedPlzLogin: string,
welcomeBackMessage: string
welcomeBackMessage: string,
welcomeTail: string = ""
) {
this.title = title;
this.startLon = startLon;
@ -43,6 +45,7 @@ export class KnownSet {
this.welcomeMessage = welcomeMessage;
this.gettingStartedPlzLogin = gettingStartedPlzLogin;
this.welcomeBackMessage = welcomeBackMessage;
this.welcomeTail = welcomeTail;
KnownSet.allSets[this.name] = this;
}
@ -50,35 +53,49 @@ export class KnownSet {
static groen = new KnownSet("groen",
"Buurtnatuur",
[new NatureReserves(), new Park(), new Bos()],
14,
51.2,
3.2,
" <img src=\"assets/groen.svg\" alt=\"logo partij groen\" id=\"logo\"/>\n" +
10,
50.8435,
4.3688,
"\n" +
" <h3>Buurtnatuur meten</h3>\n" +
"\n" +
"\n" +
" Met deze tool willen we de natuur in Belgie beter inventariseren. <br/>\n" +
" In welke natuurgebieden kan men terecht?<br/>\n" +
" In welke bossen is het goed vertoeven?<br>\n" +
" <p>Natuur maakt immers gelukkig!</p>\n" +
"\n" +
"<p>De data komt van <b>OpenStreetMap</b> en je antwoorden worden daar ook opgeslaan. " +
"Omdat iedereen aan deze data bijdraagt, kunnen we geen garantie op correctheid bieden en heeft deze data geen juridische waarde</p>\n" +
"<p>Je <b>privacy</b> is belangrijk. We tellen wel hoeveel personen de website bezoeken. Om je niet dubbel te tellen wordt er één cookie bijgehouden waar geen persoonlijke informatie in staat. " +
"Als je inlogt, komt er een tweede cookie bij met je inloggegevens.</p>\n",
" <p>Wil je meehelpen? <br/>\n" +
" Begin dan met <a href=\"https://www.openstreetmap.org/user/new\" target=\"_blank\">een account\n" +
"<img src='assets/groen.svg' alt='logo-groen' class='logo'> <br />" +
"<h3>Breng jouw buurtnatuur in kaart</h3>" +
"<b>Natuur maakt gelukkig.</b> Aan de hand van deze website willen we de natuur dicht bij ons beter inventariseren. Met als doel meer mensen te laten genieten van toegankelijke natuur én te strijden voor meer natuur in onze buurten. \n" +
"<ul>" +
"<li>In welke natuurgebieden kan jij terecht? Hoe toegankelijk zijn ze?</li>" +
"<li>In welke bossen kan een gezin in jouw gemeente opnieuw op adem komen?</li>" +
"<li>Op welke onbekende plekjes is het zalig spelen?</li>" +
"</ul>" +
"<p>Samen kleuren we heel Vlaanderen en Brussel groen.</p>" +
"<p>Blijf op de hoogte van de resultaten van buurtnatuur.be: <a href=\"https://www.groen.be/buurtnatuur\" target='_blank'>meld je aan voor e-mailupdates</a>.</p> \n"
,
"<b>Begin meteen door <a href=\"https://www.openstreetmap.org/user/new\" target=\"_blank\">een account te maken\n" +
" te maken</a> of\n" +
" <span onclick=\"authOsm()\" class=\"activate-osm-authentication\">in te loggen</span>.</p>",
"Je bent aangemeld. Klik op een element om vragen te beantwoorden."
" <span onclick=\"authOsm()\" class=\"activate-osm-authentication\">in te loggen</span>.</b>",
"",
"<h4>Tips</h4>" +
"<ul>" +
"<li>Over groen ingekleurde gebieden weten we alles wat we willen weten.</li>" +
"<li>Bij rood ingekleurde gebieden ontbreekt nog heel wat info: klik een gebied aan en beantwoord de vragen.</li>" +
"<li>Je kan altijd een foto toevoegen</li>" +
"<li>Je kan ook zelf een gebied toevoegen door op de kaart te klikken</li>" +
"</ul>" +
"<small>" +
"<p>" +
"De oorspronkelijke data komt van <b>OpenStreetMap</b> en je antwoorden worden daar bewaard.<br/> Omdat iedereen vrij kan meewerken aan dit project, kunnen we niet garanderen dat er geen fouten opduiken." +
"</p>" +
"Je privacy is belangrijk. We tellen wel hoeveel gebruikers deze website bezoeken. We plaatsen een cookie waar geen persoonlijke informatie in bewaard wordt. " +
"Als je inlogt, komt er een tweede cookie bij met je inloggegevens." +
"</small>"
);
static openToiletMap = new KnownSet(
"toilets",
"Open Toilet Map",
[new Toilets()],
14,
12,
51.2,
3.2,

View file

@ -171,7 +171,7 @@ export class FilteredLayer {
let marker;
if (style.icon === undefined) {
marker = L.circle(latLng, {
radius: 50,
radius: 25,
color: style.color
});

View file

@ -1,16 +1,25 @@
import * as $ from "jquery"
import {UIEventSource} from "../UI/UIEventSource";
import {Basemap} from "./Basemap";
export class Geocoding {
private static readonly host = "https://nominatim.openstreetmap.org/search?";
static Search(query: string, currentLocation: UIEventSource<{ lat: number, lon: number }>,
handleResult: ((places: { display_name: string, lat: number, lon: number, boundingbox : number[] }[]) => void)) {
static Search(query: string,
basemap: Basemap,
handleResult: ((places: { display_name: string, lat: number, lon: number, boundingbox: number[] }[]) => void),
onFail: (() => void)) {
const b = basemap.map.getBounds();
console.log(b);
$.getJSON(
Geocoding.host + "format=json&accept-language=nl&q=" + query,
Geocoding.host + "format=json&limit=1&viewbox=" +
`${b.getEast()},${b.getNorth()},${b.getWest()},${b.getSouth()}`+
"&accept-language=nl&q=" + query,
function (data) {
handleResult(data);
}).fail(() => {
onFail();
});
}

View file

@ -71,7 +71,8 @@ export class LayerUpdater {
if (this.IsInBounds()) {
return;
}
if (this._map.map.getZoom() < this._minzoom) {
console.log("Zoom level: ",this._map.map.getZoom(), "Least needed zoom:", this._minzoom)
if (this._map.map.getZoom() < this._minzoom || this._map.Location.data.zoom < this._minzoom) {
console.log("Not running query: zoom not sufficient");
return;
}

View file

@ -144,6 +144,12 @@ export class OsmConnection {
}
public SetPreference(k:string, v:string) {
if (this.preferences.data[k] === v) {
return;
}
console.log("Updating preference", k, " to ", v);
this.preferences.data[k] = v;
this.preferences.ping();
this.auth.xhr({

View file

@ -44,6 +44,11 @@ export class Overpass {
console.log("Query failed")
onFail(status);
}
if(json.elements === [] && json.remarks.indexOf("runtime error") > 0){
console.log("Timeout or other runtime error");
return;
}
// @ts-ignore
const geojson = OsmToGeoJson.default(json);
continuation(geojson);

43
UI/Base/CollapseButton.ts Normal file
View file

@ -0,0 +1,43 @@
import {UIElement} from "../UIElement";
import {UIEventSource} from "../UIEventSource";
export class CollapseButton extends UIElement {
public isCollapsed = new UIEventSource(false);
constructor(idToCollapse: string) {
super(undefined);
this.ListenTo(this.isCollapsed);
this.isCollapsed.addCallback((collapse) => {
const el = document.getElementById(idToCollapse);
if (el === undefined || el === null) {
console.log("Element not found")
return;
}
if (collapse) {
el.style.height = "3.5em";
el.style.width = "15em";
} else {
el.style.height = "auto";
el.style.width = "auto";
}
});
const self = this;
this.onClick(() => {
self.isCollapsed.setData(!self.isCollapsed.data);
})
}
protected InnerRender(): string {
const up = './assets/arrow-up.svg';
const down = './assets/arrow-down.svg';
let arrow = up;
if (this.isCollapsed.data) {
arrow = down;
}
return `<img class='collapse-button' src='${arrow}' alt='collapse'>`;
}
}

View file

@ -36,7 +36,7 @@ export class QuestionPicker extends UIElement {
if (highestQ === undefined) {
return "";
return "Er zijn geen vragen meer!";
}
return "<div class='infobox-questions'>" +

View file

@ -1,16 +1,14 @@
import {UIElement} from "./UIElement";
import {TextField} from "./Base/TextField";
import {VariableUiElement} from "./Base/VariableUIElement";
import {UIEventSource} from "./UIEventSource";
import {FixedUiElement} from "./Base/FixedUiElement";
import {Geocoding} from "../Logic/Geocoding";
import {Basemap} from "../Logic/Basemap";
import {VerticalCombine} from "./Base/VerticalCombine";
export class SearchAndGo extends UIElement {
private _placeholder = new UIEventSource("Ga naar een locatie...")
private _placeholder = new UIEventSource("Zoek naar een locatie...")
private _searchField = new TextField(this._placeholder);
private _foundEntries = new UIEventSource([]);
@ -39,7 +37,12 @@ export class SearchAndGo extends UIElement {
this._searchField.Clear();
this._placeholder.setData("Bezig met zoeken...");
const self = this;
Geocoding.Search(searchString, undefined, (result) => {
Geocoding.Search(searchString, this._map, (result) => {
if (result.length == 0) {
this._placeholder.setData("Niets gevonden");
return;
}
const bb = result[0].boundingbox;
const bounds = [
@ -47,7 +50,10 @@ export class SearchAndGo extends UIElement {
[bb[1], bb[3]]
]
self._map.map.fitBounds(bounds);
this._placeholder.setData("Ga naar locatie...");
this._placeholder.setData("Zoek naar een locatie...");
},
() => {
this._placeholder.setData("Niets gevonden: er ging iets mis");
});
}

View file

@ -57,6 +57,7 @@ export abstract class UIElement {
element.onclick = () => {
self._onClick();
}
element.style.pointerEvents = "all";
element.style.cursor = "pointer";
}

76
assets/arrow-down.svg Normal file
View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
viewBox="0 0 26.458333 26.458334"
version="1.1"
id="svg8"
sodipodi:docname="arrow-down.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="-22.237738"
inkscape:cy="36.323203"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1680"
inkscape:window-height="1013"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<sodipodi:guide
position="13.229167,23.859748"
orientation="1,0"
id="guide815"
inkscape:locked="false" />
<sodipodi:guide
position="14.944824,13.229167"
orientation="0,1"
id="guide817"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-270.54165)">
<path
style="fill:none;stroke:#000000;stroke-width:3.59588718;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.599389,276.87373 c 0,0 -7.53922,13.79953 -10.36091,13.84843 -2.82169,0.0489 -10.3860703,-13.84843 -10.3860703,-13.84843"
id="path821"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

76
assets/arrow-up.svg Normal file
View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
viewBox="0 0 26.458333 26.458334"
version="1.1"
id="svg8"
sodipodi:docname="arrow-up.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="-22.237738"
inkscape:cy="36.323203"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1680"
inkscape:window-height="1013"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<sodipodi:guide
position="13.229167,23.859748"
orientation="1,0"
id="guide815"
inkscape:locked="false" />
<sodipodi:guide
position="14.944824,13.229167"
orientation="0,1"
id="guide817"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-270.54165)">
<path
style="fill:none;stroke:#000000;stroke-width:3.59588718;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 2.8524437,290.69991 c 0,0 7.5392203,-13.79953 10.3609103,-13.84843 2.82169,-0.0489 10.38607,13.84843 10.38607,13.84843"
id="path821"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -203,25 +203,46 @@ body {
pointer-events: none;
}
#welcomeMessage {
display: inline-block;
max-width: 30em;
padding: 0;
padding-bottom: 1em;
}
#messagesboxmobilewrapper {
display: none; /*Only shown on small screens*/
}
#welcomeMessage {
max-width: 35em;
padding: 0;
padding-top: 1em;
padding-bottom: 1em;
}
#collapseButton {
position: absolute;
right: 0;
background-color: white;
margin: 1.5em;
border: 2px solid black;
border-radius: 2em;
padding: 0.5em;
display: inline-block;
width: 1em;
height: 1em;
}
#collapseButton img {
width: 1em;
height: 1em;
}
#messagesbox-wrapper {
}
#messagesbox {
/*Only shown on big screens*/
padding: 2em;
padding-top: 1em;
padding-bottom: 1em;
z-index: 5000;
transition: all 500ms linear;
background-color: white;
border-radius: 2em;
pointer-events: all;
@ -229,6 +250,10 @@ body {
@media only screen and (max-width: 600px) {
#messagesbox-wrapper {
display: none;
}
#messagesbox {
display: none;
}
@ -525,6 +550,10 @@ body {
/***************** Info box (box containing features and questions ******************/
.leaflet-popup-content {
width: 25vw !important;
}
.featureinfobox {
}

View file

@ -30,7 +30,9 @@
<div id="searchbox"></div>
</div>
<br/>
<div id="messagesbox">
<div id="messagesbox-wrapper">
<div id="collapseButton"></div>
<div id="messagesbox"></div>
</div>
</div>

View file

@ -20,6 +20,7 @@ import {StrayClickHandler} from "./Logic/StrayClickHandler";
import {SimpleAddUI} from "./UI/SimpleAddUI";
import {VariableUiElement} from "./UI/Base/VariableUIElement";
import {SearchAndGo} from "./UI/SearchAndGo";
import {CollapseButton} from "./UI/Base/CollapseButton";
let dryRun = false;
@ -129,6 +130,8 @@ const addButtons: {
const flayers: FilteredLayer[] = []
let minZoom = 0;
for (const layer of questSetToRender.layers) {
const generateInfo = (tagsES) => {
@ -143,6 +146,8 @@ for (const layer of questSetToRender.layers) {
)
};
minZoom = Math.max(minZoom, layer.minzoom);
const flayer = layer.asLayer(bm, allElements, changes, osmConnection.userDetails, selectedElement,
generateInfo);
@ -156,7 +161,7 @@ for (const layer of questSetToRender.layers) {
flayers.push(flayer);
}
const layerUpdater = new LayerUpdater(bm, questSetToRender.startzoom, flayers);
const layerUpdater = new LayerUpdater(bm, minZoom, flayers);
// ------------------ Setup various UI elements ------------
@ -207,6 +212,8 @@ new UserBadge(osmConnection.userDetails, pendingChanges, bm)
new SearchAndGo(bm).AttachTo("searchbox");
new CollapseButton("messagesbox")
.AttachTo("collapseButton");
var welcomeMessage = () => {
return new VariableUiElement(
osmConnection.userDetails.map((userdetails) => {
@ -215,7 +222,7 @@ var welcomeMessage = () => {
login = questSetToRender.welcomeBackMessage;
}
return "<div id='welcomeMessage'>" +
questSetToRender.welcomeMessage + login +
questSetToRender.welcomeMessage + login + questSetToRender.welcomeTail+
"</div>";
}),
function () {
@ -229,7 +236,7 @@ welcomeMessage().AttachTo("messagesbox");
var messageBox = new MessageBoxHandler(leftMessage, () => {selectedElement.setData(undefined)});
new CenterMessageBox(
questSetToRender.startzoom,
minZoom,
centerMessage,
osmConnection,
locationControl,