MapView, Camera, PointAnnotation, ShapeSource, MarkerView, SymbolLayer, and LineLayer are components in the React Native Mapbox library that allow you to display maps and add markers, annotations, and other features to them.
Here's a brief overview of each component:
MapView: This component is the main component used to display a map. It provides various props for controlling the map's appearance and behavior.
Camera: This component is used to control the map's camera position and zoom level. It can be used to animate the camera to a specific location or zoom level.
PointAnnotation: This component is used to add a marker to the map. You can customize the marker's appearance and add a callout that appears when the user taps on the marker.
ShapeSource: This component is used to add a shape to the map, such as a polygon or line. You can customize the appearance of the shape and add data to it.
MarkerView: This component is used to create a custom marker for the PointAnnotation component. It allows you to use an image or a custom component as the marker.
SymbolLayer: This component is used to add symbols to the map, such as icons or text. You can customize the appearance of the symbols and add data to them.
LineLayer: This component is used to add lines to the map. You can customize the appearance of the lines and add data to them.
In summary, these components provide a way to display maps and add various features to them in a React Native app using the Mapbox library.
The below code explains how to use ShapeSource, MarkerView, SymbolLayer in Mapbox.
INSTALLATION:
USAGE:
Sample Data:(Note: geojson data only)
polygons.js
{
"type": "FeatureCollection",
"name": "GeoJsonData",
"features": [
{
"type": "Feature",
"properties": {
"description": null,
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[46.6973896223821, 24.7938909593501],
[46.69730684623009, 24.79405349682493],
[46.69722194475514, 24.79401653642232],
[46.69730416732871, 24.79385517629931],
[46.6973896223821, 24.7938909593501]
]
]
]
}
},
*
*
*
]}
markers.js
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
36.53387,
28.41464
]
},
"properties": {
"name_ar": "تبوك",
"name_en": "Tabuk",
"avail":"A"
}
},
*
*
*
]
}
Mapbox.js
import MapboxGL, {Camera} from '@rnmapbox/maps';
import {MAP_BOX_ACCESS_TOKEN} from '../../utils/constants/constants';
import * as turf from '@turf/turf';
import PolygonsGEOJSON from './polygons.json';
import MarkersGEOJSON from './markers.json';
MapboxGL.setAccessToken(MAP_BOX_ACCESS_TOKEN);
const MapBoxSRP = ({navigation, route}) => {
let _map = useRef(null);
const camera = useRef(null);
const dispatch = useDispatch();
const [localKmlData, setLocalKmlData] = useState(null);
const [isSateliteStyle, setSateliteStyle] = useState(true);
const [selectedDist, setSelectedDist] = useState();
const defaultCamera = {
centerCoordinate: [46.6254765922189, 24.942461593578678],
zoomLevel: 8,
};
//mapbox components style
const style_MB = {
polygonBG: {
fillColor: COLOR_PURPLE_100_OPACITY,
},
polygonBorder: {
lineColor: COLOR_WHITE,
lineWidth: 1,
},
countStyle: {
circleStrokeColor: COLOR_WHITE,
textField: ['get', 'point_count'],
iconImage: IMAGES.CIRCLE_GRADIENT,
textColor: COLOR_WHITE,
textFont: ['Open Sans SemiBold'],
},
dotMarkerStyle: {
circleRadius: 4,
circleStrokeWidth: 1,
circleStrokeColor: COLOR_WHITE,
},
calloutMarkerStyle: {
iconImage: IMAGES.MAP_POINTER,
textField: '22',
iconTextFit: 'both',
iconTextFitPadding: [5, 5, 5, 5],
textSize: 16,
iconAllowOverlap: true,
textAllowOverlap: true,
textColor: COLOR_BLACK,
textFont: ['Open Sans SemiBold'],
textOffset: [0, -1],
},
deselectText: {
textColor: COLOR_WHITE,
textHaloColor: COLOR_BLACK,
textHaloWidth: 1,
},
selectedPolygonBG: {
fillColor: COLOR_SECONDARY_DISABLE_OPACITY,
},
selectedPolygonBorder: {
lineColor: COLOR_WHITE,
lineWidth: 3,
},
};
//on screen load move view to the collection of all polygons without cropping any polygon
useEffect(() => {
try {
setTimeout(() => {
if (Object.keys(PolygonsGEOJSON).length > 0) {
let bboxPolygon = turf.bbox(PolygonsGEOJSON);
let minCoor = [bboxPolygon[0], bboxPolygon[1]];
let maxCoor = [bboxPolygon[2], bboxPolygon[3]];
console.log('onMapLoad', bboxPolygon);
camera?.current?.fitBounds(minCoor, maxCoor, [50, 20], 100);
setLocalKmlData(PolygonsGEOJSON);
}
}, 1000);
} catch ({message}) {
console.log('onMapLoadERROR', message);
}
}, []);
//focus the view to the selected polygon with bound
const onPressPolygon = e => {
const feature = e?.features[0];
console.log('onPressPolygon', feature);
var bboxPolygon = turf.bbox(feature);
let minCoor = [bboxPolygon[0], bboxPolygon[1]];
let maxCoor = [bboxPolygon[2], bboxPolygon[3]];
camera?.current?.fitBounds(minCoor, maxCoor, 20, 2000);
setSelectedDist(feature);
};
const setMapTypeFunc = () => {
setSateliteStyle(v => !v);
};
const SelectedPolygon = () =>
selectedDist ? (
<MapboxGL.ShapeSource id="selectedNYC" shape={selectedDist}>
<MapboxGL.FillLayer
sourceID="selectedNYC"
id="nycSelectedFillRed"
style={style_MB.selectedPolygonBG}
/>
<MapboxGL.LineLayer
sourceID="selectedNYC"
id="nycFillLine2"
style={style_MB.selectedPolygonBorder}
/>
</MapboxGL.ShapeSource>
) : null;
const SelectedPolygonProperties = () => (
<MapboxGL.ShapeSource
id="nyc1"
shape={Cities}
cluster={true}
// clusterProperties={{
// sum: [
// ['+', ['accumulated'], ['get', 'sum']],
// ['get', 'count'],
// ],
// }}
onPress={items => {
onPressPolygon(items);
}}>
<MapboxGL.CircleLayer
sourceID="nyc1"
id="dot"
style={style_MB.dotMarkerStyle}
// minZoomLevel={14}
/>
<MapboxGL.SymbolLayer
sourceID="nyc1"
id="callout"
style={{
...style_MB.calloutMarkerStyle,
textField: '{name_en}',
}}
minZoomLevel={10}
/>
{/* <MapboxGL.SymbolLayer
filter={['has', 'point_count']}
sourceID="nyc1"
id="countCluster"
style={style_MB.countStyle}
maxZoomLevel={14}
/> */}
</MapboxGL.ShapeSource>
);
//Custom Marker
const RenderAnnotationsProperties = () => {
return selectedPolygonPropeties?.features.map((v, i) => (
<MapboxGL.MarkerView
key={i}
id="pointAnnotation"
// allowOverlap={true}
coordinate={v?.geometry?.coordinates}>
<TouchableOpacity onPress={() => setselectedMarkerId(i)}>
<View
style={{
padding: 10,
backgroundColor: selectedMarkerId === i ? COLOR_RED : COLOR_WHITE,
}}>
<Text style={{textColor: COLOR_BLACK}}>
{v?.properties?.conversionUnit +
' ' +
v?.properties?.conversionPrice}
</Text>
</View>
<View style={styles.dotProp} />
</TouchableOpacity>
</MapboxGL.MarkerView>
));
};
return (
<View style={styles.page}>
<View style={styles.container}>
<MapboxGL.MapView
ref={_map}
onPress={onPressMapView}
// onDidFinishLoadingMap={onMapLoad}
style={styles.map}
styleURL={
!isSateliteStyle
? MapboxGL.StyleURL.Satellite
: MapboxGL.StyleURL.Street
}
localizeLabels={locale: I18nManager.isRTL ? 'ar' : 'en'}
attributionEnabled={false}
compassEnabled={true}
logoEnabled={false}
scaleBarEnabled={isIOS() ? true : false}
>
<Camera
maxBounds={{
ne: [60.54, 41.5],
sw: [32.05, 9.77],
}}
ref={camera}
maxZoomLevel={20}
minZoomLevel={4}
centerCoordinate={[46.67, 24.71]}
/>
{!localKmlData ? null : (
<>
<MapboxGL.ShapeSource
id="nyc"
// url={localKmlData}
shape={localKmlData}
onPress={items => {
onPressPolygon(items);
}}>
<MapboxGL.FillLayer
id="nycFill"
style={style_MB.polygonBG}
filter={['!=', 'avail', 'A']} //show non-sold items, avail will be present in properties attribute of geojson
/>
<MapboxGL.LineLayer
sourceID="nyc"
id="nycFillLine"
style={style_MB.polygonBorder}
/>
</MapboxGL.ShapeSource>
<SelectedPolygon />
<SelectedPolygonProperties />
{selectedPolygonPropeties ? (
<RenderAnnotationsProperties />
) : null}
</>
)}
</MapboxGL.MapView>
</View>
<TouchableOpacity
style={styles.mapType(isSateliteStyle)}
onPress={setMapTypeFunc}>
<CustomIcon
color={!isSateliteStyle ? COLOR_GRAY_70 : COLOR_SECONDARY}
name={ICONOGRAPHY.FLOORS}
size={20}
/>
</TouchableOpacity>
</View>
);
};
export default MapBoxSRP;
Top comments (2)
Hello, do you have the entire sample?
From above code u can understand the usage. U just have to use geojson data.