Я работаю над сайтом местного бизнес-каталога, который будет использовать настраиваемые типы сообщений для бизнес-записей. Одно из полей будет «Почтовый индекс». Как настроить поиск по местоположению?
Я бы хотел, чтобы посетители могли вводить свой почтовый индекс и выбирать категорию, а также отображать все предприятия в определенном радиусе или все предприятия, упорядоченные по расстоянию. Я видел пару плагинов, которые утверждают, что делают это, но они не поддерживают WordPress 3.0. Какие-либо предложения?
Я начинаю щедрость, потому что это интересный и сложный вопрос. У меня есть несколько собственных идей… но я хочу посмотреть, сможет ли кто-нибудь придумать что-то более элегантное (и более простое в сборке).
Спасибо EAMann. Это может помочь: briancray.com/2009/04/01/…
единственное предложение, которое у меня есть сейчас, это использовать плагин, такой как pods
@NetConstructor.com — я бы не советовал для этого стручки; на самом деле нет никакой выгоды, что Pods предоставляет эту проблему по сравнению с пользовательскими типами сообщений.
@matt : я недавно реализовал что-то очень похожее на это, хотя сайт еще не завершен и не развернут. На самом деле его тоже немного. В какой-то момент я планирую упаковать его как плагин для поиска магазинов, но пока не могу опубликовать его как общее решение. Свяжитесь со мной в автономном режиме, и я мог бы помочь, если вы не получите ответ, который вам нужен.
Можно ли кэшировать результаты? Кроме того, не будет ли проще запросить одну из коммерческих (или бесплатных, если она есть) баз данных почтовых индексов?
@matt — Что вы подразумеваете под запросом одного из коммерческих или бесплатных? Всегда должно быть возможно кэширование, см. codex.wordpress.org/Transients_API.
@hakre: Неважно, я думаю, что сейчас говорю не по себе. Я говорю об использовании баз данных почтовых индексов (USPS, Google Maps…) для получения расстояний, но я не понимал, что они, вероятно, не хранят расстояния, они просто хранят почтовый индекс и координаты, и он будет быть до меня, чтобы вычислить его.
Я бы изменил ответ от gabrielk и связанного сообщения в блоге, используя индексы базы данных и сводя к минимуму количество расчетов фактического расстояния.
Если вы знаете координаты пользователя и знаете максимальное расстояние (скажем, 10 км), вы можете нарисовать ограничивающую рамку размером 20 на 20 км с текущим местоположением посередине. Получите эти ограничивающие координаты и запросите только хранилища между этими широтами и долготами. Пока не используйте тригонометрические функции в запросе к базе данных, так как это предотвратит использование индексов. (Таким образом, вы можете получить магазин, который находится в 12 км от вас, если он находится в северо-восточном углу ограничивающей рамки, но мы выбрасываем его на следующем шаге.)
Рассчитайте расстояние (по прямой или по фактическим направлениям движения, как вам больше нравится) только для тех немногих магазинов, которые были возвращены. Это значительно сократит время обработки, если у вас большое количество магазинов.
Для связанного поиска ( «дайте десять ближайших магазинов» ) вы можете выполнить аналогичный поиск, но с начальным приближением расстояния (таким образом, вы начинаете с области 10 км на 10 км, и если у вас недостаточно магазинов, вы расширяете его до 20км на 20км и так далее). Для этого начального расстояния вы рассчитываете количество магазинов на общей площади и используете его. Или зарегистрируйте количество необходимых запросов и адаптируйте их с течением времени.
Я добавил полный пример кода в соответствующий вопрос Майка, и вот расширение, которое дает вам ближайшие X местоположения (быстро и едва проверено):
Сначала вам нужна таблица, которая выглядит примерно так:
… заполняется для каждого почтового индекса. Вы можете расширить это, добавив поля города и штата, если хотите искать таким образом.
Затем каждому магазину может быть присвоен почтовый индекс, и когда вам нужно рассчитать расстояние, вы можете присоединить таблицу широты/долготы к данным магазина.
Затем вы запросите эту таблицу, чтобы получить широту и долготу для магазина и почтовые индексы пользователя. Как только вы его получите, вы можете заполнить свой массив и передать его функции «получить расстояние»:
Это предназначено для проверки концепции, а не для кода, который я действительно рекомендовал бы реализовать. Например, если у вас есть 10 000 магазинов, было бы довольно дорого запрашивать их все, перебирать и сортировать их при каждом запросе.
Документация MySQL также включает информацию о пространственных расширениях. Как ни странно, стандартная функция Distance() недоступна, но проверьте эту страницу: http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html для получения подробной информации о том, как «преобразовать два значения POINT в LINESTRING, а затем вычислить их длину».
Обратите внимание, что каждый поставщик, вероятно, предложит разные широты и долготы, представляющие «центроид» почтового индекса. Также стоит знать, что не существует реальных «граничных» файлов с почтовым индексом. У каждого поставщика будет свой собственный набор границ, которые примерно соответствуют конкретным спискам адресов, составляющих почтовый индекс USPS. (Например, в некоторых «границах» вам нужно будет включить обе стороны улицы, в других — только одну.) Зоны табулирования почтовых индексов (ZCTA), широко используемые продавцами, «не точно отображают области доставки почтовых индексов, и не включать все почтовые индексы, используемые для доставки почты» http://www.census.gov/geo/www/cob/zt_metadata.html
Многие предприятия в центре города будут иметь свой собственный почтовый индекс. Вам нужен как можно более полный набор данных, поэтому убедитесь, что вы нашли список почтовых индексов, который включает как «точечные» почтовые индексы (обычно предприятия), так и «пограничные» почтовые индексы.
У меня есть опыт работы с данными почтовых индексов с http://www.semaphorecorp.com/. Даже это не было на 100% точным. Например, когда мой кампус получил новый почтовый адрес и новый почтовый индекс, почтовый индекс был неуместен. Тем не менее, это был единственный источник данных, который, как я обнаружил, вообще ИМЕЛ новый почтовый индекс, так вскоре после того, как он был создан.
У меня в книге был рецепт, как именно удовлетворить вашу просьбу… в Drupal. Он опирался на модуль Google Maps Tools ( http://drupal.org/project/gmaps, не путать с http://drupal.org/project/gmap, тоже достойный модуль). Вы можете найти полезный образец код в этих модулях, хотя, конечно, они не будут работать из коробки в WordPress.