diff --git a/code/frontend/src/components/interactive/BoxConditionMap.js b/code/frontend/src/components/interactive/BoxConditionMap.js index 90c0481..c755d4b 100644 --- a/code/frontend/src/components/interactive/BoxConditionMap.js +++ b/code/frontend/src/components/interactive/BoxConditionMap.js @@ -1,4 +1,4 @@ -import React, { useCallback, useState, useRef, useMemo } from "react" +import React, { useCallback, useState, useRef, useMemo, useEffect } from "react" import BoxFull from "../base/BoxFull" import {FontAwesomeIcon} from "@fortawesome/react-fontawesome" import { faMapPin, faPlus } from "@fortawesome/free-solid-svg-icons" @@ -10,9 +10,37 @@ import useRepositoryEditor from "../../hooks/useRepositoryEditor" import Condition from "../../utils/Condition" -const STARTING_POSITION = [41.89309, 12.48289] +const STARTING_POSITION = {lat: 41.89309, lng: 12.48289} const STARTING_ZOOM = 3 +// FIXME: this only works correctly at the equator! +/** + * https://wiki.openstreetmap.org/wiki/Zoom_levels + */ +const MPIXEL = [ + 156412, + 78206, + 39103, + 19551, + 9776, + 4888, + 2444, + 1222, + 610.984, + 305.492, + 152.746, + 76.373, + 38.187, + 19.093, + 9.547, + 4.773, + 2.387, + 1.193, + 0.596, + 0.298, + 0.149, +] + /** * A {@link BoxFull} that allows the user to select a geographical location to use to filter tweets. @@ -22,35 +50,56 @@ const STARTING_ZOOM = 3 * @constructor */ export default function BoxConditionMap({ ...props }) { - const [position, setPosition] = useState({lat: STARTING_POSITION[0], lng: STARTING_POSITION[1]}) + const [position, setPosition] = useState(STARTING_POSITION) + const [zoom, setZoom] = useState(STARTING_ZOOM) + const [map, setMap] = useState(null) const {addCondition} = useRepositoryEditor() - const markerRef = useRef(null) - const eventHandlers = useMemo( - () => ({ - dragend() { - const marker = markerRef.current - if (marker != null) { - const pos = marker.getLatLng() - console.debug("Changing marker position to: ", pos) - setPosition(pos) - } - }, - }), - [], + const onMove = useCallback( + () => { + setPosition(map.getCenter()) + }, + [map] + ) + + const onZoom = useCallback( + () => { + setZoom(map.getZoom()) + }, + [map] + ) + + useEffect( + () => { + if(map === null) return + + map.on("move", onMove) + map.on("zoom", onZoom) + return () => { + map.off("move", onMove) + map.off("zoom", onZoom) + } + }, + [map] ) const onButtonClick = () => { + const mapSize = map.getSize() + const minSize = Math.min(mapSize.x, mapSize.y) + const radius = minSize * MPIXEL[zoom] + addCondition(new Condition( "COORDINATES", - `WIP WIP ${position.lat.toFixed(6)} ${position.lng.toFixed(6)}` + `< ${radius} ${position.lat} ${position.lng}` )) - setPosition({lat: STARTING_POSITION[0], lng: STARTING_POSITION[1]}) + setPosition(STARTING_POSITION) } return ( Search by zone} + header={ + Search by zone + } childrenClassName={Style.BoxConditionMapContents} {...props} > @@ -58,19 +107,23 @@ export default function BoxConditionMap({ ...props }) { center={STARTING_POSITION} zoom={STARTING_ZOOM} className={Style.MapContainer} + whenCreated={setMap} > - +
+
+ +
+
-
) } diff --git a/code/frontend/src/components/interactive/BoxConditionMap.module.css b/code/frontend/src/components/interactive/BoxConditionMap.module.css index 27da2ec..dcb726c 100644 --- a/code/frontend/src/components/interactive/BoxConditionMap.module.css +++ b/code/frontend/src/components/interactive/BoxConditionMap.module.css @@ -8,4 +8,7 @@ flex-grow: 1; height: 300px; border-radius: 0 0 25px 25px; +} + +.Button { } \ No newline at end of file diff --git a/code/frontend/src/components/interactive/ConditionBadge.js b/code/frontend/src/components/interactive/ConditionBadge.js index 1d83182..896b705 100644 --- a/code/frontend/src/components/interactive/ConditionBadge.js +++ b/code/frontend/src/components/interactive/ConditionBadge.js @@ -38,6 +38,21 @@ export default function ConditionBadge({ ...condition }) { const icon = CONDITION_ICONS[type] const {removeRawCondition} = useContext(ContextRepositoryEditor) + let displayedContent = content + if(type === 3) { + let split = displayedContent.split(" ") + let type = split[0] + let radius = Number.parseFloat(split[1]).toFixed(0) + let radiusType = "m" + if(radius >= 2000) { + radius = Math.round(radius / 1000) + radiusType = "km" + } + let lat = Number(split[2]).toFixed(3) + let lng = Number(split[3]).toFixed(3) + displayedContent = `${split[0]} ${radius}${radiusType} ${lat} ${lng}` + } + return (
- {content} + {displayedContent}
{