Создание собственного геокодера с помощью Postgis/TIGER

Изображение на обложке с сайта переписи населения
Если на прошлой неделе вам попалась моя статья о том, как легко начать работу с Postgres/Postgis, то это продолжение о том, как создать свой собственный локальный геокодер на основе данных переписи/TIGER. Это настолько просто, что разработчики Postgis даже создали скрипты для автоматизации поиска и загрузки данных переписи. Если вы следовали руководству, у вас теперь есть база данных под названием Geocoder. Внутри вашей базы данных Geocode с расширением Postgis вы можете просто следовать руководству в документации Postgis, но я надеюсь, что это руководство дает немного больше контекста и несколько дополнительных шагов, которые облегчат задачу новичкам.

Первым шагом будет запуск этих запросов в вашем инструменте запросов.

CREATE EXTENSION fuzzystrmatch;
Войдите в полноэкранный режим Выход из полноэкранного режима
CREATE EXTENSION postgis_tiger_geocoder;
Войти в полноэкранный режим Выйти из полноэкранного режима
--this one is optional if you want to use the rules based standardizer (pagc_normalize_address)
CREATE EXTENSION address_standardizer;
Войти в полноэкранный режим Выйти из полноэкранного режима

Эти запросы установят инструмент, который попытается подобрать строку с определенной степенью достоверности. Если вы когда-нибудь использовали инструмент Fuzzy Wuzzy на языке Python, вы знаете, что делает fuzzystrmatch.

Он также создает схемы в вашей базе данных. Поскольку вы создаете схемы, неплохо было бы предоставить доступ к ним другим пользователям:

GRANT USAGE ON SCHEMA tiger to PUBLIC;
GRANT USAGE ON SCHEMA tiger_data TO PUBLIC;
GRANT SELECT, REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA tiger TO PUBLIC;
GRANT SELECT, REFERENCES, TRIGGER ON ALL TABLES IN SCEHMA tiger_data TO PUBLIC;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA tiger TO PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA tiger_data
GRANT SELECT, REFERENCES ON TABLES TO PUBLIC;
Вход в полноэкранный режим Выйти из полноэкранного режима

Последний запрос установит доступ по умолчанию для будущих доказательств к этим таблицам. (Эти запросы взяты из книги Мэннинга «Postgis в действии»).

Если вы проверите таблицы в схеме, то обнаружите, что они в основном пусты. Следующий шаг — заполнить их данными, необходимыми для геокодирования!

Следующий запрос задаст переменные для сценария bash/shell, поэтому в конце запрос изменится в зависимости от вашего os. В документации этот профиль также называется 'debbie'. Вы можете называть его geocoder или как угодно. Просто запомните его для следующего запроса.

INSERT INTO tiger.loader_platform(os, declare_sect, pgbin, wget, unzip_command, psql, path_sep,
           loader, environ_set_command, county_process_command)
SELECT 'debbie', declare_sect, pgbin, wget, unzip_command, psql, path_sep,
       loader, environ_set_command, county_process_command
  FROM tiger.loader_platform
  WHERE os = 'sh';
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь, когда вы создали эту запись, зайдите в таблицу tiger.loader_platform и установите пути ко всему. Если у вас нет wget, именно так bash-скрипты будут извлекать данные из переписи, поэтому вам нужно установить его и установить путь к библиотеке (если она не установлена в вашем Path) туда, откуда вы сможете ее вызвать. Если у вас mac, вы можете легко установить wget с помощью Homebrew: brew install wget.

После того, как вы установили эти переменные (не беспокойтесь об установке pgbin, если у вас есть psql в вашем Path, как мы сделали, если вы следовали руководству в моем последнем сообщении), вам нужно создать папку gisdata/. В руководстве рекомендуется поместить ее в корень, но я поместил ее на Desktop/, чтобы можно было легко избавиться от нее после завершения захвата данных. Если вы установите его в любое другое место, кроме корня, убедитесь, что вы обновили staging_fold в tiger.loader_platform.

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

psql -c "SELECT Loader_Generate_Nation_Script('debbie')" -d geocoder -tA > /gisdata/nation_script_load.sh
Вход в полноэкранный режим Выход из полноэкранного режима

Опять же, измените ‘debbie’ на профиль, который мы создали выше. Кроме того, последний бит — это путь к каталогу /gisdata/, так что если вы поместили его на рабочий стол, как это сделал я, вам нужно будет изменить его на что-то вроде ~/Desktop/gisdata/nation_script_load.sh. Если вы работаете на ПК, вам нужно будет создать файл .bat вместо .sh.

Бум, вот так просто у вас есть сценарий для автоматического извлечения данных из переписи и загрузки их в вашу базу данных!

