Skip to content

Commit

Permalink
#10264: Fix - Layer visibility limits may prevent the Info panel of s…
Browse files Browse the repository at this point in the history
…earch results from opening (#10325)

* #10264: Layer visibility limits may prevent the Info panel of search results from opening [resolve review comments]
Description:
- edit featureInfoClick action creator by passing an optional param called 'layerWithIgnoreVisibilityLimits' to enforce it to querable layers if not exist due to visibility limits
- handle showing feature info in case of search within single layer or All layers

* #10264: Layer visibility limits may prevent the Info panel of search results from opening [resolve review comments]
Description:
- handle showing feature info in case of action in queryParameters

* #10264: Layer visibility limits may prevent the Info panel of search results from opening [resolve review comments]
Description:
- add missing check on the layer with ignoring visibility limits of making sure it is queryable
- fix FE failure test

* #10264: Layer visibility limits may prevent the Info panel of search results from opening [resolve review comments]
Description:
- add unit tests
- fix handling search for layers has visibility limits

* #10264: Layer visibility limits may prevent the Info panel of search results from opening [resolve review comments]
Description:
- fix unit test

* #10264: Layer visibility limits may prevent the Info panel of search results from opening [resolve review comments]
Description:
- add reserve to querable layers in identify file to keep the same sort of toc layers in case of 'ignoreVisibilityLimits'
- edit unit test based on the change
  • Loading branch information
mahmoudadel54 committed May 17, 2024
1 parent 94637b8 commit 13fe763
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 14 deletions.
18 changes: 18 additions & 0 deletions web/client/actions/__tests__/mapInfo-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ describe('Test correctness of the map actions', () => {
expect(action.overrideParams).toBe(overrideParams);
expect(action.itemId).toBe(itemId);
});
it('test featureInfoClick with filterNameList, overrideParams and ignoreVisibilityLimits flag [search service case]', () => {
const point = {latlng: {lat: 1, lng: 3}};
const layer = {id: "layer.1"};
const filterNameList = [];
const itemId = "itemId";
const overrideParams = {cql_filter: "ID_ORIG=1234"};
const ignoreVisibilityLimits = true;

const action = featureInfoClick(point, layer, filterNameList, overrideParams, itemId, ignoreVisibilityLimits);
expect(action).toExist();
expect(action.type).toBe(FEATURE_INFO_CLICK);
expect(action.point).toBe(point);
expect(action.layer).toBe(layer);
expect(action.filterNameList).toBe(filterNameList);
expect(action.overrideParams).toBe(overrideParams);
expect(action.itemId).toBe(itemId);
expect(action.ignoreVisibilityLimits).toBe(ignoreVisibilityLimits);
});
it('reset reverse geocode data', () => {
const e = hideMapinfoRevGeocode();
expect(e).toExist();
Expand Down
6 changes: 4 additions & 2 deletions web/client/actions/mapInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,17 @@ export function updateCenterToMarker(status) {
* @param {object[]} [filterNameList=[]] list of layers to perform the GFI request
* @param {object} [overrideParams={}] a map based on name as key and objec as value for overriding request params
* @param {string} [itemId=null] id of the item needed for filtering results
* @param {string} [ignoreVisibilityLimits=false] a boolean flag for ignoring layer visibility limits restrictions to apply GFI
*/
export function featureInfoClick(point, layer, filterNameList = [], overrideParams = {}, itemId = null) {
export function featureInfoClick(point, layer, filterNameList = [], overrideParams = {}, itemId = null, ignoreVisibilityLimits = false) {
return {
type: FEATURE_INFO_CLICK,
point,
layer,
filterNameList,
overrideParams,
itemId
itemId,
ignoreVisibilityLimits
};
}

Expand Down
221 changes: 221 additions & 0 deletions web/client/epics/__tests__/identify-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,227 @@ describe('identify Epics', () => {
}
}, state);
});
it('getFeatureInfoOnFeatureInfoClick WMS ignoring the layer that has visibility limits', (done) => {
// remove previous hook
registerHook('RESOLUTION_HOOK', undefined);
const state = {
map: {present: {...TEST_MAP_STATE.present, resolution: 100000}},
mapInfo: {
clickPoint: { latlng: { lat: 36.95, lng: -79.84 } }
},
layers: {
flat: [{
id: "TEST1",
name: "TEST",
"title": "TITLE",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json',
minResolution: 500,
maxResolution: 50000
},
{
id: "TEST_NEW",
name: "TEST",
"title": "TITLE New",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json'
},
{
id: "TEST2",
name: "TEST2",
"title": "TITLE2",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json'
}]
}
};
const sentActions = [featureInfoClick({ latlng: { lat: 36.95, lng: -79.84 } }, "TEST", ["TEST"], {"TEST": {cql_filter: "id>1"}}, "province_view.5")];
testEpic(getFeatureInfoOnFeatureInfoClick, 3, sentActions, ([a0, a1, a2]) => {
try {
expect(a0).toExist();
expect(a0.type).toBe(PURGE_MAPINFO_RESULTS);
expect(a1).toExist();
expect(a1.type).toBe(NEW_MAPINFO_REQUEST);
expect(a1.reqId).toExist();
expect(a1.request).toExist();
expect(a1.request.cql_filter).toExist();
expect(a1.request.cql_filter).toBe("id>1");
expect(a2).toExist();
expect(a2.type).toBe(LOAD_FEATURE_INFO);
expect(a2.data).toExist();
expect(a2.requestParams).toExist();
expect(a2.reqId).toExist();
expect(a2.layerMetadata.title).toBe(state.layers.flat[1].title); // layer that has no visibility limits
done();
} catch (ex) {
done(ex);
}
}, {...state, mapInfo: {
...state.mapInfo,
itemId: "province_view.5"
}});
});
it('getFeatureInfoOnFeatureInfoClick WMS with ignoreVisibilityLimits flag with true and layers includes visibility limits [search service case]', (done) => {
// remove previous hook
registerHook('RESOLUTION_HOOK', undefined);
const state = {
map: {present: {...TEST_MAP_STATE.present, resolution: 100000}},
mapInfo: {
clickPoint: { latlng: { lat: 36.95, lng: -79.84 } }
},
layers: {
flat: [{
id: "TEST1",
name: "TEST",
"title": "TITLE",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json',
minResolution: 500,
maxResolution: 50000
},
{
id: "TEST NEW 2",
name: "TEST",
"title": "TITLE NEW 2",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json',
minResolution: 500,
maxResolution: 50000
},
{
id: "TEST_NEW",
name: "TEST",
"title": "TITLE New",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json'
},
{
id: "TEST2",
name: "TEST2",
"title": "TITLE2",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json'
}]
}
};
const ignoreVisibilityLimits = true;
const sentActions = [featureInfoClick({ latlng: { lat: 36.95, lng: -79.84 } }, "TEST", ["TEST"], {"TEST": {cql_filter: "id>1"}}, "province_view.5", ignoreVisibilityLimits)];
testEpic(getFeatureInfoOnFeatureInfoClick, 5, sentActions, ([a0, a1, a2, a3]) => {
try {
expect(a0).toExist();
expect(a0.type).toBe(PURGE_MAPINFO_RESULTS);
expect(a1).toExist();
expect(a1.type).toBe(NEW_MAPINFO_REQUEST);
expect(a1.reqId).toExist();
expect(a1.request).toExist();
expect(a1.request.id).toEqual(state.layers.flat[2].id);
expect(a1.request.cql_filter).toExist();
expect(a1.request.cql_filter).toBe("id>1");
expect(a2).toExist();
expect(a2.type).toBe(NEW_MAPINFO_REQUEST);
expect(a2.reqId).toExist();
expect(a2.request).toExist();
expect(a2.request.id).toEqual(state.layers.flat[1].id);
expect(a2.request.cql_filter).toExist();
expect(a2.request.cql_filter).toBe("id>1");
expect(a3).toExist();
expect(a3.type).toBe(NEW_MAPINFO_REQUEST);
expect(a3.reqId).toExist();
expect(a3.request).toExist();
expect(a3.request.id).toEqual(state.layers.flat[0].id);
expect(a3.request.cql_filter).toExist();
expect(a3.request.cql_filter).toBe("id>1");
done();
} catch (ex) {
done(ex);
}
}, {...state, mapInfo: {
...state.mapInfo,
itemId: "province_view.5"
}});
});
it('getFeatureInfoOnFeatureInfoClick WMS with ignoreVisibilityLimits flag with true and selected layers [search service case]', (done) => {
// remove previous hook
registerHook('RESOLUTION_HOOK', undefined);
const state = {
map: {present: {...TEST_MAP_STATE.present, resolution: 100000}},
mapInfo: {
clickPoint: { latlng: { lat: 36.95, lng: -79.84 } }
},
layers: {
flat: [{
id: "TEST1",
name: "TEST",
"title": "TITLE",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json',
minResolution: 500,
maxResolution: 50000
},
{
id: "TEST NEW 2",
name: "TEST",
"title": "TITLE NEW 2",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json',
minResolution: 500,
maxResolution: 50000
},
{
id: "TEST_NEW",
name: "TEST",
"title": "TITLE New",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json'
},
{
id: "TEST2",
name: "TEST2",
"title": "TITLE2",
type: "wms",
visibility: true,
url: 'base/web/client/test-resources/featureInfo-response.json'
}],
selected: ['TEST1']
}
};
const ignoreVisibilityLimits = true;
const sentActions = [featureInfoClick({ latlng: { lat: 36.95, lng: -79.84 } }, "TEST", ["TEST"], {"TEST": {cql_filter: "id>1"}}, "province_view.5", ignoreVisibilityLimits)];
testEpic(getFeatureInfoOnFeatureInfoClick, 3, sentActions, ([a0, a1, a2]) => {
try {
expect(a0).toExist();
expect(a0.type).toBe(PURGE_MAPINFO_RESULTS);
expect(a1).toExist();
expect(a1.type).toBe(NEW_MAPINFO_REQUEST);
expect(a1.reqId).toExist();
expect(a1.request).toExist();
expect(a1.request.id).toEqual(state.layers.flat[0].id);
expect(a1.request.cql_filter).toExist();
expect(a1.request.cql_filter).toBe("id>1");
expect(a2.type).toBe(LOAD_FEATURE_INFO);
expect(a2.data).toExist();
expect(a2.requestParams).toExist();
expect(a2.reqId).toExist();
expect(a2.layerMetadata.title).toBe(state.layers.flat[0].title);
done();
} catch (ex) {
done(ex);
}
}, {...state, mapInfo: {
...state.mapInfo,
itemId: "province_view.5"
}});
});
it('handleMapInfoMarker show', done => {
testEpic(handleMapInfoMarker, 1, featureInfoClick({}), ([ a ]) => {
expect(a.type).toBe(SHOW_MAPINFO_MARKER);
Expand Down
5 changes: 5 additions & 0 deletions web/client/epics/__tests__/search-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ describe('search Epics', () => {
expect(getInfoActions[1].type).toBe(FEATURE_INFO_CLICK);
expect(getInfoActions[1].filterNameList).toEqual([]);
expect(getInfoActions[1].layer).toEqual("gs:layername");
expect(getInfoActions[1].ignoreVisibilityLimits).toEqual(true);
});

});
Expand Down Expand Up @@ -271,6 +272,7 @@ describe('search Epics', () => {
expect(getInfoActions[1].filterNameList).toEqual(["gs:layername"]);
expect(getInfoActions[1].overrideParams).toEqual({"gs:layername": {info_format: "text/html", featureid: "Feature_1", CQL_FILTER: undefined}}); // forces CQL FILTER to undefined (server do not support featureid + CQL_FILTER)
expect(getInfoActions[1].layer).toEqual("gs:layername");
expect(getInfoActions[1].ignoreVisibilityLimits).toEqual(true);
done();
}, {layers: {flat: [{name: "gs:layername", url: "base/web/client/test-resources/wms/GetFeature.json", visibility: true, featureInfo: {format: "HTML"}, queryable: true, type: "wms"}]}});
});
Expand Down Expand Up @@ -383,6 +385,7 @@ describe('search Epics', () => {
expect(getInfoActions[1].filterNameList).toEqual(["gs:layername"]);
expect(getInfoActions[1].overrideParams).toEqual({"gs:layername": {info_format: "text/html", featureid: "Feature_1", CQL_FILTER: undefined}}); // forces CQL FILTER to undefined (server do not support featureid + CQL_FILTER)
expect(getInfoActions[1].layer).toEqual("gs:layername");
expect(getInfoActions[1].ignoreVisibilityLimits).toEqual(true);
done();
}, {layers: {flat: [{name: "gs:layername", url: "base/web/client/test-resources/wms/GetFeature.json", visibility: true, featureInfo: {format: "HTML"}, queryable: true, type: "wms"}]}});
});
Expand Down Expand Up @@ -722,6 +725,7 @@ describe('search Epics', () => {
expect(actions[0].type).toBe(FEATURE_INFO_CLICK);
expect(actions[0].overrideParams.layerName.info_format).toBe("text/html");
expect(actions[0].overrideParams.layerName.featureid).toBe("layer_01");
expect(actions[0].ignoreVisibilityLimits).toEqual(true);
expect(actions[1].type).toBe(SHOW_MAPINFO_MARKER);
expect(actions[2].type).toBe(TEXT_SEARCH_ADD_MARKER);
expect(actions[3].type).toBe(ZOOM_TO_EXTENT);
Expand Down Expand Up @@ -757,6 +761,7 @@ describe('search Epics', () => {
expect(actions[1].type).toBe(FEATURE_INFO_CLICK);
expect(actions[1].overrideParams.layerName.info_format).toBe("text/html");
expect(actions[1].overrideParams.layerName.featureid).toBe("layer_01");
expect(actions[1].ignoreVisibilityLimits).toEqual(true);
expect(actions[2].type).toBe(SHOW_MAPINFO_MARKER);
expect(actions[3].type).toBe(TEXT_SEARCH_ADD_MARKER);
expect(actions[4].type).toBe(ZOOM_TO_EXTENT);
Expand Down
11 changes: 6 additions & 5 deletions web/client/epics/identify.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
itemIdSelector, overrideParamsSelector, filterNameListSelector,
currentEditFeatureQuerySelector, mapTriggerSelector, enableInfoForSelectedLayersSelector
} from '../selectors/mapInfo';
import { centerToMarkerSelector, queryableLayersSelector, queryableSelectedLayersSelector, selectedNodesSelector } from '../selectors/layers';
import { centerToMarkerSelector, getSelectedLayers, layersSelector, queryableLayersSelector, queryableSelectedLayersSelector, selectedNodesSelector } from '../selectors/layers';
import { modeSelector, getAttributeFilters, isFeatureGridOpen } from '../selectors/featuregrid';
import { spatialFieldSelector } from '../selectors/queryform';
import { mapSelector, projectionDefsSelector, projectionSelector, isMouseMoveIdentifyActiveSelector } from '../selectors/map';
Expand All @@ -52,7 +52,7 @@ import { createControlEnabledSelector, measureSelector } from '../selectors/cont
import { localizedLayerStylesEnvSelector } from '../selectors/localizedLayerStyles';
import { mouseOutSelector } from '../selectors/mousePosition';
import {getBbox, getCurrentResolution, parseLayoutValue} from '../utils/MapUtils';
import {buildIdentifyRequest, filterRequestParams} from '../utils/MapInfoUtils';
import {buildIdentifyRequest, defaultQueryableFilter, filterRequestParams} from '../utils/MapInfoUtils';
import { IDENTIFY_POPUP } from '../components/map/popups';

const gridEditingSelector = state => modeSelector(state) === 'EDIT';
Expand All @@ -74,10 +74,11 @@ import {updatePointWithGeometricFilter} from "../utils/IdentifyUtils";
*/
export const getFeatureInfoOnFeatureInfoClick = (action$, { getState = () => { } }) =>
action$.ofType(FEATURE_INFO_CLICK)
.switchMap(({ point, filterNameList = [], overrideParams = {} }) => {
.switchMap(({ point, filterNameList = [], overrideParams = {}, ignoreVisibilityLimits }) => {
// ignoreVisibilityLimits is for ignore limits of layers visibility
// Reverse - To query layer in same order as in TOC
let queryableLayers = reverse(queryableLayersSelector(getState()));
const queryableSelectedLayers = queryableSelectedLayersSelector(getState());
let queryableLayers = ignoreVisibilityLimits ? reverse([...layersSelector(getState())].filter(l=>defaultQueryableFilter(l))) : reverse(queryableLayersSelector(getState()));
const queryableSelectedLayers = ignoreVisibilityLimits ? [...getSelectedLayers(getState())].filter(l => defaultQueryableFilter(l)) : queryableSelectedLayersSelector(getState());
const enableInfoForSelectedLayers = enableInfoForSelectedLayersSelector(getState());
if (enableInfoForSelectedLayers && queryableSelectedLayers.length) {
queryableLayers = queryableSelectedLayers;
Expand Down

0 comments on commit 13fe763

Please sign in to comment.