diff --git a/__tests__/lib/geo/bbox.js b/__tests__/lib/geo/bbox.js index 5dfe4fa77..d740c0c3b 100644 --- a/__tests__/lib/geo/bbox.js +++ b/__tests__/lib/geo/bbox.js @@ -1,4 +1,4 @@ -import {diffBbox, flipBbox, isBboxFlipped} from '../../../lib/geo/bbox' +import {diffBbox, flipBbox, isBboxFlipped, isBboxValid} from '../../../lib/geo/bbox' describe('diffBbox', () => { it('should return 0 for equal bboxes', () => { @@ -50,3 +50,40 @@ describe('isBboxFlipped', () => { expect(isBboxFlipped(bbox, flipped)).toBe(true) }) }) + +describe('isBboxValid', () => { + it('should return false if the bbox is infinite', () => { + const bbox = [Infinity, Infinity, -Infinity, -Infinity] + + expect(isBboxValid(bbox)).toBe(false) + }) + + it('should return false if the bbox doesn’t have the correct length', () => { + const bbox = [1, 2, 3] + + expect(isBboxValid(bbox)).toBe(false) + }) + + it('should return false if the bbox is out of bounds', () => { + const bbox = [-181, -31, 180, 34] + + expect(isBboxValid(bbox)).toBe(false) + }) + + it('should return false if the bbox is flipped (and oob)', () => { + const bbox = [-31, -120, 42, 97] + + expect(isBboxValid(bbox)).toBe(false) + }) + + it('should return true if the bbox is valid', () => { + const bboxes = [ + [-180, -90, 180, 90], + [-8.789063, 40.178873, 14.062500, 52.321911] + ] + + bboxes.forEach(bbox => { + expect(isBboxValid(bbox)).toBe(true) + }) + }) +}) diff --git a/components/centered-map/empty.js b/components/centered-map/empty.js new file mode 100644 index 000000000..e635e2847 --- /dev/null +++ b/components/centered-map/empty.js @@ -0,0 +1,30 @@ +import React from 'react' +import PropTypes from 'prop-types' +import {translate} from 'react-i18next' + +const Empty = ({t}) => ( +
+ {t('map.emptyDataset')} + + +
+) + +Empty.propTypes = { + t: PropTypes.func.isRequired +} + +export default translate()(Empty) diff --git a/components/centered-map/enhance-map-data.js b/components/centered-map/enhance-map-data.js index 4024e0d49..759498f82 100644 --- a/components/centered-map/enhance-map-data.js +++ b/components/centered-map/enhance-map-data.js @@ -4,16 +4,16 @@ import hoist from 'hoist-non-react-statics' import computeBbox from '@turf/bbox' import flip from '@turf/flip' -import {isBboxFlipped, flipBbox} from '../../lib/geo/bbox' +import {isBboxFlipped, flipBbox, isBboxValid} from '../../lib/geo/bbox' + +const franceBbox = [-8.789063, 40.178873, 14.062500, 52.321911] export default Map => hoist(class extends React.PureComponent { static propTypes = { frozen: PropTypes.bool, extent: PropTypes.object, data: PropTypes.shape({ - features: PropTypes.arrayOf(PropTypes.shape({ - properties: PropTypes.object.isRequired - })) + features: PropTypes.array.isRequired }).isRequired } @@ -37,6 +37,10 @@ export default Map => hoist(class extends React.PureComponent { } } + if (!isBboxValid(bbox)) { + bbox = franceBbox + } + if (!frozen) { // We’re adding a unique id to all features so that we can easily identify them later. diff --git a/components/centered-map/map.js b/components/centered-map/map.js index ff17aa590..7d590044d 100644 --- a/components/centered-map/map.js +++ b/components/centered-map/map.js @@ -5,11 +5,14 @@ import mapStyle from 'mapbox-gl/dist/mapbox-gl.css' import enhanceMapData from './enhance-map-data' +import Empty from './empty' import Feature from './feature' class CenteredMap extends React.Component { static propTypes = { - data: PropTypes.object.isRequired, + data: PropTypes.shape({ + features: PropTypes.array.isRequired + }).isRequired, bbox: PropTypes.array.isRequired, frozen: PropTypes.bool.isRequired } @@ -187,6 +190,7 @@ class CenteredMap extends React.Component { render() { const {highlight} = this.state + const {data} = this.props return (
@@ -200,6 +204,12 @@ class CenteredMap extends React.Component {
)} + {data.features.length === 0 && ( +
+ +
+ )} + - - ) -} + + @media (max-width: 1080px) { + height: 200px; + } + + @media (max-width: 768px) { + height: 250px; + } + } + `} + +) SpatialExtent.propTypes = { extent: PropTypes.object.isRequired diff --git a/lib/geo/bbox.js b/lib/geo/bbox.js index e1be6a4df..444f6332a 100644 --- a/lib/geo/bbox.js +++ b/lib/geo/bbox.js @@ -26,3 +26,14 @@ export function isBboxFlipped(bbox, referenceBbox) { return reversedDiff < diff } + +// Make sure the passed bbox is valid. +export function isBboxValid(bbox) { + return ( + bbox.length === 4 && + bbox[0] >= -180 && bbox[0] <= 180 && + bbox[2] >= -180 && bbox[2] <= 180 && + bbox[1] >= -90 && bbox[1] <= 90 && + bbox[3] >= -90 && bbox[3] <= 90 + ) +} diff --git a/locales/en/common.json b/locales/en/common.json index 2985b6ebe..af1784783 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -74,6 +74,7 @@ "errors": { "noWebgl": "We couldn’t display this map because your browser doesn’t support WebGL" }, + "emptyDataset": "This dataset is empty", "additionalFeature": "One more feature…", "additionalFeature_plural": "{{ count }} more features…" }, diff --git a/locales/fr/common.json b/locales/fr/common.json index b275f63b4..da33b6b3e 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -74,6 +74,7 @@ "errors": { "noWebgl": "Nous ne pouvons pas afficher cette carte car votre navigateur ne supporte pas WebGL" }, + "emptyDataset": "Ce jeu de données est vide", "additionalFeature": "Un objet de plus…", "additionalFeature_plural": "{{ count }} objets de plus…" },