Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix (map-generation, ui): avoid selecting invalid bboxes #285

Merged
merged 4 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
name: CSS-JavaScript-Linting

on: [push]

name: JS and CSS Linting
on: [push, pull_request]
jobs:
linting:
name: Run linters for CSS and JavaScript
name: JS and CSS Linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Linters
run: |
- uses: actions/checkout@v3
- name: Set up Linters
run: |
npm install [email protected]
npm install [email protected]
npm install [email protected]
npm install [email protected]
npm install [email protected]
- name: Run ESLint
run: npx eslint .
- name: Run Stylelint
run: npx stylelint "**/*.css"
- name: Run ESLint
run: npx eslint .
- name: Run Stylelint
run: npx stylelint "**/*.css"
3 changes: 2 additions & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Python Linting
on: [ push, pull_request ]
on: [push, pull_request]
jobs:
linting:
name: Python Linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down
13 changes: 11 additions & 2 deletions client-src/base/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,15 @@ body {
display: inline-block;
}

.infobox {
.infobox,
.warningbox {
position: relative;
padding-left: 3.5rem;
margin: 0.5rem 0;
}

.infobox::before {
.infobox::before,
.warningbox::before {
content: "i";
position: absolute;
width: 2rem;
Expand All @@ -101,6 +104,12 @@ body {
top: calc(50% - 1rem);
}

.warningbox::before {
content: "!";
background-color: var(--heigit-red);
color: white;
}

.github-icon {
display: inline-block;
position: relative;
Expand Down
47 changes: 32 additions & 15 deletions client-src/create/form.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { PAPER_FORMAT, ORIENTATION, Margin } from "@giscience/ol-print-layout-control";
import {
toLonLat, get as getProjection, transformExtent,
} from "ol/proj";
import { Margin, ORIENTATION, PAPER_FORMAT } from "@giscience/ol-print-layout-control";
import { get as getProjection, toLonLat, transformExtent } from "ol/proj";
import { SKETCH_MAP_MARGINS } from "./sketchMapMargins";
import { fillSelectOptions, setDisabled } from "../shared";
import { fillSelectOptions } from "../shared";

function bindFormToPrintLayoutControl(printLayoutControl) {
function bindFormToPrintLayoutControl(printLayoutControl, messageController) {
const paperFormats = { ...PAPER_FORMAT };
delete paperFormats.BROADSHEET;

Expand Down Expand Up @@ -81,15 +79,31 @@ function bindFormToPrintLayoutControl(printLayoutControl) {
// disable form submit and display info if zoom is lower than 9
function handleZoomChange(zoom) {
if (zoom < 9) {
setDisabled("next-button", true);
document.querySelector("#infobox")
.classList
.remove("invisible");
messageController.addWarning("zoom-info");
} else {
setDisabled("next-button", false);
document.querySelector("#infobox")
.classList
.add("invisible");
messageController.removeWarning("zoom-info");
}
}

function handleAntimeridian(bboxWgs84) {
// normalizeLon uses mathematic modulo like in R, not % symetric modulo like in Java
// or Javascript
const normalizeLon = (x) => ((((x + 180) % 360) + 360) % 360) - 180;

const antimeridianLayer = printLayoutControl.getMap()
.getLayers().getArray()
.find((l) => l.get("name") === "Antimeridian");

if (!bboxWgs84) return;
// check if antimeridian is within extent -> when left (x1) is bigger than right (x2)
const [left, , right] = bboxWgs84;

if (normalizeLon(left) > normalizeLon(right)) {
messageController.addWarning("antimeridian-info");
antimeridianLayer.setVisible(true);
} else {
messageController.removeWarning("antimeridian-info");
antimeridianLayer.setVisible(false);
}
}

Expand All @@ -98,6 +112,7 @@ function bindFormToPrintLayoutControl(printLayoutControl) {
.getView();
const initialZoom = view.getZoom();
handleZoomChange(initialZoom);
handleAntimeridian(printLayoutControl.getBboxAsLonLat());

// update form state on zoomchange
printLayoutControl.getMap()
Expand All @@ -114,10 +129,12 @@ function bindFormToPrintLayoutControl(printLayoutControl) {
document.querySelector("#page-setup-form").submit();
});

// update the URL when the selection is changed (e.g. to bookmark the current selection)
printLayoutControl.on("change:bbox", (event) => {
// update the URL when the selection is changed (e.g. to bookmark the current selection)
const newCenter = printLayoutControl.getMap().getView().getCenter();
window.history.replaceState({}, document.title, `?center=${newCenter}`);
// show warning and disable form if bbox crosses the antimeridian
handleAntimeridian(event.target.getBboxAsLonLat());
});
}

Expand Down
7 changes: 5 additions & 2 deletions client-src/create/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import "@kirtandesai/ol-geocoder/dist/ol-geocoder.css";
import "./geocoder.css";
import "./create.css";

import { createMap, addPrintLayoutControl, addGeocoderControl } from "./map.js";
import { addGeocoderControl, addPrintLayoutControl, createMap } from "./map.js";
import { bindFormToPrintLayoutControl } from "./form.js";
import { MessageController } from "./messageController";

// Retrieve potentially given map center from URL (e.g. from a bookmarked selection)
const searchParams = new URLSearchParams(window.location.search);
Expand All @@ -20,5 +21,7 @@ if (centerArg != null) {
const map = createMap("map", center, 15);

const printLayoutControl = addPrintLayoutControl(map);
bindFormToPrintLayoutControl(printLayoutControl);
const messageController = new MessageController();

bindFormToPrintLayoutControl(printLayoutControl, messageController);
addGeocoderControl(map);
46 changes: 45 additions & 1 deletion client-src/create/map.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,53 @@
import { Map, View } from "ol";
import { Feature, Map, View } from "ol";
import { Tile } from "ol/layer";
import { OSM } from "ol/source";
import Geocoder from "@kirtandesai/ol-geocoder";
import { PrintLayout, PAPER_FORMAT, ORIENTATION } from "@giscience/ol-print-layout-control";
import { fromLonLat } from "ol/proj";
import { LineString } from "ol/geom";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import {
Fill, Stroke, Style, Text,
} from "ol/style";
import { SKETCH_MAP_MARGINS } from "./sketchMapMargins.js";

function createAntiMeridianLayer() {
// Create a LineString feature
const lineString = new LineString([
fromLonLat([180, -90]), // Start point just to the east of the antimeridian
fromLonLat([180, 90]), // End point just to the west of the antimeridian
]);

// Create a vector source and add the LineString feature to it
const vectorSource = new VectorSource({
features: [new Feature({
geometry: lineString,
})],
});

// Create a vector layer and set the source
return new VectorLayer({
name: "Antimeridian",
source: vectorSource,
visible: false,
style: new Style({
stroke: new Stroke({
color: "red",
width: 3,
}),
text: new Text({
text: "Antimeridian",
placement: "line",
offsetY: -10,
fill: new Fill({ color: "red" }),
font: "20px sans-serif",
repeat: 200,
}),
}),
});
}

/**
* Creates an OpenLayers Map to an element
* @param {string} [target=map] - a div id where the map will be rendered
Expand All @@ -26,6 +69,7 @@ function createMap(target = "map", lonLat = [966253.1800856147, 6344703.99262965
new Tile({
source: new OSM(),
}),
createAntiMeridianLayer(),
],
});

Expand Down
28 changes: 28 additions & 0 deletions client-src/create/messageController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { setDisabled } from "../shared";

export class MessageController {
constructor() {
this.activeMessageIds = new Set();
}

addWarning(elementId) {
if (this.activeMessageIds.has(elementId)) return;

setDisabled("next-button", true);
document.querySelector(`#${elementId}`)
.classList
.remove("hidden");

this.activeMessageIds.add(elementId);
}

removeWarning(elementId) {
this.activeMessageIds.delete(elementId);
document.querySelector(`#${elementId}`)
.classList
.add("hidden");
if (this.activeMessageIds.size === 0) {
setDisabled("next-button", false);
}
}
}
15 changes: 12 additions & 3 deletions sketch_map_tool/templates/create.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,18 @@

<div id="right">
<div class="sketchy h1 center-text">Page Setup</div>
<article id="infobox" class="infobox invisible">Your Area of Interest is too large!
<br>Zoom further in to be able to create a Sketch Map.
</article>
<div id="message-container" class="" style="height: 11rem; overflow-y: scroll; padding: 1rem; ">
<article id="zoom-info" class="infobox hidden">Your Area of Interest is too large!
<br>Zoom further in to be able to create a Sketch Map.
</article>
<article id="antimeridian-info" class="infobox">You are currently trying to
request a map that crosses the +/-180° <a href="https://en.wikipedia.org/wiki/180th_meridian" target="_blank">antimeridian</a>. This is currently not
supported, please move the map such that your extent is either left or right of
the antimeridian.
</article>
</div>


<form id="page-setup-form" action="/create/results" method="post">
<label for="format">Paper Format</label>
<select id="format" name="format"></select>
Expand Down