在react-native中我们如何显示多个点之间的路线图? 我想在react-native应用程序中显示3或4点之间的路线图。
我参考了谷歌地图API并使用 https://maps.googleapis.com/maps/api/directions/json? 但我只能显示两点之间的路线图。如何在react-native地图中连接三四个点来显示路线图?
使用react-native-maps-directions来显示多个点之间的方向。它仅显示最多 4 到 5 个点之间的方向。如果您想显示超过 5 品脱,也许您应该购买 api 密钥。
使用 DirectionsRenderer 的 waypoints 属性
在react-Native中,我集成了起点和目的地之间的多条路线来展示Android/IOS UI,以实现以下功能:-
基于客户端选定的路由并在内部使用
这里我附上了应用程序屏幕截图以便更好地理解:-
https://drive.google.com/drive/folders/16pxwHbX_FoIbiHP-0dYmJdTUeGJczWj6?usp=sharing
这是解决方案:-
`
useEffect(() => {
if (pathCordinates.length >= 2) {
getmultipleRoutes(pathCordinates[0], pathCordinates[pathCordinates.length - 1]);
}
}, [pathCordinates]);
const getmultipleRoutes = useCallback(async (origin: any, destination: any) => {
showLoader();
try {
const apikeyDemo = "YOUR API KEY";
const url = `${directionsService}?origin=${origin.latitude},${origin.longitude}&destination=${destination.latitude},${destination.longitude}&key=${apikeyDemo}&mode=driving&alternatives=true`
const response = await fetch(url);
const responseDataJson = await response.json();
setNoOfRoutes(responseDataJson.routes.length);
if (responseDataJson.status === 'OK') {
console.log('Routes fetched successfully');
const routes = responseDataJson.routes.slice(0, 3);
const newRoutes = routes.map((route: any, index: any) => {
var distanceInValue = route.legs[0].distance?.text.toString();
var distanceInKm = convertDistance(distanceInValue)
var durationInValue = route.legs[0].duration?.value.toString();
const durationInNum = convertDuration(durationInValue)
return {
id: index.toString(),
coordinates: route.legs[0].steps.map((step: any) => ({
latitude: step.end_location.lat,
longitude: step.end_location.lng,
})),
origin: route.legs[0].start_location,
destination: route.legs[0].end_location,
distance: distanceInValue,
duration: durationInNum,
totalFuelCost: totalFuelCalculation(distanceInKm, milage, fuelRatePerLiter)
}
})
setRoutesState(newRoutes);
const updateDataCostOption = DataCostOption.map((option: any) => {
const route = newRoutes.find((r: any) => r.id == option.id);
if (route) {
return {
...option,
distance: route.distance,
duration: route.duration,
totalFuelCost: route.totalFuelCost
}
};
return option;
});
setDataCostOptions(updateDataCostOption);
}
else {
console.log('ERROR fetching ROUTES :', responseDataJson.status);
}
}
catch (err) {
console.log('ERROR in CATCH ', err)
}
finally {
hideLoader();
setDragCostOption(true);
}
}, [pathCordinates])
const calculateRegion = (coordinates) => {
if (coordinates.length === 0) return {
latitude: 20.5937,
longitude: 78.9629,
latitudeDelta: 10,
longitudeDelta: 10,
};
let minLat = coordinates[0].latitude;
let maxLat = coordinates[0].latitude;
let minLon = coordinates[0].longitude;
let maxLon = coordinates[0].longitude;
coordinates.forEach(coord => {
minLat = Math.min(minLat, coord.latitude);
maxLat = Math.max(maxLat, coord.latitude);
minLon = Math.min(minLon, coord.longitude);
maxLon = Math.max(maxLon, coord.longitude);
});
const padding = 2;
const latitudeDelta = (maxLat - minLat) + padding;
const longitudeDelta = (maxLon - minLon) + padding;
const centerLat = (minLat + maxLat) / 2;
const centerLon = (minLon + maxLon) / 2;
return {
latitude: centerLat,
longitude: centerLon,
latitudeDelta: latitudeDelta,
longitudeDelta: longitudeDelta,
};
};
const region = calculateRegion(pathCordinates);
const renderCostOption = useCallback((item: CostOptionProp[]) => {
return (
<View style={styles.costOptionTypeView} >
<View style={{ ...styles.costOptionTypeContainer, justifyContent: noOfRoutes == '3' ? 'space-between' : 'flex-start', gap: noOfRoutes == '3' ? 0 : 7 }}>
{item.map((option) => {
return (
(option.id.toString() < noOfRoutes?.toString() &&
<TouchableOpacity
onPress={() => {
setHandleSelectOption(option.id),
setOnSelectColor(option.selectBorderColor)
}}
style={[
styles.costOptionTypeStyle,
{
borderBottomColor: handleSelectOption === option.id ? '#FFFFFF' : option.selectBorderColor,
borderBottomWidth: 1,
borderTopColor: handleSelectOption === option.id ? option.selectBorderColor : unSelectedBorderColor,
borderRightColor: handleSelectOption === option.id ? option.selectBorderColor : unSelectedBorderColor,
borderLeftColor: handleSelectOption === option.id ? option.selectBorderColor : unSelectedBorderColor,
},
]}
>
<Text
style={{
...styles.optionTopText,
backgroundColor: handleSelectOption === option.id ? option.selectBorderColor : unSelectedBorderColor,
color: handleSelectOption === option.id ? option.selectTextColor : '#5E5E5E',
}}
>
{option.name}
</Text>
<View style={{ flex: 1, alignSelf: 'center', paddingHorizontal: 10, paddingVertical: 6, width: 99 }}>
<Text style={[styles.amountText, { gap: 1 }]} adjustsFontSizeToFit numberOfLines={1}>
<Text style={styles.amountTextSymbol}>
₹
</Text>
{/* {tripVehicleRs} */}
{option.totalFuelCost}
</Text>
<Text adjustsFontSizeToFit numberOfLines={1} style={styles.kmText}>
{option.distance}
{/* {tripDistanceKm} */}
</Text>
<Text adjustsFontSizeToFit numberOfLines={1} style={[styles.timeText, { color: '#27AE60' }]}>
{option.duration}
{/* {tripDistanceHr} */}
</Text>
</View>
</TouchableOpacity>
))
}
)
}
</View>
<View style={[styles.costTypeStyle]}>
<View style={{ flexDirection: 'row', position: 'absolute', top: -6, width: '100%', justifyContent: 'space-between' }} >
<View style={{ height: 10, width: 99, backgroundColor: onSelectColor == '#27AE60' ? '#FFFFFF' : 'transparent' }} />
<View style={{ height: 10, width: 99, backgroundColor: onSelectColor == '#0033CC' ? '#FFFFFF' : 'transparent' }} />
<View style={{ height: 10, width: 99, backgroundColor: onSelectColor == '#FFB546' ? '#FFFFFF' : 'transparent' }} />
</View>
<View style={styles.costRow}>enter image description here
<Text style={styles.costText}>Toll Cost</Text>
<TouchableOpacity onPress={() => setTollCostRendering(!tollCostRendering)} style={styles.costTouchable}>
<Text style={styles.costAmount}>₹ 6,220</Text>
<FontAwesome size={12} name={tollCostRendering ? "chevron-up" : "chevron-right"} color={'#505050'} />
</TouchableOpacity>
</View>
{tollCostRendering &&
<View style={{
marginHorizontal: 15,
paddingVertical: 10,
marginBottom: 4,
borderColor: '#F2F2F2', borderWidth: 1, borderRadius: 5, backgroundColor: '#F9FAF9',
}}>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
<View style={styles.tollCostView}>
<Text style={styles.tollCostText}>Devanhali Toll Plaza</Text>
<Text style={styles.tollCostText}>₹ 420</Text>
</View>
</View>
}
<View style={styles.costRow}>
<Text style={styles.costText}>Diesel Cost</Text>
<TouchableOpacity style={styles.costTouchable} >
<Text style={styles.costAmount}>₹ 8,526</Text>
<FontAwesome size={12} name="chevron-right" color={'#505050'} />
</TouchableOpacity>
</View>
<View style={styles.totalCostRow}>
<Text style={styles.totalCostText}>Total Cost</Text>
<Text style={styles.totalCostAmount}>₹ 14,854</Text>
</View>
</View >
</View >
)
}, [handleSelectOption, onSelectColor, tollCostRendering, noOfRoutes])
//HERE IS THE JSX PART
<MapView
style={{ flex: 1, height: 340, width: '100%', borderWidth: 1, marginTop: 20, }}
scrollDuringRotateOrZoomEnabled
provider={PROVIDER_GOOGLE}
initialRegion={region}
region={region}
showsCompass
>
{pathCordinates.map((coordinate, index) => (
<Marker
key={index}
coordinate={coordinate}
image={coordinate.type === 1 ? imageSource.location : imageSource.dropLocation}
title={coordinate.title}
focusable
/>
))}
{routesState.map((route) => {
return (
handleSelectOption === route.id && route.coordinates ? (
<MapViewDirections
key={route?.id}
origin={{ latitude: route.origin?.lat, longitude: route.origin.lng }}
destination={{ latitude: route.destination.lat, longitude: route.destination.lng }}
apikey="AIzaSyAkWxbuO-maU16USeyELd3UP0hPLITP3Ec"
strokeColor="blue"
strokeWidth={1.4}
mode='DRIVING'
waypoints={route.coordinates}
splitWaypoints
/>) : null
)
})}
</MapView>
<View style={styles.costOptionView}>
<AppTouchableRipple onPress={() => setDragCostOption(!dragCostOption)} style={{ flex: 1, borderRadius: 4, marginVertical: 4, marginHorizontal: 4, paddingVertical: 6, paddingHorizontal: 4, alignSelf: 'center', justifyContent: 'center' }}>
<View style={{ height: 6, width: 40, backgroundColor: '#C4C4C4', borderRadius: 4, }} />
</AppTouchableRipple>
{dragCostOption && renderCostOption(dataCostOptions)}
</View>
`