2017-09-22 14:43:40 -07:00
|
|
|
|
import React from 'react';
|
|
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
|
import { NativeModules, requireNativeComponent } from 'react-native';
|
|
|
|
|
|
import { toJSONString, cloneReactChildrenWithProps } from '../utils';
|
2017-10-18 10:59:19 -07:00
|
|
|
|
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
2017-09-22 14:43:40 -07:00
|
|
|
|
|
|
|
|
|
|
const MapboxGL = NativeModules.MGLModule;
|
|
|
|
|
|
|
|
|
|
|
|
export const NATIVE_MODULE_NAME = 'RCTMGLShapeSource';
|
|
|
|
|
|
|
2017-10-19 16:18:54 -07:00
|
|
|
|
const RCTMGLShapeSource = requireNativeComponent(NATIVE_MODULE_NAME, ShapeSource, {
|
|
|
|
|
|
nativeOnly: { nativeImages: true },
|
|
|
|
|
|
});
|
2017-09-22 14:43:40 -07:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* ShapeSource is a map content source that supplies vector shapes to be shown on the map.
|
|
|
|
|
|
* The shape may be a url or a GeoJSON object
|
|
|
|
|
|
*/
|
|
|
|
|
|
class ShapeSource extends React.Component {
|
2017-10-19 16:18:54 -07:00
|
|
|
|
static NATIVE_ASSETS_KEY = 'assets';
|
|
|
|
|
|
|
2017-09-22 14:43:40 -07:00
|
|
|
|
static propTypes = {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* A string that uniquely identifies the source.
|
|
|
|
|
|
*/
|
|
|
|
|
|
id: PropTypes.string,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* An HTTP(S) URL, absolute file URL, or local file URL relative to the current application’s resource bundle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
url: PropTypes.string,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The contents of the source. A shape can represent a GeoJSON geometry, a feature, or a feature colllection.
|
|
|
|
|
|
*/
|
|
|
|
|
|
shape: PropTypes.object,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Enables clustering on the source for point shapes.
|
|
|
|
|
|
*/
|
|
|
|
|
|
cluster: PropTypes.bool,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Specifies the radius of each cluster if clustering is enabled.
|
|
|
|
|
|
* A value of 512 produces a radius equal to the width of a tile.
|
|
|
|
|
|
* The default value is 50.
|
|
|
|
|
|
*/
|
|
|
|
|
|
clusterRadius: PropTypes.number,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Specifies the maximum zoom level at which to cluster points if clustering is enabled.
|
|
|
|
|
|
* Defaults to one zoom level less than the value of maxZoomLevel so that, at the maximum zoom level,
|
|
|
|
|
|
* the shapes are not clustered.
|
|
|
|
|
|
*/
|
|
|
|
|
|
clusterMaxZoomLevel: PropTypes.number,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Specifies the maximum zoom level at which to create vector tiles.
|
|
|
|
|
|
* A greater value produces greater detail at high zoom levels.
|
|
|
|
|
|
* The default value is 18.
|
|
|
|
|
|
*/
|
|
|
|
|
|
maxZoomLevel: PropTypes.number,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Specifies the size of the tile buffer on each side.
|
|
|
|
|
|
* A value of 0 produces no buffer. A value of 512 produces a buffer as wide as the tile itself.
|
|
|
|
|
|
* Larger values produce fewer rendering artifacts near tile edges and slower performance.
|
|
|
|
|
|
* The default value is 128.
|
|
|
|
|
|
*/
|
|
|
|
|
|
buffer: PropTypes.number,
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Specifies the Douglas-Peucker simplification tolerance.
|
|
|
|
|
|
* A greater value produces simpler geometries and improves performance.
|
|
|
|
|
|
* The default value is 0.375.
|
|
|
|
|
|
*/
|
|
|
|
|
|
tolerance: PropTypes.number,
|
2017-10-18 10:59:19 -07:00
|
|
|
|
|
|
|
|
|
|
/**
|
2017-10-19 16:18:54 -07:00
|
|
|
|
* Specifies the external images in key-value pairs required for the shape source.
|
|
|
|
|
|
* If you have an asset under Image.xcassets on iOS and the drawables directory on android
|
|
|
|
|
|
* you can specify an array of string names with assets as the key `{ assets: ['pin'] }`.
|
|
|
|
|
|
*/
|
2017-10-18 10:59:19 -07:00
|
|
|
|
images: PropTypes.object,
|
2017-09-22 14:43:40 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
|
|
id: MapboxGL.StyleSource.DefaultSourceID,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-09-22 16:16:06 -07:00
|
|
|
|
_getShape () {
|
2017-09-22 14:43:40 -07:00
|
|
|
|
if (!this.props.shape) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
// TODO: Add turf validation and throw exeception
|
|
|
|
|
|
return toJSONString(this.props.shape);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-18 10:59:19 -07:00
|
|
|
|
_getImages () {
|
|
|
|
|
|
if (!this.props.images) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let images = {};
|
2017-10-19 16:18:54 -07:00
|
|
|
|
let nativeImages = [];
|
2017-10-18 10:59:19 -07:00
|
|
|
|
|
|
|
|
|
|
const imageNames = Object.keys(this.props.images);
|
|
|
|
|
|
for (let imageName of imageNames) {
|
2017-10-19 16:18:54 -07:00
|
|
|
|
if (imageName === ShapeSource.NATIVE_ASSETS_KEY && Array.isArray(this.props.images[ShapeSource.NATIVE_ASSETS_KEY])) {
|
|
|
|
|
|
nativeImages = this.props.images[ShapeSource.NATIVE_ASSETS_KEY];
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2017-10-18 10:59:19 -07:00
|
|
|
|
|
2017-10-19 16:18:54 -07:00
|
|
|
|
const res = resolveAssetSource(this.props.images[imageName]);
|
2017-10-18 10:59:19 -07:00
|
|
|
|
if (res && res.uri) {
|
|
|
|
|
|
images[imageName] = res.uri;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-19 16:18:54 -07:00
|
|
|
|
return {
|
|
|
|
|
|
images: images,
|
|
|
|
|
|
nativeImages: nativeImages,
|
|
|
|
|
|
};
|
2017-10-18 10:59:19 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-22 14:43:40 -07:00
|
|
|
|
render () {
|
|
|
|
|
|
const props = {
|
|
|
|
|
|
id: this.props.id,
|
|
|
|
|
|
url: this.props.url,
|
|
|
|
|
|
shape: this._getShape(),
|
|
|
|
|
|
cluster: this.props.cluster ? 1 : 0,
|
|
|
|
|
|
clusterRadius: this.props.clusterRadius,
|
|
|
|
|
|
clusterMaxZoomLevel: this.props.clusterMaxZoomLevel,
|
|
|
|
|
|
maxZoomLevel: this.props.maxZoomLevel,
|
|
|
|
|
|
buffer: this.props.buffer,
|
|
|
|
|
|
tolerance: this.props.tolerance,
|
2017-10-19 16:18:54 -07:00
|
|
|
|
...this._getImages(),
|
2017-09-22 14:43:40 -07:00
|
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
|
|
|
<RCTMGLShapeSource {...props}>
|
|
|
|
|
|
{cloneReactChildrenWithProps(this.props.children, { sourceID: this.props.id })}
|
|
|
|
|
|
</RCTMGLShapeSource>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default ShapeSource;
|