React Native Mapbox(v10) 사용법
11439 단어 mapreactnativemobile
용법:
SAMPLE VIDEO
샘플 데이터:
{
"type": "FeatureCollection",
"name": "GeoJsonData",
"features": [
{
"type": "Feature",
"properties": {
"status": "sold",
"Name": "دورات مياة",
"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]
]
]
]
}
},
*
*
*
]}
Mapbox.js
import React, {useRef, useState} from 'react';
import {InteractionManager, TouchableOpacity, View} from 'react-native';
import styles from './style';
import MapboxGL, {Camera} from '@rnmapbox/maps';
import {MAP_NOX_ACCESS_TOKEN} from '../../utils/constants/constants';
import {ICONOGRAPHY, IMAGES} from '../../assets';
import * as turf from '@turf/turf';
import {
COLOR_GREEN_PLOT_OPACITY,
} from '../../utils/colors';
import {isIOS} from '../../utils/helper';
import HeaderComponentPlotMap from './HeaderComponentPlotMap';
import PopupBottom from './popupBottom';
import CustomIcon from '../CustomIcon';
MapboxGL.setAccessToken(MAP_NOX_ACCESS_TOKEN);
const MapBox = props => {
const {navigation} = props || {};
const url = 'https://cdn.wasalt.com/kml3.json';
const style_MB = {
neighborhoods: {
fillColor: COLOR_RED_PLOT_OPACITY,
fillOpacity: 0.5,
},
selectedNeighborhoods: {
fillColor: COLOR_GREEN_PLOT_OPACITY,
fillOpacity: 0.5,
},
neighborhoodsD: {
fillColor: RED_SELECTED_PLOT,
},
selectedNeighborhoodsD: {
fillColor: GREEN_SELECTED_PLOT,
},
line2: {
lineColor: COLOR_WHITE,
lineWidth: 0.5,
},
selectedText: {
textColor: COLOR_WHITE,
textHaloColor: COLOR_BLACK,
textHaloWidth: 1,
textSize: 16,
},
selectedBorder: {
lineColor: COLOR_WHITE,
lineWidth: 3.5,
},
borderText: {
symbolPlacement: 'line-center',
textColor: COLOR_BLACK,
textHaloColor: COLOR_WHITE,
textHaloWidth: 1.5,
textSize: 18,
textLetterSpacing: 0.1,
},
dotStyle: {
iconImage: IMAGES.CIRCLE_FILLED,
iconSize: 0.3,
},
gobck: {
position: 'absolute',
zIndex: 1,
height: 30,
width: 30,
top: 50,
left: 20,
backgroundColor: 'red',
},
deselectText: {
textColor: COLOR_WHITE,
textHaloColor: COLOR_BLACK,
textHaloWidth: 1,
},
};
const [selectedDist, setSelectedDist] = useState();
const [selectedPolySides, setselectedPolySides] = useState();
const [isSateliteStyle, setSateliteStyle] = useState(true);
const [headerHeight, setheaderHeight] = useState(0);
let centerCoordinate = [46.691913306713104, 24.796909229152348];
let zoomLevel = 15;
let _map = useRef(null);
const camera = useRef(null);
/**
* Calculates the haversine distance between point A, and B.
* @param {number[]} latlngA [lat, lng] point A
* @param {number[]} latlngB [lat, lng] point B
* @param {boolean} isMiles If we are using meters, else km.
* @param {boolean} isMiles If we are using miles, else km.
*/
// const haversineDistance = (
// latlngA,
// latlngB,
// isMeters = false,
// isMiles = false,
// ) => {
// const squared = x => x * x;
// const toRad = x => (x * Math.PI) / 180;
// const R = 6371; // Earth’s mean radius in km
// const dLat = toRad(latlngB[0] - latlngA[0]);
// const dLon = toRad(latlngB[1] - latlngA[1]);
// const dLatSin = squared(Math.sin(dLat / 2));
// const dLonSin = squared(Math.sin(dLon / 2));
// const a =
// dLatSin +
// Math.cos(toRad(latlngA[0])) * Math.cos(toRad(latlngB[0])) * dLonSin;
// const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
// let distance = R * c;
// if (isMiles) {
// distance /= 1.609344;
// }
// if (isMeters) {
// distance *= 1000;
// }
// return distance;
// };
const onPressPolygon = items => {
console.log('onPressPolygon', items);
let feature = items?.nativeEvent.payload;
let polygonCoordinates = feature?.geometry?.coordinates[0];
let arrayOfPolygonSides = [];
//Showing polygon border dimension using LineString
for (let i = 0; i < polygonCoordinates.length - 1; i++) {
let line = turf.lineString([
polygonCoordinates[i],
polygonCoordinates[i + 1],
]);
let length = turf.length(line, {units: 'meters'});
let lineStrings = {
type: 'Feature',
properties: {
Length: Number(length).toFixed(1) + 'm',
},
geometry: {
type: 'LineString',
coordinates: [polygonCoordinates[i], polygonCoordinates[i + 1]],
},
};
arrayOfPolygonSides.push(lineStrings);
}
let finalObj = {
type: 'FeatureCollection',
features: arrayOfPolygonSides,
};
setselectedPolySides(finalObj);
setSelectedDist(feature);
//get bound area to move properly to selected polygon
var bboxPolygon = turf.bbox(feature);
let minCoor = [bboxPolygon[0], bboxPolygon[1]];
let maxCoor = [bboxPolygon[2], bboxPolygon[3]];
camera?.current?.fitBounds(minCoor, maxCoor, 20, 2000);
};
const onMapLoad = () => {
InteractionManager.runAfterInteractions(() =>
camera?.current?.setCamera({
centerCoordinate,
zoomLevel,
animationDuration: 5000,
animationMode: 'flyTo',
}),
);
};
const onPressMapView = () => {
setSelectedDist();
setselectedPolySides();
};
const setMapTypeFunc = () => {
setselectedPolySides();
setSelectedDist();
setTimeout(() => {
setSateliteStyle(v => !v);
}, 500);
};
const onCloseBottomCard = () => {
setselectedPolySides();
setSelectedDist();
};
const SelectedPolygon = () =>
selectedDist ? (
<MapboxGL.ShapeSource id="selectedNYC" shape={selectedDist}>
<MapboxGL.FillLayer
sourceID="nyc"
id="nycSelectedFillRed"
style={style_MB.neighborhoodsD}
filter={['!=', 'status', 'sold']}
/>
<MapboxGL.FillLayer
sourceID="nyc"
id="nycSelectedFillGreen"
style={style_MB.selectedNeighborhoodsD}
filter={['==', 'status', 'sold']}
/>
<MapboxGL.SymbolLayer
sourceID="selectedNYC"
id="image1"
style={style_MB.dotStyle}
maxZoomLevel={17}
/>
<MapboxGL.SymbolLayer
sourceID="selectedNYC"
id="Name1"
style={{
...style_MB.selectedText,
textField: '{Name}',
}}
minZoomLevel={17}
/>
</MapboxGL.ShapeSource>
) : null;
const SelectedPolygonBorder = () =>
selectedPolySides ? (
<MapboxGL.ShapeSource id="borderSrc" shape={selectedPolySides}>
<MapboxGL.LineLayer
sourceID="borderSrc"
id="borderLine"
style={style_MB.selectedBorder}
/>
<MapboxGL.SymbolLayer
sourceID="borderSrc"
id="border"
minZoomLevel={3}
style={{
...style_MB.borderText,
textField: '{Length}',
}}
/>
</MapboxGL.ShapeSource>
) : null;
return (
<View style={styles.page}>
<HeaderComponentPlotMap
getHeight={v => setheaderHeight(v)}
navigation={navigation}
/>
<TouchableOpacity
style={styles.mapType(isSateliteStyle, headerHeight)}
onPress={setMapTypeFunc}>
<CustomIcon
color={!isSateliteStyle ? COLOR_GRAY_70 : COLOR_SECONDARY}
name={ICONOGRAPHY.FLOORS}
size={20}
/>
</TouchableOpacity>
<View style={styles.container}>
<MapboxGL.MapView
// zoomEnabled={false}
// scrollEnabled={false}
// pitchEnabled={false}
// rotateEnabled={false}
// onRegionDidChange={onRegionDidChange}
onPress={onPressMapView}
style={styles.map}
styleURL={
isSateliteStyle
? MapboxGL.StyleURL.Satellite
: MapboxGL.StyleURL.Street
}
ref={_map}
localizeLabels={true}
scaleBarEnabled={isIOS() ? true : false}
compassEnabled={true}
scaleBarPosition={{bottom: 0, left: 8}}
compassPosition={{bottom: 20, left: 8}}
logoEnabled={false}
onDidFinishLoadingMap={onMapLoad}>
<Camera ref={camera} />
<MapboxGL.ShapeSource
id="nyc"
url={url}
onPress={items => {
onPressPolygon(items);
}}>
<MapboxGL.FillLayer
id="nycFill"
style={style_MB.neighborhoods}
filter={['!=', 'status', 'sold']}
/>
<MapboxGL.FillLayer
id="nycFilled"
style={style_MB.selectedNeighborhoods}
filter={['==', 'status', 'sold']}
/>
<MapboxGL.LineLayer
sourceID="nyc"
id="nycFillLine"
style={style_MB.line2}
/>
<MapboxGL.SymbolLayer
sourceID="nyc"
id="image"
style={style_MB.dotStyle}
maxZoomLevel={17}
/>
<MapboxGL.SymbolLayer
sourceID="nyc"
id="Name"
style={{
...style_MB.deselectText,
textField: '{Name}',
}}
minZoomLevel={17}
/>
</MapboxGL.ShapeSource>
<SelectedPolygon />
<SelectedPolygonBorder />
</MapboxGL.MapView>
</View>
{selectedDist === null || selectedDist === undefined ? null : (
<PopupBottom
navigation={navigation}
clickedPolygon={selectedDist}
onPressCloseButton={onCloseBottomCard}
/>
)}
</View>
);
};
export default MapBox;
Reference
이 문제에 관하여(React Native Mapbox(v10) 사용법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ajmal_hasan/react-native-mapbox-v10-usage-4gbp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)