Skip to content
Permalink
Browse files

Openlayers upgrade (#4236)

* Map / Add ESRI ArcGIS Rest support

* Editor / Add new protocol ESRI:REST
* View mode / Add action "add to map" to ESRI:REST links
* Search results / Add ESRI:REST links to be in the "add to map" dropdown
* Map / Add basic layer support

* Map / Add ESRI ArcGIS Rest support / Config.

* Add gnDebounce util & remove ngeoDebounce dependency

* Added gn-btn and gn-btn-group directives

Replacement of ngeo-btn and ngeo-btn-group

* Turn off web-ui-docs

* Add olDecorateLayer and remove ngeoDecorateLayer dependency

* Add olDecorateInteraction and remove ngeoDecorateInteraction dependency

* Add olDecorateLayerLoading

* Add olMap directive and remove ngeoMap dependency

* Add olProfile directive and remove ngeoProfile dependency

* Added gn-popover directives to replace ngeo-popover ones

* add openlayers legacy build

* remove angular references to ngeo

* update closure base content

* remove ngeo library

* Fix new ol.layer.Graticule

* Remove ngeo-ol-cesium bundle and include only ol-cesium in latest version

* fix injection in BtnGroupController

* MeasureDirective / adapt to newer OL api

* Update Cesium to 1.63.1

* FeaturesLoader / fix getfeatureinfo url api

* MapService / fix md bbox geom generation

* add openlayers source map

* MeasureDirective / fix for new api

* OL migration / change unByKey calls to new API

* Fix zoom buttons with view.animate

* Remove ol.animations and replace by fit duration

* register proj4 in openlayers

* PrintMapDirective / adapt to new OL api

* OwsContextDirective / fix exportMapAsImage for ol6

A new library has been added: dom-to-image
This is necessary now that OL6 does not have only one canvas in the map

* Fix measure with new ol api

* OwsContextService / fix loading layer never removed in layers collection

* Map to image / added missing dom-to-image library

* Fix for OpenLayers attribution styling

* Fix map initialization promise chain

Easier integration with custom behaviour

* Cors filter / add CORS headers also when origin is the current server host

* Correctly handle proxy for WMS layers

* WFS facets / slightly improved render for facet items

* Improve WPS handling

* handle asynchronous WPS seamlessly
* better handling of WMS outputs

The process appears are running while requests are made to the WPS endpoint
to update the status.

Also disables the complex data output display in table form
as the modal is broken.

* WFS facets / do not update the state of the last clicked facet

* Trigger a digest when the feature table is generated (using ES)

* Allow several files with the same name in wro4j dependencies

Only the first one found will be kept.
This allows upgrading bootstrap table beyond 1.9.1 (yay!)

* Map Service / do not add proxy in url when creating layer (2nd part)

* Add ETag header in hop by hop headers

Should prevent unwanted caching of resources (namely Etopo GepCapabilities)

* WPS directive / handle value ranges in input.allowedValues

* Add label for the annotation text input

* Cors Filter / mock setting manager bean to make tests pass again

* print: dont resize rectangle during animation

* print: update rectangle on layout change

* fix editor thumb generator

* Fix WroModel test when multiple css with same name
  • Loading branch information
fxprunayre committed Dec 3, 2019
1 parent 432be4d commit 706b3ad8b57176d015016da6bd5c063b71ebbbff
Showing 547 changed files with 6,438 additions and 297,753 deletions.
@@ -25,6 +25,7 @@
import org.fao.geonet.ApplicationContextHolder;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.kernel.setting.Settings;
import org.fao.geonet.utils.Log;

import javax.servlet.Filter;
@@ -86,10 +87,10 @@ public void init(FilterConfig config) {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
SettingManager settingManager =
ApplicationContextHolder.get().getBean(SettingManager.class);

if (isUsingDb) {
SettingManager settingManager =
ApplicationContextHolder.get().getBean(SettingManager.class);
String allowedHosts = settingManager.getValue(SYSTEM_CORS_ALLOWEDHOSTS);
if (allowedHosts != null) {
if (allowedHosts.equals("*")) {
@@ -106,8 +107,10 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
if (clientOriginUrl != null) {
try {
String clientOriginHost = new java.net.URI(clientOriginUrl).getHost();
String myHost = settingManager.getValue(Settings.SYSTEM_SERVER_HOST);
if (addHeaderForAllHosts ||
allowedRemoteHosts.indexOf(clientOriginHost) != -1) {
allowedRemoteHosts.indexOf(clientOriginHost) != -1 ||
clientOriginHost.equals(myHost)) {
//httpResponse.setHeader("Access-Control-Allow-Origin", clientOriginUrl);
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
@@ -22,7 +22,12 @@
*/
package org.fao.geonet.web;

import org.fao.geonet.ApplicationContextHolder;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.kernel.setting.Settings;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletResponse;

@@ -35,7 +40,9 @@
import static org.fao.geonet.web.CORSResponseFilter.ALLOWED_HOSTS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

/**
* Created by francois on 07/11/16.
@@ -47,6 +54,17 @@ private CORSResponseFilter buildFilter(String allowedHosts) {
MockFilterConfig filterConfig = new MockFilterConfig();
filterConfig.addInitParameter(ALLOWED_HOSTS, allowedHosts);
filter.init(filterConfig);

SettingManager settingManager = mock(SettingManager.class);
when(settingManager.getValue(Settings.SYSTEM_SERVER_HOST))
.thenReturn("server.host");
when(settingManager.getValue(Settings.SYSTEM_CORS_ALLOWEDHOSTS))
.thenReturn("www.geonetwork-opensource.org,osgeo.org");

final ConfigurableApplicationContext applicationContext = Mockito.mock(ConfigurableApplicationContext.class);
ApplicationContextHolder.set(applicationContext);
Mockito.when(applicationContext.getBean(SettingManager.class)).thenReturn(settingManager);

return filter;
}

@@ -96,18 +114,14 @@ public void testCorsHeaderAddedToAllowedHostOnly() throws IOException, ServletEx
}


// @Test
// public void testCorsHeaderAddedBasedOnDb() throws IOException, ServletException {
// SettingManager settingManager = mock(SettingManager.class);
// when(settingManager.getValue(Settings.SYSTEM_CORS_ALLOWEDHOSTS))
// .thenReturn("www.geonetwork-opensource.org,osgeo.org");
//
// HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
// HttpServletResponse httpServletResponse = spy(new MockHttpServletResponse());
// FilterChain filterChain = mock(FilterChain.class);
//
// when(httpServletRequest.getHeader("origin")).thenReturn("http://www.geonetwork-opensource.org");
// buildFilter("db").doFilter(httpServletRequest, httpServletResponse, filterChain);
// assertEquals("*", httpServletResponse.getHeader("Access-Control-Allow-Origin"));
// }
@Test
public void testCorsHeaderAddedBasedOnDb() throws IOException, ServletException {
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = spy(new MockHttpServletResponse());
FilterChain filterChain = mock(FilterChain.class);

when(httpServletRequest.getHeader("origin")).thenReturn("http://www.geonetwork-opensource.org");
buildFilter("db").doFilter(httpServletRequest, httpServletResponse, filterChain);
assertEquals("*", httpServletResponse.getHeader("Access-Control-Allow-Origin"));
}
}
@@ -1317,10 +1317,10 @@
</file>
</activation>
<modules>
<module>slave</module>
<module>slave</module>
<module>schemas-test</module>
<module>web-ui</module>
<module>web-ui-docs</module>
<!--<module>web-ui-docs</module>-->
<module>web</module>
</modules>
</profile>
@@ -2267,9 +2267,7 @@
<label>Protocol</label>
<description>Connection protocol to be used</description>
<helper sort="true">
<option value="ESRI:AIMS--http--configuration">ArcIMS Map Service Configuration File (*.AXL)</option>
<option value="ESRI:AIMS--http-get-feature">ArcIMS Internet Feature Map Service</option>
<option value="ESRI:AIMS--http-get-image">ArcIMS Internet Image Map Service</option>
<option value="ESRI:REST">ArcGIS REST Services</option>
<option value="GLG:KML-2.0-http-get-map">Google Earth KML service (ver 2.0)</option>
<option value="OGC:CSW">OGC-CSW Catalogue Service for the Web</option>
<option value="OGC:KML">OGC-KML Keyhole Markup Language</option>
@@ -4350,9 +4350,7 @@ la non-évaluation</b>, dans le cadre de métadonnées INSPIRE
<help>Protocole de connexion utilisé, par exemple FTP.</help>
<condition/>
<helper sort="true">
<option value="ESRI:AIMS--http--configuration">Fichier configuration ArcIMS Map Service (*.AXL)</option>
<option value="ESRI:AIMS--http-get-feature">ArcIMS Internet Feature Map Service</option>
<option value="ESRI:AIMS--http-get-image">ArcIMS Internet Image Map Service</option>
<option value="ESRI:REST">ArcGIS REST Services</option>
<option value="GLG:KML-2.0-http-get-map">Google Earth KML service (ver 2.0)</option>
<option value="OGC:CSW">OGC-CSW Catalogue Service for the Web</option>
<option value="OGC:KML">OGC-KML Keyhole Markup Language</option>
@@ -61,7 +61,7 @@
<jsSource webappPath="/catalog/lib/tinycolor.js"/>
<jsSource webappPath="/catalog/lib/style/bootstrap/dist/js/bootstrap.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/proj4js-compressed.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/ngeo/ngeo.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/openlayers/ol.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/d3.v3.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/nv.d3.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/jsonix/jsonix/Jsonix-min.js" minimize="false"/>
@@ -92,8 +92,9 @@
<jsSource webappPath="/catalog/lib/recaptcha/angular-recaptcha.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/geohash.js"/>
<jsSource webappPath="/catalog/lib/xml2json/xml2json.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/dom-to-image/dom-to-image.min.js" minimize="false"/>
</declarative>
<!-- Same as previous + ol3cesium -->
<!-- Same as previous + olcesium -->
<declarative name="lib3d" pathOnDisk="web-ui/src/main/resources">
<jsSource webappPath="/catalog/lib/modernizr.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/jquery-2.2.4.min.js" minimize="false"/>
@@ -126,15 +127,8 @@
<jsSource webappPath="/catalog/lib/proj4js-compressed.js" minimize="false"/>
<!-- FIXME in non debug mode, 3D mode does not work when WMS layer is displayed.
No errors, only block tile loading-->
<!--<jsSource webappPath="/catalog/lib/ol3cesium/ngeool3cesium.js" minimize="false"/>-->
<!--
wro4j can't minify the debug version
SEVERE: file:/data/dev/gn/develop/web-ui/src/main/resources/catalog/lib/ol3cesium/ngeool3cesium-debug.js:242: ERROR - illegal initialization of @define variable goog.DISALLOW_TEST_ONLY_CODE
goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);
-->
<!--<jsSource webappPath="/catalog/lib/ol3cesium/ngeool3cesium-debug.js"/>-->
<!-- So use the debug version -->
<jsSource webappPath="/catalog/lib/ol3cesium/ngeool3cesium-debug.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/openlayers/ol.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/olcesium/olcesium.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/d3.v3.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/nv.d3.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/jsonix/jsonix/Jsonix-min.js" minimize="false"/>
@@ -168,5 +162,6 @@
<jsSource webappPath="/catalog/lib/recaptcha/angular-recaptcha.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/geohash.js"/>
<jsSource webappPath="/catalog/lib/xml2json/xml2json.min.js" minimize="false"/>
<jsSource webappPath="/catalog/lib/dom-to-image/dom-to-image.min.js" minimize="false"/>
</declarative>
</sources>
@@ -0,0 +1,205 @@
/*
* Copyright (C) 2001-2016 Food and Agriculture Organization of the
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
* and United Nations Environment Programme (UNEP)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
* Rome - Italy. email: geonetwork@osgeo.org
*/

(function() {
goog.provide('gn_button_directive');

var module = angular.module('gn_button_directive', []);

/**
* Provides two directives: gn-btn-group and gn-btn.
*
* The gn-btn-group directive allows creating "toggle" groups. It works with
* the gn-btn directive.
*
* Example:
*
* <div gn-btn-group>
* <button gn-btn class="btn" ng-model="ctrl.drawPoint.active"></button>
* <button gn-btn class="btn" ng-model="ctrl.drawLine.active"></button>
* </div>
*
* In that example the gn-btn are combined together in a "toggle group",
* where activating a button will deactivate the others.
*
* One can use `ng-model` directive at the group level in order to know if
* a button is active.
*
* Example:
*
* <div gn-btn-group gn-btn-group-active="ctrl.drawToolActive">
*
* See our live example: {@link ../examples/interactionbtngroup.html}
*
* @htmlAttribute {*} gn-btn-group-active Any property of the scope.
* Tells whether at least one button of the group is active.
* @param {angular.$parse} $parse Angular parse service.
* @return {angular.Directive} The directive specs.
* @ngInject
* @ngdoc directive
* @ngname gnBtnGroup
*/
module.directive('gnBtnGroup', ['$parse', function($parse) {
return {
restrict: 'A',
controller: 'gnBtnGroupController',
link:
/**
* @param {!angular.Scope} scope Scope.
* @param {angular.JQLite} element Element.
* @param {angular.Attributes} attrs Attributes.
* @param {!Object} controller Controller.
*/
function(scope, element, attrs, controller) {
var setActive = $parse(attrs['gnBtnGroupActive']).assign;

if (setActive) {
scope.$watch(function() {
// return true if at least one button is active otherwise false
return controller.buttons_.some(function(buttonModel) {
return (buttonModel(scope) === true);
});
}, function(newValue) {
setActive(scope, newValue);
});
}
}
};
}]);


/**
* @param {!angular.Scope} $scope Scope.
* @constructor
* @struct
* @ngInject
* @ngdoc controller
* @ngname gnBtnGroupController
*/
var BtnGroupController = function($scope) {
/**
* @type {Array.<angular.$parse.Expression>}
* @private
*/
this.buttons_ = [];

/**
* @type {!angular.Scope}
* @private
*/
this.scope_ = $scope;
};


/**
* @param {number} index Index of the button in buttons array.
*/
BtnGroupController.prototype.activate = function(index) {
this.buttons_.forEach(function(expressionFn, i) {
if (i != index) {
expressionFn.assign(this.scope_, false);
}
}, this);
};


/**
* @param {angular.$parse.Expression} expressionFn Expression function.
* @return {number} Index of the pushed setter.
*/
BtnGroupController.prototype.addButton = function(expressionFn) {
this.buttons_.push(expressionFn);
return this.buttons_.length - 1;
};

BtnGroupController['$inject'] = [
'$scope'
];

module.controller('gnBtnGroupController', BtnGroupController);


/**
* The gn-btn allows creating toggle buttons working with ng-model. It is
* typically used with Bootstrap buttons (`btn`).
*
* Example:
*
* <button gn-btn class="btn" ng-model="ctrl.interaction.active"></button>
*
* This example is about creating a Bootstrap button that can pressed/depressed
* to activate/deactivate an OpenLayers 3 interaction.
*
* @htmlAttribute {*} ng-model Any property on the scope. Ideally a boolean.
* @param {angular.$parse} $parse Angular parse service.
* @return {angular.Directive} The directive specs.
* @ngInject
* @ngdoc directive
* @ngname gnBtn
*/
module.directive('gnBtn', ['$parse', function($parse) {
return {
require: ['?^gnBtnGroup', 'ngModel'],
restrict: 'A',
link:
/**
* @param {!angular.Scope} scope Scope.
* @param {angular.JQLite} element Element.
* @param {angular.Attributes} attrs Attributes.
* @param {!Array.<!Object>} ctrls Controllers.
*/
function(scope, element, attrs, ctrls) {
var buttonsCtrl = ctrls[0];
var ngModelCtrl = ctrls[1];
var indexInGroup = -1;

var ngModelGet = $parse(attrs['ngModel']);
var ngModelSet = ngModelGet.assign;

// Set ng-model value to false if undefined
if (ngModelGet(scope) === undefined) {
ngModelSet(scope, false);
}
if (buttonsCtrl !== null) {
indexInGroup = buttonsCtrl.addButton(ngModelGet);
}

// UI -> model
element.bind('click', function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(!ngModelCtrl.$viewValue);
ngModelCtrl.$render();
});
});

// model -> UI
ngModelCtrl.$render = function() {
if (ngModelCtrl.$viewValue && buttonsCtrl !== null) {
buttonsCtrl.activate(indexInGroup);
}
element.toggleClass('active', ngModelCtrl.$viewValue);
};
}
};
}]);
})();

0 comments on commit 706b3ad

Please sign in to comment.
You can’t perform that action at this time.