-
Notifications
You must be signed in to change notification settings - Fork 58
/
ZoomToExtentButton.tsx
111 lines (97 loc) · 3 KB
/
ZoomToExtentButton.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import logger from '@terrestris/base-util/dist/Logger';
import useMap from '@terrestris/react-util/dist/Hooks/useMap/useMap';
import _isFinite from 'lodash/isFinite';
import { Coordinate as OlCoordinate } from 'ol/coordinate';
import { easeOut } from 'ol/easing';
import { Extent as OlExtent } from 'ol/extent';
import OlSimpleGeometry from 'ol/geom/SimpleGeometry';
import { FitOptions as OlViewFitOptions } from 'ol/View';
import * as React from 'react';
import { CSS_PREFIX } from '../../constants';
import SimpleButton, { SimpleButtonProps } from '../SimpleButton/SimpleButton';
interface OwnProps {
/**
* Options for fitting to the given extent. See
* https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#fit
*/
fitOptions?: OlViewFitOptions;
/**
* If true, the view will always animate to the closest zoom level after an interaction.
* False means intermediary zoom levels are allowed.
* Default is false.
*/
constrainViewResolution?: boolean;
/**
* The extent `[minx, miny, maxx, maxy]` in the maps coordinate system or an
* instance of ol.geom.SimpleGeometry that the map should zoom to.
*/
extent?: OlExtent | OlSimpleGeometry;
/**
* The center `[x,y]` in the maps coordinate system or an
* instance of ol.coordinate that the map should zoom to if no extent is given.
*/
center?: OlCoordinate;
/**
* The zoom level 'x' the map should zoom to if no extent is given.
*/
zoom?: number;
/**
* The className which should be added.
*/
className?: string;
}
export type ZoomToExtentButtonProps = OwnProps & SimpleButtonProps;
// The class name for the component.
const defaultClassName = `${CSS_PREFIX}zoomtoextentbutton`;
const ZoomToExtentButton: React.FC<ZoomToExtentButtonProps> = ({
fitOptions = {
duration: 250,
easing: easeOut
},
constrainViewResolution = false,
extent,
center,
zoom,
className,
...passThroughProps
}) => {
const map = useMap();
const onClick = () => {
if (!map) {
return;
}
const view = map.getView();
if (!view) { // no view, no zooming
return;
}
if (!extent && (!center || !_isFinite(zoom))) {
logger.error('zoomToExtentButton: You need to provide either an extent or a center and a zoom.');
return;
}
if (view.getAnimating()) {
view.cancelAnimations();
}
view.setConstrainResolution(constrainViewResolution);
if (extent && (center && _isFinite(zoom))) {
logger.warn('zoomToExtentButton: Both extent and center / zoom are provided. ' +
'Extent will be used in favor of center / zoom');
}
if (extent) {
view.fit(extent, fitOptions);
} else if (center && _isFinite(zoom)) {
view.setCenter(center);
view.setZoom(zoom!);
}
};
const finalClassName = className
? `${defaultClassName} ${className}`
: defaultClassName;
return (
<SimpleButton
className = {finalClassName}
onClick = {onClick}
{ ...passThroughProps}
/>
);
};
export default ZoomToExtentButton;