Skip to content

Commit 5845b0d

Browse files
committed
Merge PR from @altheaFeu about selection from popup geometry for LWC 3.5 #77
1 parent 3d0506d commit 5845b0d

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/**
2+
* Add the select by geometry button for the given popup element
3+
*
4+
* @param {HTMLElement} featureToolbar The feature toolbar HTML element of the popup
5+
* @param {string} featureGeometry The geometry of the feature in WKT
6+
* @param {string} featureCrs The CRS of the geometry
7+
*/
8+
function addSelectionButton(featureToolbar, featureGeometry, featureCrs) {
9+
var featureToolbarDiv = featureToolbar.find('div.feature-toolbar');
10+
11+
// Get the button if it already exists
12+
const buttonValue = `${featureGeometry}@${featureCrs}`;
13+
14+
// Selection button HTML
15+
const selectionButtonHtml = `
16+
<button class="btn btn-mini popup-select-by-geometry" value="${buttonValue}" type="button" data-original-title="Selection" title="Selection">
17+
<i class="icon-star"></i>
18+
&nbsp;
19+
</button>
20+
`;
21+
22+
// Check if the button already exists
23+
const existingButton = featureToolbarDiv.find(`button.popup-select-by-geometry[value="${buttonValue}"]`);
24+
if (existingButton.length > 0) {
25+
return false;
26+
}
27+
28+
// Append the button to the toolbar
29+
featureToolbarDiv.append(selectionButtonHtml);
30+
// Trigger the action when clicking on button
31+
featureToolbarDiv.on('click', `button.popup-select-by-geometry[value="${buttonValue}"]`, popupSelectionButtonClickHandler);
32+
}
33+
34+
35+
/**
36+
* Function which wait for te given ms before returning the promise
37+
*
38+
* @param {integer} time - The time in milliseconds
39+
*
40+
*/
41+
function delay(time) {
42+
return new Promise(resolve => setTimeout(resolve, time));
43+
}
44+
45+
/**
46+
* Reacts to the click on a popup select by geometry/
47+
*
48+
* @param event The event triggered on the button click
49+
*/
50+
function popupSelectionButtonClickHandler(event) {
51+
// Only go on when the button has been clicked
52+
// not the child <i> icon
53+
let target = $(event.target);
54+
if (!target.is('.popup-select-by-geometry')) {
55+
target = target.parent();
56+
}
57+
58+
// Get the button which triggered the click event
59+
const button = target;
60+
const value = button.val();
61+
const wkt = value.split('@')[0];
62+
const featureToolbar = button.closest('lizmap-feature-toolbar');
63+
const featureToolbarValue = featureToolbar.attr('value');
64+
65+
// check geometry type
66+
let isPolygon = (wkt.toUpperCase().indexOf('POLYGON') !== -1);
67+
let isLinestring = (wkt.toUpperCase().indexOf('LINE') !== -1);
68+
let isPoint = (wkt.toUpperCase().indexOf('POINT') !== -1);
69+
70+
// Create a temporary layer from the WKT
71+
const temporaryVector = new OpenLayers.Layer.Vector("Vector Layer");
72+
// Convert WKT as a geometry
73+
const format = new OpenLayers.Format.WKT();
74+
const feature = format.read(wkt);
75+
temporaryVector.addFeatures([feature]);
76+
lizMap.map.addLayer(temporaryVector);
77+
78+
// Open the selection tool to activate it
79+
const selectionMenu = $('#mapmenu li.selectiontool a');
80+
let selectionMenuIsActive = selectionMenu.parent().hasClass("active");
81+
if (!selectionMenuIsActive) {
82+
selectionMenu.click();
83+
}
84+
85+
let drawLayer = lizMap.mainLizmap.digitizing.drawLayer;
86+
// Clear the previously drawn geometries
87+
if (drawLayer.getSource && typeof drawLayer.getSource().clear === 'function') {
88+
drawLayer.getSource().clear();
89+
} else {
90+
drawLayer.removeAllFeatures();
91+
}
92+
93+
// Add the features to drawLayer
94+
if (drawLayer.addFeature && typeof drawLayer.addFeature() === 'function') {
95+
drawLayer.addFeature(feature);
96+
} else {
97+
drawLayer.addFeatures(temporaryVector.features);
98+
}
99+
100+
// For polygons
101+
// We must add a buffer 1 to force the transformation of multipolygon
102+
// into compatible types. If not done, we get a <multisurface>
103+
// built up by OpenLayers and sent to the GetFeature request, which fails
104+
// and return no features
105+
let hadBuffer = false;
106+
let hadBufferValue = false;
107+
if (isPolygon) {
108+
const selectionToolDiv = $('#selectiontool');
109+
const bufferInput = selectionToolDiv.find('div.selectiontool-buffer input');
110+
hadBufferValue = bufferInput.val();
111+
if (bufferInput.val() == 0) {
112+
lizMap.mainLizmap.selectionTool._bufferValue = 0.00001;
113+
hadBuffer = true;
114+
}
115+
}
116+
117+
// change color of feature selected for yellow highlight
118+
selectionTool.bufferLayer.styleMap.styles.select.defaultStyle.strokeColor = "yellow";
119+
selectionTool.bufferLayer.styleMap.styles.select.defaultStyle.fillColor = "yellow";
120+
selectionTool.bufferLayer.styleMap.styles.select.defaultStyle.fillOpacity = 0.3;
121+
122+
// Select only inside
123+
let oldOperator = lizMap.mainLizmap.selectionTool._geomOperator;
124+
if (isPolygon) {
125+
lizMap.mainLizmap.selectionTool._geomOperator = 'within';
126+
}
127+
128+
// Send the event to let Lizmap run the selection
129+
lizMap.mainEventDispatcher.dispatch('digitizing.featureDrawn');
130+
131+
// Remove the temporary vector layer
132+
lizMap.map.removeLayer(temporaryVector);
133+
134+
// Set back the buffer if necessary
135+
if (isPolygon && hadBuffer) {
136+
lizMap.mainLizmap.selectionTool._bufferValue = hadBufferValue;
137+
}
138+
if (isPolygon) {
139+
lizMap.mainLizmap.selectionTool._geomOperator = oldOperator;
140+
}
141+
142+
// Remove the selection geometry
143+
if (drawLayer.getSource && typeof drawLayer.getSource().clear === 'function') {
144+
drawLayer.getSource().clear();
145+
} else {
146+
drawLayer.removeAllFeatures();
147+
}
148+
149+
// Deactivate back the selection tool
150+
if (!selectionMenuIsActive) {
151+
selectionMenu.click();
152+
}
153+
154+
// // Deselect the feature which triggered the selection
155+
delay(5000).then(() => {
156+
// Get the popup again (it could have disappeared and reappeared after the selection
157+
const parentToolbar = $(`lizmap-feature-toolbar[value="${featureToolbarValue}"]`);
158+
if (!parentToolbar.length) return;
159+
const unselectButton = parentToolbar.find('button.feature-select');
160+
if (!unselectButton.length) return;
161+
if (unselectButton.hasClass('btn-primary')) {
162+
unselectButton.click();
163+
}
164+
});
165+
}
166+
167+
lizMap.events.on({
168+
lizmappopupdisplayed: function (e) {
169+
// Loop through each layer+feature item
170+
const popupContainer = $('#' + e.containerId); // Container
171+
const items = popupContainer.find('div.lizmapPopupDiv');
172+
173+
items.each(function() {
174+
// Get the layer ID
175+
const featureId = $(this).find('input.lizmap-popup-layer-feature-id').val();
176+
177+
// Check if there is a geometry
178+
const featureGeometryInput = $(this).find('input.lizmap-popup-layer-feature-geometry');
179+
if (!featureGeometryInput.length) {
180+
return;
181+
}
182+
const featureGeometry = featureGeometryInput.val();
183+
184+
// Geometry CRS
185+
let featureCrs = 'EPSG:4326';
186+
const featureCrsInput = $(this).find('input.lizmap-popup-layer-feature-crs');
187+
if (featureCrsInput.length) {
188+
featureCrs = featureCrsInput.val();
189+
}
190+
191+
// Get feature toolbar
192+
let featureToolbar = $(this).find(`lizmap-feature-toolbar[value="${featureId}"]`);
193+
194+
if (!featureToolbar.length) {
195+
// Create feature toolbar
196+
featureToolbar = $('<lizmap-feature-toolbar>')
197+
.attr('value', featureId)
198+
.css('display', 'inline-flex')
199+
.append($(this).find('input[value="' + featureId + '"]').nextUntil('br'))
200+
.append($('<div>').addClass('feature-toolbar').css('display', 'inline'));
201+
202+
// Insert feature toolbar after input element
203+
$(this).find('input[value="' + featureId + '"]').after(featureToolbar);
204+
}
205+
206+
// Add a button in the popup feature bar
207+
if (featureGeometry && featureCrs) {
208+
addSelectionButton(featureToolbar, featureGeometry, featureCrs);
209+
}
210+
});
211+
}
212+
});

0 commit comments

Comments
 (0)