KSvend Claude Happy commited on
Commit ·
b15c51f
1
Parent(s): 5c28888
fix: replace broken draw_rectangle with two-tap rectangle for mobile support
Browse filesdraw_rectangle is not a built-in MapboxDraw mode and no plugin was loaded,
so rectangle drawing silently failed. Replaced with a two-tap approach:
first tap sets one corner, second tap sets the opposite corner. Works on
both touch (mobile) and click (desktop).
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- frontend/index.html +1 -1
- frontend/js/map.js +55 -4
frontend/index.html
CHANGED
|
@@ -210,7 +210,7 @@
|
|
| 210 |
<div class="form-group">
|
| 211 |
<label class="label">Draw on map</label>
|
| 212 |
<div class="draw-tools">
|
| 213 |
-
<button id="draw-rect-btn" class="draw-btn" type="button">
|
| 214 |
</div>
|
| 215 |
<div id="aoi-area-display" class="aoi-area-display" style="display:none;"></div>
|
| 216 |
</div>
|
|
|
|
| 210 |
<div class="form-group">
|
| 211 |
<label class="label">Draw on map</label>
|
| 212 |
<div class="draw-tools">
|
| 213 |
+
<button id="draw-rect-btn" class="draw-btn" type="button">Tap two corners</button>
|
| 214 |
</div>
|
| 215 |
<div id="aoi-area-display" class="aoi-area-display" style="display:none;"></div>
|
| 216 |
</div>
|
frontend/js/map.js
CHANGED
|
@@ -94,6 +94,7 @@ class BasemapToggle {
|
|
| 94 |
let _aoiMap = null;
|
| 95 |
let _draw = null;
|
| 96 |
let _onAoiChange = null; // callback(bbox | null)
|
|
|
|
| 97 |
|
| 98 |
/**
|
| 99 |
* Initialise the AOI draw map inside containerId.
|
|
@@ -160,12 +161,62 @@ function getAllCoords(geometry) {
|
|
| 160 |
}
|
| 161 |
|
| 162 |
/**
|
| 163 |
-
* Activate rectangle
|
|
|
|
|
|
|
| 164 |
*/
|
| 165 |
export function activateDrawRect() {
|
| 166 |
-
if (!
|
| 167 |
-
_draw.deleteAll();
|
| 168 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
}
|
| 170 |
|
| 171 |
/**
|
|
|
|
| 94 |
let _aoiMap = null;
|
| 95 |
let _draw = null;
|
| 96 |
let _onAoiChange = null; // callback(bbox | null)
|
| 97 |
+
let _rectFirstCorner = null; // [lon, lat] or null — for two-tap rectangle
|
| 98 |
|
| 99 |
/**
|
| 100 |
* Initialise the AOI draw map inside containerId.
|
|
|
|
| 161 |
}
|
| 162 |
|
| 163 |
/**
|
| 164 |
+
* Activate two-tap rectangle mode.
|
| 165 |
+
* First tap sets one corner, second tap sets the opposite corner.
|
| 166 |
+
* Works on both touch (mobile) and click (desktop).
|
| 167 |
*/
|
| 168 |
export function activateDrawRect() {
|
| 169 |
+
if (!_aoiMap) return;
|
| 170 |
+
if (_draw) _draw.deleteAll();
|
| 171 |
+
_rectFirstCorner = null;
|
| 172 |
+
_aoiMap.getCanvas().style.cursor = 'crosshair';
|
| 173 |
+
// Remove previous listener if any, then add fresh
|
| 174 |
+
_aoiMap.off('click', _onRectClick);
|
| 175 |
+
_aoiMap.on('click', _onRectClick);
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
function _onRectClick(e) {
|
| 179 |
+
const { lng, lat } = e.lngLat;
|
| 180 |
+
|
| 181 |
+
if (!_rectFirstCorner) {
|
| 182 |
+
// First tap — store corner
|
| 183 |
+
_rectFirstCorner = [lng, lat];
|
| 184 |
+
return;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
// Second tap — build rectangle from two corners
|
| 188 |
+
const [lon1, lat1] = _rectFirstCorner;
|
| 189 |
+
const lon2 = lng;
|
| 190 |
+
const lat2 = lat;
|
| 191 |
+
_rectFirstCorner = null;
|
| 192 |
+
_aoiMap.getCanvas().style.cursor = '';
|
| 193 |
+
_aoiMap.off('click', _onRectClick);
|
| 194 |
+
|
| 195 |
+
const minLon = Math.min(lon1, lon2);
|
| 196 |
+
const maxLon = Math.max(lon1, lon2);
|
| 197 |
+
const minLat = Math.min(lat1, lat2);
|
| 198 |
+
const maxLat = Math.max(lat1, lat2);
|
| 199 |
+
|
| 200 |
+
const feature = {
|
| 201 |
+
type: 'Feature',
|
| 202 |
+
geometry: {
|
| 203 |
+
type: 'Polygon',
|
| 204 |
+
coordinates: [[
|
| 205 |
+
[minLon, minLat],
|
| 206 |
+
[maxLon, minLat],
|
| 207 |
+
[maxLon, maxLat],
|
| 208 |
+
[minLon, maxLat],
|
| 209 |
+
[minLon, minLat],
|
| 210 |
+
]],
|
| 211 |
+
},
|
| 212 |
+
properties: {},
|
| 213 |
+
};
|
| 214 |
+
|
| 215 |
+
if (_draw) {
|
| 216 |
+
_draw.deleteAll();
|
| 217 |
+
_draw.add(feature);
|
| 218 |
+
_onDrawUpdate();
|
| 219 |
+
}
|
| 220 |
}
|
| 221 |
|
| 222 |
/**
|