根据半径向用户显示附近的位置
Posted
技术标签:
【中文标题】根据半径向用户显示附近的位置【英文标题】:Showing users nearby locations based off radius 【发布时间】:2021-08-06 07:35:00 【问题描述】:我正在构建一个向用户显示最近位置的谷歌地图。我现在有一个 json 文件,但稍后将与数据库一起使用。我需要根据一定的半径向用户显示位置。下面是一个试图实现这一目标的组件。当我 setState 它只捕获数组中的最后一个元素。我不知道为什么。
Geocode.setApiKey("apikey");
Geocode.setLocationType("ROOFTOP");
const distances = [
value: 50,
label: "50",
,
value: 150,
label: "150",
,
value: 250,
label: "250",
,
value: 500,
label: "500",
,
];
//Gathers location and calculates distances then sets state of that distance
function Map()
const classes = useStyles();
// sets state
const [selected, setSelected] = useState();
const [center] = useState( lat: 43.211243, lng: -112.413304 );
const [userLocation, setUserLocation] = useState();
const [input, setInput] = useState("");
const [nearestPlace, setNearestPlace] = useState([]);
const [miles, setMiles] = React.useState(50);
// gets user location
useEffect(() =>
geocode();
, []);
// Grabs users location
const geocode = async () =>
let location = input;
await axios
.get("https://maps.googleapis.com/maps/api/geocode/json",
params:
address: location,
key: "apikey",
,
)
.then((response) =>
const lat, lng = response.data.results[0].geometry.location;
setUserLocation( lat, lng ); // sets user location
)
.catch((error) =>
console.log(error);
);
;
//calculation of lat and lng
function distance(lat1, lng1, lat2, lng2, miles)
// miles optional
if (typeof miles === "undefined")
miles = false;
function deg2rad(deg)
return deg * (Math.PI / 180);
function square(x)
return Math.pow(x, 2);
var r = 6371; // radius of the earth in km
lat1 = deg2rad(lat1);
lat2 = deg2rad(lat2);
var lat_dif = lat2 - lat1;
var lng_dif = deg2rad(lng2 - lng1);
var a =
square(Math.sin(lat_dif / 2)) +
Math.cos(lat1) * Math.cos(lat2) * square(Math.sin(lng_dif / 2));
var d = 2 * r * Math.asin(Math.sqrt(a));
if (miles)
return d * 0.621371;
//return miles
else
return d;
//return km
// this is where I get tripped up. Its not working properly
const handleSubmit = (e) =>
e.preventDefault();
geocode();
let nearest = [];
for (let i = 0; i < locations.length; i++)
nearest.push(
distance(
userLocation.lat,
userLocation.lng,
locations[i].location.lat,
locations[i].location.lng,
"miles"
)
);
const result = nearest.map((item) =>
let closest = [];
if ((miles === "50" && item <= 50) || item <= 100)
closest.push(item);
return closest;
);
result.forEach((el) =>
if (el === "undefined")
return;
else
console.log(el) // this provides the correct values
setNearestPlace(el); // Here is where it wont set my state to the values
console.log(nearestPlace);
return el;
);
;
const onSelect = (item) =>
setSelected(item);
;
const handleChange = (event) =>
setMiles(event.target.value);
;
return (
<>
<LoadScript googleMapsApiKey="apikey">
<GoogleMap
className=classes.map
mapContainerStyle=mapStyles
zoom=7
center=center
>
locations.map((item) =>
return (
<Marker
key=item.name
position=item.location
onClick=() => onSelect(item)
/>
);
)
selected.location && (
<InfoWindow
position=selected.location
clickable=true
onCloseClick=() => setSelected()
>
<div>
selected.image ? (
<img
style= width: "200px"
src=selected.image
/>
) : null
<p>selected.name</p>
<p>selected.address</p>
<p>selected.phone</p>
</div>
</InfoWindow>
)
</GoogleMap>
</LoadScript>
<div className=classes.formControl>
<form
className=classes.form
onSubmit=handleSubmit
autoComplete="on"
>
<div>
<TextField
className=classes.input
onChange=(e) => setInput(e.target.value)
value=input
size="small"
id="outlined-basic"
variant="outlined"
InputProps=
endAdornment: (
<InputAdornment position="end">
<SearchIcon className=classes.searchIcon />
</InputAdornment>
),
/>
</div>
</form>
<div>
<Select
native
value=miles
onChange=handleChange
label="Age"
inputProps=
name: "miles",
id: "outlined-age-native-simple",
>
<option aria-label="None" value="" />
<option value=50>50</option>
<option value=100>100</option>
<option value=150>150</option>
<option value=200>200</option>
<option value=250>250</option>
<option value=500>500</option>
</Select>
</div>
</div>
</>
);
export default Map;
【问题讨论】:
【参考方案1】:在这里
result.forEach((el) =>
if (el === "undefined")
return;
else
console.log(el) // this provides the correct values
setNearestPlace(el); // Here is where it wont set my state to the values
console.log(nearestPlace);
return el;
);
您在循环中调用setNearestPlace()
并将数组元素作为参数传递。结果,传递的最后一个值,即数组的最后一个元素将是您的最终状态。
我相信你正在尝试做这样的事情
setNearestPlace(result.filter(ele => Boolean(ele))); // Boolean(ele) check whether the ele is null or undefined.
【讨论】:
以上是关于根据半径向用户显示附近的位置的主要内容,如果未能解决你的问题,请参考以下文章