А начинается все с того что скачанные dbf фораты некуда приткнуть, ибо LAMP. И начинается поиск dbf2mysql. Надо сказать я так и не нашёл нормального, либо платный, либо глючит. Поэтому все решил промежуточный формат - csv. Качаем DBF2CSV 5.0 и читаем DBF2CSV.TXT. Если вкратце - нужно в cmd вбить
path/perl4w32.exe path/dbf2csv.pl somefile.dbf
На выходе вас будет ждать somefile.csv который можно легко выгрузить через phpMyAdmin, поменяв в импортере разделитель ячеек с ";" на ",".
Однако конечно перед тем как выгружать данные таблиц, нужно их создать. Мои выглядят так:
CREATE TABLE `doma` (
`name` varchar(65) NOT NULL,
`korp` varchar(2) NOT NULL,
`cut` char(6) NOT NULL,
`code` char(19) NOT NULL,
`index` mediumint(6) unsigned NOT NULL,
`gninmb` smallint(4) unsigned NOT NULL,
`uno` varchar(4) NOT NULL,
`ocatd` char(11) NOT NULL,
KEY `name` (`name`),
KEY `index` (`index`),
KEY `code` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `kladr` (
`name` varchar(78) NOT NULL,
`cut` varchar(20) NOT NULL,
`code` char(13) NOT NULL,
`index` char(6) NOT NULL,
`gninmb` char(4) NOT NULL,
`uno` varchar(4) NOT NULL,
`ocatd` char(11) NOT NULL,
`status` char(1) NOT NULL,
KEY `name` (`name`),
KEY `code` (`code`),
KEY `index` (`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `socrbase` (
`level` char(1) NOT NULL,
`cut` varchar(20) NOT NULL,
`full` varchar(56) NOT NULL,
`kod_t_st` smallint(3) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `street` (
`name` varchar(78) NOT NULL,
`cut` varchar(20) NOT NULL,
`code` char(17) NOT NULL,
`index` char(6) NOT NULL,
`gninmb` char(4) NOT NULL,
`uno` varchar(4) NOT NULL,
`ocatd` char(11) NOT NULL,
KEY `name` (`name`),
KEY `code` (`code`),
KEY `cut` (`cut`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
КЛАДР в публичном виде содержит пустую таблицу flat, поэтому я её даже создавать не стал. Ещё есть altnames, но она мне пригодилась пока что, тоже не выгружал.
Теперь когда есть таблицы - выгружаем данные и приступаем к сприпту!
Выбор адреса начинается с выбора объектов первого уровня, у которых код имеет только 2 значащие цифры, а остальное - нули. Соответственно запрос:
SELECT T1.name, T1.code, T1.cut
FROM kladr as T1
WHERE (T1.code LIKE "__00000000000")
ORDER BY T1.name ASC
Полученные объекты группирую по сокращению и вывожу пользователю список сокращений. На первом уровне от всегда такой:
- Автономный округ
- Автономная область
- Республика
- Чувашия
- Город
- Край
- Область
Когда пользователь выбрал сокращения ему показываются объекты этого типа. Когда пользователь перешёл к следующему объекту мы переходим к следущему уровню.
Что мы имеем на текущий момент? Код объекта первого уровня вида у котого 2 первые цифры значащие, а остальные нули (xx000000000000000). Что делать дальше? Искать потомков!
Первое что приходит в ум это искать все code LIKE xx%, однако это не сработает. Объясняю почему - ответ таблицы будет таков - вот вам все улицы, поселки, города и т.п. Он вернет вообще все. Проблема в том что нужно найти таких потомков у которых ближайший родитель является текущим кодом (xx). Для этого генерится подобный запрос:
SELECT T1.name, T1.code, T1.cut
FROM kladr as T1
WHERE (T1.code != "7100000000000") AND (T1.code LIKE "71___00000000" OR T1.code LIKE "71000___00000" OR T1.code LIKE "71000000___00")
ORDER BY T1.name ASC
Условие T1.code != "7100000000000" - для того чтобы не выбрать себя же. Остальное - о том что я говорил. Рассмотрим подробнее что это значит.
Код в таблице kladr (СС РРР ГГГ ППП АА) состоит из таких частей:
СС - код субъекта Российской Федерации (региона), коды регионов представлены в Приложении 2 к Описанию классификатора адресов Российской Федерации (КЛАДР);
РРР - код района;
ГГГ - код города;
ППП - код населенного пункта,
АА - признак актуальности наименования адресного объекта
В сформированных условиях актуальность всегда ставится 00, но это не суть. А суть в том что выбираются лишь те объекты у которых установлен код района ИЛИ код города ИЛИ код населенного пункта. Если у объекта установлен скажем и код населенного пункта и код города - это значит что для текущей выборке он не нужен, т.к. будет нужен для выборки когда человек обозначит город.
Вот и вся логика, хотя чтобы дойти до неё понадобилось достаточно много времени, ведь КЛАДР с самого начала пугает, хотя бы названиями своих таблиц :)
PS. К сожалению код проекта очень завязан на куче классов, поэтому чтобы выдернуть только нужно придется пол дня возиться. Но если кому то действительно очень нужно будет - постараюсь выдернуть и выложить.
update 22.01.2012:
С большой задержкой, но все таки выкладываю исходник. Да, немного там запутано все. Саму суть алгоритма смотреть в /sitedir/utils/ajax/kladr.php, остальное вспомогательное. Сами файлы:
Приветствую, меня подобная система переброса понравилась, сам планировал использовать стандартные кладр'овские коды, только прогрмму я пишу на c# переброс я буду делать сторонней программой как указанно выше, но на код если есть возможность хотел бы взглянуть!))) Буду признателен!
ОтветитьУдалитьTihoN9
ОтветитьУдалитьэту базу еле еле перенес
с консоли mysql
для устранения ошибок 2006 пропишите
SET GLOBAL max_allowed_packet=желаемый_размер_файла*1024*1024;
и для увеличения времени
SET SESSION wait_timeout = 600;
а так все супер - не хватает файлов вроде для чистого демопримера
Просьба автору выложить недостающий код для просмотра демки
ОтветитьУдалитьдавно искал что-то подобное, но никак не мог наткнуться на более менее рабочий исходник. ваш набор явно на него смахивает но либо обращение к файлу kladr.php должно быть с переменными (типо kladr.php?c=7700000000000) либо в коде нехватает отображения начала выбора субъекта РФ
кстати базу кладра проще импортировать из файлов dbf через программу navicat
В самой базе есть куча глюков(((
ОтветитьУдалитьНапример республика Адыгея (код СС-01)
Теучежский район (код РРР - 006)
село Гатлукай - ФОНАРЬ!
А все потому, что оно имеет код 01 000 002 001 00 !!!
Район указан - 000 !!!!
И таких глюков в базе ВАЛОМ!
Может есть в этом какая-то логика, которой я не понял?? Помогите понять! Плиз.
Этот комментарий был удален автором.
ОтветитьУдалить