- PVSM.RU - https://www.pvsm.ru -
Вопрос «Где?» возникает сразу же после вопроса «Что?» эта закономерность верна и в вебразработке. Многие сайты запрашивают информацию у пользователя, предлагая ему ввести свой адрес, т. е. страну, регион, город, улицу, дом почтовый индекс. Но как потом обрабатывать эти данные, если они были указаны в свободной форме? В своих первых проектах мы использовали свой «велосипед», но по мере роста и развития это «чудо» превратилось в «чудовище», которое поставило крест на эффективной обработке гео-информации о наших пользователях. Мне была поставлена задача прибить этого монстра, заменив его стандартизованной гео-базой и простым интерфейсом для работы с ней. Гугление на эту тему не дали готового решения, поэтому пришлось отбросить простой вариант и сделать свой гео-модуль.
Для начала, нужно было найти базу адресов России. В поисках базы адресов я наткнулся на две и вполне возможно, что единственные:
Разница между ними такая: 400 Мб КЛАДР-а против 9 Гб ФИАС-а — существенно, не правда ли? По этому определённо хочется пользоваться ФИАС-ом, т. к. по объёму можно полагать, что данные у него более избыточны, что соответственно и лучше. Но работа с ФИАС у меня не сложилась. Запросы по таблице адресов, были ужасно долгие и ни расстановка индексов, ни оптимизация запросов мне не помогли, пользовался я при этом MySQL 5.5
С КЛАДР-ом же, работа сложилась и как выяснилось позже, его детализации для моих (стандартных) задач, вполне хватает. Обзор по структуре таблиц КЛАДР-а можно почитать здесь [1]/ Для него же кто-то сделал api [2], которое не работает :-), но авось ребята допилят, думаю многим будет полезно.
Для того, что бы можно было использовать КЛАДР в проекте, нужно его из распространяемого dbf формата конвертировать в что-то понятное MySQL. Впрочем можно залить базу напрямую, для этого можно использовать navicat [3] или mydbf2mysql [4]
Таким образом, я сделал простой гео-модуль, который можно докрутить под любые нужды.
Проект можно получить на Github [5]
Проект писался с использованием php 5.3, что важно.
СУБД MySQL 5.5, что не очень важно
.project # Корень проекта -css -js --plugins ---autocomplete ----jquery.autocomplete.js ---jquery.form.js --cabinet.js # скрипт для страницы с формой --initialize.js # скрипт инициализации --jquery-1.7.2.js -Entities --GeoLocation.php # Сущность с данными локации ip адреса --UserLocation.php # Сущность с данными локации пользователя --Kladr.php # Сущность содержит записи с объектами первых четырех уровней классификации --Socrbase.php # Сущность содержит записи с краткими наименованиями типов адресных объектов --Street.php # Сущность содержит записи с объектами пятого уровня классификации --Doma.php # Сущность содержит записи с объектами шестого уровня классификации --KladrRepository.php --HomeRepository.php --StreetRepository.php -Geo --Providers ---Deliveries # Поставщики услуг доставки ----Ems -----EmsDeliveryDecorator.php # Класс декоратор рассчитывающий EMS доставку -----EmsDiliveryProvider.php # Класс реализующий API сервиса EMS для расчёта доставки -----ENUM_EMS.php # перечисления команд ----RussianPost -----RussianPostDeliveryDecorator.php # Класс декоратор рассчитывающий доставку Почты России -----RussianPostDeliveryProvider.php # Класс реализующий API сервиса PostCalc для расчёта доставки ---Geocoder # Поставщики сервисов гео-кодирования ----Yandex -----Geocoder.php ----MapApiBase.php # Абстрактный класс для гео-кодирования ---Delivery.php ---DeliveryBase.php ---DeliveryDecoratorBase.php ---DeliveryDecoratorRound.php ---DeliveryProviderBase.php --common.php --Geo.php --GoecoderCreater.php # Фабрика для объекта гео-кодирования --ILocationBuilder.php --Location.php # класс умеющий делать запросы в сервис geo-ip --LocationBuilder.php # строитель объкта EntitiesUserLocation, по данным полученны от геокодера -_content.php -autobox.php # точка входа для запросов плагина выпадающих списков(оркуг/город) -autocomlete.php # точка входа для -Autoloader.php # мой авто-загрузчик классов -delivery.php # точка входа для запросов на расчёт доставки -index.php # основная точка входа -popup.php # пример реализации через модальное popup окно colorbox -run.php # bootstrap example приложения -String.php # строковые общие статические методы
Процесс устроен так: при загрузки страницы, получаем по ip адресу geo расположения пользователя, для этого сначала смотрим существует ли запись с ключом(ip адресом) в таблице geoLocation, если есть берём от туда, если нет, делаем запрос в сервис ipGeo полученные данные сохраняем в табличке geoLocation, для последующего сокращения трафика запросов в ipgeo сервис. Имеющиеся данные о расположении пользователя используем для предсказания расположения пользователя, т.е. три (регион/округ/город) выпадающих списках, заполняем данными и выделяем в них нужное расположение. Если расположение угадано верно, то пользователю останется указать только улицу и дом, а индекс (если он есть в кладре) подставится автоматически. Впрочем если по ip адресу расположение было не угадано, то регион/округ/город можно изменить. Для этого был написал простенки js плагин, который согласно выбранного региона запрашивает округ и большие города региона, а согласно выбранного округа, города округа.
Есть yandex карта для отображения сохраненного расположения пользователя. Впрочем, можно сделать что бы карта на лету реагировала, на выбор пользователем локации.
В конце страницы с формой задания адреса, для демонстрации имеется блок с расчётом доставки. Сам пакет доставки реализован, как «декоратор», поэтому можно настраивать калькуляцию сумм или время доставки. Собственно как работает калькуляция, должно быть понятно, нужно знать откуда и куда, а далее дело техники. Расчёт доставки можно расширить, путём добавления нового *поставщика*.
Удачно то, что структура указания адресов ФИАС схожа с КЛАДР, прошу заметить не идентична, а схожа поэтому если немного от-рефакторить код репозитория EntitiesKadrRepository, то можно использовать и ФИАС как хранилище адресов, вопрос только нужно ли это.
Подробное описание API модуля публикую в WiKi проекта на github [9]
Надеюсь, что кому-то этот модуль будет полезен, но не претендую на идеальное решение, буду рад услышать замечания и предложения.
Автор: zpayment
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/yandeks-kartyi/13545
Ссылки в тексте:
[1] здесь: http://www.ksoft.ru/opis_kladr.htm#_Toc137607897
[2] api: http://www.magora.ru/info/kladr
[3] navicat: http://www.navicat.com
[4] mydbf2mysql: http://sourceforge.net/projects/mydbf2mysql/
[5] Github: https://github.com/shotonoff/kladr_geo.git
[6] blog.ipgeobase.ru: http://blog.ipgeobase.ru
[7] emspost.ru/: http://emspost.ru/
[8] postcalc.ru: http://postcalc.ru
[9] WiKi проекта на github: https://github.com/shotonoff/kladr_geo/wiki/%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-api-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0
Нажмите здесь для печати.