diff --git a/web/client/components/TOC/DefaultLayer.jsx b/web/client/components/TOC/DefaultLayer.jsx index d5b2e506d0..cb82c00574 100644 --- a/web/client/components/TOC/DefaultLayer.jsx +++ b/web/client/components/TOC/DefaultLayer.jsx @@ -24,6 +24,7 @@ var DefaultLayer = React.createClass({ settings: React.PropTypes.object, propertiesChangeHandler: React.PropTypes.func, onToggle: React.PropTypes.func, + onZoom: React.PropTypes.func, onSettings: React.PropTypes.func, style: React.PropTypes.object, sortableStyle: React.PropTypes.object, @@ -34,6 +35,7 @@ var DefaultLayer = React.createClass({ activateLegendTool: React.PropTypes.bool, activateRemoveLayer: React.PropTypes.bool, activateSettingsTool: React.PropTypes.bool, + activateZoomTool: React.PropTypes.bool, settingsText: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]), opacityText: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]), saveText: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]), @@ -52,10 +54,12 @@ var DefaultLayer = React.createClass({ sortableStyle: {}, propertiesChangeHandler: () => {}, onToggle: () => {}, + onZoom: () => {}, onSettings: () => {}, activateRemoveLayer: false, activateLegendTool: false, activateSettingsTool: false, + activateZoomTool: false, includeDeleteButtonInSettings: false, modalOptions: {}, settingsOptions: {}, @@ -134,6 +138,15 @@ var DefaultLayer = React.createClass({ onClick={(node) => this.props.onToggle(node.id, node.expanded)}/> ); } + if (this.props.activateZoomTool && this.props.node.bbox) { + tools.push( + this.props.onZoom(node.bbox.bounds, node.bbox.crs)}/> + ); + } return tools; }, render() { diff --git a/web/client/components/TOC/__tests__/DefaultLayer-test.jsx b/web/client/components/TOC/__tests__/DefaultLayer-test.jsx index 1fdd4cd8e6..1fe7f94c4e 100644 --- a/web/client/components/TOC/__tests__/DefaultLayer-test.jsx +++ b/web/client/components/TOC/__tests__/DefaultLayer-test.jsx @@ -136,6 +136,38 @@ describe('test DefaultLayer module component', () => { expect(spy.calls.length).toBe(1); }); + it('tests zoom tool', () => { + const l = { + name: 'layer00', + title: 'Layer', + visibility: true, + storeIndex: 9, + type: 'wms', + bbox: { + crs: "EPSG:4326", + bounds: { + minx: 11.0, + maxx: 13.0, + miny: 43.0, + maxy: 44.0 + } + } + }; + const actions = { + onZoom: () => {} + }; + let spy = expect.spyOn(actions, "onZoom"); + const comp = ReactDOM.render(, + document.getElementById("container")); + expect(comp).toExist(); + const domNode = ReactDOM.findDOMNode(comp); + expect(domNode).toExist(); + const tool = ReactDOM.findDOMNode(TestUtils.scryRenderedDOMComponentsWithClass(comp, "glyphicon")[1]); + expect(tool).toExist(); + tool.click(); + expect(spy.calls.length).toBe(1); + }); + it('tests removelayer tool', () => { const l = { name: 'layer000', diff --git a/web/client/components/catalog/RecordItem.jsx b/web/client/components/catalog/RecordItem.jsx index 8f93c1b545..e4b2e1f31d 100644 --- a/web/client/components/catalog/RecordItem.jsx +++ b/web/client/components/catalog/RecordItem.jsx @@ -186,7 +186,15 @@ const RecordItem = React.createClass({ visibility: true, name: wms.params && wms.params.name, title: this.props.record.title || (wms.params && wms.params.name), - boundingBox: this.props.record.boundingBox, + bbox: { + crs: this.props.record.boundingBox.crs, + bounds: { + minx: this.props.record.boundingBox.extent[0], + miny: this.props.record.boundingBox.extent[1], + maxx: this.props.record.boundingBox.extent[2], + maxy: this.props.record.boundingBox.extent[3] + } + }, links: this.getLinks(this.props.record), params: params, allowedSRS: allowedSRS diff --git a/web/client/components/catalog/__tests__/RecordItem-test.jsx b/web/client/components/catalog/__tests__/RecordItem-test.jsx index d43b19f624..678c4aa41f 100644 --- a/web/client/components/catalog/__tests__/RecordItem-test.jsx +++ b/web/client/components/catalog/__tests__/RecordItem-test.jsx @@ -190,4 +190,33 @@ describe('This test for RecordItem', () => { button.click(); expect(actionsSpy.calls.length).toBe(1); }); + it('check add layer with bounding box', () => { + let actions = { + onLayerAdd: () => { + + }, + onZoomToExtent: () => { + + } + }; + let actionsSpy = expect.spyOn(actions, "onLayerAdd"); + const item = ReactDOM.render((), document.getElementById("container")); + expect(item).toExist(); + + const itemDom = ReactDOM.findDOMNode(item); + expect(itemDom).toExist(); + expect(itemDom.className).toBe('record-item panel panel-default'); + let button = TestUtils.findRenderedDOMComponentWithTag( + item, 'button' + ); + expect(button).toExist(); + button.click(); + expect(actionsSpy.calls.length).toBe(1); + expect(actionsSpy.calls[0].arguments[0].bbox).toExist(); + expect(actionsSpy.calls[0].arguments[0].bbox.crs).toExist(); + expect(actionsSpy.calls[0].arguments[0].bbox.bounds).toExist(); + }); }); diff --git a/web/client/config.json b/web/client/config.json index aaaa037de8..784069c3f7 100644 --- a/web/client/config.json +++ b/web/client/config.json @@ -95,7 +95,11 @@ "title": "Weather data", "name": "nurc:Arc_Sample", "group": "Meteo", - "format": "image/png" + "format": "image/png", + "bbox": { + "bounds": {"minx": -25.6640625, "miny": 26.194876675795218, "maxx": 48.1640625, "maxy": 56.80087831233043}, + "crs": "EPSG:4326" + } }, { "type": "tileprovider", diff --git a/web/client/plugins/Save.jsx b/web/client/plugins/Save.jsx index a8002ce344..26cd5b3145 100644 --- a/web/client/plugins/Save.jsx +++ b/web/client/plugins/Save.jsx @@ -96,6 +96,7 @@ const Save = React.createClass({ transparent: layer.transparent, type: layer.type, url: layer.url, + bbox: layer.bbox, visibility: layer.visibility }; }); diff --git a/web/client/plugins/SaveAs.jsx b/web/client/plugins/SaveAs.jsx index 0776219574..56873414ee 100644 --- a/web/client/plugins/SaveAs.jsx +++ b/web/client/plugins/SaveAs.jsx @@ -128,6 +128,7 @@ const SaveAs = React.createClass({ transparent: layer.transparent, type: layer.type, url: layer.url, + bbox: layer.bbox, visibility: layer.visibility }; }); diff --git a/web/client/plugins/TOC.jsx b/web/client/plugins/TOC.jsx index d7a2087b4d..69f376dfa8 100644 --- a/web/client/plugins/TOC.jsx +++ b/web/client/plugins/TOC.jsx @@ -10,6 +10,8 @@ const {connect} = require('react-redux'); const {createSelector} = require('reselect'); const {changeLayerProperties, changeGroupProperties, toggleNode, sortNode, showSettings, hideSettings, updateSettings, updateNode, removeNode} = require('../actions/layers'); +const {zoomToExtent} = require('../actions/map'); + const {groupsSelector} = require('../selectors/layers'); const LayersUtils = require('../utils/LayersUtils'); @@ -46,6 +48,7 @@ const LayerTree = React.createClass({ layerPropertiesChangeHandler: React.PropTypes.func, onToggleGroup: React.PropTypes.func, onToggleLayer: React.PropTypes.func, + onZoomToExtent: React.PropTypes.func, onSort: React.PropTypes.func, onSettings: React.PropTypes.func, hideSettings: React.PropTypes.func, @@ -54,6 +57,7 @@ const LayerTree = React.createClass({ removeNode: React.PropTypes.func, activateRemoveLayer: React.PropTypes.bool, activateLegendTool: React.PropTypes.bool, + activateZoomTool: React.PropTypes.bool, activateSettingsTool: React.PropTypes.bool, visibilityCheckType: React.PropTypes.string, settingsOptions: React.PropTypes.object @@ -64,10 +68,12 @@ const LayerTree = React.createClass({ layerPropertiesChangeHandler: () => {}, onToggleGroup: () => {}, onToggleLayer: () => {}, + onZoomToExtent: () => {}, onSettings: () => {}, updateNode: () => {}, removeNode: () => {}, activateLegendTool: true, + activateZoomTool: true, activateSettingsTool: true, activateRemoveLayer: true, visibilityCheckType: "checkbox", @@ -96,6 +102,7 @@ const LayerTree = React.createClass({ } opacityText={} @@ -126,6 +134,7 @@ const TOCPlugin = connect(tocSelector, { onToggleLayer: LayersUtils.toggleByType('layers', toggleNode), onSort: LayersUtils.sortUsing(LayersUtils.sortLayers, sortNode), onSettings: showSettings, + onZoomToExtent: zoomToExtent, hideSettings, updateSettings, updateNode,