Существует большая зависимость, называемая geolib
, которая позволяет выполнять вычисления, такие как расстояния между координатами.
Вы можете установить его npm i geolib
. Используя предоставляемую им функцию .getDistance
, вы можете отфильтровать маркеры в зависимости от того, как далеко они находятся от вашей «центральной» точки.
const geolib = require('geolib');
...
getLocations() {
let { region } = this.state;
let { latitude, longitude } = region;
fetch('http://media-panda.de/cologne.geojson')
.then(response => response.json())
.then(responseData => {
let markers = responseData.features.map(feature => {
let coords = feature.geometry.coordinates
return {
coordinate: {
latitude: coords[1],
longitude: coords[0],
}
}
}).filter(marker => {
let distance = this.calculateDistance(latitude, longitude, marker.coordinate.latitude, marker.coordinate.longitude);
return distance <= 500;
});
this.setState({
markers: markers,
loaded: true,
});
}).done(); // should probably have a catch on here otherwise you've got no way to handle your errors
}
// this function uses geolib to calculate the distance between the points
calculateDistance(origLat, origLon, markerLat, markerLon) {
return geolib.getDistance(
{latitude: origLat, longitude: origLon},
{latitude: markerLat, longitude: markerLon}
);
}
По сути, я делаю сопоставление маркеров, возвращаемых вашим запросом fetch
, и превращаю их каждый в следующий объект
{ coordinate: { latitude: number, longitude: number } }
Затем я фильтрую их, используя [ 117], чтобы удалить все, которые находятся на расстоянии более 500 м от центральной точки.
Хотя следует отметить, что в текущей настройке кода вы можете получить GeoJson, прежде чем получите координаты местоположения пользователя. Вы можете рассмотреть возможность рефакторинга ваших функций getLocations
и getPosition
, чтобы getLocations
запускался только после того, как функция getPosition
вернула регион. В противном случае вы не сможете фильтровать, потому что значение состояния для region
не будет существовать.
Возможно, вы захотите позвонить getLocations
после того, как вы получили регион из getPosition
, возможно, что-то вроде этого, используя свойство обратного вызова из setState
. Таким образом, регион будет в состоянии, и вы сможете фильтровать без проблем.
getPosition(){
navigator.geolocation.getCurrentPosition(
(position) => {
console.log(position);
this.setState({
region: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.020,
longitudeDelta: 0.020,
}
}, () => this.getLocations());
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 },
);
}
Это ни в коем случае не единственный способ сделать это. Это действительно зависит от вашего варианта использования, но должно дать вам достаточно представления о том, что делать.
Да, есть + [NSThread sleepForTimeInterval:]
(Точно так же, как вы знаете для будущих вопросов, Objective-C - это сам язык; библиотека объектов (один из них по крайней мере) является какао.)
Почему ты спишь? Когда вы спите, вы блокируете пользовательский интерфейс, а также любую фоновую загрузку URL не в других потоках (асинхронные методы NSURL по-прежнему работают в текущем потоке).
Скорее всего, то, что вы действительно хотите - это executeSelector: withObject: AfterDelay. Это метод в NSObject, который вы можете использовать для вызова метода через некоторый заранее заданный интервал позже - он планирует вызов, который будет выполнен позднее, но все остальные вещи, которые обрабатывает поток (например, пользовательский интерфейс и загрузка данных), будут все еще продолжается.
Конечно, вы также можете использовать стандартные вызовы Unix sleep () и usleep (). (Если бы я писал Cocoa, я бы остановился на [NSThread sleepForTimeInterval:], однако.)