/ / Мога ли да използвам директни SQL заявки, вместо да използвам Nominatim или други геодекодери? - геопространствени, постгисни, пространствени запитвания, номинати

Мога ли да използвам директни SQL заявки вместо да използвам Nominatim или други геодекодери? - геопространствени, пощенски, пространствено-заявки, номинации

Погледнах на изходния код на Nominatim и изглежда, че най-вече от неговата функционалност е само подготовката на SQL заявка и формирането на нейния резултат.

А възможните други гео (de) кодери работят по същия начин. Мога ли да използвам директни SQL заявки за получаване на данни от DB?

Къде мога да намеря примери за тях? Искам да получа името на мястото от координатите.

Отговори:

1 за отговор № 1

Да, това е възможно.

Опитах го преди няколко години и дойде с прост, суров геокодер, който можете да намерите на Github: https://github.com/plechi/mini-geocoder

Нуждаете се от PostgreSQL-сървър с инсталирани PostGIS и HSTORE разширения.

Създайте нова база данни на Postgres.

Активиране на разширенията PostGIS и HSTORE:

CREATE EXTENSION postgis;
CREATE EXTENSION hstore;

След това имате нужда осмоза и набор от данни от Openstreetmap, погледнете в OSM-Wiki за подробности: http://wiki.openstreetmap.org/wiki/Downloading_data

Създайте схемата на базата данни от Osmosis (изпълнете команди в терминала):

psql -d <database> -f <osmosis-folder>/script/pgsnapshot_schema_0.6.sql

Импортирайте данните (също изпълнени в терминала):

osmosis --read-xml file="<downloaded_datafile>.osm" --write-apidb host="<dbhost>" database="<dbname>" user="<dbuser>" password="<dbpassword>"

Теоретично, можете да направите заявка за получената база данни (да проверите схемата за подробности).

За моя геокодер създадох „таблица за оптимизация“ за по-лесни заявки:

CREATE TABLE geocode_optimized
AS SELECT
w.tags -> "addr:street"                            AS street,
w.tags -> "addr:housenumber"                       AS housenumber,
w.tags -> "addr:postcode"                          AS postcode,
w.tags -> "addr:city"                              AS city,
w.tags -> "addr:country"                           AS country,
AVG(ST_X(n.geom))                                  AS longitude,
AVG(ST_Y(n.geom))                                  AS latitude,
to_tsvector(concat_ws(" ", w.tags -> "addr:street",
w.tags -> "addr:housenumber",
w.tags -> "addr:postcode",
w.tags -> "addr:city",
w.tags -> "addr:country"
))                                     AS full_text,
st_makepoint(AVG(ST_X(n.geom)), AVG(ST_Y(n.geom))) AS point
FROM ways w
INNER JOIN way_nodes wn ON w.id = wn.way_id
INNER JOIN nodes n ON n.id = wn.node_id
WHERE exist(w.tags, "addr:housenumber") AND exist(w.tags, "addr:street")
GROUP BY housenumber, street, postcode, city, country;

CREATE INDEX idx_geocode_full_text ON geocode_optimized USING GIN (full_text);

Геокод (адрес към координатите):

SELECT
street,
housenumber,
postcode,
city,
country,
longitude,
latitude
FROM geocode_optimized
WHERE full_text @@ plainto_tsquery("YOUR ADDRESS")

Обратен геокод (координати до адрес)

SELECT
street,
housenumber,
postcode,
city,
country,
longitude,
latitude,
CAST (st_distance_sphere(st_makepoint(longitude,latitude), st_makepoint("<longitude>","<latitude>")) AS FLOAT) as distance
FROM geocode_optimized;

Както споменахме, това е доста грубо и вероятно не е най-ефективното решение.