Skip to content

Commit

Permalink
Handle map popups w/ OL8 (3liz#4008)
Browse files Browse the repository at this point in the history
  • Loading branch information
nboisteault authored Dec 7, 2023
1 parent de47bea commit a81a3de
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 104 deletions.
54 changes: 30 additions & 24 deletions assets/src/legacy/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -2282,31 +2282,38 @@ window.lizMap = function() {
}
}
else{
if (!text || text == null || text == '')
if (!text || text == null || text == ''){
return false;
// Use openlayers map popup anchored
popupContainerId = "liz_layer_popup";
popup = new OpenLayers.Popup.LizmapAnchored(
popupContainerId,
eventLonLatInfo,
null,
text,
null,
true,
function() {
map.removePopup(this);
if(mCheckMobile()){
$('#navbar').show();
$('#overview-box').show();
}
}

// clean locate layer
clearDrawLayer('locatelayer');
return false;
}
);
popup.panMapIfOutOfView = true;
map.addPopup(popup);
if (lizMap.mainLizmap.newOlMap) {
document.getElementById('popup-content').innerHTML = text;
} else {
// Use openlayers map popup anchored
popupContainerId = "liz_layer_popup";
popup = new OpenLayers.Popup.LizmapAnchored(
popupContainerId,
eventLonLatInfo,
null,
text,
null,
true,
function() {
map.removePopup(this);
if(mCheckMobile()){
$('#navbar').show();
$('#overview-box').show();
}

// clean locate layer
clearDrawLayer('locatelayer');
return false;
}
);
popup.panMapIfOutOfView = true;
map.addPopup(popup);
popup.verifySize();
}

// Activate Boostrap 2 tabs here as they are not
// automatically activated when created in popup anchored
Expand All @@ -2315,7 +2322,6 @@ window.lizMap = function() {
$(this).tab('show');
});

popup.verifySize();
// Hide navbar and overview in mobile mode
if(mCheckMobile()){
$('#navbar').hide();
Expand Down
12 changes: 12 additions & 0 deletions assets/src/modules/Digitizing.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,18 @@ export default class Digitizing {
return null;
}

/**
* Is digitizing tool active or not
* @todo active state should be set on UI's events
* @readonly
* @memberof Digitizing
* @returns {boolean}
*/
get isActive() {
const isActive = document.getElementById('button-draw')?.parentElement?.classList?.contains('active');
return isActive ? true : false;
}

get isEdited() {
return this._isEdited;
}
Expand Down
4 changes: 4 additions & 0 deletions assets/src/modules/Lizmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export default class Lizmap {
});
}

get newOlMap() {
return this.map._newOlMap;
}

/**
* @param {boolean} mode - switch new OL map on top of OL2 one
*/
Expand Down
188 changes: 110 additions & 78 deletions assets/src/modules/Popup.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { mainLizmap } from '../modules/Globals.js';
import Overlay from 'ol/Overlay.js';
import WMS from '../modules/WMS.js';

export default class Popup {

constructor() {

this._pointTolerance = mainLizmap.config.options?.pointTolerance || 25;
this._lineTolerance = mainLizmap.config.options?.lineTolerance || 10;
this._polygonTolerance = mainLizmap.config.options?.polygonTolerance || 5;

// OL2
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'single': true,
Expand All @@ -31,83 +27,119 @@ export default class Popup {
);
},
trigger: evt => {
if(lizMap.editionPending){
return;
}

let candidateLayers = mainLizmap.state.rootMapGroup.findMapLayers().reverse();

// Only request visible layers
candidateLayers = candidateLayers.filter(layer => layer.visibility);

// Only request layers with 'popup' checked in plugin
// Or some edition capabilities
candidateLayers = candidateLayers.filter(layer => {
const layerCfg = layer.layerConfig;

let editionLayerCapabilities;

if (mainLizmap.initialConfig?.editionLayers?.layerNames.includes(layer.name)) {
editionLayerCapabilities = mainLizmap.initialConfig?.editionLayers?.getLayerConfigByLayerName(layer.name)?.capabilities;
}
return layerCfg.popup || editionLayerCapabilities?.modifyAttribute || editionLayerCapabilities?.modifyGeometry || editionLayerCapabilities?.deleteFeature;
});

if(!candidateLayers.length){
return;
}

const layersWMS = candidateLayers.map(layer => layer.wmsName).join();

const wms = new WMS();

const [width, height] = lizMap.mainLizmap.map.getSize();

let bbox = mainLizmap.map.getView().calculateExtent();

if (mainLizmap.map.getView().getProjection().getAxisOrientation().substring(0, 2) === 'ne') {
bbox = [bbox[1], bbox[0], bbox[3], bbox[2]];
}

const wmsParams = {
QUERY_LAYERS: layersWMS,
LAYERS: layersWMS,
CRS: mainLizmap.projection,
BBOX: bbox,
FEATURE_COUNT: 10,
WIDTH: width,
HEIGHT: height,
I: Math.round(evt.xy.x),
J: Math.round(evt.xy.y),
FI_POINT_TOLERANCE: this._pointTolerance,
FI_LINE_TOLERANCE: this._lineTolerance,
FI_POLYGON_TOLERANCE: this._polygonTolerance
};

const filterTokens = [];
candidateLayers.forEach(layer => {
let filterToken = layer.wmsParameters?.FILTERTOKEN;
if (filterToken) {
filterTokens.push(filterToken);
}
});

if (filterTokens.length) {
wmsParams['FILTERTOKEN'] = filterTokens.join(';');
}

document.getElementById('map').style.cursor = 'wait';

wms.getFeatureInfo(wmsParams).then(response => {
lizMap.displayGetFeatureInfo(response, evt.xy);
}).finally(() => {
document.getElementById('map').style.cursor = 'auto';
});
this.handleClickOnMap(evt);
}
});