Загляните в скрипт и убедитесь, что все получилось нормально. Есть ли в нем имя и пароль вашей базы данных? Сможет ли он запустить psql с тем, как он установлен? Если psql находится в вашем Пути, то вам не нужно указывать, где находится pgbin. Я полностью удалил эту переменную и ссылки на нее из сценария, когда проходил это руководство.

Следующая задача — запустить скрипт. Это не должно занять много времени в зависимости от скорости вашего интернета.

sh nation_script_load.sh
Вход в полноэкранный режим Выход из полноэкранного режима

Вы только что загрузили основные данные по всем штатам и округам США. Чтобы убедиться в этом, вы можете выполнить следующий запрос:

SELECT count(*) FROM tiger_data.county_all;
Войти в полноэкранный режим Выйти из полноэкранного режима

Он вернет 3233. Выполнение того же запроса FROM tiger_data.state_all; вернет все 50 штатов + округ Колумбия + территории для подсчета 56.

Теперь пришло время принять пару решений. Будете ли вы работать с данными переписи населения с помощью геокодера? Захотите ли вы узнать, в каком переписном участке находится адрес? Если нет, пропустите следующий запрос. Если да, выполните этот запрос:

UPDATE tiger.loader_lookuptables SET load = true WHERE load = false AND lookup_name IN('tract', 'bg', 'tabblock');
Войти в полноэкранный режим Выйти из полноэкранного режима

Это позволит вам загрузить необходимые файлы для поиска переписного участка, квартала и группы кварталов для адресов, которые вы геокодируете.

Следующее решение — для какого адреса вы будете использовать геокодер. Если вы живете в Нью-Йорке, есть вероятность, что вам будет важно геокодирование адресов в NY, но не очень важно геокодирование адресов в WY, так зачем тратить время/дисковое пространство?

Таким же образом мы создали автоматизированный скрипт для загрузки основных данных о стране/округах (необходимое требование, независимо от того, нужен ли вам только Нью-Йорк), теперь пришло время получить данные для нужного вам штата (штатов) с помощью следующего запроса:

psql -c "SELECT Loader_Generate_Script(ARRAY['NY'], 'debbie')" -d geocoder -tA > /gisdata/ny_load.sh
Войти в полноэкранный режим Выйти из полноэкранного режима

Опять же, заполните нужные вам штаты в ARRAY по их аббревиатуре; измените ‘debbie’ на то, как вы назвали свой профиль для хранения переменных ('geocode'); и убедитесь, что у вас есть правильный пункт назначения для вашего файла (например, ~/Desktop/gisdata/ny_load.sh). Запустите ваш скрипт (это может занять много времени в зависимости от скорости вашего интернета/компьютера): sh ny_load.sh.

Вот и все, теперь у вас есть геокодер на вашей локальной машине!

Документация рекомендует вам очистить ваши таблицы. Если вы создали их заново и у вас не было проблем во время установки, эти запросы не должны многого сделать, если вообще что-то сделать, но всегда полезно очистить «зомбированные» строки для повышения производительности.

SELECT install_missing_indexes();
vacuum (analyze, verbose) tiger.addr;
vacuum (analyze, verbose) tiger.edges;
vacuum (analyze, verbose) tiger.faces;
vacuum (analyze, verbose) tiger.featnames;
vacuum (analyze, verbose) tiger.place;
vacuum (analyze, verbose) tiger.cousub;
vacuum (analyze, verbose) tiger.county;
vacuum (analyze, verbose) tiger.state;
vacuum (analyze, verbose) tiger.zip_lookup_base;
vacuum (analyze, verbose) tiger.zip_state;
vacuum (analyze, verbose) tiger.zip_state_loc;
Вход в полноэкранный режим Выход из полноэкранного режима

Проведите тест! Если вы выбрали Нью-Йорк, как я в учебнике, выполните этот запрос, чтобы получить геокоординаты для площади Рокфеллер-центра:

SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat,
    (addy).address As stno, (addy).streetname As street,
    (addy).streettypeabbrev As styp, (addy).location As city, (addy).stateabbrev As state,(addy).zip
    FROM geocode('45 Rockefeller Plaza, New York, NY 10111', 1) As g;
Войти в полноэкранный режим Выйти из полноэкранного режима

При выполнении этого запроса вы заметите нечто, называемое рейтингом. Если вы получите рейтинг 0, это означает, что адрес был определен правильно. Чем выше рейтинг, тем меньше fuzzystrmatch уверен в том, что он правильно указал адрес. Вы можете поиграть с этим, написав Rockefeller как-нибудь иначе, например Rockfella, и посмотреть, что получится. Вы также можете запустить этот запрос без почтового индекса, и он выдаст правильные координаты (хотя и немного медленнее).

Вы также можете выполнять пакетные запросы, если хотите получить несколько геокоординат за один запрос.

Счастливого геокодирования!

Оцените статью
Procodings.ru
Добавить комментарий