Updated fitBounds to also accept an array so we can control padding on each side

This commit is contained in:
Nick
2017-10-23 16:41:52 -07:00
parent 33f6cffce6
commit 7b7cdbe2f5
8 changed files with 219 additions and 24 deletions
@@ -25,7 +25,11 @@ public class CameraStop {
private LatLng mLatLng;
private LatLngBounds mBounds;
private int mBoundsPadding = 0;
private int mBoundsPaddingLeft = 0;
private int mBoundsPaddingRight = 0;
private int mBoundsPaddingBottom = 0;
private int mBooundsPaddingTop = 0;
private int mMode = CameraMode.EASE;
private int mDuration = 2000;
private MapboxMap.CancelableCallback mCallback;
@@ -56,9 +60,12 @@ public class CameraStop {
mCallback = callback;
}
public void setBounds(LatLngBounds bounds, int padding) {
public void setBounds(LatLngBounds bounds, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) {
mBounds = bounds;
mBoundsPadding = padding;
mBoundsPaddingLeft = paddingLeft;
mBoundsPaddingRight = paddingRight;
mBooundsPaddingTop = paddingTop;
mBoundsPaddingBottom = paddingBottom;
}
public void setMode(@CameraMode.Mode int mode) {
@@ -67,7 +74,8 @@ public class CameraStop {
public CameraUpdateItem toCameraUpdate() {
if (mBounds != null) {
CameraUpdate update = CameraUpdateFactory.newLatLngBounds(mBounds, mBoundsPadding);
CameraUpdate update = CameraUpdateFactory.newLatLngBounds(mBounds, mBoundsPaddingLeft,
mBooundsPaddingTop, mBoundsPaddingRight, mBoundsPaddingBottom);
return new CameraUpdateItem(update, mDuration, mCallback, CameraMode.FLIGHT);
}
@@ -117,9 +125,14 @@ public class CameraStop {
}
if (readableMap.hasKey("bounds")) {
int padding = readableMap.hasKey("boundsPadding") ? readableMap.getInt("boundsPadding") : 0;
int paddingTop = getBoundsPaddingByKey(readableMap, "boundsPaddingTop");
int paddingRight = getBoundsPaddingByKey(readableMap, "boundsPaddingRight");
int paddingBottom = getBoundsPaddingByKey(readableMap, "boundsPaddingBottom");
int paddingLeft = getBoundsPaddingByKey(readableMap, "boundsPaddingLeft");
FeatureCollection collection = FeatureCollection.fromJson(readableMap.getString("bounds"));
stop.setBounds(ConvertUtils.toLatLngBounds(collection), padding);
stop.setBounds(ConvertUtils.toLatLngBounds(collection), paddingLeft, paddingRight,
paddingTop, paddingBottom);
}
if (readableMap.hasKey("mode")) {
@@ -138,4 +151,8 @@ public class CameraStop {
stop.setCallback(callback);
return stop;
}
private static int getBoundsPaddingByKey(ReadableMap map, String key) {
return map.hasKey(key) ? map.getInt(key) : 0;
}
}
+33 -1
View File
@@ -39,6 +39,36 @@
| onSetCameraComplete | `func` | `none` | `false` | This event is triggered once the camera is finished after calling setCamera |
### methods
#### queryRenderedFeaturesAtPoint(coordinate[, filter][, layerIDs])
##### arguments
| Name | Type | Required | Description |
| ---- | :--: | :------: | :----------: |
| `coordinate` | `Array` | `Yes` | A point expressed in the map views coordinate system. |
| `filter` | `Array` | `No` | A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. |
| `layerIDs` | `Array` | `No` | A array of layer id's to filter the features by |
```javascript
this._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2'])
```
#### queryRenderedFeaturesInRect(bbox[, filter][, layerIDs])
##### arguments
| Name | Type | Required | Description |
| ---- | :--: | :------: | :----------: |
| `bbox` | `Array` | `Yes` | A rectangle expressed in the map views coordinate system. |
| `filter` | `Array` | `No` | A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. |
| `layerIDs` | `Array` | `No` | A array of layer id's to filter the features by |
```javascript
this._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2'])
```
#### fitBounds(northEastCoordinates, southWestCoordinates[, padding][, duration])
##### arguments
| Name | Type | Required | Description |
@@ -52,7 +82,9 @@
```javascript
this.map.fitBounds([lng, lat], [lng, lat])
this.map.fitBounds([lng, lat], [lng, lat], 20, 1000)
this.map.fitBounds([lng, lat], [lng, lat], 20, 1000) // padding for all sides
this.map.fitBounds([lng, lat], [lng, lat], [verticalPadding, horizontalPadding], 1000)
this.map.fitBounds([lng, lat], [lng, lat], [top, right, bottom, left], 1000)
```
+86 -2
View File
@@ -778,9 +778,93 @@
"MapView": {
"description": "MapView backed by Mapbox Native GL",
"methods": [
{
"name": "queryRenderedFeaturesAtPoint",
"docblock": "Returns an array of rendered map features that intersect with a given point.\n\n@example\nthis._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n@param {Array<Number>} coordinate - A point expressed in the map views coordinate system.\n@param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.\n@param {Array=} layerIDs - A array of layer id's to filter the features by\n@return {FeatureCollection}",
"modifiers": [
"async"
],
"params": [
{
"name": "coordinate",
"description": "A point expressed in the map views coordinate system.",
"type": {
"name": "Array"
}
},
{
"name": "filter",
"description": "A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.",
"type": {
"name": "Array"
},
"optional": true
},
{
"name": "layerIDs",
"description": "A array of layer id's to filter the features by",
"type": {
"name": "Array"
},
"optional": true
}
],
"returns": {
"description": null,
"type": {
"name": "FeatureCollection"
}
},
"description": "Returns an array of rendered map features that intersect with a given point.",
"examples": [
"\nthis._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n"
]
},
{
"name": "queryRenderedFeaturesInRect",
"docblock": "Returns an array of rendered map features that intersect with the given rectangle,\nrestricted to the given style layers and filtered by the given predicate.\n\n@example\nthis._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n@param {Array<Number>} bbox - A rectangle expressed in the map views coordinate system.\n@param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.\n@param {Array=} layerIDs - A array of layer id's to filter the features by\n@return {FeatureCollection}",
"modifiers": [
"async"
],
"params": [
{
"name": "bbox",
"description": "A rectangle expressed in the map views coordinate system.",
"type": {
"name": "Array"
}
},
{
"name": "filter",
"description": "A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.",
"type": {
"name": "Array"
},
"optional": true
},
{
"name": "layerIDs",
"description": " A array of layer id's to filter the features by",
"type": {
"name": "Array"
},
"optional": true
}
],
"returns": {
"description": null,
"type": {
"name": "FeatureCollection"
}
},
"description": "Returns an array of rendered map features that intersect with the given rectangle,\nrestricted to the given style layers and filtered by the given predicate.",
"examples": [
"\nthis._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n"
]
},
{
"name": "fitBounds",
"docblock": "Map camera transitions to fit provided bounds\n\n@example\nthis.map.fitBounds([lng, lat], [lng, lat])\nthis.map.fitBounds([lng, lat], [lng, lat], 20, 1000)\n\n@param {Array<Number>} northEastCoordinates - North east coordinate of bound\n@param {Array<Number>} southWestCoordinates - South west coordinate of bound\n@param {Number=} padding - Camera padding for bound\n@param {Number=} duration - Duration of camera animation\n@return {void}",
"docblock": "Map camera transitions to fit provided bounds\n\n@example\nthis.map.fitBounds([lng, lat], [lng, lat])\nthis.map.fitBounds([lng, lat], [lng, lat], 20, 1000) // padding for all sides\nthis.map.fitBounds([lng, lat], [lng, lat], [verticalPadding, horizontalPadding], 1000)\nthis.map.fitBounds([lng, lat], [lng, lat], [top, right, bottom, left], 1000)\n\n@param {Array<Number>} northEastCoordinates - North east coordinate of bound\n@param {Array<Number>} southWestCoordinates - South west coordinate of bound\n@param {Number=} padding - Camera padding for bound\n@param {Number=} duration - Duration of camera animation\n@return {void}",
"modifiers": [],
"params": [
{
@@ -822,7 +906,7 @@
},
"description": "Map camera transitions to fit provided bounds",
"examples": [
"\nthis.map.fitBounds([lng, lat], [lng, lat])\nthis.map.fitBounds([lng, lat], [lng, lat], 20, 1000)\n\n"
"\nthis.map.fitBounds([lng, lat], [lng, lat])\nthis.map.fitBounds([lng, lat], [lng, lat], 20, 1000) // padding for all sides\nthis.map.fitBounds([lng, lat], [lng, lat], [verticalPadding, horizontalPadding], 1000)\nthis.map.fitBounds([lng, lat], [lng, lat], [top, right, bottom, left], 1000)\n\n"
]
},
{
+7 -4
View File
@@ -10,10 +10,13 @@
@interface CameraStop : NSObject
@property (nonatomic, assign) NSNumber* pitch;
@property (nonatomic, assign) NSNumber* heading;
@property (nonatomic, assign) NSNumber* zoom;
@property (nonatomic, assign) NSNumber *boundsPadding;
@property (nonatomic, assign) NSNumber *pitch;
@property (nonatomic, assign) NSNumber *heading;
@property (nonatomic, assign) NSNumber *zoom;
@property (nonatomic, assign) NSNumber *boundsPaddingLeft;
@property (nonatomic, assign) NSNumber *boundsPaddingRight;
@property (nonatomic, assign) NSNumber *boundsPaddingTop;
@property (nonatomic, assign) NSNumber *boundsPaddingBottom;
@property (nonatomic, assign) NSNumber *mode;
@property (nonatomic, assign) NSTimeInterval duration;
+14 -2
View File
@@ -52,8 +52,20 @@
if (args[@"bounds"]) {
stop.bounds = [RCTMGLUtils fromFeatureCollection:args[@"bounds"]];
if (args[@"boundsPadding"]) {
stop.boundsPadding = args[@"boundsPadding"];
if (args[@"boundsPaddingLeft"]) {
stop.boundsPaddingLeft = args[@"boundsPaddingLeft"];
}
if (args[@"boundsPaddingRight"]) {
stop.boundsPaddingRight = args[@"boundsPaddingRight"];
}
if (args[@"boundsPaddingTop"]) {
stop.boundsPaddingTop = args[@"boundsPaddingTop"];
}
if (args[@"boundsPaddingBottom"]) {
stop.boundsPaddingBottom = args[@"boundsPaddingBottom"];
}
}
+6 -3
View File
@@ -47,7 +47,10 @@
- (void)_fitBoundsCamera:(RCTMGLMapView*)mapView withCompletionHandler:(void (^)(void))completionHandler
{
MGLCoordinateBounds bounds = _cameraStop.bounds;
CGFloat padding = [_cameraStop.boundsPadding floatValue];
CGFloat paddingTop = [_cameraStop.boundsPaddingTop floatValue];
CGFloat paddingRight = [_cameraStop.boundsPaddingRight floatValue];
CGFloat paddingBottom = [_cameraStop.boundsPaddingBottom floatValue];
CGFloat paddingLeft = [_cameraStop.boundsPaddingLeft floatValue];
CLLocationCoordinate2D coordinates[] = {
{ bounds.ne.latitude, bounds.sw.longitude },
@@ -55,10 +58,10 @@
{ bounds.sw.latitude, bounds.ne.longitude },
bounds.ne
};
[mapView setVisibleCoordinates:coordinates
count:4
edgePadding:UIEdgeInsetsMake(padding, padding, padding, padding)
edgePadding:UIEdgeInsetsMake(paddingTop, paddingLeft, paddingBottom, paddingRight)
direction:mapView.direction
duration:_cameraStop.duration
animationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]
+34 -4
View File
@@ -275,7 +275,7 @@ class MapView extends React.Component {
*
* @param {Array<Number>} northEastCoordinates - North east coordinate of bound
* @param {Array<Number>} southWestCoordinates - South west coordinate of bound
* @param {Number=} padding - Camera padding for bound
* @param {(Number|Array<Number>)=} padding - Camera padding for bound
* @param {Number=} duration - Duration of camera animation
* @return {void}
*/
@@ -283,11 +283,38 @@ class MapView extends React.Component {
if (!this._nativeRef) {
return;
}
let pad = {
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
paddingBottom: 0,
};
if (Array.isArray(padding)) {
if (padding.length === 2) {
pad.paddingTop = padding[0];
pad.paddingBottom = padding[0];
pad.paddingLeft = padding[1];
pad.paddingRight = padding[1];
} else if (padding.length === 4) {
pad.paddingTop = padding[0];
pad.paddingRight = padding[1];
pad.paddingBottom = padding[2];
pad.paddingLeft = padding[3];
}
} else {
pad.paddingLeft = padding;
pad.paddingRight = padding;
pad.paddingTop = padding;
pad.paddingBottom = padding;
}
return this.setCamera({
bounds: {
ne: northEastCoordinates,
sw: southWestCoordinates,
padding: padding,
...pad,
},
duration: duration,
mode: MapboxGL.CameraModes.Flight,
@@ -403,9 +430,12 @@ class MapView extends React.Component {
}
if (config.bounds && config.bounds.ne && config.bounds.sw) {
const { ne, sw, padding } = config.bounds;
const { ne, sw, paddingLeft, paddingRight, paddingTop, paddingBottom } = config.bounds;
stopConfig.bounds = toJSONString(makeLatLngBounds(ne, sw));
stopConfig.boundsPadding = padding;
stopConfig.boundsPaddingTop = paddingTop || 0;
stopConfig.boundsPaddingRight = paddingRight || 0;
stopConfig.boundsPaddingBottom = paddingBottom || 0;
stopConfig.boundsPaddingLeft = paddingLeft || 0;
}
return stopConfig;
+16 -2
View File
@@ -1,7 +1,7 @@
import turfHelpers from '@turf/helpers';
export function makePoint (coordinates) {
return turfHelpers.point(coordinates);
export function makePoint (coordinates, properties) {
return turfHelpers.point(coordinates, properties);
}
export function makeLatLngBounds (northEastCoordinates, southWestCoordinates) {
@@ -10,3 +10,17 @@ export function makeLatLngBounds (northEastCoordinates, southWestCoordinates) {
turfHelpers.point(southWestCoordinates),
]);
}
export function makeFeature(geometry, properties) {
return turfHelpers.feature(geometry, properties);
}
export function makeFeatureCollection (features = []) {
return turfHelpers.featureCollection(features);
}
export function addToFeatureCollection (featureCollection, feature) {
let shallowFeatureCollection = Object.assign({}, featureCollection);
featureCollection.features.push(feature);
return featureCollection;
}