Как проверить два списка адресов с геокоординатами на предмет пересечения друг с другом в радиусе 1000 метров?
Работаю в развитии крупной сети супермаркетов. Время от времени агенты по недвижимости предоставляют большой пул (список с адресами xls) объектов под аренду . Возникает необходимости проверить поступающие адреса на предмет пересечения с адресами действующей сети, т.к. минимальное расстояние между супермаркетами должно составлять более 1 км.
Я новичок в программировании, но имею большое желание автоматизировать данную задачу. На тему чтения данных из xls с помощью Apache POI в интернете достаточно гайдов - с этим разберусь сам попозже.
Сейчас нуждаюсь в советах относительно следующего:
Нужно каждый адрес действующей сети сравнить с каждым адресом предложенного агентом списка объектов. Затем отсортировать по условия if(distance<1000)- отказ. Итоговым результатом по окончанию работы мы должны получить список адресов агента, которые находятся в удаленности более чем на 1000 метров от действующей сети.
Что я имею сейчас:
public class GPSHelper {
// ПИ
public static final double PI = 3.14159265358979324;
// Экваториальный радиус (м)
private static final double EARTH_RADIUS = 6378137;
/**
* Преобразовано в радианы (рад)
* */
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* Есть формула на основе алгоритма в googleMap для получения расстояния между двумя широтой и долготой,
* @param lon1 Долгота первой точки
* @param lat1 Широта первой точки
* @param lon2 Долгота второй точки
* @param lat2 Широта второй точки
* @return s возвращает расстояние в КМ
* */
/* public static double GetDistance(double lon1,double lat1,double lon2, double lat2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1) - rad(lon2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2)+Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
s = s * EARTH_RADIUS;
//s = Math.round(s * 10000) / 10000;
return s;
} */
//Я её немного изменил, для того чтобы вычислить расстояние между массивом координат действующей
// сети и координатами адреса из предложенных агентом объектов. Результат возвращаем в ArrayList.
public static ArrayList<Double> GetDistanceBetweenArraysGPS (double[] lon1, double[]lat1, double lon2, double lat2) {
ArrayList<Double> arrDistance = new ArrayList<>();
for ( int i = 0; i < lon1.length; i++) {
double radLat1 = rad(lat1[i]);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1[i]) - rad(lon2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2)+Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
s = s * EARTH_RADIUS;
//s = Math.round(s * 10000) / 10000;
arrDistance.add(s);
}
return (arrDistance);
}
}
//Ниже реализация метода в main
public class Task1 {
public static void main(String[] args) {
//Ниже случайные координаты
double[] arrayLongitude1 = {37.652966, 37.729467, 37.733491, 37.645485 };
double[] arrayLatitude1 = {55.587845, 55.585825, 55.911123, 55.583778};
double arrayLongitude2 = 37.640291;
double arrayLatitude2 = 55.586807;
List dist = GetDistanceBetweenArraysGPS(arrayLongitude1, arrayLatitude1, arrayLongitude2, arrayLatitude2);
for (int i = 0; i < dist.size(); i++) {
if ((double) dist.get(i) < 1000){
double a = (double) dist.get(i);
System.out.println(a);
}
//вывод в консоль:
//805.7399867172365
//469.5549013780302
}
}
}
Таким образом, если в конце я получаю хоть 1 результат после условия if((double) dist.get(i) < 1000) , то это значит точка из координат 2 (предложенное агентом) - не подходит, поскольку есть пересечение с массивом координат из списка 1 адресов (действующая сеть), с расстоянием менее 1000 м.
Но это только 1 адрес, а точнее набор координат, я даже не знаю какой именно это адрес, поскольку нет никакого ключа. Я полагаю, что для сравнения двух наборов координат можно сделать вложенный цикл, где снаружи мы будем передавать массив координат 2 (предложенных агентом), а внутри будем передавать координаты 1 (собственной сети) и вычислять расстояние при помощи вышеуказанного метода. Что можно сделать дальше, чтобы на выходе получить список адресов, где условие (distance < 1000) выполняется и где не выполняется ? Как передать результаты в List или Map (адрес, значение)? Помогите решить, пожалуйста. Буду рад любым рекомендациям.
Ответы (1 шт):
цикл по таблице кандидатов
пометить кандидата как подходящего
цикл по таблице магазинов
если разность по X больше 1000 и разность по Y больше 1000
перейти к проверке следующего магазина
если расстояние меньше 1000
пометить кандидата как неподходящего
перейти к следующему кандидату
вывести кандидатов, помеченных как подходящие