I think I have something. It prints the name of the road and all the names of the administrative groups it belongs to. It also gives the bbox of the geometry of the street and also its half-way point. Note that it produces JSON but it is not GeoJSON compatible because I filtered out things like type which add hugely to the final size. Disclaimer Googleâs AI assistant got me started on the SQL by providing a rudimentary skeleton:
DBNAME=mydbname
DBUSER=mydbuser
OUTFILE='out.json'
# set a limit as to how many to fetch, e.g. 'LIMIT 10' or leave empty
LIMIT='LIMIT 10'
psql -U postgres -d "${DBNAME}" -o "${OUTFILE}" -v ON_ERROR_STOP=1 -t <<EOS
SELECT jsonb_build_object(
'f', jsonb_agg(feature)
) AS jsonout
FROM (
SELECT
jsonb_build_object(
--- geometry of the street
--- note how we filter coordinates using ->'coordinates'
--- note how we add bbox by the last 1 in options of ST_AsGeoJSON(...,1)
--- decimal digits is 9 is the last-but-one option
--- WARNING: GeoJSON needs a 'type' to be valid, but we don't want GeoJSON
'p', jsonb_build_object(
--- linesegment points on the street
'EPSG:4326', jsonb_build_object(
'p', ST_AsGeoJSON(ST_LineMerge(ST_Transform(roads.way, 4326)), 9, 1)::json->'coordinates',
'b', ST_AsGeoJSON(ST_LineMerge(ST_Transform(roads.way, 4326)), 9, 1)::json->'bbox'
),
'EPSG:3857', jsonb_build_object(
'p', ST_AsGeoJSON(ST_LineMerge(roads.way), 9, 1)::json->'coordinates',
'b', ST_AsGeoJSON(ST_LineMerge(roads.way), 9, 1)::json->'bbox'
)
),
--- halfway point of the street
'c', jsonb_build_object(
--- centroid of the linesegment falling on the line
--- see https://gis.stackexchange.com/questions/254151/how-to-find-the-center-point-which-lies-on-the-linestring-geometry
--- see http://postgis.net/docs/manual-1.5/ST_Line_Interpolate_Point.html
--- last parameter (0.5) puts the point HALFway on the street, 0.0 will be at the start, 1.0 will be at the end
'EPSG:4326', ST_AsGeoJSON(ST_LineInterpolatePoint(ST_LineMerge(ST_Transform(roads.way, 4326)), 0.5), 9, 0)::jsonb->'coordinates',
'EPSG:3857', ST_LineInterpolatePoint(ST_LineMerge(roads.way), 0.5)::jsonb->'coordinates'
),
'n', roads.name,
'a', ARRAY_AGG(admin.name ORDER BY admin.admin_level DESC)
) AS feature
FROM
planet_osm_roads AS roads
JOIN
planet_osm_polygon AS admin ON ST_Intersects(roads.way, admin.way)
WHERE
roads.highway IS NOT NULL
AND roads.name IS NOT NULL
AND admin.boundary = 'administrative'
AND admin.admin_level IN ('2', '4', '6', '8', '9', '10')
GROUP BY
roads.osm_id, roads.name, roads.way
${LIMIT}
) AS subquery;
EOS
if [ $? -ne 0 ]; then echo "$0 : error, failed to execute SQL"; exit 1; fi
echo "$0 : done, check output in '$OUTFILE'."
run against the postgis db created from OSM regional pbf file.
I have one question though, How can I cache certain data? like: ST_LineMerge(ST_Transform(roads.way, 4326)
which I use several times and is exactly the same? Unless it is cached already by Pg?