Remove usage of deprecated interactive properties in map styles (#621)

This commit is contained in:
Xiaoji Chen 2018-10-13 21:27:47 -07:00 committed by GitHub
parent 8b75b1ed81
commit 91550c7c18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 83 deletions

View File

@ -136,12 +136,15 @@ This object must implement the following interface:
- `events` - An array of subscribed events
- `handleEvent(event, context)` - A method that handles interactive events
Parameters
- `event` - The pointer event.
+ `event.lngLat` - The geo coordinates that is being hovered.
+ `event.features` - The array of features under the pointer, queried using Mapbox's
[queryRenderedFeatures](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures) API.
To make a layer interactive, set the `interactive` property in the layer style to `true`.
##### `interactiveLayerIds` {Array} [default: null]
A list of layer ids that are interactive. If specified:
- Pointer event callbacks will only query the features under the pointer of these layers.
- The `getCursor` callback will receive `isHovering: true` when hover over features of these layers.
If not specified:
- Pointer event callbacks will query the features under the pointer of all layers.
- The `getCursor` callback will always receive `isHovering: false`.
##### `onHover` {Function}
@ -152,7 +155,7 @@ Parameters
+ `event.lngLat` - The geo coordinates that is being clicked.
+ `event.features` - The array of features under the pointer, queried using Mapbox's
[queryRenderedFeatures](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures) API.
To make a layer interactive, set the `interactive` property in the layer style to `true`.
To make only selected layers interactive, set the `interactiveLayerIds` prop.
##### `onClick` {Function}
@ -163,7 +166,7 @@ Parameters
+ `event.lngLat` - The geo coordinates that is being clicked.
+ `event.features` - The array of features under the pointer, queried using Mapbox's
[queryRenderedFeatures](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures) API.
To make a layer interactive, set the `interactive` property in the layer style to `true`.
To make only selected layers interactive, set the `interactiveLayerIds` prop.
##### `onContextMenu` {Function}
@ -178,7 +181,9 @@ Accessor that returns a cursor style to show interactive state. Called when the
Parameters
- `state` - The current state of the component.
+ `state.isDragging` - If the map is being dragged.
+ `state.isHovering` - If the pointer is over a clickable feature.
+ `state.isHovering` - If the pointer is over an interactive feature. See `interactiveLayerIds` prop.
The default implementation of `getCursor` returns `'pointer'` if `isHovering`, `'grabbing'` if `isDragging` and `'grab'` otherwise.
##### `transitionDuration` {Number}

View File

@ -6,7 +6,6 @@ import {MAPBOX_LIMITS} from '../utils/map-state';
import WebMercatorViewport from 'viewport-mercator-project';
import TransitionManager from '../utils/transition-manager';
import {getInteractiveLayerIds} from '../utils/style-utils';
import {EventManager} from 'mjolnir.js';
import MapControls from '../utils/map-controls';
@ -104,6 +103,9 @@ const propTypes = Object.assign({}, StaticMap.propTypes, {
/** Radius to detect features around a clicked point. Defaults to 0. */
clickRadius: PropTypes.number,
/** List of layers that are interactive */
interactiveLayerIds: PropTypes.array,
/** Accessor that returns a cursor style to show interactive state */
getCursor: PropTypes.func,
@ -168,8 +170,6 @@ export default class InteractiveMap extends PureComponent {
});
this._width = 0;
this._height = 0;
this._updateQueryParams(props.mapStyle);
}
componentDidMount() {
@ -186,10 +186,6 @@ export default class InteractiveMap extends PureComponent {
}
componentWillUpdate(nextProps) {
if (this.props.mapStyle !== nextProps.mapStyle) {
this._updateQueryParams(nextProps.mapStyle);
}
this._setControllerProps(nextProps);
}
@ -217,23 +213,23 @@ export default class InteractiveMap extends PureComponent {
_getFeatures({pos, radius}) {
let features;
const queryParams = {};
if (this.props.interactiveLayerIds) {
queryParams.layers = this.props.interactiveLayerIds;
}
if (radius) {
// Radius enables point features, like marker symbols, to be clicked.
const size = radius;
const bbox = [[pos[0] - size, pos[1] + size], [pos[0] + size, pos[1] - size]];
features = this._map.queryRenderedFeatures(bbox, this._queryParams);
features = this._map.queryRenderedFeatures(bbox, queryParams);
} else {
features = this._map.queryRenderedFeatures(pos, this._queryParams);
features = this._map.queryRenderedFeatures(pos, queryParams);
}
return features;
}
// Hover and click only query layers whose interactive property is true
_updateQueryParams(mapStyle) {
const interactiveLayerIds = getInteractiveLayerIds(mapStyle);
this._queryParams = {layers: interactiveLayerIds};
}
_onInteractionStateChange = (interactionState) => {
const {isDragging = false} = interactionState;
if (isDragging !== this.state.isDragging) {
@ -276,7 +272,7 @@ export default class InteractiveMap extends PureComponent {
const pos = this._getPos(event);
const features = this._getFeatures({pos, radius: this.props.clickRadius});
const isHovering = features && features.length > 0;
const isHovering = this.props.interactiveLayerIds && features && features.length > 0;
if (isHovering !== this.state.isHovering) {
this.setState({isHovering});
}

View File

@ -1,24 +1,3 @@
// TODO - remove in the next major release
// Mapbox dropped the `interactive` property: https://github.com/mapbox/mapbox-gl-js/issues/1479
export function getInteractiveLayerIds(style) {
if (!style) {
return null;
}
if (typeof style === 'string') {
return null;
}
if (style.toJS) {
style = style.toJS();
}
if (Array.isArray(style.layers)) {
return style.layers.filter(l => l.interactive).map(l => l.id);
}
return null;
}
// Prepare a map style object for diffing
// If immutable - convert to plain object
// Work around some issues in the styles that would fail Mapbox's diffing

View File

@ -1,5 +1,4 @@
import './transition';
import './style-utils.spec';
import './map-state.spec';
import './map-constraints.spec';
import './dynamic-position.spec';

View File

@ -1,36 +0,0 @@
import test from 'tape-catch';
import Immutable from 'immutable';
import deepEqual from 'deep-equal';
import {getInteractiveLayerIds} from 'react-map-gl/utils/style-utils';
const TEST_STYLE_STRING = 'mapbox://styles/mapbox/streets-v9';
const TEST_STYLE_JS = {
layers: [
{
id: 'interactive',
interactive: true
}, {
id: 'non-interactive',
interactive: false
}
]
};
const TEST_STYLE_IMMUTABLE = Immutable.fromJS(TEST_STYLE_JS);
test('getInteractiveLayerIds#String style', t => {
const layers = getInteractiveLayerIds(TEST_STYLE_STRING);
t.notOk(layers, 'should not return layer ids');
t.end();
});
test('getInteractiveLayerIds#JS style', t => {
const layers = getInteractiveLayerIds(TEST_STYLE_JS);
t.equal(deepEqual(layers, ['interactive']), true, 'got expected layer ids');
t.end();
});
test('getInteractiveLayerIds#Immutable style', t => {
const layers = getInteractiveLayerIds(TEST_STYLE_IMMUTABLE);
t.equal(deepEqual(layers, ['interactive']), true, 'got expected layer ids');
t.end();
});