首页 > 解决方案 > Manage LAT + LON as variables to get DISTANCE

问题描述

I have working snack with my geolocation, lat + lon. I'm trying to add the getDistance and isPointInCircle functions, they both work until I want to substitute a point with myLAT + myLON.

With good help I've been recomended to declare "const { latitude, longitude } = this.state;" but I'm missing something because I still get errors. I tried putting the functions inside and outside "componentDidMount()" but I'm not able to make it work.

import geolib from "geolib";

export default class App extends Component {

 constructor(props) {
 super(props);
 this.state = {
  latitude: null,
  longitude: null,
  speed: null,
  error: null,
};
  }    

  componentDidMount() {
  this.watchId = navigator.geolocation.watchPosition(
  (position) => {
   const { latitude, longitude } = this.state;        
      this.setState({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude,
      speed: position.coords.speed,
      error: null,
    });

  },
  (error) => this.setState({ error: error.message }),
  { enableHighAccuracy: true, timeout: 20000, maximumAge: 0, distanceFilter: 1},
);
}

  componentWillUnmount() {
  navigator.geolocation.clearWatch(this.watchId);
  }

  render() {
  return (  
     <View style={styles.container}>  
    <View style={{ flexGrow: 0.3, alignItems: 'center', justifyContent: 'center' }}>          
     <Text>GeoLib:: Distance: {DIST} meters</Text> //I'd like to put the DISTANCE here 
     {this.state.error ? <Text>Error: {this.state.error}</Text> : null}           
     </View>                  
);
  }
}

  let RADIUS = geolib.isPointInCircle(                 
       { latitude: latitude, longitude: longitude },
       {latitude: 37.600530, longitude: -122.482629},
        1000
    );

   let DIST = geolib.getDistance(
       { latitude: latitude, longitude: longitude },
       {latitude: 37.600530, longitude: -122.482629}
       );

   if(RADIUS == true){
       console.log("I am in Radius.");
   }else{
       console.log("I am NOT in Radius.");
    }

标签: react-nativeobjectvariables

解决方案


要访问处于状态的值,您需要使用this.state.key. 您正在尝试在没有正确表示法的情况下从状态访问值。您还只是在组件外部添加依赖于组件内部值的值,这是行不通的。

这是我将如何实现您的组件的方式,这只是您的组件可以重构的许多不同方式之一。

// other import statements eg React etc. 
import geolib from 'geolib';

export default class App extends Component {
  constructor (props) {
    super(props);
    this.state = {
      latitude: null,
      longitude: null,
      speed: null,
      distance: null,
      radius: null,
      error: null
    };
  }

  componentDidMount () {
    this.watchId = navigator.geolocation.watchPosition(
      (position) => {
        const { latitude, longitude, speed } = position.coords;
        const center = { latitude: 37.600530, longitude: -122.482629 };
        const { radius, distance } = this.calculateMeasurements(latitude, longitude, center);

        this.setState({
          latitude: latitude,
          longitude: longitude,
          speed: speed,
          radius: radius,
          distance: distance,
          error: null
        });
      },
      (error) => this.setState({ error: error.message }),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 0, distanceFilter: 1 }
    );
  }

  componentWillUnmount () {
    navigator.geolocation.clearWatch(this.watchId);
  }

  /*
   * latitude: user's latitude
   * longitude: user's longitude
   * center: center of the circle eg: { latitude: 37.600530, longitude: -122.482629 }
   * this function is now reusable you don't have to hard code the center coordinates
   */
  calculateMeasurements = (latitude, longitude, center) => {
    const radius = geolib.isPointInCircle(
      { latitude: latitude, longitude: longitude },
      { latitude: center.latitude, longitude: center.longitude },
      1000
    );
    const distance = geolib.getDistance(
      { latitude: latitude, longitude: longitude },
      { latitude: center.latitude, longitude: center.longitude }
    );
    console.log(radius, distance);
    return { radius, distance };
  }

  render () {
    const { radius, distance } = this.state;

    if (radius === true) {
      console.log('I am in Radius.');
    } else if (radius === null) {
      console.log('Radius has not been calculated');
    } else if (radius === false) {
      console.log('I am NOT in Radius.');
    }

    return (
      <View style={styles.container}>
        <View style={{ flexGrow: 0.3, alignItems: 'center', justifyContent: 'center' }}>
          <Text>GeoLib:: Distance: {distance !== null ? distance : 'unknown'} meters</Text>
          {this.state.error ? <Text>Error: {this.state.error}</Text> : null}
        </View>
      </View>
    );
  }
}
  1. 将半径和距离初始值添加到状态
  2. 删除在 componentDidMount 中获取纬度和经度值,它们为空,并且您没有在任何地方使用这些值。
  3. 从 position.coords 解构纬度、经度和速度。这样可以节省您position.coords.key每次要使用其中的值时都必须键入的内容。
  4. 创建一个辅助函数calculateMeasurements,它将计算您想要的radiusdistance值。componentDidMount使用您刚刚找到的坐标调用它。然后将radiusand保存distancecomponentDidMount
  5. 更新render以便它使用状态中的值。
  6. 修复缺少的</View>标签render
  7. 从底部删除let RADIUS = ...和其他计算,因为它们在这个地方无效。

推荐阅读