Map events and methods

This commit is contained in:
Nick
2017-10-23 16:41:36 -07:00
parent 29a70dc421
commit 967cef979d
38 changed files with 1113 additions and 491 deletions
+164 -123
View File
@@ -1,55 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import { requireNativeComponent } from 'react-native';
import { isFunction, runNativeCommand, noop } from '../utils';
import { NativeModules, requireNativeComponent } from 'react-native';
import { makePoint, makeLatLngBounds } from '../utils/geoUtils';
import { isFunction, runNativeCommand } from '../utils';
const DEFAULT_CENTER_COORDINATE = {
type: 'Point',
coordinates: [-77.036086, 38.910233],
};
const MapboxGL = NativeModules.MGLModule;
export const NATIVE_MODULE_NAME = 'RCTMGLMapView';
const RCTMGLMapView = requireNativeComponent(NATIVE_MODULE_NAME, MapView, {
nativeOnly: { onMapChange: true }
nativeOnly: { onMapChange: true },
});
/**
* MapView backed by Mapbox Native GL
*/
class MapView extends React.Component {
static StyleURL = {
Street: 'mapbox-streets',
Dark: 'mapbox-dark',
Light: 'mapbox-light',
Outdoors: 'mapbox-outdoors',
Satellite: 'mapbox-satellite',
};
static EventTypes = {
// UI Interaction events
Press: 'press',
LongPress: 'longpress',
// Map change events
RegionWillChange: 'regionwillchange',
RegionIsChanging: 'regionischanging',
RegionDidChange: 'regiondidchange',
WillStartLoadinMap: 'willstartloadingmap',
DidFinishLoadingMap: 'didfinishloadingmap',
DidFailLoadingMap: 'didfailoadingmap',
WillStartRenderingFrame: 'willstartrenderingframe',
DidFinishRenderingFrame: 'didfinishrenderingframe',
DidFinishRenderingFrameFully: 'didfinishrenderingframefully',
WillStartRenderingMap: 'willstartrenderingmap',
DidFinishRenderingMap: 'didfinishrenderingmap',
DidFinishRenderingMapFully: 'didfinishrenderingmapfully',
DidFinishLoadingStyle: 'didfinishloadingstyle',
// Animation completion events
FlyToComplete: 'flytocomplete',
};
static propTypes = {
/**
* Animates changes between pitch and bearing
@@ -57,9 +23,19 @@ class MapView extends React.Component {
animated: PropTypes.bool,
/**
* Initial center coordinate on map
* Initial center coordinate on map [lng, lat]
*/
centerCoordinate: PropTypes.object,
centerCoordinate: PropTypes.arrayOf(PropTypes.number),
/**
* Shows the users location on the map
*/
showUserLocation: PropTypes.bool,
/**
* The mode used to track the user location on the map
*/
userTrackingMode: PropTypes.number,
/**
* Initial heading on map
@@ -109,93 +85,103 @@ class MapView extends React.Component {
/**
* Map press listener, gets called when a user presses the map
*/
onPress: PropTypes.func,
onPress: PropTypes.func,
/**
* Map long press listener, gets called when a user long presses the map
*/
onLongPress: PropTypes.func,
/**
* Map long press listener, gets called when a user long presses the map
*/
onLongPress: PropTypes.func,
/**
* This event is triggered whenever the currently displayed map region is about to change.
*/
onRegionWillChange: PropTypes.func,
/**
* This event is triggered whenever the currently displayed map region is about to change.
*/
onRegionWillChange: PropTypes.func,
/**
* This event is triggered whenever the currently displayed map region is changing.
*/
onRegionIsChanging: PropTypes.func,
/**
* This event is triggered whenever the currently displayed map region is changing.
*/
onRegionIsChanging: PropTypes.func,
/**
* This event is triggered whenever the currently displayed map region finished changing
*/
onRegionDidChange: PropTypes.func,
/**
* This event is triggered whenever the currently displayed map region finished changing
*/
onRegionDidChange: PropTypes.func,
/**
* This event is triggered when the map is about to start loading a new map style.
*/
onWillStartLoadingMap: PropTypes.func,
/**
* This event is triggered when the map is about to start loading a new map style.
*/
onWillStartLoadingMap: PropTypes.func,
/**
* This is triggered when the map has successfully loaded a new map style.
*/
onDidFinishLoadingMap: PropTypes.func,
/**
* This is triggered when the map has successfully loaded a new map style.
*/
onDidFinishLoadingMap: PropTypes.func,
/**
* This event is triggered when the map has failed to load a new map style.
*/
onDidFailLoadingMap: PropTypes.func,
/**
* This event is triggered when the map has failed to load a new map style.
*/
onDidFailLoadingMap: PropTypes.func,
/**
* This event is triggered when the map will start rendering a frame.
*/
onWillStartRenderingFrame: PropTypes.func,
/**
* This event is triggered when the map will start rendering a frame.
*/
onWillStartRenderingFrame: PropTypes.func,
/**
* This event is triggered when the map finished rendering a frame.
*/
onDidFinishRenderingFrame: PropTypes.func,
/**
* This event is triggered when the map finished rendering a frame.
*/
onDidFinishRenderingFrame: PropTypes.func,
/**
* This event is triggered when the map fully finished rendering a frame.
*/
onDidFinishRenderingFrameFully: PropTypes.func,
/**
* This event is triggered when the map fully finished rendering a frame.
*/
onDidFinishRenderingFrameFully: PropTypes.func,
/**
* This event is triggered when the map will start rendering the map.
*/
onWillStartRenderingMap: PropTypes.func,
/**
* This event is triggered when the map will start rendering the map.
*/
onWillStartRenderingMap: PropTypes.func,
/**
* This event is triggered when the map finished rendering the map.
*/
onDidFinishRenderingMap: PropTypes.func,
/**
* This event is triggered when the map finished rendering the map.
*/
onDidFinishRenderingMap: PropTypes.func,
/**
* This event is triggered when the map fully finished rendering the map.
*/
onDidFinishRenderingMapFully: PropTypes.func,
/**
* This event is triggered when the map fully finished rendering the map.
*/
onDidFinishRenderingMapFully: PropTypes.func,
/**
* This event is triggered when a style has finished loading.
*/
onDidFinishLoadingStyle: PropTypes.func,
/**
* This event is triggered when a style has finished loading.
*/
onDidFinishLoadingStyle: PropTypes.func,
/**
* This event is triggered when a fly to animation is cancelled or completed
*/
onFlyToComplete: PropTypes.func,
/**
* This event is triggered when a fly to animation is cancelled or completed after calling flyTo
*/
onFlyToComplete: PropTypes.func,
/**
* This event is triggered once the camera is finished after calling setCamera
*/
onSetCameraComplete: PropTypes.func,
/**
* This event is triggered when the users location changes depands on showUserLocation
*/
onUserLocationChange: PropTypes.func,
};
static defaultProps = {
animated: true,
centerCoordinate: DEFAULT_CENTER_COORDINATE,
animated: false,
heading: 0,
pitch: 0,
scrollEnabled: true,
pitchEnabled: true,
zoomLevel: 16,
styleURL: MapView.StyleURL.Street,
userTrackingMode: MapboxGL.UserTrackingModes.None,
styleURL: MapboxGL.StyleURL.Street,
};
constructor (props) {
@@ -204,6 +190,18 @@ class MapView extends React.Component {
this._onPress = this._onPress.bind(this);
this._onLongPress = this._onLongPress.bind(this);
this._onChange = this._onChange.bind(this);
this._onUserLocationChange = this._onUserLocationChange.bind(this);
}
fitBounds (northEastCoordinates, southWestCoordinates, padding = 0, duration = 2000) {
if (!this._nativeRef) {
return;
}
runNativeCommand(NATIVE_MODULE_NAME, 'fitBounds', this._nativeRef, [
this._packGeoJSON(makeLatLngBounds(northEastCoordinates, southWestCoordinates)),
padding,
duration,
]);
}
flyTo (coordinates, duration = 2000) {
@@ -211,11 +209,31 @@ class MapView extends React.Component {
return;
}
runNativeCommand(NATIVE_MODULE_NAME, 'flyTo', this._nativeRef, [
{ type: 'Point', coordinates: coordinates },
this._packGeoJSON(makePoint(coordinates)),
duration,
]);
}
setCamera (config = {}) {
if (!this._nativeRef) {
return;
}
let centerCoordFeature;
if (config.centerCoordinate) {
centerCoordFeature = this._packGeoJSON(makePoint(config.centerCoordinate));
}
const cameraConfig = {
centerCoordinate: centerCoordFeature,
pitch: config.pitch,
heading: config.heading,
duration: config.duration || 2000,
};
runNativeCommand(NATIVE_MODULE_NAME, 'setCamera', this._nativeRef, [cameraConfig]);
}
_onPress (e) {
if (isFunction(this.props.onPress)) {
this.props.onPress(e.nativeEvent.payload);
@@ -228,53 +246,62 @@ class MapView extends React.Component {
}
}
_onUserLocationChange (e) {
if (isFunction(this.props.onUserLocationChange)) {
this.props.onUserLocationChange(e.nativeEvent);
}
}
_onChange (e) {
const { type, payload } = e.nativeEvent;
let propName = '';
switch (type) {
case MapView.EventTypes.RegionWillChange:
case MapboxGL.EventTypes.RegionWillChange:
propName = 'onRegionWillChange';
break;
case MapView.EventTypes.RegionIsChanging:
case MapboxGL.EventTypes.RegionIsChanging:
propName = 'onRegionIsChanging';
break;
case MapView.EventTypes.RegionDidChange:
case MapboxGL.EventTypes.RegionDidChange:
propName = 'onRegionDidChange';
break;
case MapView.EventTypes.WillStartLoadinMap:
case MapboxGL.EventTypes.WillStartLoadinMap:
propName = 'onWillStartLoadingMap';
break;
case MapView.EventTypes.DidFinishLoadingMap:
case MapboxGL.EventTypes.DidFinishLoadingMap:
propName = 'onDidFinishLoadingMap';
break;
case MapView.EventTypes.DidFailLoadingMap:
case MapboxGL.EventTypes.DidFailLoadingMap:
propName = 'onDidFailLoadingMap';
break;
case MapView.EventTypes.WillStartRenderingFrame:
case MapboxGL.EventTypes.WillStartRenderingFrame:
propName = 'onWillStartRenderingFrame';
break;
case MapView.EventTypes.DidFinishRenderingFrame:
case MapboxGL.EventTypes.DidFinishRenderingFrame:
propName = 'onDidFinishRenderingFrame';
break;
case MapView.EventTypes.DidFinishRenderingFrameFully:
case MapboxGL.EventTypes.DidFinishRenderingFrameFully:
propName = 'onDidFinishRenderingFrameFully';
break;
case MapView.EventTypes.WillStartRenderingMap:
case MapboxGL.EventTypes.WillStartRenderingMap:
propName = 'onWillStartRenderingMap';
break;
case MapView.EventTypes.DidFinishRenderingMap:
case MapboxGL.EventTypes.DidFinishRenderingMap:
propName = 'onDidFinishRenderingMap';
break;
case MapView.EventTypes.DidFinishRenderingMapFully:
case MapboxGL.EventTypes.DidFinishRenderingMapFully:
propName = 'onDidFinishRenderingMapFully';
break;
case MapView.EventTypes.DidFinishLoadingStyle:
case MapboxGL.EventTypes.DidFinishLoadingStyle:
propName = 'onDidFinishLoadingStyle';
break;
case MapView.EventTypes.FlyToComplete:
case MapboxGL.EventTypes.FlyToComplete:
propName = 'onFlyToComplete';
break;
case MapboxGL.EventTypes.SetCameraComplete:
propName = 'onSetCameraComplete';
break;
}
if (propName.length) {
@@ -282,16 +309,29 @@ class MapView extends React.Component {
}
}
_handleOnChange(propName, payload) {
_handleOnChange (propName, payload) {
if (isFunction(this.props[propName])) {
this.props[propName](payload);
}
}
_getCenterCoordinate () {
if (!this.props.centerCoordinate) {
return;
}
return this._packGeoJSON((makePoint(this.props.centerCoordinate)));
}
_packGeoJSON (geoJSON) {
return JSON.stringify(geoJSON);
}
render () {
const props = {
let props = {
animated: this.props.animated,
centerCoordinate: this.props.centerCoordinate,
centerCoordinate: this._getCenterCoordinate(),
showUserLocation: this.props.showUserLocation,
userTrackingMode: this.props.userTrackingMode,
heading: this.props.heading,
pitch: this.props.pitch,
style: this.props.style,
@@ -307,6 +347,7 @@ class MapView extends React.Component {
onPress: this._onPress,
onLongPress: this._onLongPress,
onMapChange: this._onChange,
onUserLocationChange: this._onUserLocationChange,
};
return (
+6 -1
View File
@@ -1,8 +1,13 @@
import { NativeModules } from 'react-native';
import MapView from './components/MapView';
import * as geoUtils from './utils/geoUtils';
let MapboxGL = {};
let MapboxGL = { ...NativeModules.MGLModule };
// components
MapboxGL.MapView = MapView;
// utils
MapboxGL.geoUtils = geoUtils;
export default MapboxGL;
+12
View File
@@ -0,0 +1,12 @@
import turfHelpers from '@turf/helpers';
export function makePoint (coordinates) {
return turfHelpers.point(coordinates);
}
export function makeLatLngBounds (northEastCoordinates, southWestCoordinates) {
return turfHelpers.featureCollection([
turfHelpers.point(northEastCoordinates),
turfHelpers.point(southWestCoordinates),
]);
}