2014-11-26 3 views
0

Предположим, у меня есть база данных, хранящая 1000000 геолокаций разных пользователей в городе. Было бы больно, если сервер выполнит команду SearchNearbyUsers(myLocation, 50), если я использую список или массив для хранения всех геолокаций и сравнения расстояний один за другим.Реализация функции "Найти близлежащих пользователей" на сервере

Сервер закодирован на C# с веб-интерфейсом API 2. Есть ли библиотека, предназначенная для таких расчетов с геолокациями?

Если библиотеки нет, какую структуру данных следует использовать, чтобы сделать этот расчет проще? Раньше я смотрел на R-tree, но, честно говоря, я не понимаю логику, и это кажется довольно сложным.

Это то, что класс геолокации выглядит следующим образом:

public class GeoLocation 
{ 
    public float latitude { get; set; } 
    public float longitude { get; set; } 
} 

И широта и долготы направляются клиентами. Значения получены через navigator.geolocation.getCurrentPosition().

+0

Если вы используете систему баз данных, такую ​​как MongoDB или MySQL, она может выполнить эту работу за вас, вам просто нужно сначала ее настроить. Для MySQL внимательно прочитайте эту главу: http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html. В противном случае (и я надеюсь, что у вас есть веская причина не делать этого), R-деревья - это путь, вы должны изучить их! – Rerito

ответ

3

Обычно эти пространственные операции выполняются с использованием пространственных индексов. R-Tress - всего лишь один из примеров этого, но вы также можете получить более простые. Просто разделите всю область на более мелкие части (например, прямоугольники) и выполните поиск в тех областях, которые соответствуют общему индексу с заданной координатой. Поэтому я предлагаю включить пространственные индексы на ваш сервер, а затем использовать пространственную библиотеку, такую ​​как GDAL.

Итак, если у вас есть координата (4,5), вы сначала посмотрите на все прямоугольники, пересекающие буфер witdh x вокруг вашей точки. И теперь вы просто выполняете поиск по всем геометриям, расположенным внутри этих прямоугольников.

EDIT: На SQL Server вы также можете использовать его пространственное расширение для извлечения тех близлежащих функций (см. here). В основном создайте буфер вокруг вашей геометрии ввода, используя STBuffer, а затем выполните пересечение в этом буфере. Используя описанный пространственный индекс, эти операции выполняются довольно быстро.

+0

Что делать, если оба пользователя действительно очень близки друг к другу, но лежат в разных пространственных блоках? –

+1

@ AldourCheng, R-деревья разработаны, чтобы избежать такой проблемы ... Механизм запроса гарантирует, что вы найдете каждый объект (сохраненный в дереве) в заданной пространственной области. Они обычно являются ядром пространственных индексов в системах БД :) – Rerito

+1

Вот почему я написал, чтобы посмотреть на прямоугольники, которые пересекают буфер. Таким образом, вы получите до четырех прямоугольников для одной точки (что еще намного меньше, чем поиск всей области). – HimBromBeere

1

Если вы используете хранилище данных, такое как Mongo, геопространственные запросы довольно просты и довольно приятны. Вот Docs

Вы можете попробовать изучить что-то вроде этого. Это то, что я использовал для того, чтобы клиент загружал данные о местоположении в недавнем проекте, и он работает сон.

EDIT Для нахождения местоположения в реальном мире с Lat и Long, чтобы получить правильный результат при запросе с расстоянием, вы должны использовать сферический индекс

This Question помогут Вам с рядом запросов, используя mongo C# driver.

Редактировать 2 Узнав о вас, используя MS SQL, ознакомьтесь с некоторыми полезными ссылками, чтобы перейти к одному Phillip, предоставленному в другом ответе.

Query Spatial Data For Nearest Neighbour
Spatial Data

+0

Используется ли это на сервере MS SQL? –

+0

К сожалению, MongoDB - это отдельная база данных. Вы прочно связаны с MS SQL? Вы даете себе гандикап, работающий с геопространственными запросами с использованием MS SQL. Монго - это даже не единственный вариант. Существует множество баз данных с гораздо лучшей поддержкой геопространственных запросов, чем MS SQL. –

+0

Спасибо за информацию. Похоже, что MS SQL теперь добавляет больше функций для обработки пространственных данных. Я имею в виду ссылку, опубликованную PhillipH. –

2

Если вы новичок и хотите избежать использования деревьев ...

  1. создать карту сеточного поддерживаемома области

    • только простая сетка 2D клеток
    • cell grid
    • каждую ячейка имеет свои координаты i,j или индекс ix=i+j*ni где п есть число клеток на i ось
    • поэтому для каждой точки вы можете просто вычислить право собственности на ячейку
    • составить список точек в каждой ячейке
    • что-то вроде:
    • Vector<int> map[nj][ni];
    • и заполнить список с индексом точки внутри клетки ...
  2. сравнения

    • вычислить местоположение ячейки пользователя
    • и сравнить только точки в этой ячейке и в 8 соседних s ...
    • более плотная сетка ячейка больше скорость у вас есть
    • , если ваша ячейка меньше, то диапазон сравнения затем сравнить также больше соседей
    • , чтобы покрыть весь диапазон безопасно
    • enter image description here
+0

Что делать, если все данные геолокации первоначально хранятся в базе данных, но не в словаре, определенном в коде? –

+0

@AldourCheng вы можете просто написать цикл for, проходящий через все точки, и заполнить карту указателями точек до реализации этого, чтобы добавить/del point подпрограммы ... – Spektre

+0

@ AldourCheng единственным существенным недостатком является то, что удаление точки необходимо обновить все точечные индексы больше, чем удаленные, уменьшая его на единицу ... во всех ячейках. но этого можно избежать, добавив флаг _deleted в список точек ... – Spektre