var click = new OpenLayers.Control.Click();
lizMap.map.addControl(click);
click.activate();

// OL8
/**
* Create an overlay to anchor the popup to the map.
*/
document.getElementById('popup-closer').onclick = () => {
this._overlay.setPosition(undefined);
return false;
};
this._overlay = new Overlay({
element: document.getElementById('popup'),
autoPan: {
animation: {
duration: 250,
},
},
});

mainLizmap.map.addOverlay(this._overlay);
mainLizmap.map.on('singleclick', evt => this.handleClickOnMap(evt));
}

get mapPopup() {
return this._overlay;
}

handleClickOnMap(evt) {
const pointTolerance = mainLizmap.config.options?.pointTolerance || 25;
const lineTolerance = mainLizmap.config.options?.lineTolerance || 10;
const polygonTolerance = mainLizmap.config.options?.polygonTolerance || 5;

if (lizMap.editionPending || mainLizmap.selectionTool.isActive || mainLizmap.digitizing.isActive) {
return;
}

const xCoord = evt?.xy?.x || evt?.pixel?.[0];
const yCoord = evt?.xy?.y || evt?.pixel?.[1];

let candidateLayers = mainLizmap.state.rootMapGroup.findMapLayers().reverse();

// Only request visible layers
candidateLayers = candidateLayers.filter(layer => layer.visibility);

// Only request layers with 'popup' checked in plugin
// Or some edition capabilities
candidateLayers = candidateLayers.filter(layer => {
const layerCfg = layer.layerConfig;

let editionLayerCapabilities;

if (mainLizmap.initialConfig?.editionLayers?.layerNames.includes(layer.name)) {
editionLayerCapabilities = mainLizmap.initialConfig?.editionLayers?.getLayerConfigByLayerName(layer.name)?.capabilities;
}
return layerCfg.popup || editionLayerCapabilities?.modifyAttribute || editionLayerCapabilities?.modifyGeometry || editionLayerCapabilities?.deleteFeature;
});

if(!candidateLayers.length){
return;
}

const layersWMS = candidateLayers.map(layer => layer.wmsName).join();

const wms = new WMS();

const [width, height] = lizMap.mainLizmap.map.getSize();

let bbox = mainLizmap.map.getView().calculateExtent();

if (mainLizmap.map.getView().getProjection().getAxisOrientation().substring(0, 2) === 'ne') {
bbox = [bbox[1], bbox[0], bbox[3], bbox[2]];
}

const wmsParams = {
QUERY_LAYERS: layersWMS,
LAYERS: layersWMS,
CRS: mainLizmap.projection,
BBOX: bbox,
FEATURE_COUNT: 10,
WIDTH: width,
HEIGHT: height,
I: Math.round(xCoord),
J: Math.round(yCoord),
FI_POINT_TOLERANCE: pointTolerance,
FI_LINE_TOLERANCE: lineTolerance,
FI_POLYGON_TOLERANCE: polygonTolerance
};

const filterTokens = [];
candidateLayers.forEach(layer => {
let filterToken = layer.wmsParameters?.FILTERTOKEN;
if (filterToken) {
filterTokens.push(filterToken);
}
});

if (filterTokens.length) {
wmsParams['FILTERTOKEN'] = filterTokens.join(';');
}

document.getElementById('map').style.cursor = 'wait';

wms.getFeatureInfo(wmsParams).then(response => {
this._overlay.setPosition(evt.coordinate);
lizMap.displayGetFeatureInfo(response, {x: xCoord, y: yCoord});
}).finally(() => {
document.getElementById('map').style.cursor = 'auto';
});
}
}
4 changes: 2 additions & 2 deletions assets/src/modules/SelectionTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ export default class SelectionTool {
});
}


/**
* Is selection tool active or not
* @todo active state should be set on UI's events
Expand All @@ -268,7 +267,8 @@ export default class SelectionTool {
* @returns {boolean}
*/
get isActive() {
return document.getElementById('button-selectiontool').parentElement.classList.contains('active')
const isActive = document.getElementById('button-selectiontool')?.parentElement?.classList?.contains('active');
return isActive ? true : false;
}

get layers() {
Expand Down
4 changes: 4 additions & 0 deletions lizmap/modules/view/templates/map.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
<div id="map-content">
<div id="newOlMap" style="width:100%;height:100%;position: absolute;"></div>
<div id="baseLayersOlMap" style="width:100%;height:100%;position: absolute;"></div>
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content" class="lizmapPopupContent"></div>
</div>
<div id="map"></div>

<div id="mini-dock">
Expand Down
46 changes: 46 additions & 0 deletions lizmap/www/assets/css/map.css
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,52 @@ lizmap-mouse-position > div.coords-unit > select{
word-break: normal;
}

/* Map's popup OL8 */

.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}

/* Tooltip */

#tooltipPopupContent {
background-color:#F0F0F0 !important;
border: rgba(0,0,0,0.7) solid 4px;
Expand Down

0 comments on commit a81a3de

Please sign in to comment.