KSvend Claude Happy commited on
Commit
b15c51f
·
1 Parent(s): 5c28888

fix: replace broken draw_rectangle with two-tap rectangle for mobile support

Browse files

draw_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>

Files changed (2) hide show
  1. frontend/index.html +1 -1
  2. 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">Draw rectangle</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 draw mode.
 
 
164
  */
165
  export function activateDrawRect() {
166
- if (!_draw) return;
167
- _draw.deleteAll();
168
- _draw.changeMode('draw_rectangle');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
  /**