-
Notifications
You must be signed in to change notification settings - Fork 819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rendering specific access tags #4952
Changes from 6 commits
f8488d2
9c8098b
a413991
911569e
8f386d2
e04589c
a300250
8f92b8d
42a9e75
f99920e
cdc9ace
987258c
a1dfd94
194d641
c4c775c
15c75d6
1d369dc
b1f77c2
af8400a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* Additional database functions for openstreetmap-carto */ | ||
|
||
/* Access functions below adapted from https://github.com/imagico/osm-carto-alternative-colors/tree/591c861112b4e5d44badd108f4cd1409146bca0b/sql/roads.sql */ | ||
|
||
/* Simplified 'yes', 'destination', 'no', 'unknown', NULL scale for access restriction | ||
'no' is returned if the rendering for highway category does not support 'restricted'. | ||
NULL is functionally equivalent to 'yes', but indicates the absence of a restriction | ||
rather than a positive access = yes. 'unknown' corresponds to an uninterpretable | ||
access restriction e.g. access=unknown or motorcar=occasionally */ | ||
CREATE OR REPLACE FUNCTION carto_int_access(int_highway text, accesstag text) | ||
RETURNS text | ||
LANGUAGE SQL | ||
IMMUTABLE PARALLEL SAFE | ||
AS $$ | ||
SELECT | ||
CASE | ||
WHEN accesstag IN ('yes', 'designated', 'permissive') THEN 'yes' | ||
WHEN accesstag IN ('destination', 'delivery', 'customers') THEN | ||
CASE WHEN int_highway IN ('road', 'pedestrian') THEN 'restricted' ELSE 'no' END | ||
dch0ph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
WHEN accesstag IN ('no', 'permit', 'private', 'agricultural', 'forestry', 'agricultural;forestry') THEN 'no' | ||
WHEN NULL THEN NULL | ||
ELSE 'unknown' | ||
END | ||
END | ||
$$; | ||
|
||
/* Try to promote path to cycleway (if bicycle allowed), then bridleway (if horse) | ||
This duplicates existing behaviour where designated access is required */ | ||
CREATE OR REPLACE FUNCTION carto_path_type(bicycle text, horse text) | ||
RETURNS text | ||
LANGUAGE SQL | ||
IMMUTABLE PARALLEL SAFE | ||
AS $$ | ||
SELECT | ||
CASE | ||
WHEN bicycle IN ('designated') THEN 'cycleway' | ||
WHEN horse IN ('designated') THEN 'bridleway' | ||
ELSE 'path' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The conservative option is to keep the option of rendering |
||
END | ||
END | ||
$$; | ||
|
||
/* Coalesce highways that will be treated in the same way, e.g. all roads become 'road' | ||
Note that bicycle, horse arguments are only relevant if considering highway=path */ | ||
CREATE OR REPLACE FUNCTION carto_highway_int_highway(highway text, bicycle text, horse text) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This SQL function is called in exactly one place and consists of a single CASE statement. This makes it equivalent to SELECT
CASE CASE WHEN highway in (..) THEN 'road' WHEN ... END
WHEN 'road' THEN ... END
WHEN 'pedestrian' THEN ... END
END Just modify the SQL statement calling it to remove the need for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not quite that simple since |
||
RETURNS text | ||
LANGUAGE SQL | ||
IMMUTABLE PARALLEL SAFE | ||
AS $$ | ||
SELECT | ||
CASE | ||
WHEN highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', | ||
'secondary_link', 'tertiary', 'tertiary_link', 'residential', 'unclassified', 'living_street', 'service', 'road') THEN 'road' | ||
WHEN highway IN ('footway', 'steps') THEN 'footway' | ||
WHEN highway = 'path' THEN carto_path_type(bicycle, horse) | ||
ELSE highway | ||
END | ||
END | ||
$$; | ||
|
||
/* Return int_access value which will be used to determine access marking. | ||
Only a restricted number of types can be returned, with NULL corresponding to no access restriction */ | ||
CREATE OR REPLACE FUNCTION carto_highway_int_access(highway text, "access" text, foot text, bicycle text, horse text, motorcar text, motor_vehicle text, vehicle text) | ||
dch0ph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
RETURNS text | ||
LANGUAGE SQL | ||
IMMUTABLE PARALLEL SAFE | ||
AS $$ | ||
SELECT | ||
CASE carto_highway_int_highway(highway, bicycle, horse) | ||
WHEN 'road' THEN | ||
carto_int_access('road', CASE | ||
WHEN motorcar <> 'unknown' THEN motorcar | ||
WHEN motor_vehicle <> 'unknown' THEN motor_vehicle | ||
WHEN vehicle <> 'unknown' THEN vehicle | ||
ELSE "access" END) | ||
WHEN 'pedestrian' THEN carto_int_access('pedestrian', CASE WHEN foot <> 'unknown' THEN foot ELSE "access" END) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
WHEN 'footway' THEN carto_int_access('footway', CASE WHEN foot <> 'unknown' THEN foot ELSE "access" END) | ||
WHEN 'cycleway' THEN carto_int_access('cycleway', CASE WHEN bicycle <> 'unknown' THEN bicycle ELSE "access" END) | ||
WHEN 'brideway' THEN carto_int_access('bridleway', CASE WHEN horse <> 'unknown' THEN horse ELSE "access" END) | ||
dch0ph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ELSE carto_int_access(NULL, "access") | ||
END | ||
END | ||
$$; | ||
|
||
/* Uncomment lines below to create generated column for int_access | ||
ALTER TABLE planet_osm_line DROP COLUMN IF EXISTS int_access; | ||
ALTER TABLE planet_osm_line | ||
ADD int_access text GENERATED ALWAYS AS (CASE WHEN highway IS NOT NULL THEN carto_highway_int_access(highway, "access", foot, bicycle, horse, tags->'motorcar', tags->'motor_vehicle', tags->'vehicle') ELSE NULL END) STORED; | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -444,32 +444,24 @@ Layer: | |
(SELECT | ||
way, | ||
(CASE WHEN feature IN ('highway_motorway_link', 'highway_trunk_link', 'highway_primary_link', 'highway_secondary_link', 'highway_tertiary_link') THEN substr(feature, 0, length(feature)-4) ELSE feature END) AS feature, | ||
horse, | ||
foot, | ||
bicycle, | ||
tracktype, | ||
int_surface, | ||
access, | ||
int_access, | ||
construction, | ||
service, | ||
link, | ||
layernotnull | ||
FROM ( -- subselect that contains both roads and rail | ||
SELECT | ||
way, | ||
'highway_' || highway AS feature, --only motorway to tertiary links are accepted later on | ||
horse, | ||
foot, | ||
bicycle, | ||
'highway_' || (CASE WHEN highway = 'path' THEN carto_path_type(bicycle, horse) ELSE highway END) AS feature, --only motorway to tertiary links are accepted later on | ||
tracktype, | ||
CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', | ||
'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' | ||
WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', | ||
'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' | ||
END AS int_surface, | ||
CASE WHEN access IN ('destination') THEN 'destination'::text | ||
WHEN access IN ('no', 'private') THEN 'no'::text | ||
END AS access, | ||
carto_highway_int_access(highway, access, foot, bicycle, horse, tags->'motorcar', tags->'motor_vehicle', tags->'vehicle') AS int_access, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This reveals an inconsistency of how we're treating access tags. If we're storing the raw tag text here, let's put them all in the tags column. If we're preprocessing we could have a smaller number of columns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, our current database schema has foot, bicycle, and horse as columns (because these have been interpreted in rendering of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see any issue with doing a reload. Being consistent on columns is a plus, even if we aren't able to reach a consensus on any preprocessing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am fine with removing foot/bicycle/horse from the columns. I am just not sure if it is worth doing a database layout change breaking backwards compatibility just because of this. We could also source foot/bicycle/horse from hstore in anticipation of such a change now and defer the actual removal of the columns to when we do a database reload anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This would make sense. But if we are sourcing all the detailed access tags via hstore, I suggest passing the hstore tags as a function argument to both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have to correct myself here: I wrongly remembered that tags in columns are also available in hstore, but they are not. Hence my suggestion would not work. |
||
construction, | ||
CASE | ||
WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text | ||
|
@@ -491,15 +483,9 @@ Layer: | |
WHEN (railway = 'rail' AND service IN ('spur', 'siding', 'yard')) THEN 'INT-spur-siding-yard' | ||
WHEN (railway = 'tram' AND service IN ('spur', 'siding', 'yard')) THEN 'tram-service' | ||
ELSE railway END) AS feature, | ||
horse, | ||
foot, | ||
bicycle, | ||
tracktype, | ||
'null', | ||
CASE | ||
WHEN access IN ('destination') THEN 'destination'::text | ||
WHEN access IN ('no', 'private') THEN 'no'::text | ||
END AS access, | ||
NULL, | ||
construction, | ||
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service, | ||
'no' AS link, | ||
|
@@ -514,7 +500,7 @@ Layer: | |
z_order, | ||
CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, | ||
CASE WHEN feature IN ('railway_INT-preserved-ssy', 'railway_INT-spur-siding-yard', 'railway_tram-service') THEN 0 ELSE 1 END, | ||
CASE WHEN access IN ('no', 'private') THEN 0 WHEN access IN ('destination') THEN 1 ELSE 2 END, | ||
CASE int_access WHEN 'no' THEN 0 WHEN 'restricted' THEN 1 ELSE 2 END, | ||
CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 1 END | ||
) AS tunnels | ||
properties: | ||
|
@@ -681,32 +667,24 @@ Layer: | |
(SELECT | ||
way, | ||
(CASE WHEN feature IN ('highway_motorway_link', 'highway_trunk_link', 'highway_primary_link', 'highway_secondary_link', 'highway_tertiary_link') THEN substr(feature, 0, length(feature)-4) ELSE feature END) AS feature, | ||
horse, | ||
foot, | ||
bicycle, | ||
tracktype, | ||
int_surface, | ||
access, | ||
int_access, | ||
construction, | ||
service, | ||
link, | ||
layernotnull | ||
FROM ( -- subselect that contains both roads and rail/aero | ||
SELECT | ||
way, | ||
('highway_' || highway) AS feature, --only motorway to tertiary links are accepted later on | ||
horse, | ||
foot, | ||
bicycle, | ||
'highway_' || (CASE WHEN highway = 'path' THEN carto_path_type(bicycle, horse) ELSE highway END) AS feature, --only motorway to tertiary links are accepted later on | ||
tracktype, | ||
CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', | ||
'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' | ||
WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', | ||
'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' | ||
END AS int_surface, | ||
CASE WHEN access IN ('destination') THEN 'destination'::text | ||
WHEN access IN ('no', 'private') THEN 'no'::text | ||
END AS access, | ||
carto_highway_int_access(highway, access, foot, bicycle, horse, tags->'motorcar', tags->'motor_vehicle', tags->'vehicle') AS int_access, | ||
construction, | ||
CASE | ||
WHEN service IN ('parking_aisle', 'drive-through', 'driveway') OR leisure IN ('slipway') THEN 'INT-minor'::text | ||
|
@@ -731,20 +709,14 @@ Layer: | |
WHEN (railway = 'rail' AND service IN ('spur', 'siding', 'yard')) THEN 'INT-spur-siding-yard' | ||
WHEN (railway = 'tram' AND service IN ('spur', 'siding', 'yard')) THEN 'tram-service' | ||
ELSE railway END)) AS feature, | ||
horse, | ||
foot, | ||
bicycle, | ||
tracktype, | ||
CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', | ||
'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' | ||
WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', | ||
'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' | ||
ELSE NULL | ||
END AS int_surface, | ||
CASE | ||
WHEN access IN ('destination') THEN 'destination'::text | ||
WHEN access IN ('no', 'private') THEN 'no'::text | ||
END AS access, | ||
NULL, | ||
construction, | ||
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') OR leisure IN ('slipway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service, | ||
'no' AS link, | ||
|
@@ -763,7 +735,7 @@ Layer: | |
z_order, | ||
CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, | ||
CASE WHEN feature IN ('railway_INT-preserved-ssy', 'railway_INT-spur-siding-yard', 'railway_tram-service') THEN 0 ELSE 1 END, | ||
CASE WHEN access IN ('no', 'private') THEN 0 WHEN access IN ('destination') THEN 1 ELSE 2 END, | ||
CASE int_access WHEN 'no' THEN 0 WHEN 'restricted' THEN 1 ELSE 2 END, | ||
CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 1 END, | ||
osm_id | ||
) AS roads_sql | ||
|
@@ -913,32 +885,24 @@ Layer: | |
(SELECT | ||
way, | ||
(CASE WHEN feature IN ('highway_motorway_link', 'highway_trunk_link', 'highway_primary_link', 'highway_secondary_link', 'highway_tertiary_link') THEN substr(feature, 0, length(feature)-4) ELSE feature END) AS feature, | ||
horse, | ||
foot, | ||
bicycle, | ||
tracktype, | ||
int_surface, | ||
access, | ||
int_access, | ||
construction, | ||
service, | ||
link, | ||
layernotnull | ||
FROM ( -- subselect that contains both roads and rail/aero | ||
SELECT | ||
way, | ||
'highway_' || highway AS feature, --only motorway to tertiary links are accepted later on | ||
horse, | ||
foot, | ||
bicycle, | ||
'highway_' || (CASE WHEN highway = 'path' THEN carto_path_type(bicycle, horse) ELSE highway END) AS feature, --only motorway to tertiary links are accepted later on | ||
dch0ph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
tracktype, | ||
CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', | ||
'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' | ||
WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', | ||
'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' | ||
END AS int_surface, | ||
CASE WHEN access IN ('destination') THEN 'destination'::text | ||
WHEN access IN ('no', 'private') THEN 'no'::text | ||
END AS access, | ||
carto_highway_int_access(highway, access, foot, bicycle, horse, tags->'motorcar', tags->'motor_vehicle', tags->'vehicle') AS int_access, | ||
construction, | ||
CASE | ||
WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text | ||
|
@@ -960,15 +924,9 @@ Layer: | |
WHEN (railway = 'rail' AND service IN ('spur', 'siding', 'yard')) THEN 'INT-spur-siding-yard' | ||
WHEN (railway = 'tram' AND service IN ('spur', 'siding', 'yard')) THEN 'tram-service' | ||
ELSE railway END) AS feature, | ||
horse, | ||
foot, | ||
bicycle, | ||
tracktype, | ||
'null', | ||
CASE | ||
WHEN access IN ('destination') THEN 'destination'::text | ||
WHEN access IN ('no', 'private') THEN 'no'::text | ||
END AS access, | ||
NULL, | ||
construction, | ||
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service, | ||
'no' AS link, | ||
|
@@ -983,7 +941,7 @@ Layer: | |
z_order, | ||
CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, | ||
CASE WHEN feature IN ('railway_INT-preserved-ssy', 'railway_INT-spur-siding-yard', 'railway_tram-service') THEN 0 ELSE 1 END, | ||
CASE WHEN access IN ('no', 'private') THEN 0 WHEN access IN ('destination') THEN 1 ELSE 2 END, | ||
CASE int_access WHEN 'no' THEN 0 WHEN 'restricted' THEN 1 ELSE 2 END, | ||
CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 1 END | ||
) AS bridges | ||
properties: | ||
|
@@ -1923,8 +1881,7 @@ Layer: | |
CASE | ||
WHEN oneway IN ('yes', '-1') THEN oneway | ||
WHEN junction IN ('roundabout') AND (oneway IS NULL OR NOT oneway IN ('no', 'reversible')) THEN 'yes' | ||
END AS oneway, | ||
horse, bicycle | ||
END AS oneway | ||
FROM planet_osm_line l | ||
WHERE highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary', | ||
'tertiary_link', 'residential', 'unclassified', 'road', 'service', 'pedestrian', 'raceway', 'living_street', 'construction') | ||
|
@@ -1949,15 +1906,13 @@ Layer: | |
table: |- | ||
(SELECT | ||
way, | ||
highway, | ||
CASE WHEN highway = 'path' THEN carto_path_type(bicycle, horse) ELSE highway END AS highway, | ||
construction, | ||
name, | ||
CASE | ||
WHEN oneway IN ('yes', '-1') THEN oneway | ||
WHEN junction IN ('roundabout') AND (oneway IS NULL OR NOT oneway IN ('no', 'reversible')) THEN 'yes' | ||
END AS oneway, | ||
horse, | ||
bicycle | ||
END AS oneway | ||
FROM planet_osm_line | ||
WHERE highway IN ('bridleway', 'footway', 'cycleway', 'path', 'track', 'steps', 'construction') | ||
AND (name IS NOT NULL | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combined with the other changes I think this can be removed but the other changes would need to be done first.