Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge remote-tracking branch 'origin/2.4' #4951

Merged
merged 7 commits into from
Jun 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ cd ngeo
make serve-ngeo
```

The ngeo examples are now available on your http://localhost:3000/examples/.
The ngeo examples are now available on your https://localhost:3000/examples/.

### Run GeoMapFish

Expand All @@ -56,7 +56,7 @@ To run the GeoMapFish examples:
make serve-gmf
```

then visit http://localhost:3000/contribs/gmf/examples/.
then visit https://localhost:3000/contribs/gmf/examples/.

To run the GeoMapFish applications:

Expand All @@ -65,8 +65,8 @@ serve-gmf-apps
```

then visit them using
http://localhost:3000/contribs/gmf/apps/<app_name>.html, for example:
http://localhost:3000/contribs/gmf/apps/desktop.html
https://localhost:3000/contribs/gmf/apps/<app_name>.html, for example:
https://localhost:3000/contribs/gmf/apps/desktop.html

### Go further

Expand Down
2 changes: 1 addition & 1 deletion api/dist/apihelp/apihelp.html
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ <h2>A map with some additional controls</h2>
div: 'map5',
zoom: 3,
center: [544500, 210100],
layers: ['bank'],
layers: ['osm_open'],
addLayerSwitcher: true,
addMiniMap: true,
miniMapExpanded: true,
Expand Down
84 changes: 68 additions & 16 deletions api/src/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {get as getProjection} from 'ol/proj.js';

import constants from './constants.js';

import {getFeaturesFromLayer} from './Querent.js';
import {getFeaturesFromIds, getFeaturesFromCoordinates} from './Querent.js';
import * as themes from './Themes.js';


Expand All @@ -54,6 +54,12 @@ import * as themes from './Themes.js';
* @property {string[]} [layers]
*/

/**
* @type {Array<string>}
*/
const EXCLUDE_PROPERTIES = ['geom', 'geometry', 'boundedBy'];


/**
* @private
* @hidden
Expand Down Expand Up @@ -184,6 +190,33 @@ class Map {
this.selectObject(selected.getId());
}
});


this.map_.on('singleclick', (event) => {
const resolution = this.map_.getView().getResolution();
if (resolution === undefined) {
throw new Error('Missing resolution');
}
const visibleLayers = this.map_.getLayers().getArray().filter(layer => layer.getVisible());
const visibleLayersName = visibleLayers.map(layer => layer.get('config.name'));

this.clearSelection();

for (const layer of constants.queryableLayers) {
if (visibleLayersName.includes(layer)) {
getFeaturesFromCoordinates(layer, event.coordinate, resolution).then((feature) => {
if (feature) {
this.vectorSource_.addFeature(feature);
const featureId = feature.getId();
if (featureId === undefined) {
throw new Error('Missing feature ID');
}
this.selectObject(featureId, true);
}
});
}
}
});
}

/**
Expand All @@ -195,11 +228,8 @@ class Map {
overlayContainer.className = 'ol-popup';
const overlayCloser = document.createElement('div');
overlayCloser.className = 'ol-popup-closer';
overlayCloser.addEventListener('click', (event) => {
// clear the selected features
this.selectInteraction_.getFeatures().clear();
// hide the overlay
this.overlay_.setPosition(undefined);
overlayCloser.addEventListener('click', () => {
this.clearSelection();
return false;
});
const overlayContent = document.createElement('div');
Expand Down Expand Up @@ -250,11 +280,10 @@ class Map {
/**
* @param {string} layer Name of the layer to fetch the features from
* @param {string[]} ids List of ids
* @param {boolean} [highlight=false] Whether to add the features on
* the map or not.
* @param {boolean} [highlight=false] Whether to add the features on the map or not.
*/
recenterOnObjects(layer, ids, highlight = false) {
getFeaturesFromLayer(layer, ids)
getFeaturesFromIds(layer, ids)
.then((features) => {
if (!features.length) {
console.error('Could not recenter: no objects were found.');
Expand Down Expand Up @@ -346,15 +375,32 @@ class Map {
}

/**
* @param {string} id Identifier.
* @param {string|number} id Identifier.
* @param {boolean} table Display all properties in a table
*/
selectObject(id) {
selectObject(id, table = false) {
const feature = this.vectorSource_.getFeatureById(id);
if (feature) {
const coordinates = /** @type {import('ol/geom/Point.js').default} */(
feature.getGeometry()
).getCoordinates();
const properties = feature.getProperties();
let contentHTML = '';
if (table) {
contentHTML += '<table><tbody>';
for (const key in properties) {
if (!EXCLUDE_PROPERTIES.includes(key)) {
contentHTML += '<tr>';
contentHTML += `<th>${key}</th>`;
contentHTML += `<td>${properties[key]}</td>`;
contentHTML += '</tr>';
}
}
contentHTML += '</tbody></table>';
} else {
contentHTML += `<div><b>${properties.title}</b></div>`;
contentHTML += `<p>${properties.description}</p>`;
}
const element = this.overlay_.getElement();
if (!element) {
throw new Error('Missing element');
Expand All @@ -363,18 +409,24 @@ class Map {
if (!content) {
throw new Error('Missing content');
}
content.innerHTML = '';
content.innerHTML += `<div><b>${properties.title}</b></div>`;
content.innerHTML += `<p>${properties.description}</p>`;
content.innerHTML = contentHTML;
this.overlay_.setPosition(coordinates);

this.view_.setCenter(coordinates);
}
}

/**
*
*/
clearSelection() {
// clear the selected features
this.selectInteraction_.getFeatures().clear();
this.vectorSource_.clear();
// hide the overlay
this.overlay_.setPosition(undefined);
}
}


/**
* @param {string[]} keys Keys.
* @param {Array<*>} values Values.
Expand Down
87 changes: 80 additions & 7 deletions api/src/Querent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@ import {getOverlayDefs} from './Themes.js';
import {appendParams as olUriAppendParams} from 'ol/uri.js';
import olFormatGML2 from 'ol/format/GML2.js';
import olFormatWFS from 'ol/format/WFS.js';
import {buffer, createOrUpdateFromCoordinate} from 'ol/extent.js';


/**
* Click tolerance in pixel
* @type {number}
*/
const TOLERANCE = 10;


/**
* @param {import('./Themes.js').overlayDefinition} def Overlay definition.
* @return {boolean} Is the overlay queryable.
*/
function querable(def) {
return def.layer.type === 'WMS' && !!def.ogcServer.wfsSupport && !!def.ogcServer.urlWfs;
}


/**
* Issues a simple WFS GetFeature request for a single layer to fetch
Expand All @@ -18,7 +36,7 @@ import olFormatWFS from 'ol/format/WFS.js';
* @return {Promise<Array<import('ol/Feature.js').default<import("ol/geom/Geometry.js").default>>>} Promise.
* @hidden
*/
export function getFeaturesFromLayer(layer, ids) {
export function getFeaturesFromIds(layer, ids) {
return new Promise((resolve, reject) => {
getOverlayDefs().then((overlayDefs) => {

Expand All @@ -31,12 +49,7 @@ export function getFeaturesFromLayer(layer, ids) {
return;
}

if (
!overlayDef.ogcServer ||
!overlayDef.ogcServer.wfsSupport ||
!overlayDef.ogcServer.urlWfs ||
overlayDef.layer.type !== 'WMS'
) {
if (!querable(overlayDef)) {
reject(`Layer "${layer}" does not support WFS.`);
return;
}
Expand Down Expand Up @@ -70,3 +83,63 @@ export function getFeaturesFromLayer(layer, ids) {
});
});
}


/**
* @param {string} layer Name of the layer to query
* @param {number[]} coordinate Coordinate.
* @param {number} resolution Resolution
*
* @return {Promise<import('ol/Feature.js').default<import('ol/geom/Geometry.js').default>>} Promise.
* @hidden
*/
export function getFeaturesFromCoordinates(layer, coordinate, resolution) {
return new Promise((resolve, reject) => {
getOverlayDefs().then((overlayDefs) => {

const overlayDef = overlayDefs.get(layer);

if (!overlayDef) {
reject(`Layer "${layer}" was not found in themes.`);
return;
}

if (!querable(overlayDef)) {
reject(`Layer "${layer}" does not support WFS.`);
return;
}

const bbox = buffer(createOrUpdateFromCoordinate(coordinate), TOLERANCE * resolution);

const params = {
'BBOX': bbox.join(','),
'MAXFEATURES': 1,
'REQUEST': 'GetFeature',
'SERVICE': 'WFS',
'TYPENAME': layer,
'VERSION': '1.0.0'
};
const url = olUriAppendParams(overlayDef.ogcServer.urlWfs, params);

/** @type {?import('ol/Feature.js').default<import('ol/geom/Geometry.js').default>} */
let feature;
fetch(url)
.then(response => response.text().then((responseText) => {
const wfsFormat = new olFormatWFS({
featureNS: overlayDef.ogcServer.namespace,
gmlFormat: new olFormatGML2()
});
feature = wfsFormat.readFeature(responseText);
}))
.catch((response) => {
console.error(`WFS GetFeature request failed, response: ${response}`);
})
.then(() => {
if (!feature) {
throw new Error('Missing feature');
}
resolve(feature);
});
});
});
}
23 changes: 12 additions & 11 deletions api/src/Themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export function getBackgroundLayers() {
const layerWMTS = /** @type {import('gmf/themes.js').GmfLayerWMTS} */(config);
promises.push(
createWMTSLayer(layerWMTS).then((layer) => {
layer.set('config.layer', layerWMTS.layer);
layer.set('config.name', layerWMTS.name);
return layer;
})
Expand All @@ -56,7 +55,6 @@ export function getBackgroundLayers() {
const ogcServer = themes.ogcServers[config.ogcServer];
promises.push(
createWMSLayer(layerWMS, ogcServer).then((layer) => {
layer.set('config.layer', layerWMS.layers);
layer.set('config.name', layerWMS.name);
return layer;
})
Expand Down Expand Up @@ -194,19 +192,21 @@ export function getOverlayLayers(layerNames) {
* @hidden
*/
export function createWMSLayer(config, ogcServer) {
const source = new ImageWMS({
url: ogcServer.url,
projection: undefined, // should be removed in next OL version
params: {
'LAYERS': config.layers
},
serverType: ogcServer.type
});
// @ts-ignore: OL issue
const layer = new ImageLayer({
source
source: new ImageWMS({
url: ogcServer.url,
projection: undefined, // FIXME: should be removed in next OL version
params: {
'LAYERS': config.layers
},
serverType: ogcServer.type
}),
minResolution: config.minResolutionHint,
maxResolution: config.maxResolutionHint
});
layer.set('title', config.name);
layer.set('config.name', config.name);
return Promise.resolve(layer);
}

Expand All @@ -232,6 +232,7 @@ export function createWMTSLayer(config) {
source: source
});
layer.set('title', config.name);
layer.set('config.name', config.name);
return layer;
});
}
Expand Down
6 changes: 6 additions & 0 deletions api/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import EPSG21781 from '@geoblocks/proj/src/EPSG_21781.js';
* @property {number[]} resolutions
* @property {[number, number, number, number]} [extent]
* @property {string} backgroundLayer
* @property {string[]} queryableLayers
*/

export default /** @type {APIConfig} */({
Expand All @@ -28,4 +29,9 @@ export default /** @type {APIConfig} */({
// The name of the GeoMapFish layer to use as background. May be a single value
// (WMTS) or a comma-separated list of layer names (WMS).
backgroundLayer: 'orthophoto',

/**
* The list of layers (names) declared as queryable.
*/
queryableLayers: ['osm_open', 'many_attributes']
});
4 changes: 2 additions & 2 deletions contribs/gmf/examples/editfeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ MainController.prototype.handleMapSingleClick_ = function(evt) {
const map = this.map;
const view = map.getView();
const resolution = view.getResolution();
if (!resolution) {
if (resolution === undefined) {
throw new Error('Missing resolution');
}
const buffer = resolution * this.pixelBuffer_;
Expand Down Expand Up @@ -190,7 +190,7 @@ MainController.prototype.insertFeature = function() {
const map = this.map;
const view = map.getView();
const resolution = view.getResolution();
if (!resolution) {
if (resolution === undefined) {
throw new Error('Missing resolution');
}
const buffer = resolution * -50; // 50 pixel buffer inside the extent
Expand Down
2 changes: 1 addition & 1 deletion contribs/gmf/src/drawing/drawFeatureComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ Controller.prototype.handleMapContextMenu_ = function(evt) {
/** @type {import('ngeo/Menu').MenuActionOptions[]} */
let actions = [];
const resolution = this.map.getView().getResolution();
if (!resolution) {
if (resolution === undefined) {
throw new Error('Missing resolution');
}
const vertexInfo = this.featureHelper_.getVertexInfoAtCoordinate(feature, coordinate, resolution);
Expand Down
Loading