在react-native-maps中动态更改圆形组件的半径,并相应地更新latitudeDelta和longitudeDelta的值。

3

我正在尝试使用select动态设置组件中的半径值。当我将初始值设置为“500”并更改为“1000”时,圆的半径会改变,但是当我再次选择“500”时,没有任何变化。

此外,我如何控制地图的缩放值,以便如果选择10km 的半径,则圆形组件适合屏幕?

代码:

import React, { useState } from 'react';
import {View, Text, StyleSheet, SafeAreaView, Image } from 'react-native';
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
import {Picker} from '@react-native-community/picker';

import marker from '../assets/icons8-marker.png';


const LocationSearchScreen = props => {

    const locParam = props.navigation.getParam('locParam');

    const locParamLat = locParam.location.lat;
    const locParamLng = locParam.location.lng;

    const [loc, setLoc] = useState({
        latitudeDelta: 0.025,
        longitudeDelta: 0.025,
        latitude: locParam ? locParamLat : 28.6466773,
        longitude: locParam ? locParamLng : 76.813073
    });

    const [radius, setRadius] = useState(500);

    const regionChangeHandler = (region ) => {
        setLoc(region);
    }

    const radiusChangeHandler = (rad) => {
        setRadius(rad);
    }

    return(
        <View style={styles.screen}>
            <MapView
                initialRegion={loc}
                onRegionChangeComplete={regionChangeHandler}
                style={styles.map}
            >
                <MapView.Circle
                        key = { (loc.latitude + loc.longitude).toString() }
                        center = { {
                            latitude: loc.latitude,
                            longitude: loc.longitude
                        } }
                        radius = { radius }
                        strokeWidth = { 1 }
                        strokeColor = { '#1a66ff' }
                        fillColor = { 'rgba(230,238,255,0.5)' }
                        //onRegionChangeComplete = { regionChangeHandler }
                />
            </MapView>
            <View style={styles.markerFixed}>
                <Image style={styles.marker} source={marker} />
            </View>
            <SafeAreaView style={styles.locFooter}>
                {/*===== Radius Container Start =====*/}

                <View style={styles.radContainer}>
                    <Text style={styles.radTitle}>Radius:</Text>
                    <View  style={styles.radBtnContainer}>
                        <Picker
                            selectedValue={radius}
                            style={{height: 50, width: 100}}
                            onValueChange={(itemValue, itemIndex) =>{
                                let itemValueNum = Number(itemValue);
                                radiusChangeHandler(itemValueNum)
                            }}
                        >
                            <Picker.Item label="500m" value="500" />
                            <Picker.Item label="1Km" value="1000" />
                            <Picker.Item label="2Km" value="2000" />
                            <Picker.Item label="5Km" value="5000" />
                            <Picker.Item label="10Km" value="10000" />
                        </Picker>
                    </View>
                </View>

                {/*==== Radius Container End ====*/}
            </SafeAreaView>
        </View>
    )
}

const styles = StyleSheet.create({
    screen: {
        flex: 1
    },
    map: {
        width: '100%',
        height: '80%'
    },
    markerFixed: {
        left: '50%',
        marginLeft: -24,
        marginTop: -48,
        position: 'absolute',
        top: '40%'
    },
    marker: {
        height: 48,
        width: 48
    },
    locFooter: {
        backgroundColor: 'rgb(255, 255, 255)',
        bottom: 0,
        position: 'absolute',
        width: '100%',
        padding: 15,
    },
    radContainer: {
        flex: 1,
        marginBottom: 10
    },
    radTitle: {
        fontSize: 16,
        fontWeight: 'bold',
        marginBottom: 5
    },
    radBtnContainer: {
        flexDirection: 'row',
        flex: 1,
        justifyContent: 'space-between',
        flexWrap: 'wrap'
    }
})

export default LocationSearchScreen;
1个回答

0

你可以通过使用中心纬度、经度(屏幕中心点)和东北角纬度、经度(屏幕边缘点),简单地找到半径。

编辑后的代码:

import React, { useState, useRef } from 'react';
import { View, Text, StyleSheet, SafeAreaView, Image } from 'react-native';
import Constants from 'expo-constants';
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

export default function App(props) {
    const mapRef = useRef(null)
    const locParamLat = 24.8693697;
    const locParamLng = 67.0822045;

    const [loc, setLoc] = useState({
        latitudeDelta: 0.025,
        longitudeDelta: 0.025,
        latitude: locParamLat,
        longitude: locParamLng
    });

    // const [radius, setRadius] = useState(2500);
    const [radius, setRadius] = useState(2500);

    function getDistanceBetweenTwoPoints(lat1: any, lon1: any, lat2: any, lon2: any) {
        if (lat1 == lon1?.lat && lat2 == lon2) {
            return 0;
        }

        const radlat1 = (Math.PI * lat1) / 180;
        const radlat2 = (Math.PI * lat2) / 180;

        const theta = lon1 - lon2;
        const radtheta = (Math.PI * theta) / 180;

        let dist =
            Math.sin(radlat1) * Math.sin(radlat2) +
            Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);

        if (dist > 1) {
            dist = 1;
        }

        dist = Math.acos(dist);
        dist = (dist * 180) / Math.PI;
        dist = dist * 60 * 1.1515;
        dist = dist * 1.609344; //convert miles to km

        return dist;
    }

    const regionChangeHandler = (region) => {
        setLoc(region);
        radiusGet(region)
    }

    const radiusGet = (region) => {
        mapRef.current.getMapBoundaries()
            .then((ra) => {
                let d = getDistanceBetweenTwoPoints(region.latitude, region.longitude, JSON.stringify(ra.northEast.latitude), JSON.stringify(ra.northEast.longitude)) / 4 * 1609.34 //3000
                setRadius(d);
            })
    }


    return (
        <View style={styles.screen}>
            <MapView
                initialRegion={loc}
                onRegionChangeComplete={regionChangeHandler}
                style={styles.map}
                ref={mapRef}
            >
                <MapView.Circle
                    key={(loc.latitude + loc.longitude).toString()}
                    center={{
                        latitude: loc.latitude,
                        longitude: loc.longitude
                    }}
                    radius={radius}
                    strokeWidth={1}
                    strokeColor={'#1a66ff'}
                    fillColor={'rgba(230,238,255,0.5)'}
                // onRegionChangeComplete = { regionChangeHandler }

                />
            </MapView>

            <SafeAreaView style={styles.locFooter}>
                {/*===== Radius Container Start =====*/}

                <View style={styles.radContainer}>
                    <Text style={styles.radTitle}>Radius: {radius}</Text>

                </View>

                {/*==== Radius Container End ====*/}
            </SafeAreaView>
        </View>
    )
}

const styles = StyleSheet.create({
    screen: {
        flex: 1
    },
    map: {
        width: '100%',
        height: '80%'
    },
    markerFixed: {
        left: '50%',
        marginLeft: -24,
        marginTop: -48,
        position: 'absolute',
        top: '40%'
    },
    marker: {
        height: 48,
        width: 48
    },
    locFooter: {
        backgroundColor: 'rgb(255, 255, 255)',
        bottom: 0,
        position: 'absolute',
        width: '100%',
        padding: 15,
    },
    radContainer: {
        flex: 1,
        marginBottom: 10
    },
    radTitle: {
        fontSize: 16,
        fontWeight: 'bold',
        marginBottom: 5
    },
    radBtnContainer: {
        flexDirection: 'row',
        flex: 1,
        justifyContent: 'space-between',
        flexWrap: 'wrap'
    }
})


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接