我目前正在使用一个按需应用程序(学校项目),并且我一直在尝试找出一种方法,以便使用react-native绘制从勤杂工的当前位置回到客户(用户)位置的路线-maps-directions通过socket.io传递时,但我似乎无法正确处理。 我已经能够发出客户的lng和lat信息,但是单击请求勤杂工按钮时,无法在勤杂工应用程序中绘制到客户位置的折线。 我遇到了一种使用google geocoder api对其进行硬编码的方法。 我想知道是否可以通过使用此反应本机地图方向来实现。 我是Node和socket.io的新手,所以一些解释将非常有帮助。下面是双方的服务器代码(我可能做错了,请纠正我)。
下面是我当前正在使用的代码。
server.js
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);
const port = 3000;
let customerRequestSocket = null;
io.on('connection', socket => {
console.log('a user is connected :D');
socket.on('customerRequest', (region) => {
console.log('Customer needs a handyman');
if (customerRequestSocket != null) {
customerRequestSocket.emit('customerRequest', region);
}
});
socket.on('lookingForCustomer', () => {
console.log('Handyman is online');
customerRequestSocket = socket;
});
});
server.listen(port, () => console.log(`the server running on port : ${port}`));
Customer.js
import React, { Component, Fragment } from 'react';
import { StyleSheet, View, Text, Platform,
TouchableOpacity,
} from 'react-native';
import MapView from 'react-native-maps';
import { Ionicons } from '@expo/vector-icons';
import socketIO from 'socket.io-client';
import Geocoder from 'react-native-geocoding';
import MapViewDirections from 'react-native-maps-directions';
import Search from '../Search';
class Customer extends Component {
static navigationOptions = {
header: null
}
constructor(props) {
super(props);
this.state = {
region: null,
destination: null,
location: null,
};
}
async componentDidMount() {
this.watchId = navigator.geolocation.watchPosition(
async ({ coords: { latitude, longitude } }) => {
const response = await Geocoder.from({ latitude, longitude });
const address = response.results[0].formatted_address;
const location = address.substring(0, address.indexOf(','));
this.setState({
location,
region: {
latitude,
longitude,
title: location,
latitudeDelta: 0.0143,
longitudeDelta: 0.0134
}
});
}, //sucesso
() => {}, //erro
{
timeout: 2000,
enableHighAccuracy: true,
maximumAge: 1000
}
);
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchId);
}
handleLocationSelected = (data, { geometry }) => {
const {
location: { lat: latitude, lng: longitude }
} = geometry;
this.setState({
destination: {
latitude,
longitude,
title: data.structured_formatting.main_text
}
});
};
handleBack = () => {
this.setState({
destination: null,
});
};
requestHandyman = () => {
const socket = socketIO.connect('http://192.168.10.2:3000');
socket.on('connect', () => {
console.log('client connected');
//Handyman requested
socket.emit('senderRequest', this.state.region);
socket.emit('senderRequest', this.state.destination);
});
}
render() {
const { region, destination, } = this.state;
return (
<View style={styles.body}>
<MapView
style={{ flex: 1 }}
initialRegion={region}
showsUserLocation
loadingEnabled
ref={el => (this.mapView = el)}
>
{destination && (
<Fragment>
<MapViewDirections
origin={region}
destination={destination}
apikey='apikey'
strokeWidth={5}
strokeColor={'#333333'}
mode='DRIVING'
optimizeWaypoints
onReady={result => {
this.setState({ duration: Math.floor(result.duration) });
this.setState({ distance: Math.floor(result.distance) });
}}
/>
<MapView.Marker
coordinate={destination}
anchor={{ x: 0, y: 0 }}
image={markerImage}
/>
<MapView.Marker
coordinate={region}
anchor={{ x: 0, y: 0 }}
/>
</Fragment>
) }
</MapView>
{ destination ? (
<Fragment>
<View style={styles.Back}>
<TouchableOpacity onPress={this.handleBack}>
<Ionicons
name='md-arrow-back'
size={25}
color='#333333'
/>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => this.requestHandyman()}
style={styles.bottomButton}
>
<Text style={styles.bottomButtonText}>Find Handyman</Text>
</TouchableOpacity>
</Fragment>
) : (
<Search onLocationSelected={this.handleLocationSelected} />
)}
</View>
);
}
}
const styles = StyleSheet.create({
body: {
flex: 1,
},
Back: {
position: 'absolute',
width: 50,
height: 50,
borderRadius: 50,
backgroundColor: '#FFF',
shadowColor: '#000',
shadowOffset: { x: 0, y: 0 },
shadowOpacity: 0.2,
shadowRadius: 10,
elevation: 2,
bottom: Platform.select({ ios: 270, android: 270 }),
justifyContent: 'center',
alignItems: 'center',
left: 10,
},
bottomButton: {
backgroundColor: 'black',
position: 'absolute',
bottom: 30,
margin: 20,
padding: 15,
paddingLeft: 30,
paddingRight: 30,
alignSelf: 'center',
},
bottomButtonText: {
color: 'white',
fontSize: 18,
},
});
export default Customer;
handyman.js
import React, { Component } from 'react';
import { View, TouchableOpacity, StyleSheet, Text,
ActivityIndicator
} from 'react-native';
import MapView from 'react-native-maps';
import socketIO from 'socket.io-client';
import MapViewDirections from 'react-native-maps-directions';
class Handyman extends Component {
static navigationOptions = {
header: null
}
constructor(props) {
super(props);
this.state = {
region: null,
lookingForCustomer: false,
};
}
async componentDidMount() {
navigator.geolocation.getCurrentPosition(
({ coords: { latitude, longitude } }) => {
this.setState({
region: {
latitude,
longitude,
latitudeDelta: 0.0143,
longitudeDelta: 0.0134,
}
});
}, //success
() => {}, //error
{
timeout: 2000,
enableHighAccuracy: true,
maximumAge: 1000,
}
);
}
async lookForDelivery() {
this.setState({
lookingForCustomer: true
});
const socket = socketIO.connect('http://192.168.10.2:3000');
socket.on('connect', () => {
socket.emit('lookingForCustomer');
});
socket.on('customerRequest', region => {
console.log(region);
return (<MapViewDirections
origin={this.state.region}
destination={region.Object[0].latitude.longitude}
strokeWidth={5}
strokeColor={'#333'}
apikey='apikey'
mode='DRIVING'
optimizeWaypoints
/>);
});
}
render() {
const { region } = this.state;
return (
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
region={region}
showsUserLocation
loadingEnabled
/>
<TouchableOpacity
onPress={() => this.lookForcustomer()}
style={styles.bottomButton}
>
<Text style={styles.bottomButtonText}>Find Delivery</Text>
{this.state.lookingForCustomer === true ? (
<ActivityIndicator
animating={this.state.lookingForCustomer}
size='large'
/>
) : null }
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
bottomButton: {
backgroundColor: 'black',
position: 'absolute',
bottom: 30,
margin: 20,
padding: 15,
paddingLeft: 30,
paddingRight: 30,
alignSelf: 'center',
},
bottomButtonText: {
color: 'white',
fontSize: 18,
},
});
export default Handyman;