diff --git a/.eslintrc.yaml b/.eslintrc.yaml
index ac33066afd5..ab8beb119f9 100644
--- a/.eslintrc.yaml
+++ b/.eslintrc.yaml
@@ -5,16 +5,11 @@ env:
jasmine: true
parserOptions:
ecmaVersion: 2017
-plugins:
- - '@openlayers'
rules:
no-console: 0
comma-dangle: 0
import/no-unresolved: 0
valid-jsdoc: 0
- '@openlayers/valid-tsdoc':
- - error
- - requireReturn: false
max-len:
- error
- code: 110
diff --git a/.jshintrc b/.jshintrc
index 2b6f469f0ce..2c68de8a886 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -1,3 +1,4 @@
{
- "esversion": 6
+ "esversion": 6,
+ "-W014": true
}
diff --git a/.travis.yml b/.travis.yml
index 97dd5f24970..b19e8505b4d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -67,7 +67,7 @@ script:
- '! (npm run typecheck|sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"|grep ^src)'
- '! (npm run typecheck|grep api)'
- '! (npm run typecheck|grep gmf)'
-- '! (npm run typecheck|grep test)'
+- '! (npm run typecheck|grep test/)'
- '! (npm run typecheck|grep examples)'
- npm run doc
- npm run build-api
diff --git a/api/src/Map.js b/api/src/Map.js
index 846ed3d1655..d716c30dda8 100644
--- a/api/src/Map.js
+++ b/api/src/Map.js
@@ -36,6 +36,13 @@ import {getFeaturesFromLayer} from './Querent.js';
import * as themes from './Themes.js';
+/**
+ * @typedef {Object} MarkerOptions
+ * @property {[number, number]} [position]
+ * @property {string} [icon]
+ */
+
+
/**
* @private
* @hidden
@@ -51,7 +58,9 @@ class Map {
* TODO: more options
*/
constructor(options) {
-
+ if (!constants.extent) {
+ throw new Error('Missing extent');
+ }
/**
* @private
* @type {View}
@@ -95,11 +104,15 @@ class Map {
}));
}
if (options.addMiniMap) {
+ const resolutions = this.view_.getResolutions();
+ if (!resolutions) {
+ throw new Error('Missing resolutions');
+ }
this.map_.addControl(new OverviewMap({
collapsed: !options.miniMapExpanded,
view: new View({
projection: this.view_.getProjection(),
- resolutions: this.view_.getResolutions()
+ resolutions
})
}));
}
@@ -153,7 +166,7 @@ class Map {
const hasDescription = feature.get('description') !== undefined;
return hasId && hasTitle && hasDescription;
},
- style: () => null
+ style: () => []
});
this.map_.addInteraction(this.selectInteraction_);
@@ -200,21 +213,27 @@ class Map {
}
/**
- * @param {Object} options Options.
+ * @param {MarkerOptions} options Options.
* @property {import("ol/coordinate.js").Coordinate} position
* @property {string} [icon]
* @property {import("ol/size.js").Size} [size]
*/
addMarker(options = {}) {
+ const position = options.position ? options.position : this.view_.getCenter();
+ if (!position) {
+ throw new Error('Missing positon');
+ }
const marker = new Feature({
- geometry: new Point(options.position ? options.position : this.view_.getCenter())
+ geometry: new Point(position)
});
if (options.icon) {
// FIXME: use size?
+ const image = new Icon({
+ src: options.icon
+ });
+ // @ts-ignore: OL issue
marker.setStyle(new Style({
- image: new Icon({
- src: options.icon
- })
+ image
}));
}
this.vectorSource_.addFeature(marker);
@@ -267,7 +286,11 @@ class Map {
.then((text) => {
const attr = options.attr || ['title', 'description'];
const lines = text.split(/\r\n|\r|\n/);
- const columns = lines.shift().split('\t');
+ const shiftedLines = lines.shift();
+ if (!shiftedLines) {
+ throw new Error('Missing shiftedLines');
+ }
+ const columns = shiftedLines.split('\t');
for (const line of lines) {
if (line) {
const values = zip(columns, line.split('\t'));
@@ -276,10 +299,14 @@ class Map {
});
marker.setProperties(filterByKeys(values, attr));
marker.setId(values.id);
+ // FIXME: handle values.iconSize
+ // FIXME: handle values.iconOffset
+ const image = new Icon({
+ src: values.icon
+ });
+ // @ts-ignore: OL issue
marker.setStyle(new Style({
- image: new Icon({
- src: values.icon
- })
+ image
}));
this.vectorSource_.addFeature(marker);
}
@@ -308,7 +335,14 @@ class Map {
feature.getGeometry()
).getCoordinates();
const properties = feature.getProperties();
- const content = this.overlay_.getElement().querySelector('.ol-popup-content');
+ const element = this.overlay_.getElement();
+ if (!element) {
+ throw new Error('Missing element');
+ }
+ const content = element.querySelector('.ol-popup-content');
+ if (!content) {
+ throw new Error('Missing content');
+ }
content.innerHTML = '';
content.innerHTML += `
${properties.title}
`;
content.innerHTML += `${properties.description}
`;
diff --git a/api/src/Themes.js b/api/src/Themes.js
index 7627a61ee9b..00ce6feff75 100644
--- a/api/src/Themes.js
+++ b/api/src/Themes.js
@@ -19,6 +19,9 @@ let themesPromise;
*/
function getThemesPromise() {
if (!themesPromise) {
+ if (!constants.themesUrl) {
+ throw new Error('Missing constants.themesUrl');
+ }
themesPromise = fetch(constants.themesUrl).then(response => response.json());
}
return themesPromise;
@@ -72,6 +75,7 @@ export function getBackgroundLayers() {
const layerWMS = /** @type {import('gmf/themes.js').GmfLayerWMS} */ (child);
return createWMSLayer(layerWMS, themes.ogcServers[child.ogcServer]);
}
+ throw new Error('Unknow layer type');
}));
promises.push(
groupPromise.then((layers) => {
@@ -123,14 +127,13 @@ export function getOverlayDefs() {
/**
* @param {Object} config Config
* @param {import('gmf/themes.js').GmfOgcServers} ogcServers OGC servers
- * @param {import('gmf/themes.js').GmfOgcServer} [opt_ogcServer] OGC server
+ * @param {import('gmf/themes.js').GmfOgcServer} [opt_ogcServer] OGC server
* @returns {void}
* @hidden
*/
export function writeOverlayDefs(config, ogcServers, opt_ogcServer) {
const group = /** @type {import('gmf/themes.js').GmfGroup} */(config);
- const ogcServer = opt_ogcServer ? opt_ogcServer :
- group.ogcServer ? ogcServers[group.ogcServer] : undefined;
+ const ogcServer = opt_ogcServer ? opt_ogcServer : ogcServers[group.ogcServer];
if (group.children) {
for (const childConfig of group.children) {
writeOverlayDefs(childConfig, ogcServers, ogcServer);
@@ -187,15 +190,17 @@ 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: new ImageWMS({
- url: ogcServer.url,
- projection: undefined, // should be removed in next OL version
- params: {
- 'LAYERS': config.layers
- },
- serverType: ogcServer.type
- })
+ source
});
layer.set('title', config.name);
return Promise.resolve(layer);
@@ -213,6 +218,9 @@ export function createWMTSLayer(config) {
layer: config.layer,
matrixSet: config.matrixSet
});
+ if (!options) {
+ throw new Error('Missing options');
+ }
const source = new WMTS(options);
source.updateDimensions(config.dimensions);
const layer = new TileLayer({
diff --git a/api/src/constants.js b/api/src/constants.js
index f912f43fad2..04ccac60a33 100644
--- a/api/src/constants.js
+++ b/api/src/constants.js
@@ -1,14 +1,23 @@
import EPSG21781 from '@geoblocks/proj/src/EPSG_21781.js';
-export default {
- themesUrl: undefined,
+/**
+ * @typedef {Object} APIConfig
+ * @property {?string} themesUrl
+ * @property {string} projection
+ * @property {Array} resolutions
+ * @property {?[number, number, number, number]} extent
+ * @property {string} backgroundLayer
+ */
+
+export default /** @type {APIConfig} */({
+ themesUrl: null,
projection: EPSG21781,
resolutions: [250, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.25, 0.1, 0.05],
- extent: undefined,
+ extent: null,
/**
* The name of the layer to use as background. May be a single value
* (WMTS) or a comma-separated list of layer names (WMS).
*/
backgroundLayer: 'orthophoto',
-};
+});
diff --git a/contribs/gmf/examples/datepicker.js b/contribs/gmf/examples/datepicker.js
index ff34490dd08..2fe674c97f1 100644
--- a/contribs/gmf/examples/datepicker.js
+++ b/contribs/gmf/examples/datepicker.js
@@ -41,8 +41,6 @@ function MainController($scope, ngeoWMSTime) {
widget: TimePropertyWidgetEnum.DATEPICKER,
maxValue: '2013-12-31T00:00:00Z',
minValue: '2006-01-01T00:00:00Z',
- maxDefValue: null,
- minDefValue: null,
resolution: TimePropertyResolutionEnum.DAY,
mode: TimePropertyModeEnum.RANGE,
interval: [0, 1, 0, 0]
@@ -55,8 +53,6 @@ function MainController($scope, ngeoWMSTime) {
widget: /** @type {TimePropertyWidgetEnum} */ ('datepicker'),
maxValue: '2015-12-31T00:00:00Z',
minValue: '2014-01-01T00:00:00Z',
- maxDefValue: null,
- minDefValue: null,
resolution: /** @type {TimePropertyResolutionEnum}*/ ('month'),
mode: /** @type {TimePropertyModeEnum} */ ('value'),
interval: [0, 1, 0, 0]
@@ -65,12 +61,12 @@ function MainController($scope, ngeoWMSTime) {
/**
* @type {string}
*/
- this.value;
+ this.value = '';
/**
* @type {string}
*/
- this.rangeValue;
+ this.rangeValue = '';
this.onDateSelected = function(date) {
this.value = this.ngeoWMSTime_.formatWMSTimeParam(this.wmsTimeValueMode, date);
@@ -79,11 +75,9 @@ function MainController($scope, ngeoWMSTime) {
this.onDateRangeSelected = function(date) {
this.rangeValue = this.ngeoWMSTime_.formatWMSTimeParam(this.wmsTimeRangeMode, date);
};
-
}
module.controller('MainController', MainController);
-
export default module;
diff --git a/contribs/gmf/examples/editfeature.js b/contribs/gmf/examples/editfeature.js
index fdee4323760..87bff63826a 100644
--- a/contribs/gmf/examples/editfeature.js
+++ b/contribs/gmf/examples/editfeature.js
@@ -78,6 +78,7 @@ function MainController($scope, gmfEditFeature, gmfUser) {
* @type {import("ol/layer/Image.js").default}
* @private
*/
+ // @ts-ignore: OL issue
this.wmsLayer_ = new olLayerImage({
source: this.wmsSource_
});
@@ -95,7 +96,7 @@ function MainController($scope, gmfEditFeature, gmfUser) {
this.layerId_ = 113;
/**
- * @type {import("ol/Feature.js").default}
+ * @type {?import("ol/Feature.js").default}
*/
this.feature = null;
@@ -143,6 +144,9 @@ MainController.prototype.handleMapSingleClick_ = function(evt) {
const map = this.map;
const view = map.getView();
const resolution = view.getResolution();
+ if (!resolution) {
+ throw new Error('Missing resolution');
+ }
const buffer = resolution * this.pixelBuffer_;
const extent = olExtent.buffer(
[coordinate[0], coordinate[1], coordinate[0], coordinate[1]],
@@ -186,6 +190,9 @@ MainController.prototype.insertFeature = function() {
const map = this.map;
const view = map.getView();
const resolution = view.getResolution();
+ if (!resolution) {
+ throw new Error('Missing resolution');
+ }
const buffer = resolution * -50; // 50 pixel buffer inside the extent
const size = /** @type {!Array.} */ (map.getSize());
const extent = olExtent.buffer(
@@ -226,8 +233,9 @@ MainController.prototype.insertFeature = function() {
* Update the currently selected feature with a new name.
*/
MainController.prototype.updateFeature = function() {
-
- console.assert(this.feature);
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
this.pending = true;
@@ -248,8 +256,9 @@ MainController.prototype.updateFeature = function() {
* Delete currently selected feature.
*/
MainController.prototype.deleteFeature = function() {
-
- console.assert(this.feature);
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
// (1) Launch request
this.editFeature_.deleteFeature(
diff --git a/contribs/gmf/examples/layertree.js b/contribs/gmf/examples/layertree.js
index afa8d27e7ba..16ffcb247d6 100644
--- a/contribs/gmf/examples/layertree.js
+++ b/contribs/gmf/examples/layertree.js
@@ -193,6 +193,7 @@ function MainController(gmfTreeManager, gmfThemes, gmfThemeManager, ngeoLocation
if (n.id === node.id) {
return alreadyAdded = true;
}
+ return false;
});
if (!alreadyAdded) {
nodes.push(node);
diff --git a/contribs/gmf/examples/layertreeadd.js b/contribs/gmf/examples/layertreeadd.js
index 7ab6826560d..3fd906dd995 100644
--- a/contribs/gmf/examples/layertreeadd.js
+++ b/contribs/gmf/examples/layertreeadd.js
@@ -193,6 +193,7 @@ function MainController(gmfTreeManager, gmfThemes, gmfThemeManager, ngeoLocation
if (n.id === node.id) {
return alreadyAdded = true;
}
+ return false;
});
if (!alreadyAdded) {
nodes.push(node);
diff --git a/contribs/gmf/examples/lidarprofile.js b/contribs/gmf/examples/lidarprofile.js
index 1d740e60590..d5d415c1955 100644
--- a/contribs/gmf/examples/lidarprofile.js
+++ b/contribs/gmf/examples/lidarprofile.js
@@ -32,7 +32,7 @@ module.value('pytreeLidarprofileJsonUrl', 'https://sitn.ne.ch/pytree');
*/
function MainController($scope) {
/**
- * @type {import("ol/geom/LineString.js").default}
+ * @type {?import("ol/geom/LineString.js").default}
*/
this.profileLine = null;
diff --git a/contribs/gmf/examples/objecteditinghub.js b/contribs/gmf/examples/objecteditinghub.js
index e2abecbc2a4..c1bc3b50ec6 100644
--- a/contribs/gmf/examples/objecteditinghub.js
+++ b/contribs/gmf/examples/objecteditinghub.js
@@ -101,16 +101,16 @@ function MainController($http, $q, $scope, gmfThemes, gmfXSDAttributes) {
this.selectedUrl = this.urls[0];
/**
- * @type {import('gmf/themes.js').GmfOgcServers} ogcServers OGC servers.
+ * @type {?import('gmf/themes.js').GmfOgcServers} ogcServers OGC servers.
* @private
*/
- this.gmfServers_;
+ this.gmfServers_ = null;
/**
- * @type {import('gmf/themes.js').GmfOgcServer} ogcServer OGC server to use.
+ * @type {?import('gmf/themes.js').GmfOgcServer} ogcServer OGC server to use.
* @private
*/
- this.gmfServer_;
+ this.gmfServer_ = null;
/**
* @type {Array}
@@ -130,7 +130,7 @@ function MainController($http, $q, $scope, gmfThemes, gmfXSDAttributes) {
/**
* @type {Array}
*/
- this.features = null;
+ this.features = [];
/**
* @type {?import("ol/Feature.js").default}
@@ -184,8 +184,8 @@ function MainController($http, $q, $scope, gmfThemes, gmfXSDAttributes) {
let i, ii;
// (2) Find OE theme
- /** @type {import('gmf/themes.js').GmfTheme} */
- let theme;
+ /** @type {?import('gmf/themes.js').GmfTheme} */
+ let theme = null;
for (i = 0, ii = themes.length; i < ii; i++) {
if (themes[i].name === this.themeName) {
theme = themes[i];
@@ -202,6 +202,9 @@ function MainController($http, $q, $scope, gmfThemes, gmfXSDAttributes) {
// (4) Set OGC server, which must support WFS for this example to work
console.assert(groupNode.ogcServer);
+ if (!this.gmfServers_) {
+ throw new Error('Missing gmfServers');
+ }
const gmfServer = this.gmfServers_[groupNode.ogcServer];
if (gmfServer && gmfServer.wfsSupport === true && gmfServer.urlWfs) {
this.gmfServer_ = gmfServer;
@@ -232,6 +235,12 @@ function MainController($http, $q, $scope, gmfThemes, gmfXSDAttributes) {
/**
*/
MainController.prototype.runEditor = function() {
+ if (!this.selectedGmfLayerNode) {
+ throw new Error('Missing selectedGmfLayerNode');
+ }
+ if (!this.selectedFeature) {
+ throw new Error('Missing selectedFeature');
+ }
const geomType = this.selectedGeomType;
const feature = this.selectedFeature;
@@ -271,6 +280,9 @@ MainController.prototype.runViewerHosted = function() {
* @private
*/
MainController.prototype.runViewer_ = function(baseUrl) {
+ if (!this.selectedGmfLayerNode) {
+ throw new Error('Missing selectedGmfLayerNode');
+ }
const node = this.selectedGmfLayerNode;
const nodeId = node.id;
@@ -287,7 +299,7 @@ MainController.prototype.runViewer_ = function(baseUrl) {
}
const params = {};
- params['wfs_layer'] = nodeName;
+ params.wfs_layer = nodeName;
params[`wfs_${nodeIdAttrFieldName}`] = ids.join(',');
const url = MainController.appendParams(baseUrl, params);
@@ -321,6 +333,9 @@ MainController.prototype.getFeatures_ = function(gmfLayerNode) {
* @private
*/
MainController.prototype.issueGetFeatures_ = function(gmfLayerNode) {
+ if (!this.gmfServer_) {
+ throw new Error('Missing gmfServer');
+ }
const id = gmfLayerNode.id;
@@ -335,6 +350,9 @@ MainController.prototype.issueGetFeatures_ = function(gmfLayerNode) {
);
this.http_.get(url).then((response) => {
+ if (!this.getFeaturesDeferred_) {
+ throw new Error('Missing getFeaturesDeferred');
+ }
const features = new olFormatWFS().readFeatures(response.data);
this.featuresCache_[id] = features;
this.getFeaturesDeferred_.resolve();
@@ -402,6 +420,9 @@ MainController.prototype.issueGetAttributesRequest_ = function(
* @param {Array} attributes The attributes
*/
function(gmfLayerNode, attributes) {
+ if (!this.getGeometryTypeDeferred_) {
+ throw new Error('Missing getGeometryTypeDeferred');
+ }
// Get geom type from attributes and set
const geomAttr = getGeometryAttribute(attributes);
if (geomAttr && geomAttr.geomType) {
diff --git a/contribs/gmf/examples/profile.js b/contribs/gmf/examples/profile.js
index f03b27cbd6b..5c7bf3dc3e5 100644
--- a/contribs/gmf/examples/profile.js
+++ b/contribs/gmf/examples/profile.js
@@ -46,7 +46,7 @@ module.constant('angularLocaleScript', '../build/angular-locale_{{locale}}.js');
*/
function MainController($scope, ngeoFeatureOverlayMgr) {
/**
- * @type {import("ol/geom/LineString.js").default}
+ * @type {?import("ol/geom/LineString.js").default}
*/
this.profileLine = null;
diff --git a/contribs/gmf/examples/timeslider.js b/contribs/gmf/examples/timeslider.js
index 87193b9bdcd..af4ffdf3e97 100644
--- a/contribs/gmf/examples/timeslider.js
+++ b/contribs/gmf/examples/timeslider.js
@@ -38,8 +38,6 @@ function MainController($scope, ngeoWMSTime) {
widget: TimePropertyWidgetEnum.SLIDER,
maxValue: '2013-12-31T00:00:00Z',
minValue: '2006-01-01T00:00:00Z',
- maxDefValue: null,
- minDefValue: null,
resolution: TimePropertyResolutionEnum.DAY,
mode: TimePropertyModeEnum.RANGE,
interval: [0, 1, 0, 0]
@@ -52,8 +50,6 @@ function MainController($scope, ngeoWMSTime) {
widget: TimePropertyWidgetEnum.SLIDER,
maxValue: '2015-12-31T00:00:00Z',
minValue: '2014-01-01T00:00:00Z',
- maxDefValue: null,
- minDefValue: null,
resolution: TimePropertyResolutionEnum.YEAR,
mode: TimePropertyModeEnum.VALUE,
interval: [0, 0, 1, 0]
@@ -62,12 +58,12 @@ function MainController($scope, ngeoWMSTime) {
/**
* @type {string}
*/
- this.sliderValue;
+ this.sliderValue = '';
/**
* @type {string}
*/
- this.sliderRangeValue;
+ this.sliderRangeValue = '';
this.onDateSelected = function(date) {
this.sliderValue = this.ngeoWMSTime_.formatWMSTimeParam(this.wmsTimeValueMode, date);
diff --git a/contribs/gmf/examples/xsdattributes.js b/contribs/gmf/examples/xsdattributes.js
index 28bd875abc7..865e218a89d 100644
--- a/contribs/gmf/examples/xsdattributes.js
+++ b/contribs/gmf/examples/xsdattributes.js
@@ -156,6 +156,7 @@ MainController.prototype.getDistinctFlatNodes_ = function(node, nodes) {
if (n.id === node.id) {
return alreadyAdded = true;
}
+ return false;
});
if (!alreadyAdded) {
nodes.push(node);
diff --git a/contribs/gmf/src/authentication/Service.js b/contribs/gmf/src/authentication/Service.js
index 2c7fabc7e35..a7c3ba846e7 100644
--- a/contribs/gmf/src/authentication/Service.js
+++ b/contribs/gmf/src/authentication/Service.js
@@ -186,7 +186,7 @@ export class AuthenticationService extends olEventsEventTarget {
* @return {angular.IPromise} Promise.
*/
logout() {
- const noReload = this.getRolesNames().indexOf(this.noReloadRole_) !== -1;
+ const noReload = this.noReloadRole_ ? this.getRolesNames().indexOf(this.noReloadRole_) !== -1 : false;
const url = `${this.baseUrl_}/${RouteSuffix.LOGOUT}`;
return this.$http_.get(url, {withCredentials: true}).then(() => {
this.resetUser_(noReload);
diff --git a/contribs/gmf/src/authentication/component.js b/contribs/gmf/src/authentication/component.js
index 13b37999f65..9ee51a79bac 100644
--- a/contribs/gmf/src/authentication/component.js
+++ b/contribs/gmf/src/authentication/component.js
@@ -34,7 +34,7 @@ const module = angular.module('gmfAuthentication', [
* @hidden
*/
function gmfAuthenticationTemplateUrl_(element, attrs) {
- const templateUrl = attrs['gmfAuthenticationTemplateurl'];
+ const templateUrl = attrs.gmfAuthenticationTemplateurl;
return templateUrl !== undefined ? templateUrl :
'gmf/authentication';
}
@@ -185,12 +185,12 @@ class AuthenticationController {
/**
* @type {boolean}
*/
- this.allowPasswordReset;
+ this.allowPasswordReset = false;
/**
* @type {boolean}
*/
- this.allowPasswordChange;
+ this.allowPasswordChange = false;
/**
* @type {PasswordValidator?}
@@ -200,7 +200,7 @@ class AuthenticationController {
/**
* @type {boolean}
*/
- this.forcePasswordChange;
+ this.forcePasswordChange = false;
/**
* @type {?string}
@@ -429,11 +429,14 @@ class AuthenticationController {
}
errors.forEach((error) => {
- this.notification_.notify({
+ const options = {
msg: error,
target: container,
- type: messageType
- });
+ };
+ if (messageType) {
+ options.type = messageType;
+ }
+ this.notification_.notify(options);
});
}
diff --git a/contribs/gmf/src/backgroundlayerselector/component.js b/contribs/gmf/src/backgroundlayerselector/component.js
index 5cd755755af..b9968016c83 100644
--- a/contribs/gmf/src/backgroundlayerselector/component.js
+++ b/contribs/gmf/src/backgroundlayerselector/component.js
@@ -20,7 +20,7 @@ module.value('gmfBackgroundlayerselectorTemplateUrl',
* @return {string} Template URL.
*/
($element, $attrs) => {
- const templateUrl = $attrs['gmfBackgroundlayerselectorTemplateurl'];
+ const templateUrl = $attrs.gmfBackgroundlayerselectorTemplateurl;
return templateUrl !== undefined ? templateUrl :
'gmf/backgroundlayerselector';
}
@@ -102,7 +102,7 @@ function Controller($scope, ngeoBackgroundLayerMgr, gmfThemes) {
/**
* @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
* @type {!string|undefined}
@@ -113,22 +113,22 @@ function Controller($scope, ngeoBackgroundLayerMgr, gmfThemes) {
* Function called when a layer was selected by the user.
* @type {?Function}
*/
- this.select;
+ this.select = null;
/**
* @type {?import("ol/layer/Base.js").default}
*/
- this.bgLayer;
+ this.bgLayer = null;
/**
* @type {?Array.}
*/
- this.bgLayers;
+ this.bgLayers = null;
/**
- * @type {import("ol/layer/Base.js").default}
+ * @type {?import("ol/layer/Base.js").default}
*/
- this.opacityLayer;
+ this.opacityLayer = null;
/**
* @type {!import("gmf/theme/Themes.js").ThemesService}
@@ -201,7 +201,10 @@ Controller.prototype.handleThemesChange_ = function() {
* @returns {number} The background layer opacity.
*/
Controller.prototype.getSetBgLayerOpacity = function(val) {
- if (val !== undefined) {
+ if (!this.opacityLayer) {
+ throw new Error('Missing opacityLayer');
+ }
+ if (val !== null) {
this.opacityLayer.setOpacity(val);
}
return this.opacityLayer.getOpacity();
@@ -212,6 +215,9 @@ Controller.prototype.getSetBgLayerOpacity = function(val) {
* @param {boolean=} opt_silent Do not notify listeners.
*/
Controller.prototype.setLayer = function(layer, opt_silent) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.bgLayer = layer;
this.backgroundLayerMgr_.set(this.map, layer);
if (!opt_silent && this.select) {
@@ -224,6 +230,9 @@ Controller.prototype.setLayer = function(layer, opt_silent) {
* @param {import("ol/layer/Base.js").default} layer The opacity background layer.
*/
Controller.prototype.setOpacityBgLayer = function(layer) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.backgroundLayerMgr_.setOpacityBgLayer(this.map, layer);
};
diff --git a/contribs/gmf/src/contextualdata/component.js b/contribs/gmf/src/contextualdata/component.js
index bfce6b60800..d78c22abf2c 100644
--- a/contribs/gmf/src/contextualdata/component.js
+++ b/contribs/gmf/src/contextualdata/component.js
@@ -62,9 +62,12 @@ function contextualDataComponent() {
* @param {angular.IScope} scope Scope.
* @param {JQuery} element Element.
* @param {angular.IAttributes} attrs Attributes.
- * @param {angular.IController} controller Controller.
+ * @param {angular.IController=} controller Controller.
*/
link: (scope, element, attrs, controller) => {
+ if (!controller) {
+ throw new Error('Missing controller');
+ }
controller.init();
}
};
@@ -88,25 +91,25 @@ module.directive('gmfContextualdata', contextualDataComponent);
export function ContextualdataController($compile, $timeout, $scope, gmfRaster, $injector) {
/**
- * @type {import("ol/Map.js").default}
+ * @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
* @type {Array}
*/
- this.projections;
+ this.projections = [];
/**
* @type {function(import("ol/coordinate.js").Coordinate, Object):Object}
*/
- this.callback;
+ this.callback = (c, o) => ({});
/**
- * @type {import("ol/Overlay.js").default}
+ * @type {?import("ol/Overlay.js").default}
* @private
*/
- this.overlay_;
+ this.overlay_ = null;
/**
* @type {angular.ICompileService}
@@ -147,6 +150,9 @@ export function ContextualdataController($compile, $timeout, $scope, gmfRaster,
*/
ContextualdataController.prototype.init = function() {
this.preparePopover_();
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const mapDiv = this.map.getTargetElement();
console.assert(mapDiv);
@@ -161,6 +167,9 @@ ContextualdataController.prototype.init = function() {
*/
ContextualdataController.prototype.handleMapContextMenu_ = function(event) {
this.$scope_.$apply(() => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const pixel = this.map.getEventPixel(event);
const coordinate = this.map.getCoordinateFromPixel(pixel);
this.setContent_(coordinate);
@@ -170,12 +179,21 @@ ContextualdataController.prototype.handleMapContextMenu_ = function(event) {
// Use timeout to let the popover content to be rendered before displaying it.
this.timeout_(() => {
+ if (!this.overlay_) {
+ throw new Error('Missing overlay');
+ }
this.overlay_.setPosition(coordinate);
});
});
};
ContextualdataController.prototype.setContent_ = function(coordinate) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
+ if (!this.content_) {
+ throw new Error('Missing content');
+ }
const scope = this.$scope_.$new(true);
this.$compile_(this.content_)(scope);
@@ -207,6 +225,9 @@ ContextualdataController.prototype.setContent_ = function(coordinate) {
* @private
*/
ContextualdataController.prototype.preparePopover_ = function() {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const container = document.createElement('DIV');
container.classList.add('popover');
@@ -234,11 +255,25 @@ ContextualdataController.prototype.preparePopover_ = function() {
};
ContextualdataController.prototype.showPopover = function() {
- this.overlay_.getElement().style.display = 'block';
+ if (!this.overlay_) {
+ throw new Error('Missing overlay');
+ }
+ const element = this.overlay_.getElement();
+ if (!element) {
+ throw new Error('Missing element');
+ }
+ element.style.display = 'block';
};
ContextualdataController.prototype.hidePopover = function() {
- this.overlay_.getElement().style.display = 'none';
+ if (!this.overlay_) {
+ throw new Error('Missing overlay');
+ }
+ const element = this.overlay_.getElement();
+ if (!element) {
+ throw new Error('Missing element');
+ }
+ element.style.display = 'none';
};
module.controller('GmfContextualdataController', ContextualdataController);
diff --git a/contribs/gmf/src/controllers/AbstractAPIController.js b/contribs/gmf/src/controllers/AbstractAPIController.js
index 2edc984c2b9..ced2d31693b 100644
--- a/contribs/gmf/src/controllers/AbstractAPIController.js
+++ b/contribs/gmf/src/controllers/AbstractAPIController.js
@@ -30,13 +30,17 @@ export class AbstractAPIController extends AbstractAppController {
};
Object.assign(viewConfig, config.mapViewConfig || {});
+ const scaleline = document.getElementById('scaleline');
+ if (!scaleline) {
+ throw new Error('Missing scaleline');
+ }
super(config, new olMap({
pixelRatio: config.mapPixelRatio,
layers: [],
view: new olView(viewConfig),
controls: config.mapControls || [
new olControlScaleLine({
- target: document.getElementById('scaleline')
+ target: scaleline
}),
new olControlZoom({
zoomInTipLabel: '',
diff --git a/contribs/gmf/src/controllers/AbstractAppController.js b/contribs/gmf/src/controllers/AbstractAppController.js
index f98cdbd8854..aa839c2c4b6 100644
--- a/contribs/gmf/src/controllers/AbstractAppController.js
+++ b/contribs/gmf/src/controllers/AbstractAppController.js
@@ -230,6 +230,9 @@ export function AbstractAppController(config, map, $scope, $injector) {
if (evt.type !== 'ready') {
const themeName = this.permalink_.defaultThemeNameFromFunctionalities();
+ if (!themeName) {
+ throw new Error('Missing themeName');
+ }
this.gmfThemeManager.updateCurrentTheme(themeName, previousThemeName);
}
this.setDefaultBackground_(null);
@@ -244,7 +247,6 @@ export function AbstractAppController(config, map, $scope, $injector) {
* @type {Array}
*/
this.searchDatasources = [{
- datasetTitle: undefined,
labelKey: 'label',
groupValues: /** @type {Array} **/ ($injector.get('gmfSearchGroups')),
groupActions: /** @type {Array} **/(
@@ -432,7 +434,7 @@ export function AbstractAppController(config, map, $scope, $injector) {
/**
* @type {string}
*/
- this.lang;
+ this.lang = '';
/**
* Default language
@@ -671,7 +673,7 @@ export function AbstractAppController(config, map, $scope, $injector) {
/**
* @param {Array} layers Layers list.
* @param {Array} labels default_basemap list.
- * @return {import("ol/layer/Base.js").default} layer or null
+ * @return {?import("ol/layer/Base.js").default} layer or null
* @private
* @hidden
*/
@@ -726,7 +728,7 @@ AbstractAppController.prototype.initLanguage = function() {
/**
- * @param {import('gmf/themes.js').GmfTheme} theme Theme.
+ * @param {?import('gmf/themes.js').GmfTheme} theme Theme.
* @private
*/
AbstractAppController.prototype.setDefaultBackground_ = function(theme) {
diff --git a/contribs/gmf/src/controllers/AbstractDesktopController.js b/contribs/gmf/src/controllers/AbstractDesktopController.js
index 9ec360047ea..cc5a008787b 100644
--- a/contribs/gmf/src/controllers/AbstractDesktopController.js
+++ b/contribs/gmf/src/controllers/AbstractDesktopController.js
@@ -149,7 +149,7 @@ export class AbstractDesktopController extends AbstractAPIController {
};
/**
- * @type {import("ol/geom/LineString.js").default}
+ * @type {?import("ol/geom/LineString.js").default}
*/
this.profileLine = null;
@@ -246,7 +246,11 @@ export class AbstractDesktopController extends AbstractAPIController {
this.$dataPanel_.resizable('option', 'maxWidth', maxWidth);
- if (this.$dataPanel_.width() > maxWidth) {
+ const width = this.$dataPanel_.width();
+ if (!width) {
+ throw new Error('Missing width');
+ }
+ if (width > maxWidth) {
this.$dataPanel_.width(maxWidth);
this.map.updateSize();
}
diff --git a/contribs/gmf/src/controllers/bootstrap.js b/contribs/gmf/src/controllers/bootstrap.js
index 296c2b97bfe..c71bae43b20 100644
--- a/contribs/gmf/src/controllers/bootstrap.js
+++ b/contribs/gmf/src/controllers/bootstrap.js
@@ -27,9 +27,8 @@ function bootstrap(module) {
const interface_ = $('meta[name=interface]')[0].getAttribute('content');
const dynamicUrl_ = $('meta[name=dynamicUrl]')[0].getAttribute('content');
- const dynamicUrl = `${dynamicUrl_}?interface=${interface_}&query=${encodeURIComponent(
- document.location.search
- )}`;
+ const search = document.location ? document.location.search || '' : '';
+ const dynamicUrl = `${dynamicUrl_}?interface=${interface_}&query=${encodeURIComponent(search)}`;
const request = $.ajax(dynamicUrl, {
'dataType': 'json',
'xhrFields': {
@@ -40,15 +39,15 @@ function bootstrap(module) {
window.alert(`Failed to get the dynamic: ${textStatus}`);
});
request.done((dynamic) => {
- if (dynamic['doRedirect']) {
+ if (dynamic.doRedirect) {
const small_screen = window.matchMedia ? window.matchMedia('(max-width: 1024px)') : false;
if (small_screen && TOUCH) {
- window.location.href = dynamic['redirectUrl'];
+ window.location.href = dynamic.redirectUrl;
}
}
- for (const name in dynamic['constants']) {
- module.constant(name, dynamic['constants'][name]);
+ for (const name in dynamic.constants) {
+ module.constant(name, dynamic.constants[name]);
}
angular.bootstrap(document, [`App${interface_}`]);
diff --git a/contribs/gmf/src/datasource/ExternalDataSourcesManager.js b/contribs/gmf/src/datasource/ExternalDataSourcesManager.js
index 0cff7edb86c..7953560c943 100644
--- a/contribs/gmf/src/datasource/ExternalDataSourcesManager.js
+++ b/contribs/gmf/src/datasource/ExternalDataSourcesManager.js
@@ -283,10 +283,11 @@ export class ExternalDatSourcesManager {
* this service.
*/
get layerGroup() {
- const map = this.map_;
- console.assert(map);
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
return this.ngeoLayerHelper_.getGroupFromMap(
- map,
+ this.map_,
EXTERNALLAYERGROUP_NAME
);
}
@@ -322,9 +323,9 @@ export class ExternalDatSourcesManager {
createAndAddDataSourceFromWMSCapability(layer, capabilities, url) {
const id = getId(layer);
- const service = capabilities['Service'];
+ const service = capabilities.Service;
- url = service['OnlineResource'] || url;
+ url = service.OnlineResource || url;
let dataSource;
@@ -332,39 +333,42 @@ export class ExternalDatSourcesManager {
if (this.extDataSources_[id]) {
dataSource = this.extDataSources_[id];
} else {
- const req = capabilities['Capability']['Request'];
+ const req = capabilities.Capability.Request;
// ogcImageType
- const formats = req['GetMap']['Format'];
+ const formats = req.GetMap.Format;
const imagePngType = 'image/png';
const ogcImageType = formats.includes(imagePngType) ?
imagePngType : formats[0];
// wmsInfoFormat
- const infoFormats = req['GetFeatureInfo']['Format'];
+ const infoFormats = req.GetFeatureInfo.Format;
const wmsInfoFormat = infoFormats.includes(
WMSInfoFormat.GML
) ? WMSInfoFormat.GML : undefined;
// queryable
- const queryable = layer['queryable'] === true &&
+ const queryable = layer.queryable === true &&
wmsInfoFormat !== undefined;
// TODO - MaxScaleDenominator
// TODO - MinScaleDenominator
- dataSource = new ngeoDatasourceOGC({
+ const options = {
id: id,
- name: layer['Title'],
+ name: layer.Title,
ogcImageType: ogcImageType,
ogcLayers: [{
- name: layer['Name'],
+ name: layer.Name,
queryable: queryable
}],
ogcType: Type.WMS,
visible: true,
- wmsInfoFormat: wmsInfoFormat,
wmsUrl: url
- });
+ };
+ if (wmsInfoFormat) {
+ options.wmsInfoFormat = wmsInfoFormat;
+ }
+ dataSource = new ngeoDatasourceOGC(options);
// Keep a reference to the external data source in the cache
this.extDataSources_[id] = dataSource;
@@ -385,7 +389,7 @@ export class ExternalDatSourcesManager {
wmsGroup = new ngeoDatasourceWMSGroup({
dataSources: [dataSource],
injector: this.injector_,
- title: service['Title'],
+ title: service.Title,
url: url
}, this.ngeoLayerHelper_);
this.addLayer_(wmsGroup.layer);
@@ -415,8 +419,8 @@ export class ExternalDatSourcesManager {
dataSource = this.extDataSources_[id];
} else {
- const name = typeof layer['Title'];
- const wmtsLayer = typeof layer['Identifier'];
+ const name = typeof layer.Title;
+ const wmtsLayer = typeof layer.Identifier;
// TODO - MaxScaleDenominator
// TODO - MinScaleDenominator
@@ -438,7 +442,7 @@ export class ExternalDatSourcesManager {
if (!wmtsGroup) {
wmtsGroup = new ngeoDatasourceOGCGroup({
dataSources: [],
- title: capabilities['ServiceIdentification']['Title'],
+ title: capabilities.ServiceIdentification.Title,
url: wmtsUrl
});
this.addWMTSGroup_(wmtsGroup);
@@ -483,6 +487,9 @@ export class ExternalDatSourcesManager {
success = false;
} else {
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
// (1) No need to do anything if the file has already been added...
if (fileGroup.dataSources.includes(dataSource)) {
return;
@@ -530,6 +537,9 @@ export class ExternalDatSourcesManager {
} else {
const ngeoFile = this.ngeoFile_;
ngeoFile.read(file).then((content) => {
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
let features;
const readOptions = {
featureProjection: this.map_.getView().getProjection()
@@ -625,10 +635,11 @@ export class ExternalDatSourcesManager {
removeOGCDataSource_(dataSource) {
if (dataSource.ogcType === Type.WMS) {
// WMS data source
- const url = dataSource.wmsUrl;
- console.assert(url);
+ if (!dataSource.wmsUrl) {
+ throw new Error('Missing dataSource.wmsUrl');
+ }
- const wmsGroup = this.getWMSGroup(url);
+ const wmsGroup = this.getWMSGroup(dataSource.wmsUrl);
if (wmsGroup && wmsGroup.dataSources.includes(dataSource)) {
// Remove from group
wmsGroup.removeDataSource(dataSource);
@@ -643,10 +654,11 @@ export class ExternalDatSourcesManager {
}
} else if (dataSource.ogcType === Type.WMTS) {
// WMTS data source
- const url = dataSource.wmtsUrl;
- console.assert(url);
+ if (!dataSource.wmtsUrl) {
+ throw new Error('Missing dataSource.wmsUrl');
+ }
- const wmtsGroup = this.getWMTSGroup(url);
+ const wmtsGroup = this.getWMTSGroup(dataSource.wmtsUrl);
if (wmtsGroup && wmtsGroup.dataSources.includes(dataSource)) {
// Remove from group
wmtsGroup.removeDataSource(dataSource);
diff --git a/contribs/gmf/src/datasource/Helper.js b/contribs/gmf/src/datasource/Helper.js
index f67ba12b363..6b10eab33db 100644
--- a/contribs/gmf/src/datasource/Helper.js
+++ b/contribs/gmf/src/datasource/Helper.js
@@ -50,16 +50,16 @@ export class DatasourceHelper {
// === Other properties ===
/**
- * @type {import('ngeo/datasource/DataSource.js').DataSources}
+ * @type {?import('ngeo/datasource/DataSource.js').DataSources}
* @protected
*/
- this.collection_;
+ this.collection_ = null;
/**
- * @type {Object.}
+ * @type {Object}
* @protected
*/
- this.cache_;
+ this.cache_ = {};
}
/**
diff --git a/contribs/gmf/src/datasource/Manager.js b/contribs/gmf/src/datasource/Manager.js
index 422e9536012..e63e7adbf85 100644
--- a/contribs/gmf/src/datasource/Manager.js
+++ b/contribs/gmf/src/datasource/Manager.js
@@ -5,7 +5,7 @@ import gmfLayertreeSyncLayertreeMap, {getLayer} from 'gmf/layertree/SyncLayertre
import gmfLayertreeTreeManager from 'gmf/layertree/TreeManager.js';
import gmfThemeThemes, {ThemeNodeType} from 'gmf/theme/Themes.js';
-import {ServerType, WFSOutputFormat, Type} from 'ngeo/datasource/OGC.js';
+import OGC, {ServerType, WFSOutputFormat, Type} from 'ngeo/datasource/OGC.js';
import ngeoDatasourceDataSources from 'ngeo/datasource/DataSources.js';
import ngeoFilterRuleHelper from 'ngeo/filter/RuleHelper.js';
@@ -412,15 +412,15 @@ export class DatasourceManager {
*
* Once a data source is created, it is added to the data sources cache.
*
- * @param {import('gmf/themes.js').GmfGroup} firstLevelGroup The first level group node.
- * @param {!import('gmf/themes.js').GmfGroup|!import('gmf/themes.js').GmfLayer} node The node, which
+ * @param {?import('gmf/themes.js').GmfGroup} firstLevelGroup The first level group node.
+ * @param {import('gmf/themes.js').GmfGroup|import('gmf/themes.js').GmfLayer} node The node, which
* may have children or not.
- * @param {!import('gmf/themes.js').GmfOgcServers} ogcServers OGC servers.
+ * @param {import('gmf/themes.js').GmfOgcServers} ogcServers OGC servers.
* @private
*/
createDataSource_(firstLevelGroup, node, ogcServers) {
- const groupNode = /** @type {!import('gmf/themes.js').GmfGroup} */ (node);
+ const groupNode = /** @type {import('gmf/themes.js').GmfGroup} */ (node);
const children = groupNode.children;
// (1) Group node (node that has children). Loop in the children
@@ -537,14 +537,14 @@ export class DatasourceManager {
// (7) Dimensions
const dimensions = this.dimensions_;
- const dimensionsConfig = node.dimensions || firstLevelGroup.dimensions;
+ const dimensionsConfig = node.dimensions || firstLevelGroup === null ? {} : firstLevelGroup.dimensions;
const dimensionsFiltersConfig = gmfLayer.dimensionsFilters;
// (8) Time values (lower or lower/upper)
let timeLowerValue;
let timeUpperValue;
if (timeProperty) {
- const timeValues = this.ngeoWMSTime_.getOptions(timeProperty)['values'];
+ const timeValues = this.ngeoWMSTime_.getOptions(timeProperty).values;
if (Array.isArray(timeValues)) {
timeLowerValue = timeValues[0];
timeUpperValue = timeValues[1];
@@ -560,39 +560,76 @@ export class DatasourceManager {
const timeAttributeName = meta.timeAttribute;
const visible = meta.isChecked === true;
- // Create the data source and add it to the cache
- this.dataSourcesCache_[id] = new gmfDatasourceOGC({
+ const options = {
copyable,
- dimensions,
dimensionsConfig,
dimensionsFiltersConfig,
gmfLayer,
id,
identifierAttribute,
- maxResolution,
- minResolution,
name,
- ogcImageType,
- ogcLayers,
- ogcServerType,
- wfsFeatureNS,
ogcType,
snappable,
- snappingTolerance,
- snappingToEdges,
- snappingToVertice,
timeAttributeName,
- timeLowerValue,
- timeProperty,
- timeUpperValue,
visible,
wfsOutputFormat,
- wfsUrl,
- wmsIsSingleTile,
- wmsUrl,
- wmtsLayer,
- wmtsUrl
- });
+ };
+ if (dimensions) {
+ options.dimensions = dimensions;
+ }
+ if (maxResolution) {
+ options.maxResolution = maxResolution;
+ }
+ if (minResolution) {
+ options.minResolution = minResolution;
+ }
+ if (ogcImageType) {
+ options.ogcImageType = ogcImageType;
+ }
+ if (ogcLayers) {
+ options.ogcLayers = ogcLayers;
+ }
+ if (ogcServerType) {
+ options.ogcServerType = ogcServerType;
+ }
+ if (wfsFeatureNS) {
+ options.wfsFeatureNS = wfsFeatureNS;
+ }
+ if (snappingTolerance) {
+ options.snappingTolerance = snappingTolerance;
+ }
+ if (snappingToEdges) {
+ options.snappingToEdges = snappingToEdges;
+ }
+ if (snappingToVertice) {
+ options.snappingToVertice = snappingToVertice;
+ }
+ if (timeLowerValue) {
+ options.timeLowerValue = timeLowerValue;
+ }
+ if (timeProperty) {
+ options.timeProperty = timeProperty;
+ }
+ if (timeUpperValue) {
+ options.timeUpperValue = timeUpperValue;
+ }
+ if (wfsUrl) {
+ options.wfsUrl = wfsUrl;
+ }
+ if (wmsIsSingleTile) {
+ options.wmsIsSingleTile = wmsIsSingleTile;
+ }
+ if (wmsUrl) {
+ options.wmsUrl = wmsUrl;
+ }
+ if (wmtsLayer) {
+ options.wmtsLayer = wmtsLayer;
+ }
+ if (wmtsUrl) {
+ options.wmtsUrl = wmtsUrl;
+ }
+ // Create the data source and add it to the cache
+ this.dataSourcesCache_[id] = new gmfDatasourceOGC(options);
}
/**
@@ -672,7 +709,9 @@ export class DatasourceManager {
// (1) Remove data source
const dataSource = item.treeCtrl.getDataSource();
- console.assert(dataSource, 'DataSource should be set');
+ if (!dataSource) {
+ throw new Error('DataSource should be set');
+ }
this.dataSources_.remove(dataSource);
// (2) Remove item and clear event listeners
@@ -715,7 +754,9 @@ export class DatasourceManager {
*/
handleTreeCtrlStateChange_(treeCtrl, newVal) {
const treeDataSource = treeCtrl.getDataSource();
- console.assert(treeDataSource, 'DataSource should be set');
+ if (!treeDataSource) {
+ throw new Error('DataSource should be set');
+ }
const visible = newVal === 'on';
treeDataSource.visible = visible;
@@ -775,14 +816,16 @@ export class DatasourceManager {
layer instanceof olLayerTile
);
- const source = /** @type {olLayerImage|olLayerTile} */ (layer).getSource();
- if (!(source instanceof olSourceImageWMS ||
- source instanceof olSourceTileWMS)) {
+ if (!(layer instanceof olLayerImage || layer instanceof olLayerTile)) {
+ return;
+ }
+ const source = layer.getSource();
+ if (!(source instanceof olSourceImageWMS || source instanceof olSourceTileWMS)) {
return;
}
const params = source.getParams();
- const layersParam = params['LAYERS'];
+ const layersParam = params.LAYERS;
const layersList = layersParam.split(',');
console.assert(layersList.length >= 1);
@@ -810,6 +853,9 @@ export class DatasourceManager {
const treeCtrl = item.treeCtrl;
const projCode = treeCtrl.map.getView().getProjection().getCode();
+ if (!(dataSource instanceof OGC)) {
+ throw new Error('Wrong datasource');
+ }
const filterString = dataSource.visible ?
this.ngeoRuleHelper_.createFilterString({
dataSource: dataSource,
@@ -883,12 +929,15 @@ export class DatasourceManager {
let timeParam;
const range = dataSource.timeRangeValue;
if (range) {
+ if (!timeProperty) {
+ throw new Error('Missing timeProperty');
+ }
timeParam = this.ngeoWMSTime_.formatWMSTimeParam(timeProperty, range);
}
// No need to update the TIME param if already the same value;
const params = wmsSource.getParams();
- const currentTimeParam = params['TIME'];
+ const currentTimeParam = params.TIME;
if (currentTimeParam === timeParam) {
return;
}
@@ -897,7 +946,7 @@ export class DatasourceManager {
// gets reset.
this.ngeoLayerHelper_.updateWMSLayerState(
wmsLayer,
- wmsSource.getParams()['LAYERS'],
+ wmsSource.getParams().LAYERS,
timeParam
);
}
diff --git a/contribs/gmf/src/disclaimer/component.js b/contribs/gmf/src/disclaimer/component.js
index 23f1110d0b8..a40e6c5f18a 100644
--- a/contribs/gmf/src/disclaimer/component.js
+++ b/contribs/gmf/src/disclaimer/component.js
@@ -61,7 +61,7 @@ function Controller(
/**
* @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
* @type {boolean|undefined}
@@ -149,6 +149,9 @@ function Controller(
* Initialise the controller.
*/
Controller.prototype.$onInit = function() {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.layerVisibility = this.layerVisibility !== undefined ? this.layerVisibility : true;
this.dataLayerGroup_ = this.ngeoLayerHelper_.getGroupFromMap(this.map, DATALAYERGROUP_NAME);
@@ -279,6 +282,9 @@ Controller.prototype.unregisterLayer_ = function(layer) {
Controller.prototype.$onDestroy = function() {
+ if (!this.dataLayerGroup_) {
+ throw new Error('Missing dataLayerGroup');
+ }
this.unregisterLayer_(this.dataLayerGroup_);
};
@@ -296,12 +302,15 @@ Controller.prototype.showDisclaimerMessage_ = function(msg) {
this.msg = `${this.sce_.trustAsHtml(this.msgs_.join('
'))}`;
this.visibility = true;
} else {
- this.disclaimer_.alert({
- popup: this.popup,
+ const options = {
msg: msg,
target: this.element_,
type: MessageType.WARNING
- });
+ };
+ if (this.popup) {
+ options.popup = this.popup;
+ }
+ this.disclaimer_.alert(options);
}
};
@@ -317,12 +326,15 @@ Controller.prototype.closeDisclaimerMessage_ = function(msg) {
this.msgs_.length = 0;
this.msg = '';
} else {
- this.disclaimer_.close({
- popup: this.popup,
+ const options = {
msg: msg,
target: this.element_,
type: MessageType.WARNING
- });
+ };
+ if (this.popup) {
+ options.popup = this.popup;
+ }
+ this.disclaimer_.close(options);
}
};
diff --git a/contribs/gmf/src/drawing/drawFeatureComponent.js b/contribs/gmf/src/drawing/drawFeatureComponent.js
index 716b68f6e49..8e1eb371ae6 100644
--- a/contribs/gmf/src/drawing/drawFeatureComponent.js
+++ b/contribs/gmf/src/drawing/drawFeatureComponent.js
@@ -105,18 +105,14 @@ module.directive('gmfDrawfeature', drawinfDrawFeatureComponent);
function Controller($scope, $timeout, gettextCatalog, ngeoFeatureHelper, ngeoFeatures, ngeoToolActivateMgr) {
/**
- * @type {!import("ol/Map.js").default}
+ * @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
* @type {boolean}
*/
- this.active;
-
- if (this.active === undefined) {
- this.active = false;
- }
+ this.active = false;
/**
* @type {boolean}
@@ -297,6 +293,9 @@ function Controller($scope, $timeout, gettextCatalog, ngeoFeatureHelper, ngeoFea
$scope.$watch(
() => this.selectedFeature,
(newFeature, previousFeature) => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.selectedFeatures.clear();
if (previousFeature) {
this.featureHelper_.setStyle(previousFeature);
@@ -340,6 +339,12 @@ function Controller($scope, $timeout, gettextCatalog, ngeoFeatureHelper, ngeoFea
*/
Controller.prototype.closeMenu_ = function() {
if (this.menu_) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
+ if (!this.menuListenerKey_) {
+ throw new Error('Missing menuListenerKey');
+ }
this.map.removeOverlay(this.menu_);
this.menu_ = null;
olEvents.unlistenByKey(this.menuListenerKey_);
@@ -365,6 +370,9 @@ Controller.prototype.initializeInteractions_ = function() {
*/
Controller.prototype.registerInteractions_ = function() {
this.interactions_.forEach((interaction) => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.map.addInteraction(interaction);
});
};
@@ -376,6 +384,9 @@ Controller.prototype.registerInteractions_ = function() {
*/
Controller.prototype.unregisterInteractions_ = function() {
this.interactions_.forEach((interaction) => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.map.removeInteraction(interaction);
});
};
@@ -516,8 +527,10 @@ Controller.prototype.handleFeaturesRemove_ = function(evt) {
* @param {boolean} active Whether the map select is active or not.
* @private
*/
-Controller.prototype.handleMapSelectActiveChange_ = function(
- active) {
+Controller.prototype.handleMapSelectActiveChange_ = function(active) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const mapDiv = this.map.getViewport();
console.assert(mapDiv);
@@ -544,9 +557,12 @@ Controller.prototype.handleMapSelectActiveChange_ = function(
*/
Controller.prototype.handleMapClick_ = function(evt) {
if (evt instanceof MapBrowserEvent) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const pixel = evt.pixel;
- let feature = /** @type {import('ol/Feature.js').default|undefined} */ (this.map.forEachFeatureAtPixel(
+ let feature = this.map.forEachFeatureAtPixel(
pixel,
(feature) => {
let ret = null;
@@ -561,7 +577,7 @@ Controller.prototype.handleMapClick_ = function(evt) {
hitTolerance: 5,
layerFilter: undefined
}
- ));
+ );
feature = feature ? feature : null;
@@ -593,6 +609,9 @@ Controller.prototype.handleMapTouchStart_ = function(evt) {
* @private
*/
Controller.prototype.handleMapTouchEnd_ = function(evt) {
+ if (!this.longPressTimeout_) {
+ throw new Error('Missing longPressTimeout');
+ }
clearTimeout(this.longPressTimeout_);
};
@@ -603,11 +622,14 @@ Controller.prototype.handleMapTouchEnd_ = function(evt) {
*/
Controller.prototype.handleMapContextMenu_ = function(evt) {
if (evt instanceof Event) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const gettextCatalog = this.gettextCatalog_;
const pixel = this.map.getEventPixel(evt);
const coordinate = this.map.getCoordinateFromPixel(pixel);
- let feature = /** @type {import('ol/Feature.js').default|undefined} */ (this.map.forEachFeatureAtPixel(
+ let feature = this.map.forEachFeatureAtPixel(
pixel,
(feature) => {
if (feature instanceof Feature) {
@@ -622,7 +644,7 @@ Controller.prototype.handleMapContextMenu_ = function(evt) {
hitTolerance: 7,
layerFilter: undefined
}
- ));
+ );
feature = feature ? feature : null;
@@ -632,9 +654,11 @@ Controller.prototype.handleMapContextMenu_ = function(evt) {
this.closeMenu_();
let actions = [];
-
- const vertexInfo = this.featureHelper_.getVertexInfoAtCoordinate(
- feature, coordinate, this.map.getView().getResolution());
+ const resolution = this.map.getView().getResolution();
+ if (!resolution) {
+ throw new Error('Missing resolution');
+ }
+ const vertexInfo = this.featureHelper_.getVertexInfoAtCoordinate(feature, coordinate, resolution);
if (!vertexInfo) {
const type = this.featureHelper_.getType(feature);
if (type == ngeoGeometryType.CIRCLE ||
@@ -696,6 +720,9 @@ Controller.prototype.handleMapContextMenu_ = function(evt) {
*/
Controller.prototype.handleMenuActionClick_ = function(vertexInfo, evt) {
const action = /** @type{import('ngeo/filter/ruleComponent.js').MenuEvent} */(evt).detail.action;
+ if (!this.selectedFeature) {
+ throw new Error('Missing selectedFeature');
+ }
switch (action) {
case 'delete':
diff --git a/contribs/gmf/src/drawing/featureStyleComponent.js b/contribs/gmf/src/drawing/featureStyleComponent.js
index a2c9dc69a23..27875bd7dc0 100644
--- a/contribs/gmf/src/drawing/featureStyleComponent.js
+++ b/contribs/gmf/src/drawing/featureStyleComponent.js
@@ -74,7 +74,7 @@ function Controller($scope, ngeoFeatureHelper) {
/**
* @type {?import("ol/Feature.js").default}
*/
- this.feature;
+ this.feature = null;
/**
* @type {!angular.IScope}
@@ -168,7 +168,9 @@ Controller.prototype.handleFeatureSet_ = function(newFeature, previousFeature) {
});
const geometry = newFeature.getGeometry();
- console.assert(geometry, 'Geometry should be thruthy');
+ if (!geometry) {
+ throw new Error('Missing geometry');
+ }
keys.push(
olEvents.listen(
@@ -271,6 +273,9 @@ Controller.prototype.getSetStroke = function(value) {
* @private
*/
Controller.prototype.getSetProperty_ = function(key, value) {
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
if (value !== undefined) {
this.feature.set(key, value);
}
@@ -296,7 +301,9 @@ Controller.prototype.handleFeatureChange_ = function() {
* @private
*/
Controller.prototype.handleGeometryChange_ = function() {
- console.assert(this.feature);
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
this.measure = this.featureHelper_.getMeasure(this.feature);
const showMeasure = this.featureHelper_.getShowMeasureProperty(this.feature);
diff --git a/contribs/gmf/src/editing/Snapping.js b/contribs/gmf/src/editing/Snapping.js
index 802c59cb060..9505b079632 100644
--- a/contribs/gmf/src/editing/Snapping.js
+++ b/contribs/gmf/src/editing/Snapping.js
@@ -124,14 +124,18 @@ export function EditingSnappingService($http, $q, $rootScope, $timeout, gmfTheme
*
*/
EditingSnappingService.prototype.ensureSnapInteractionsOnTop = function() {
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
const map = this.map_;
- console.assert(map);
let item;
for (const uid in this.cache_) {
item = this.cache_[+uid];
if (item.active) {
- console.assert(item.interaction);
+ if (!item.interaction) {
+ throw new Error('Missing item.interaction');
+ }
map.removeInteraction(item.interaction);
map.addInteraction(item.interaction);
}
@@ -148,6 +152,9 @@ EditingSnappingService.prototype.setMap = function(map) {
const keys = this.listenerKeys_;
if (this.map_) {
+ if (!this.treeCtrlsUnregister_) {
+ throw new Error('Missing treeCtrlsUnregister');
+ }
this.treeCtrlsUnregister_();
this.unregisterAllTreeCtrl_();
keys.forEach(olEvents.unlistenByKey);
@@ -166,6 +173,9 @@ EditingSnappingService.prototype.setMap = function(map) {
// leaf nodes are created and they are the ones we're looking for here.
this.timeout_(() => {
if (value) {
+ if (!this.gmfTreeManager_.rootCtrl) {
+ throw new Error('Missing gmfTreeManager_.rootCtrl');
+ }
this.unregisterAllTreeCtrl_();
this.gmfTreeManager_.rootCtrl.traverseDepthFirst(this.registerTreeCtrl_.bind(this));
}
@@ -226,6 +236,9 @@ EditingSnappingService.prototype.registerTreeCtrl_ = function(treeCtrl) {
);
const ogcServer = this.getOGCServer_(treeCtrl);
+ if (!ogcServer) {
+ throw new Error('Missing ogcServer');
+ }
this.cache_[uid] = {
active: false,
featureNS: ogcServer.wfsFeatureNS,
@@ -292,6 +305,9 @@ EditingSnappingService.prototype.getOGCServer_ = function(treeCtrl) {
if (!ogcServerName) {
return null;
}
+ if (!this.ogcServers_) {
+ throw new Error('Missing ogcServers');
+ }
return this.ogcServers_[ogcServerName];
};
@@ -386,6 +402,9 @@ EditingSnappingService.prototype.handleTreeCtrlStateChange_ = function(treeCtrl,
* @private
*/
EditingSnappingService.prototype.activateItem_ = function(item) {
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
// No need to do anything if item is already active
if (item.active) {
@@ -420,6 +439,9 @@ EditingSnappingService.prototype.activateItem_ = function(item) {
* @private
*/
EditingSnappingService.prototype.deactivateItem_ = function(item) {
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
// No need to do anything if item is already inactive
if (!item.active) {
@@ -427,9 +449,11 @@ EditingSnappingService.prototype.deactivateItem_ = function(item) {
}
const map = this.map_;
- console.assert(map);
const interaction = item.interaction;
+ if (!interaction) {
+ throw new Error('Missing interaction');
+ }
map.removeInteraction(interaction);
item.interaction = null;
@@ -477,6 +501,9 @@ EditingSnappingService.prototype.refresh = function() {
* @private
*/
EditingSnappingService.prototype.loadItemFeatures_ = function(item) {
+ if (!this.map_) {
+ throw new Error('Missing map');
+ }
// If a previous request is still running, cancel it.
if (item.requestDeferred) {
diff --git a/contribs/gmf/src/editing/editFeatureComponent.js b/contribs/gmf/src/editing/editFeatureComponent.js
index a0dc09fe154..79efc494644 100644
--- a/contribs/gmf/src/editing/editFeatureComponent.js
+++ b/contribs/gmf/src/editing/editFeatureComponent.js
@@ -49,6 +49,7 @@ import olStyleStyle from 'ol/style/Style.js';
import olStyleText from 'ol/style/Text.js';
import MapBrowserEvent from 'ol/MapBrowserEvent.js';
import {CollectionEvent} from 'ol/Collection.js';
+import VectorSource from 'ol/source/Vector.js';
/**
* The different possible values of the `state` inner property.
@@ -211,34 +212,34 @@ function Controller($element, $q, $scope, $timeout,
* properties change, which includes the geometry.
* @type {boolean}
*/
- this.dirty;
+ this.dirty = false;
/**
- * @type {import("ngeo/layertree/Controller.js").LayertreeController}
+ * @type {?import("ngeo/layertree/Controller.js").LayertreeController}
*/
- this.editableTreeCtrl;
+ this.editableTreeCtrl = null;
/**
- * @type {import("ol/Map.js").default}
+ * @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
* The state property shared with the `gmf-editfeatureselector` directive.
* For more info, see in that directive.
* @type {string}
*/
- this.state;
+ this.state = '';
/**
* @type {number}
*/
- this.tolerance;
+ this.tolerance = 0;
/**
- * @type {import("ol/layer/Vector.js").default}
+ * @type {?import("ol/layer/Vector.js").default}
*/
- this.vectorLayer;
+ this.vectorLayer = null;
/**
* @type {boolean}
@@ -324,21 +325,21 @@ function Controller($element, $q, $scope, $timeout,
// === Private properties ===
/**
- * @type {import('gmf/themes.js').GmfLayer}
+ * @type {?import('gmf/themes.js').GmfLayer}
* @private
*/
- this.editableNode_;
+ this.editableNode_ = null;
/**
- * @type {import("ol/layer/Image.js").default|import("ol/layer/Tile.js").default}
+ * @type {?import("ol/layer/Image.js").default|import("ol/layer/Tile.js").default}
* @private
*/
- this.editableWMSLayer_;
+ this.editableWMSLayer_ = null;
/**
* A deferred object resolved after the confirm modal "continue w/o saving" or
* "save" buttons are clicked.
- * @type {angular.IDeferred|null}
+ * @type {?angular.IDeferred}
* @private
*/
this.confirmDeferred_ = null;
@@ -398,9 +399,9 @@ function Controller($element, $q, $scope, $timeout,
this.featureId = undefined;
/**
- * @type {import("ol/Collection.js").default}
+ * @type {?import("ol/Collection.js").default}
*/
- this.features;
+ this.features = null;
/**
* @type {import("ol/Collection.js").default}
@@ -409,15 +410,15 @@ function Controller($element, $q, $scope, $timeout,
this.interactions_ = new olCollection();
/**
- * @type {import("ol/interaction/Modify.js").default}
+ * @type {?import("ol/interaction/Modify.js").default}
* @private
*/
- this.modify_;
+ this.modify_ = null;
/**
- * @type {import("ngeo/misc/ToolActivate.js").default}
+ * @type {?import("ngeo/misc/ToolActivate.js").default}
*/
- this.modifyToolActivate;
+ this.modifyToolActivate = null;
/**
* @type {import("ngeo/Menu.js").default}
@@ -448,42 +449,42 @@ function Controller($element, $q, $scope, $timeout,
});
/**
- * @type {import("ngeo/interaction/Translate.js").default}
+ * @type {?import("ngeo/interaction/Translate.js").default}
* @private
*/
- this.translate_;
+ this.translate_ = null;
/**
- * @type {import("ngeo/interaction/Rotate.js").default}
+ * @type {?import("ngeo/interaction/Rotate.js").default}
* @private
*/
- this.rotate_;
+ this.rotate_ = null;
/**
- * @type {!import("ngeo/misc/ToolActivate.js").default}
+ * @type {?import("ngeo/misc/ToolActivate.js").default}
*/
- this.rotateToolActivate;
+ this.rotateToolActivate = null;
/**
- * @type {!import("ngeo/misc/ToolActivate.js").default}
+ * @type {?import("ngeo/misc/ToolActivate.js").default}
*/
- this.translateToolActivate;
+ this.translateToolActivate = null;
/**
- * @type {!Array.}
+ * @type {Array}
* @private
*/
this.listenerKeys_ = [];
/**
- * @type {?Array.}
+ * @type {?Array}
*/
this.attributes = null;
/**
- * @type {string|undefined}
+ * @type {?string}
*/
- this.geomType;
+ this.geomType = null;
/**
* @type {boolean}
@@ -512,6 +513,9 @@ function Controller($element, $q, $scope, $timeout,
* Called on initialization of the controller.
*/
Controller.prototype.$onInit = function() {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const lang = this.gettextCatalog_.getCurrentLanguage();
// @ts-ignore: $.datetimepicker is available, as it is imported
@@ -521,9 +525,17 @@ Controller.prototype.$onInit = function() {
// (1) Set default values and other properties
this.dirty = this.dirty === true;
- this.editableNode_ = /** @type {import('gmf/themes.js').GmfLayer} */ (
- this.editableTreeCtrl.node);
- const source = /** @type {import('ol/source/Vector.js').default} */(this.vectorLayer.getSource());
+ if (!this.editableTreeCtrl) {
+ throw new Error('Missing editableTreeCtrl');
+ }
+ this.editableNode_ = /** @type {import('gmf/themes.js').GmfLayer} */ (this.editableTreeCtrl.node);
+ if (!this.vectorLayer) {
+ throw new Error('Missing vectorLayer');
+ }
+ const source = this.vectorLayer.getSource();
+ if (!(source instanceof VectorSource)) {
+ throw new Error('Wrong source');
+ }
this.features = source.getFeaturesCollection();
this.tolerance = this.tolerance !== undefined ? this.tolerance : 10;
@@ -664,7 +676,15 @@ Controller.prototype.$onInit = function() {
* Save the currently selected feature modifications.
*/
Controller.prototype.save = function() {
- console.assert(this.attributes);
+ if (!this.attributes) {
+ throw new Error('Missing attributes');
+ }
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
+ if (!this.editableNode_) {
+ throw new Error('Missing editableNode');
+ }
const feature = this.feature.clone();
feature.setId(this.feature.getId());
@@ -716,8 +736,8 @@ Controller.prototype.save = function() {
})
.catch((response) => {
this.showServerError = true;
- this.serverErrorType = `error type : ${response.data['error_type']}`;
- this.serverErrorMessage = `error message : ${response.data['message']}`;
+ this.serverErrorType = `error type : ${response.data.error_type}`;
+ this.serverErrorMessage = `error message : ${response.data.message}`;
})
.finally(() => {
this.pending = false;
@@ -728,6 +748,9 @@ Controller.prototype.save = function() {
/**
*/
Controller.prototype.cancel = function() {
+ if (!this.features) {
+ throw new Error('Missing features');
+ }
this.dirty = false;
this.feature = null;
this.features.clear();
@@ -778,6 +801,9 @@ Controller.prototype.checkForModifications_ = function(
/**
*/
Controller.prototype.continueWithoutSaving = function() {
+ if (!this.confirmDeferred_) {
+ throw new Error('Missing confirmDeferred_');
+ }
this.cancel();
this.confirmDeferred_.resolve();
};
@@ -786,6 +812,12 @@ Controller.prototype.continueWithoutSaving = function() {
/**
*/
Controller.prototype.delete = function() {
+ if (!this.editableNode_) {
+ throw new Error('Missing editableNode_');
+ }
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
const msg = this.gettextCatalog_.getString(
'Do you really want to delete the selected feature?');
// Confirm deletion first
@@ -798,6 +830,9 @@ Controller.prototype.delete = function() {
this.feature
).then(
(response) => {
+ if (!this.editableWMSLayer_) {
+ throw new Error('Missing editableWMSLayer_');
+ }
this.dirty = false;
this.pending = false;
this.ngeoLayerHelper_.refreshWMSLayer(this.editableWMSLayer_);
@@ -808,8 +843,8 @@ Controller.prototype.delete = function() {
(response) => {
this.showServerError = true;
this.pending = false;
- this.serverErrorType = `error type : ${response.data['error_type']}`;
- this.serverErrorMessage = `error message : ${response.data['message']}`;
+ this.serverErrorType = `error type : ${response.data.error_type}`;
+ this.serverErrorMessage = `error message : ${response.data.message}`;
}
);
@@ -838,6 +873,12 @@ Controller.prototype.submit = function() {
Controller.prototype.handleEditFeature_ = function(resp) {
const features = new olFormatGeoJSON().readFeatures(resp.data);
if (features.length) {
+ if (!this.editableWMSLayer_) {
+ throw new Error('Missing editableWMSLayer_');
+ }
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
this.feature.setId(features[0].getId());
this.ngeoLayerHelper_.refreshWMSLayer(this.editableWMSLayer_);
}
@@ -883,7 +924,9 @@ Controller.prototype.handleFeatureAdd_ = function(evt) {
if (evt instanceof CollectionEvent) {
this.feature = null;
this.timeout_(() => {
- console.assert(this.attributes);
+ if (!this.attributes) {
+ throw new Error('Missing attributes');
+ }
const feature = evt.element;
console.assert(feature instanceof olFeature);
const dateFormatter = new DateFormatter();
@@ -930,6 +973,21 @@ Controller.prototype.handleFeatureAdd_ = function(evt) {
* @private
*/
Controller.prototype.toggle_ = function(active) {
+ if (!this.modifyToolActivate) {
+ throw new Error('Missing modifyToolActivate');
+ }
+ if (!this.translateToolActivate) {
+ throw new Error('Missing translateToolActivate');
+ }
+ if (!this.rotateToolActivate) {
+ throw new Error('Missing rotateToolActivate');
+ }
+ if (!this.modify_) {
+ throw new Error('Missing modify');
+ }
+ if (!this.editableTreeCtrl) {
+ throw new Error('Missing editableTreeCtrl');
+ }
const keys = this.listenerKeys_;
const createUid = ['create-', olUtilGetUid(this)].join('-');
@@ -937,6 +995,12 @@ Controller.prototype.toggle_ = function(active) {
const toolMgr = this.ngeoToolActivateMgr_;
if (active) {
+ if (!this.translate_) {
+ throw new Error('Missing translate');
+ }
+ if (!this.rotate_) {
+ throw new Error('Missing rotate');
+ }
// FIXME
//this.registerInteractions_();
@@ -976,7 +1040,7 @@ Controller.prototype.toggle_ = function(active) {
this.modify_.setActive(active);
this.mapSelectActive = active;
- this.editableTreeCtrl.properties['editing'] = active;
+ this.editableTreeCtrl.properties.editing = active;
};
@@ -987,6 +1051,9 @@ Controller.prototype.toggle_ = function(active) {
* @private
*/
Controller.prototype.handleMapSelectActiveChange_ = function(active) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const mapDiv = this.map.getViewport();
console.assert(mapDiv);
@@ -1020,6 +1087,9 @@ Controller.prototype.handleMapSelectActiveChange_ = function(active) {
*/
Controller.prototype.handleMapClick_ = function(evt) {
if (evt instanceof MapBrowserEvent) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const coordinate = evt.coordinate;
const pixel = evt.pixel;
@@ -1028,6 +1098,9 @@ Controller.prototype.handleMapClick_ = function(evt) {
const feature = this.map.forEachFeatureAtPixel(
pixel,
(feature) => {
+ if (!this.features) {
+ throw new Error('Missing features');
+ }
let ret = null;
if (this.features.getArray().includes(feature)) {
ret = feature;
@@ -1047,10 +1120,19 @@ Controller.prototype.handleMapClick_ = function(evt) {
// (2) If a feature is being edited and has unsaved changes, show modal
// to let the user decide what to do
this.checkForModifications_(true).then(() => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
+ if (!this.editableNode_) {
+ throw new Error('Missing editableNode');
+ }
const map = this.map;
const view = map.getView();
const resolution = view.getResolution();
+ if (!resolution) {
+ throw new Error('Missing resolution');
+ }
const buffer = resolution * this.tolerance;
const extent = olExtent.buffer(
[coordinate[0], coordinate[1], coordinate[0], coordinate[1]],
@@ -1079,12 +1161,18 @@ Controller.prototype.handleMapClick_ = function(evt) {
*/
Controller.prototype.handleMapContextMenu_ = function(evt) {
if (evt instanceof Event) {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
const pixel = this.map.getEventPixel(evt);
const coordinate = this.map.getCoordinateFromPixel(pixel);
- let feature = /** @type {olFeature|undefined} */ (this.map.forEachFeatureAtPixel(
+ let feature = this.map.forEachFeatureAtPixel(
pixel,
(feature) => {
+ if (!this.features) {
+ throw new Error('Missing features');
+ }
let ret = null;
if (this.features.getArray().includes(feature)) {
ret = feature;
@@ -1095,7 +1183,7 @@ Controller.prototype.handleMapContextMenu_ = function(evt) {
hitTolerance: 7,
layerFilter: undefined
}
- ));
+ );
feature = feature ? feature : null;
@@ -1104,10 +1192,13 @@ Controller.prototype.handleMapContextMenu_ = function(evt) {
this.vertexInfo_ = null;
// show contextual menu when clicking on certain types of features
- if (feature) {
-
+ if (feature instanceof olFeature) {
+ const resolutions = this.map.getView().getResolution();
+ if (!resolutions) {
+ throw new Error('Missing resolutions');
+ }
const vertexInfo = this.ngeoFeatureHelper_.getVertexInfoAtCoordinate(
- feature, coordinate, this.map.getView().getResolution());
+ feature, coordinate, resolutions);
if (vertexInfo) {
this.vertexInfo_ = vertexInfo;
this.menuVertex_.open(coordinate);
@@ -1138,6 +1229,9 @@ Controller.prototype.handleGetFeatures_ = function(features) {
this.pending = false;
this.timeout_(() => {
+ if (!this.features) {
+ throw new Error('Missing features');
+ }
if (features.length) {
const feature = features[0];
this.feature = feature;
@@ -1165,6 +1259,9 @@ Controller.prototype.initializeInteractions_ = function() {
*/
Controller.prototype.registerInteractions_ = function() {
this.interactions_.forEach((interaction) => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.map.addInteraction(interaction);
});
};
@@ -1176,6 +1273,9 @@ Controller.prototype.registerInteractions_ = function() {
*/
Controller.prototype.unregisterInteractions_ = function() {
this.interactions_.forEach((interaction) => {
+ if (!this.map) {
+ throw new Error('Missing map');
+ }
this.map.removeInteraction(interaction);
});
};
@@ -1192,7 +1292,9 @@ Controller.prototype.handleFeatureChange_ = function(newFeature, oldFeature) {
if (oldFeature) {
olEvents.unlisten(oldFeature, 'propertychange', this.handleFeaturePropertyChange_, this);
geom = oldFeature.getGeometry();
- console.assert(geom);
+ if (!geom) {
+ throw new Error('Missing geom');
+ }
olEvents.unlisten(
geom,
'change',
@@ -1206,7 +1308,9 @@ Controller.prototype.handleFeatureChange_ = function(newFeature, oldFeature) {
this.featureId = newFeature.getId();
olEvents.listen(newFeature, 'propertychange', this.handleFeaturePropertyChange_, this);
geom = newFeature.getGeometry();
- console.assert(geom);
+ if (!geom) {
+ throw new Error('Missing geom');
+ }
olEvents.listen(
geom,
'change',
@@ -1260,10 +1364,16 @@ Controller.prototype.handleMenuActionClick_ = function(evt) {
switch (action) {
case 'move':
+ if (!this.translate_) {
+ throw new Error('Missing translate');
+ }
this.translate_.setActive(true);
this.scope_.$apply();
break;
case 'rotate':
+ if (!this.rotate_) {
+ throw new Error('Missing rotate');
+ }
this.rotate_.setActive(true);
this.scope_.$apply();
break;
@@ -1282,6 +1392,12 @@ Controller.prototype.handleMenuVertexActionClick_ = function(evt) {
switch (action) {
case 'delete':
+ if (!this.feature) {
+ throw new Error('Missing feature');
+ }
+ if (!this.vertexInfo_) {
+ throw new Error('Missing vertexInfo');
+ }
const feature = this.feature;
const vertexInfo = this.vertexInfo_;
this.ngeoFeatureHelper_.removeVertex(feature, vertexInfo);
@@ -1298,6 +1414,9 @@ Controller.prototype.handleMenuVertexActionClick_ = function(evt) {
* @private
*/
Controller.prototype.handleTranslateEnd_ = function(evt) {
+ if (!this.translate_) {
+ throw new Error('Missing translate');
+ }
this.translate_.setActive(false);
this.scope_.$apply();
};
@@ -1308,6 +1427,9 @@ Controller.prototype.handleTranslateEnd_ = function(evt) {
* @private
*/
Controller.prototype.handleRotateEnd_ = function(evt) {
+ if (!this.rotate_) {
+ throw new Error('Missing rotate');
+ }
this.rotate_.setActive(false);
this.scope_.$apply();
};
@@ -1317,6 +1439,9 @@ Controller.prototype.handleRotateEnd_ = function(evt) {
* @private
*/
Controller.prototype.handleDestroy_ = function() {
+ if (!this.features) {
+ throw new Error('Missing features');
+ }
this.features.clear();
this.handleFeatureChange_(null, this.feature);
this.feature = null;
diff --git a/contribs/gmf/src/editing/editFeatureSelectorComponent.js b/contribs/gmf/src/editing/editFeatureSelectorComponent.js
index d5cff7dac68..276fcaeb426 100644
--- a/contribs/gmf/src/editing/editFeatureSelectorComponent.js
+++ b/contribs/gmf/src/editing/editFeatureSelectorComponent.js
@@ -105,25 +105,25 @@ function Controller($scope, $timeout, gmfThemes, gmfTreeManager) {
);
/**
- * @type {import("ol/Map.js").default}
+ * @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
- * @type {number|undefined}
+ * @type {?number}
*/
- this.tolerance;
+ this.tolerance = null;
/**
- * @type {import("ol/layer/Vector.js").default}
+ * @type {?import("ol/layer/Vector.js").default}
*/
- this.vectorLayer;
+ this.vectorLayer = null;
/**
* @type {boolean}
* @export
*/
- this.closeAfterSave;
+ this.closeAfterSave = false;
// === Injected services ===
@@ -163,6 +163,9 @@ function Controller($scope, $timeout, gmfThemes, gmfTreeManager) {
const editables = this.editableTreeCtrls;
editables.length = 0;
+ if (!this.gmfTreeManager_.rootCtrl) {
+ throw new Error('Missing gmfTreeManager_.rootCtrl');
+ }
this.gmfTreeManager_.rootCtrl.traverseDepthFirst((treeCtrl) => {
if (treeCtrl.node.editable) {
console.assert(treeCtrl.children.length === 0);
@@ -181,6 +184,7 @@ function Controller($scope, $timeout, gmfThemes, gmfTreeManager) {
if (gmfTreeManager.rootCtrl) {
return gmfTreeManager.rootCtrl.children;
}
+ return [];
}, updateEditableTreeCtrls);
diff --git a/contribs/gmf/src/filters/filterselectorComponent.js b/contribs/gmf/src/filters/filterselectorComponent.js
index 60a6f4e983a..aba5db31c12 100644
--- a/contribs/gmf/src/filters/filterselectorComponent.js
+++ b/contribs/gmf/src/filters/filterselectorComponent.js
@@ -54,15 +54,15 @@ module.value('gmfFilterselectorTemplateUrl',
* @return {string} The template url.
*/
($attrs) => {
- const templateUrl = $attrs['gmfFilterselectorTemplateUrl'];
+ const templateUrl = $attrs.gmfFilterselectorTemplateUrl;
return templateUrl !== undefined ? templateUrl :
'gmf/filters/filterselectorcomponent';
});
/**
- * @param {!angular.IAttributes} $attrs Attributes.
- * @param {!function(!angular.IAttributes): string} gmfFilterselectorTemplateUrl Template function.
+ * @param {angular.IAttributes} $attrs Attributes.
+ * @param {function(angular.IAttributes): string} gmfFilterselectorTemplateUrl Template function.
* @return {string} Template URL.
* @ngInject
* @private
@@ -80,8 +80,8 @@ function gmfFilterselectorTemplateUrl($attrs, gmfFilterselectorTemplateUrl) {
class Controller {
/**
- * @param {!angular.IScope} $scope Angular scope.
- * @param {!angular.ITimeoutService} $timeout Angular timeout service.
+ * @param {angular.IScope} $scope Angular scope.
+ * @param {angular.ITimeoutService} $timeout Angular timeout service.
* @param {angular.gettext.gettextCatalog} gettextCatalog Gettext catalog.
* @param {import('gmf/datasource/DataSourceBeingFiltered.js').DataSourceBeingFiltered} gmfDataSourceBeingFiltered
* The Gmf value service that determines the data source currently being filtered.
@@ -91,9 +91,9 @@ class Controller {
* @param {import('gmf/authentication/Service.js').User} gmfUser User.
* @param {import("ngeo/message/Notification.js").MessageNotification} ngeoNotification Ngeo notification
* service.
- * @param {!import("ngeo/map/FeatureOverlayMgr.js").FeatureOverlayMgr} ngeoFeatureOverlayMgr Ngeo
+ * @param {import("ngeo/map/FeatureOverlayMgr.js").FeatureOverlayMgr} ngeoFeatureOverlayMgr Ngeo
* FeatureOverlay manager
- * @param {!import("ngeo/filter/RuleHelper.js").RuleHelper} ngeoRuleHelper Ngeo rule helper service.
+ * @param {import("ngeo/filter/RuleHelper.js").RuleHelper} ngeoRuleHelper Ngeo rule helper service.
* @private
* @ngInject
* @ngdoc controller
@@ -109,7 +109,7 @@ class Controller {
/**
* @type {boolean}
*/
- this.active;
+ this.active = false;
$scope.$watch(
() => this.active,
@@ -117,14 +117,14 @@ class Controller {
);
/**
- * @type {!import("ol/Map.js").default}
+ * @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
/**
- * @type {string}
+ * @type {?string}
*/
- this.toolGroup;
+ this.toolGroup = null;
// Injected properties
@@ -228,7 +228,7 @@ class Controller {
this.filtrableDataSources = [];
/**
- * @type {Array.}
+ * @type {?Array}
* @private
*/
this.filtrableLayerNodeNames_ = null;
@@ -297,10 +297,10 @@ class Controller {
/**
* The name of the data source that should be automatically selected
* by this component.
- * @type {string|undefined}
+ * @type {?string}
* @private
*/
- this.defaultFiltrableDataSourceName_;
+ this.defaultFiltrableDataSourceName_ = null;
// Initialize the data sources registration
this.toggleDataSourceRegistration_();
@@ -320,7 +320,7 @@ class Controller {
if (usrFunc && usrFunc.preset_layer_filter && usrFunc.preset_layer_filter[0]) {
this.defaultFiltrableDataSourceName_ = usrFunc.preset_layer_filter[0];
} else {
- this.defaultFiltrableDataSourceName_ = undefined;
+ this.defaultFiltrableDataSourceName_ = null;
}
this.toggleDataSourceRegistration_();
}
@@ -483,6 +483,9 @@ class Controller {
* @private
*/
isDataSourceFiltrable_(dataSource, opt_notify) {
+ if (!this.filtrableLayerNodeNames_) {
+ throw new Error('Missing filtrableLayerNodeNames');
+ }
let filtrable = true;
const gettext = this.gettextCatalog_;
const notify = opt_notify !== false;
@@ -623,6 +626,9 @@ class Controller {
/**
*/
saveFilterSave() {
+ if (!this.readyDataSource) {
+ throw new Error('Missing readyDataSource');
+ }
const name = this.saveFilterName;
const dataSource = this.readyDataSource;
@@ -662,7 +668,9 @@ class Controller {
* @param {!import("gmf/filters/SavedFilters.js").SavedFilterItem} filterItem Filter item.
*/
saveFilterLoadItem(filterItem) {
-
+ if (!this.readyDataSource) {
+ throw new Error('Missing readyDataSource');
+ }
const dataSource = this.readyDataSource;
// (1) Reset current rules
@@ -686,6 +694,9 @@ class Controller {
// (4) Update cache item
const cacheItem = this.getRuleCacheItem_(dataSource);
+ if (!cacheItem) {
+ throw new Error('Missing cacheItem');
+ }
cacheItem.customRules = customRules;
cacheItem.directedRules = directedRules;
});
diff --git a/contribs/gmf/src/import/importdatasourceComponent.js b/contribs/gmf/src/import/importdatasourceComponent.js
index 3eb8ac7422d..ac717e421f9 100644
--- a/contribs/gmf/src/import/importdatasourceComponent.js
+++ b/contribs/gmf/src/import/importdatasourceComponent.js
@@ -46,7 +46,7 @@ module.value('gmfImportdatasourceTemplateUrl',
* @return {string} The template url.
*/
($attrs) => {
- const templateUrl = $attrs['gmfImportdatasourceTemplateUrl'];
+ const templateUrl = $attrs.gmfImportdatasourceTemplateUrl;
return templateUrl !== undefined ? templateUrl :
'gmf/import/importdatasourceComponent';
});
@@ -101,39 +101,39 @@ class Controller {
// Binding properties
/**
- * @type {!import("ol/Map.js").default}
+ * @type {?import("ol/Map.js").default}
*/
- this.map;
+ this.map = null;
// Injected properties
/**
- * @type {!JQuery}
+ * @type {JQuery}
* @private
*/
this.element_ = $element;
/**
- * @type {!angular.IScope}
+ * @type {angular.IScope}
* @private
*/
this.scope_ = $scope;
/**
- * @type {!angular.ITimeoutService}
+ * @type {angular.ITimeoutService}
* @private
*/
this.timeout_ = $timeout;
/**
- * @type {!import("gmf/datasource/ExternalDataSourcesManager.js").ExternalDatSourcesManager}
+ * @type {import("gmf/datasource/ExternalDataSourcesManager.js").ExternalDatSourcesManager}
* @private
*/
this.gmfExternalDataSourcesManager_ = gmfExternalDataSourcesManager;
/**
- * @type {!import("ngeo/query/Querent.js").Querent}
+ * @type {import("ngeo/query/Querent.js").Querent}
* @private
*/
this.ngeoQuerent_ = ngeoQuerent;
@@ -142,14 +142,14 @@ class Controller {
// Model properties
/**
- * @type {File|undefined}
+ * @type {?File}
*/
- this.file;
+ this.file = null;
/**
- * @type {string|undefined}
+ * @type {?string}
*/
- this.url;
+ this.url = null;
// Inner properties
@@ -206,18 +206,17 @@ class Controller {
this.wmtsCapabilities = null;
/**
- * @type {Bloodhound|undefined}
+ * @type {?Bloodhound}
* @private
*/
- this.serversEngine_;
+ this.serversEngine_ = null;
- const servers = $injector.has('gmfExternalOGCServers') ?
- /** @type {Array.|undefined} */ (
- $injector.get('gmfExternalOGCServers')
- ) : undefined;
+ /** @type {?Array} */
+ const servers = $injector.has('gmfExternalOGCServers') ? $injector.get('gmfExternalOGCServers')
+ : null;
if (servers) {
- const serverUrls = servers.map(server => server['url']);
+ const serverUrls = servers.map(server => server.url);
this.serversEngine_ = new Bloodhound({
/**
* Allows search queries to match from string from anywhere within
@@ -258,7 +257,7 @@ class Controller {
this.fileInput_.on('change', () => {
const fileInput = /** @type HTMLInputElement */ (this.fileInput_[0]);
const files = fileInput.files;
- this.file = files && files[0] ? files[0] : undefined;
+ this.file = files && files[0] ? files[0] : null;
this.scope_.$apply();
});
}
@@ -274,7 +273,9 @@ class Controller {
// Timeout to let Angular render the placeholder of the input properly,
// otherwise typeahead would copy the string with {{}} in it...
this.timeout_(() => {
- console.assert(this.serversEngine_);
+ if (!this.serversEngine_) {
+ throw new Error('Missing serversEngine');
+ }
const $urlInput = this.element_.find('input[name=url]');
const $connectBtn = this.element_.find('button.gmf-importdatasource-connect-btn');
$urlInput.typeahead({
@@ -307,6 +308,9 @@ class Controller {
* Connect to given online resource URL.
*/
connect() {
+ if (!this.url) {
+ throw new Error('Missing url');
+ }
const url = this.url;
const serviceType = guessServiceTypeByUrl(url);
@@ -345,6 +349,9 @@ class Controller {
* Create data source from file.
*/
load() {
+ if (!this.file) {
+ throw new Error('Missing file');
+ }
const file = this.file;
this.gmfExternalDataSourcesManager_.createAndAddDataSourceFromFile(file, (success) => {
if (!success) {
@@ -357,6 +364,9 @@ class Controller {
* @return {string} The name of the file and human-readable size.
*/
get fileNameAndSize() {
+ if (!this.file) {
+ return '';
+ }
let nameAndSize = '';
const file = this.file;
diff --git a/contribs/gmf/src/import/wmsCapabilityLayertreeComponent.js b/contribs/gmf/src/import/wmsCapabilityLayertreeComponent.js
index ea49ab3a2b2..9fa4dbff3bc 100644
--- a/contribs/gmf/src/import/wmsCapabilityLayertreeComponent.js
+++ b/contribs/gmf/src/import/wmsCapabilityLayertreeComponent.js
@@ -33,7 +33,7 @@ module.value('gmfWmscapabilitylayertreenodeTemplateUrl',
* @return {string} The template url.
*/
($attrs) => {
- const templateUrl = $attrs['gmfWmscapabilitylayertreenodeTemplateUrl'];
+ const templateUrl = $attrs.gmfWmscapabilitylayertreenodeTemplateUrl;
return templateUrl !== undefined ? templateUrl :
'gmf/import/wmsCapabilityLayertreeComponent';
});
@@ -74,28 +74,28 @@ class Controller {
/**
* WMS Capabilities definition
- * @type {!Object}
+ * @type {Object}
*/
- this.capabilities;
+ this.capabilities = {};
/**
* WMS Capability Layer object.
- * @type {!Object}
+ * @type {Object}
*/
- this.layer;
+ this.layer = {};
/**
* The original server url that was used to build the WMS GetCapabilities
* request.
- * @type {string}
+ * @type {?string}
*/
- this.url;
+ this.url = null;
// Injected properties
/**
- * @type {!import("gmf/datasource/ExternalDataSourcesManager.js").ExternalDatSourcesManager}
+ * @type {import("gmf/datasource/ExternalDataSourcesManager.js").ExternalDatSourcesManager}
* @private
*/
this.gmfExternalDataSourcesManager_ = gmfExternalDataSourcesManager;
@@ -105,6 +105,9 @@ class Controller {
* @param {!Object} layer WMS Capability Layer object
*/
createAndAddDataSource(layer) {
+ if (!this.url) {
+ throw new Error('Missing url');
+ }
this.gmfExternalDataSourcesManager_.createAndAddDataSourceFromWMSCapability(
layer,
this.capabilities,
diff --git a/contribs/gmf/src/import/wmtsCapabilityLayertreeComponent.js b/contribs/gmf/src/import/wmtsCapabilityLayertreeComponent.js
index ad0c9abb907..81dfafbfe8a 100644
--- a/contribs/gmf/src/import/wmtsCapabilityLayertreeComponent.js
+++ b/contribs/gmf/src/import/wmtsCapabilityLayertreeComponent.js
@@ -31,9 +31,8 @@ module.value('gmfWmtscapabilitylayertreTemplateUrl',
* @return {string} The template url.
*/
($attrs) => {
- const templateUrl = $attrs['gmfWmtscapabilitylayertreTemplateUrl'];
- return templateUrl !== undefined ? templateUrl :
- 'ngeo/import/wmtsCapabilityLayertreeComponent';
+ const templateUrl = $attrs.gmfWmtscapabilitylayertreTemplateUrl;
+ return templateUrl !== undefined ? templateUrl : 'ngeo/import/wmtsCapabilityLayertreeComponent';
});
@@ -71,22 +70,22 @@ class Controller {
/**
* WMS Capabilities definition
- * @type {!Object}
+ * @type {Object}
*/
- this.capabilities;
+ this.capabilities = {};
/**
* List of WMTS Capability Layer objects.
- * @type {!Array.}
+ * @type {Array