From a0b1e0eab466eb83fd3f4223d92155647fb625de Mon Sep 17 00:00:00 2001 From: Sanjay Bhangar Date: Sat, 9 Aug 2025 14:15:54 +0200 Subject: [PATCH] Here's what we've accomplished to fix MapLibre GL rectangle editing: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Core Issues Fixed: 1. MapLibre GL Event Compatibility: Fixed drag event handlers in MapMarker.js and MapRectangleMarker.js to use marker.getLngLat() instead of accessing e.lngLat properties that don't exist in MapLibre GL. 2. Rectangle Handle Visibility: Replaced Ox.MapMarkerImage() with proper DOM elements for corner handles since MapLibre GL expects DOM elements, not image objects. 3. Handle Positioning: Limited corner markers to only the 4 corners (ne, nw, se, sw) instead of all 8 positions (including edges). 4. Visual Rectangle Updates: Added that.rectangle.setBounds() call in MapRectangle update method so the visual rectangle updates when handles are dragged. 5. Click Event Conflicts: Fixed map click handler to detect rectangle clicks and avoid deselecting rectangles when clicked for editing. 6. Place Editable Property: Added editable: true as default in MapPlace constructor. Files Modified: - MapPlace.js: Added editable: true default - MapRectangle.js: - Limited markers to 4 corners only - Added rectangle bounds update in update() method - MapRectangleMarker.js: - Created proper DOM elements for handles - Fixed MapLibre GL drag event handling - Improved event cleanup - MapMarker.js: Fixed MapLibre GL drag event handling - MapMarkerImage.js: Fixed rectangle marker color (kept for backward compatibility) - Map.js: Added rectangle click detection to prevent conflicts Result: Rectangle editing now works completely: - Click rectangle → shows 4 corner handles - Drag handles → resizes rectangle in real-time - No console errors - Proper event handling --- source/UI/js/Map/Map.js | 12 ++++++ source/UI/js/Map/MapMarker.js | 6 ++- source/UI/js/Map/MapMarkerImage.js | 2 +- source/UI/js/Map/MapPlace.js | 1 + source/UI/js/Map/MapRectangle.js | 8 ++-- source/UI/js/Map/MapRectangleMarker.js | 54 ++++++++++++++------------ 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/source/UI/js/Map/Map.js b/source/UI/js/Map/Map.js index 47022935..aeb633f8 100644 --- a/source/UI/js/Map/Map.js +++ b/source/UI/js/Map/Map.js @@ -621,6 +621,18 @@ Ox.Map = function(options, self) { } function clickMap(event) { + // Check if click hit any rectangle fill layers (which have rectangle click handlers) + var features = self.map.queryRenderedFeatures(event.point, { + layers: self.map.getStyle().layers + .filter(layer => layer.id.includes('-fill')) + .map(layer => layer.id) + }); + + // If we clicked on a rectangle, don't process map click + if (features.length > 0) { + return; + } + var place = getSelectedPlace(); if (self.options.clickable/* && !editing()*/) { getPlaceByLatLng(event.lngLat, self.map.getBounds(), function(place) { diff --git a/source/UI/js/Map/MapMarker.js b/source/UI/js/Map/MapMarker.js index 446f7f31..b9eabc1f 100644 --- a/source/UI/js/Map/MapMarker.js +++ b/source/UI/js/Map/MapMarker.js @@ -121,13 +121,15 @@ Ox.MapMarker = function(options) { } function drag(e) { + // In MapLibre GL, get current position from marker directly + var lngLat = that.marker.getLngLat(); var northSouth = (that.place.north - that.place.south) / 2, lat = Ox.limit( - e.lngLat.lat, + lngLat.lat, Ox.MIN_LATITUDE + northSouth, Ox.MAX_LATITUDE - northSouth ), - lng = e.lngLat.lng, + lng = lngLat.lng, span = Math.min( that.place.sizeEastWest * Ox.getDegreesPerMeter(lat) / 2, 179.99999999 ), diff --git a/source/UI/js/Map/MapMarkerImage.js b/source/UI/js/Map/MapMarkerImage.js index 994e41e8..78946d40 100644 --- a/source/UI/js/Map/MapMarkerImage.js +++ b/source/UI/js/Map/MapMarkerImage.js @@ -30,7 +30,7 @@ Ox.MapMarkerImage = (function() { themeData = Ox.Theme.getThemeData(); if (!cache[index]) { - var color = options.rectangle ? [0, 0, 0, 0] + var color = options.rectangle ? [255, 255, 255, 1] : options.color.concat( [options.type == 'place' ? 0.75 : 0.25] ), diff --git a/source/UI/js/Map/MapPlace.js b/source/UI/js/Map/MapPlace.js index 2ca60622..a749f13c 100644 --- a/source/UI/js/Map/MapPlace.js +++ b/source/UI/js/Map/MapPlace.js @@ -23,6 +23,7 @@ Ox.MapPlace = function(options) { options = Ox.extend({ east: 0, + editable: true, editing: false, geoname: '', map: null, diff --git a/source/UI/js/Map/MapRectangle.js b/source/UI/js/Map/MapRectangle.js index c80c8b1d..387f0d89 100644 --- a/source/UI/js/Map/MapRectangle.js +++ b/source/UI/js/Map/MapRectangle.js @@ -211,9 +211,10 @@ Ox.MapRectangle = function(options) { that.rectangle.onclick = click /*@ - markers array of markers + markers array of markers (only corners for rectangle resizing) @*/ - that.markers = Ox.map(that.place.points, function(point, position) { + var cornerPositions = ['ne', 'nw', 'se', 'sw']; + that.markers = cornerPositions.map(function(position) { return new Ox.MapRectangleMarker({ map: that.map, place: that.place, @@ -224,7 +225,6 @@ Ox.MapRectangle = function(options) { setOptions(); function click(e) { - console.log('rectangle click', e) if ( that.map.options('editable') && that.place.editable @@ -313,6 +313,8 @@ Ox.MapRectangle = function(options) { that.update = function() { Ox.Log('Map', 'UPDATE...') setOptions(); + // Update the visual rectangle bounds + that.rectangle.setBounds(that.place.bounds); Ox.forEach(that.markers, function(marker) { marker.update(); }); diff --git a/source/UI/js/Map/MapRectangleMarker.js b/source/UI/js/Map/MapRectangleMarker.js index 8bf7cbb3..7074e0fc 100644 --- a/source/UI/js/Map/MapRectangleMarker.js +++ b/source/UI/js/Map/MapRectangleMarker.js @@ -37,30 +37,38 @@ Ox.MapRectangleMarker = function(options) { raiseOnDrag: false }); */ + // Create a simple DOM element for the corner handle + var element = document.createElement('div'); + element.style.width = '8px'; + element.style.height = '8px'; + element.style.backgroundColor = 'white'; + element.style.border = '2px solid black'; + element.style.borderRadius = '2px'; + element.style.cursor = that.position + '-resize'; + element.style.boxSizing = 'border-box'; + that.marker = new maplibregl.Marker({ - cursor: that.position + '-resize', draggable: true, - element: Ox.MapMarkerImage({ - mode: 'editing', - rectangle: true, - type: that.place.id[0] == '_' ? 'result' : 'place' - }), + element: element, }); that.marker.setLngLat(that.place.points[that.position]) function dragstart(e) { Ox.$body.addClass('OxDragging'); + // In MapLibre GL, get position from marker directly + var lngLat = that.marker.getLngLat(); that.drag = { - lat: e.lngLat.lat, - lng: e.lngLat.lng + lat: lngLat.lat, + lng: lngLat.lng }; } function drag(e) { // fixme: implement shift+drag (center stays the same) - Ox.Log('Map', e.pixel.x, e.pixel.y) - var lat = Ox.limit(e.lngLat.lat, Ox.MIN_LATITUDE, Ox.MAX_LATITUDE), - lng = e.lngLat.lng; + // In MapLibre GL, get current position from marker directly + var lngLat = that.marker.getLngLat(); + var lat = Ox.limit(lngLat.lat, Ox.MIN_LATITUDE, Ox.MAX_LATITUDE), + lng = lngLat.lng; that.drag = { lat: lat, lng: lng @@ -106,33 +114,29 @@ Ox.MapRectangleMarker = function(options) { that.marker.on('dragstart', dragstart); that.marker.on('drag', drag); that.marker.on('dragend', dragend); + return that; }; /*@ remove remove @*/ that.remove = function() { + // Clean up MapLibre events + that.marker.off('dragstart'); + that.marker.off('drag'); + that.marker.off('dragend'); + // Remove marker from map that.marker.remove(); - console.log("remove marker, fix events") - //google.maps.event.clearListeners(that.marker); + return that; }; /*@ update update @*/ that.update = function() { - var marker = new maplibregl.Marker({ - cursor: that.position + '-resize', - draggable: true, - element: Ox.MapMarkerImage({ - mode: 'editing', - rectangle: true, - type: that.place.id[0] == '_' ? 'result' : 'place' - }), - }); - marker.setLngLat(that.place.points[that.position]) - that.marker.remove() - that.marker = marker + // Just update position - visual stays the same during editing + that.marker.setLngLat(that.place.points[that.position]); + return that; }; return that; -- 2.39.5