-
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 all 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,74 @@ | ||
/* 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', 'unrecognised', 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. 'unrecognised' corresponds to an uninterpretable | ||
access restriction e.g. access=unknown or motorcar=occasionally */ | ||
CREATE OR REPLACE FUNCTION carto_int_access(accessvalue text, allow_restricted boolean) | ||
RETURNS text | ||
LANGUAGE SQL | ||
IMMUTABLE PARALLEL SAFE | ||
AS $$ | ||
SELECT | ||
CASE | ||
WHEN accessvalue IN ('yes', 'designated', 'permissive') THEN 'yes' | ||
WHEN accessvalue IN ('destination', 'delivery', 'customers') THEN | ||
CASE WHEN allow_restricted = TRUE THEN 'restricted' ELSE 'yes' END | ||
WHEN accessvalue IN ('no', 'permit', 'private', 'agricultural', 'forestry', 'agricultural;forestry') THEN 'no' | ||
WHEN accessvalue IS NULL THEN NULL | ||
ELSE 'unrecognised' | ||
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' | ||
END | ||
$$; | ||
|
||
/* Return int_access value which will be used to determine access marking. | ||
Return values are documented above for carto_int_access function. | ||
|
||
Note that the code handling the promotion of highway=path assumes that | ||
promotion to cycleway or bridleway is based on the value of bicycle or | ||
horse respectively. A more general formulation would be, for example, | ||
WHEN 'cycleway' THEN carto_int_access(COALESCE(NULLIF(bicycle, 'unknown'), "access"), FALSE) */ | ||
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 | ||
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 | ||
carto_int_access( | ||
COALESCE( | ||
NULLIF(motorcar, 'unknown'), | ||
NULLIF(motor_vehicle, 'unknown'), | ||
NULLIF(vehicle, 'unknown'), | ||
"access"), TRUE) | ||
WHEN highway = 'path' THEN | ||
CASE carto_path_type(bicycle, horse) | ||
WHEN 'cycleway' THEN carto_int_access(bicycle, FALSE) | ||
imagico marked this conversation as resolved.
Show resolved
Hide resolved
|
||
WHEN 'bridleway' THEN carto_int_access(horse, FALSE) | ||
ELSE carto_int_access(COALESCE(NULLIF(foot, 'unknown'), "access"), FALSE) | ||
END | ||
WHEN highway IN ('pedestrian', 'footway', 'steps') THEN carto_int_access(COALESCE(NULLIF(foot, 'unknown'), "access"), FALSE) | ||
WHEN highway = 'cycleway' THEN carto_int_access(COALESCE(NULLIF(bicycle, 'unknown'), "access"), FALSE) | ||
WHEN highway = 'bridleway' THEN carto_int_access(COALESCE(NULLIF(horse, 'unknown'), "access"), FALSE) | ||
ELSE carto_int_access("access", TRUE) | ||
END | ||
$$; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -444,12 +444,9 @@ 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, | ||
|
@@ -458,19 +455,14 @@ Layer: | |
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, | ||
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 | ||
|
@@ -493,15 +485,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, | ||
|
@@ -520,7 +506,7 @@ Layer: | |
z_order, | ||
CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, | ||
CASE WHEN feature IN ('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: | ||
|
@@ -687,12 +673,9 @@ 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, | ||
|
@@ -701,19 +684,14 @@ Layer: | |
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, | ||
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 | ||
|
@@ -739,20 +717,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, | ||
|
@@ -775,7 +747,7 @@ Layer: | |
z_order, | ||
CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, | ||
CASE WHEN feature IN ('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 | ||
|
@@ -925,12 +897,9 @@ 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, | ||
|
@@ -939,19 +908,14 @@ Layer: | |
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, | ||
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 | ||
|
@@ -974,15 +938,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, | ||
|
@@ -1001,7 +959,7 @@ Layer: | |
z_order, | ||
CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, | ||
CASE WHEN feature IN ('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: | ||
|
@@ -1941,8 +1899,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') | ||
|
@@ -1967,15 +1924,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.
This needs to be
footway
rather thanpath
if you want to eliminatehighway_path
from MSS altogether.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.
The conservative option is to keep the option of rendering
highway=path
differently fromhighway=footway
(there already seems to be some difference in thatfootway
can have an area render, but notpath
).