Размер
Таргетинг пользователей: регион, город, улица
Play

Таргетинг пользователей: регион, город, улица

Иногда в своих проектах мне хотелось прикрутить некоторую географическую базу, с помощью которой я бы разделял пользователей ресурса по их месту пребывания. Но постоянная занятость делами насущными никак не давала реализовать идею с базой регионов и мало-мальски удобным интерфейсом для ее визуализации. Волею судьбы и заказчика (или судьбы заказчика или заказчика судьбы) такая задача, наконец-то, возникла — необходимо создать базу регионов, городов и улиц для сегментирования пользователей и реализовать удобную web-форму, собственно, для ее использования. Благо заказчик ориентировал свой бизнес на Россию, что резко упростило задачу.

Поиск по интернету готовых баз субъектов РФ особых результатов не принес — нашел базу КЛАДР, но она оказалась не очень-то актуальной. Порыскав дальше я наткнулся на пост КЛАДР умер, да здравствует ФИАС?. Спасибо sergpenza, теперь есть куда копать!

База ФИАС действительно оказалась максимально полной и актуальной, и даже слишком — в ней очень много ненужного. Еще один минус базы — она «плоская»: основная табличка — ADDROBJ.dbf, в ней содержатся области, районы, города и улицы и все это ссылается само на себя. Еще один минус — в ней нет списка регионов РФ. Но это просто — их можно с легкостью спарсить с сайта ГНИВЦ ФНС РОССИИ.

Не буду вдаваться в процесс перепиливания базы в реляционный вид — это рутина, да и ссылка на уже готовую базу есть внизу моего поста.

Отлично база есть. Нужно создать интерфейс для ее визуализации под web, на этой части я остановлюсь более подробно. Интерфейс включает в себя фронт и бек-энд.

  1. Фронт-энд это html, js, jQuery
  2. Бек-энд MVC от MS (c#)
Фронт-энд

Задача: пользователь должен иметь возможность заполнить данные о своем месте пребывания, для этого он последовательно вводит регион, город и улицу. Учитывая количество городов (более 160к) и количество улиц в каждом городе задача усложняется — использовать выпадающие списки отпадает, нужно предусмотреть какой-то механизм быстрого поиска и фильтрации. Конечно же, механизм должен быть универсальным и охватывать не только регион, но и города с улицами. Такой механизм лучше всего реализовать в виде библиотеки, подключаемой в нужных местах на сайте. Назовем библиотеку jquery.locateme.js. По названию библиотеки понятно, что она зависима от jQuery. Изначально у меня была мысль написать плагин для jQuery в соответствии с идеологией фреймворка, но в итоге я от нее отказался.

  • поиск по все объектам БД (регионы, города, улицы)
  • вывод результатов поиска (как списком так и автозаполнением)
  • управление с клавиатуры (навигация по результатам поиска)
  • обработка всевозможных callback для масштабирования функционала

Использовать контрол на странице надо так

field_wrapper — селектор по классу, оболочка, в которой будет создан контрол field_name — название поля контрола field_label — то, что будет написано над полем с поиском search_URL — URL, который будет запрашиваться для поиска (метод POST) [search_URL_DATA] — опциональные параметры, передаваемые в search_URL (объект) [applyHandler] — функция, будет вызвана после завершения поиска в поле [cancelHandler] — функция, вызывается при изменении поля (если конечно, поиск был завершен)

В примере создается поле с именем «region» в div ".uloc_region". Для поиска будет запрашиваться url "/region" без параметров, а после нахождения нужного региона появится алерт с текстом «регион ID:%regionID%».

Бэк-энд

Задача: реализовать выборку из базы данных полей, удовлетворяющих поисковому запросу пользователя, для любых объектов БД (регион, город или улица) Типичное поведение пользователя желающего найти свой город — начать вводить его название в текстовое поле, в этот момент начинает работать фронт-энд контрол, предлагающий автозаполнение по мере ввода поискового запроса.

Архитектура решения (solution, .sln) состоит из 4 библиотек:

  • BO (BusinesObjects)
  • DC (DataContext)
  • DP (DataProvider)
  • LocateMe (UI, web-интерфейс)

Описывать BO,DC,DP не имеет смысла, так как они типичны (linq, DTO, database context). Ссылка на архив со всем решением (solution) в конце поста. Что касается UI, то его можно рассмотреть, в общих чертах. А именно сигнатуры методов поиска

Все просто: 3 метода на три объекта БД. Каждый принимает строку searchquery, которая является поисковым запросом пользователя. В двух последних методах присутствует еще один параметр RegionId и CityId — они указывают в каком именно регионе (или городе) производить поиск. Результаты поиска ограничены 5 записями. В качестве возвращаемого объекта используется сериализованный в JSON анонимный тип, где v — это название региона\города или улицы, а k — это их индефикаторы.

Проект (полностью) тут (github) База (дамп) там же

В качестве сервера БД — MS SQL 2012 Актуальность базы данных 2014 год, I квартал. Новые регионы Крым и Севастополь, а также территории Байконура присутствуют Бек-энд .Net 4.0, mvc 3

Файл базы (mdf, log) тык (на гитхаб не коммитится, наверно размер велик)

Спасибо WindDrop, Andriyan Исправлено \ добавлено: 1. Повторные нажатия на [ENTER], [TAB] или [RIGHT ARROW] после ручного ввода или автозаполнения 2. Автозаполенение с учетом регистра (case sensitivity) 3. Отображение окошка с результатами поиска при пустом поле 4. Произвольное заполнение поля регион («Республика Башко. » или «Башко. ») будет иметь одинаковый резуьтат (без изменения БД)

Не исправлено: Непонятно поведение библиотеки (нажатия клавиатуры) в FF

📎📎📎📎📎📎📎📎📎📎