Преобразование географии SQL в геометрию SQL или иное улучшение скорости поиска

НЕОБХОДИМОСТЬ: Я ищу оператор SQL для преобразования содержимого поля "География SQL" таблицы в тип поля "Геометрия SQL", новое поле таблицы, которое я собираюсь добавить в существующую таблицу. Или лучшее решение, отсюда и пост.

ПРИЧИНА: Я ищу, чтобы ускорить поиск мест рядом с местом, вставленным пользователем. В настоящее время местоположения хранятся в таблице с типами полей Lat, Long и SQL Geography, на которых основан пространственный индекс. Поскольку вычисления с типом Geometry менее ресурсоемки, чем с типом Geography, я мог бы принять потерю точности в пользу скорости выполнения. Мои текущие расчеты ограничены США, и я не вижу пересечения международной шкалы времени или полюсов (возможно, в будущем?...)

ДОПОЛНИТЕЛЬНЫЕ СООБРАЖЕНИЯ:

  1. В моем случае поиск - это не только расстояние, но и внутри определенного района (района или города).
  2. Я пытался создать вычисляемый столбец, но не могу сделать его постоянным для индексации. Я слышал, что это возможно в 2012 году, но я работаю с 2008 R2.

ОКРУЖАЮЩАЯ СРЕДА: VS 2012, ASP.NET 4.0, Entity Framework 5 (неправильно отображает новые географические поля в C#, но это нормально, так как они все равно используются только на стороне SQL).

ВОПРОСЫ:

  1. Означает ли это, что мой пространственный индекс (основанный на поле Geodata таблицы Location) не будет использоваться, потому что я использую STIntersects, а не STDistance?
  2. Должен ли я каким-то образом переделать из "STIntersects" в "STDistance" (я не знаю расстояние каждый раз, так как оно будет варьироваться в зависимости от размера области, например, район или город)

ХОРОШИЕ СТАТЬИ, Я ПОСМОТРЕЛ НА:

  1. http://msdn.microsoft.com/en-us/library/ff929109.aspx
  2. http://workshops.opengeo.org/postgis-intro/geography.html

ВЫДЕРЖКИ ИЗ SQL QUERY:

...
SELECT @bounds = 'POLYGON(('...'))';
SELECT @location = geography::Parse(@bounds);
...
SELECT p.ID
FROM Property p
INNER JOIN Location l WITH(INDEX(SPATIAL_Location)) ON p.LocationID = l.ID
WHERE 
...
AND (l.Geodata.STIntersects(@location) = 1
AND l.Geodata.STDifference(@location).STIsEmpty() = 1)
...
ORDER BY
...
l.Geodata.STDistance(@location.EnvelopeCenter());

1 ответ

Ответ на вопрос о преобразовании географии в геометрию приведен здесь. Преобразование географии в геометрию SQL Server 2008R2 По сути, преобразование в текст, а затем обратно в геометрию.

Конечно, быстрее вычислить расстояние между двумя точками, чем пересечением (обычно, за исключением случаев, когда пересечение является тривиальным, например, включает в себя только линии или точки), но в своем коде вы позволяете пользователю вводить то, что составляет многоугольник, поэтому находится ли одно из ваших свойств Locations (широта в длину) на расстоянии до многоугольника, на самом деле не имеет смысла, если, возможно, вы сначала не возьмете центр многоугольника.

Он будет использовать пространственный индекс для фильтрации до допустимого диапазона сканирования длинных длин, но большая часть обработки заключается в первом нахождении граничной области предоставленного пользователем многоугольника. Механизм БД должен выполнить эту часть в первую очередь, прежде чем сможет найти подходящие баллы. Расстояние довольно схоже, но требует некоторых быстрых клавиш выполнения, потому что область, чтобы проверить, попадает ли местоположение, фактически является кругом.

Другие вопросы по тегам