Skip to content

Commit

Permalink
move to more generic method of buffering
Browse files Browse the repository at this point in the history
  • Loading branch information
imagico committed Sep 21, 2015
1 parent cbc48dc commit c8fcb23
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 42 deletions.
2 changes: 1 addition & 1 deletion project.mml
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@
"srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
"Datasource": {
"extent": "-20037508,-20037508,20037508,20037508",
"table": "(SELECT\n way,\n COALESCE(\n ('highway_' || (CASE WHEN highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'cycleway', 'living_street', 'track', 'path', 'platform', 'services') THEN highway ELSE NULL END)),\n ('railway_' || (CASE WHEN railway IN ('platform') THEN railway ELSE NULL END)),\n (('aeroway_' || CASE WHEN aeroway IN ('runway', 'taxiway', 'helipad') THEN aeroway ELSE NULL END))\n ) AS feature\n FROM (\n SELECT \n way, highway, railway, aeroway, z_order, way_area FROM planet_osm_polygon\n WHERE highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'living_street', 'track', 'path', 'platform', 'services')\n OR railway IN ('platform')\n OR aeroway IN ('taxiway', 'helipad')\n UNION ALL\n SELECT -- runways with width either tagged or estimated from runway length\n ST_Buffer(\n way,\n -- more generic estimation for scale factor on arbitrary projections would be:\n -- 0.5*(St_Distance(ST_StartPoint(way), ST_EndPoint(way))/St_Distance_Sphere(ST_Transform(ST_StartPoint(way), 4326), ST_Transform(ST_EndPoint(way), 4326)))*\n (0.5 / cos(radians(ST_y(st_transform(st_centroid(way),4326)))))* -- works on Mercator only\n CASE\n WHEN width ~ '^\\d{1,3}(\\.\\d+)?$' THEN width::real\n ELSE LEAST(GREATEST(ST_Length(st_transform(way,4326)::geography)/50,12.0),75.0)\n END,\n 'endcap=flat join=round'\n ),\n highway, railway, aeroway, z_order, ST_Length(way)*ST_Length(way) AS way_area FROM planet_osm_line\n WHERE aeroway IN ('runway')\n UNION ALL\n SELECT -- taxiways with width either tagged or guessed\n ST_Buffer(\n way,\n -- more generic estimation for scale factor on arbitrary projections would be:\n -- 0.5*(St_Distance(ST_StartPoint(way), ST_EndPoint(way))/St_Distance_Sphere(ST_Transform(ST_StartPoint(way), 4326), ST_Transform(ST_EndPoint(way), 4326)))*\n (0.5 / cos(radians(ST_y(st_transform(st_centroid(way),4326)))))* -- works on Mercator only\n CASE\n WHEN width ~ '^\\d{1,3}(\\.\\d+)?$' THEN width::real\n ELSE 6\n END,\n 'endcap=flat join=round'\n ),\n highway, railway, aeroway, z_order, ST_Length(way)*ST_Length(way) AS way_area FROM planet_osm_line AS tline\n WHERE aeroway IN ('taxiway')\n ) AS features\n ORDER BY z_order, way_area desc\n) AS highway_area_fill",
"table": "(SELECT\n way, feature\n FROM (\n SELECT -- features mapped as polygons\n way, \n COALESCE(\n ('highway_' || (CASE WHEN highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'cycleway', 'living_street', 'track', 'path', 'platform', 'services') THEN highway ELSE NULL END)),\n ('railway_' || (CASE WHEN railway IN ('platform') THEN railway ELSE NULL END)),\n ('aeroway_' || (CASE WHEN aeroway IN ('taxiway', 'helipad') THEN aeroway ELSE NULL END))\n ) AS feature,\n z_order, way_area FROM planet_osm_polygon\n WHERE (highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'living_street', 'track', 'path', 'platform', 'services')\n OR railway IN ('platform')\n OR aeroway IN ('taxiway', 'helipad'))\n AND way && !bbox!\n UNION ALL\n SELECT -- aeroway lines, converted to areas\n way, feature, z_order, ST_Area(way) AS way_area\n FROM\n (SELECT \n ST_Transform(\n ST_Buffer(\n ST_Transform( -- Use a projection that allows accurate buffering\n way,\n _ST_BestSRID(ST_Transform(way, 4326)::geography) -- Find the SRID to use\n ),\n 0.5 * CASE -- Buffer by the half-width\n WHEN width ~ '^\\d{1,3}(\\.\\d+)?$' -- Validate the width tag\n THEN LEAST(width::real, 150) -- Place a maximum on the width\n WHEN aeroway = 'runway' -- No valid width, so estimate from length if a runway\n THEN LEAST(GREATEST(ST_Length(ST_Transform(way,4326)::geography)/50,12.0),75.0)\n ELSE --taxiway\n 6\n END,\n 'endcap=flat join=round'\n ),\n ST_SRID(way)\n ) AS way,\n 'aeroway_' || aeroway AS feature,\n z_order FROM planet_osm_line\n WHERE aeroway IN ('runway', 'taxiway')\n AND way && -- extend bounding box by maximum buffer width\n CASE WHEN ST_Perimeter(ST_Transform(!bbox!,4326)) >= 360 THEN !bbox!\n ELSE ST_Transform(\n ST_Expand(\n ST_Transform(\n !bbox!,\n _ST_BestSRID(ST_Transform(!bbox!,4326)::geography)),\n 150),\n ST_SRID(!bbox!))\n END\n ) AS p\n ) AS features\n ORDER BY z_order, way_area desc\n) AS highway_area_fill",
"geometry_field": "way",
"type": "postgis",
"key_field": "",
Expand Down
91 changes: 50 additions & 41 deletions project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -901,48 +901,57 @@ Layer:
<<: *osm2pgsql
table: |-
(SELECT
way,
COALESCE(
('highway_' || (CASE WHEN highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'cycleway', 'living_street', 'track', 'path', 'platform', 'services') THEN highway ELSE NULL END)),
('railway_' || (CASE WHEN railway IN ('platform') THEN railway ELSE NULL END)),
(('aeroway_' || CASE WHEN aeroway IN ('runway', 'taxiway', 'helipad') THEN aeroway ELSE NULL END))
) AS feature
way, feature
FROM (
SELECT
way, highway, railway, aeroway, z_order, way_area FROM planet_osm_polygon
WHERE highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'living_street', 'track', 'path', 'platform', 'services')
OR railway IN ('platform')
OR aeroway IN ('taxiway', 'helipad')
UNION ALL
SELECT -- runways with width either tagged or estimated from runway length
ST_Buffer(
way,
-- more generic estimation for scale factor on arbitrary projections would be:
-- 0.5*(St_Distance(ST_StartPoint(way), ST_EndPoint(way))/St_Distance_Sphere(ST_Transform(ST_StartPoint(way), 4326), ST_Transform(ST_EndPoint(way), 4326)))*
(0.5 / cos(radians(ST_y(st_transform(st_centroid(way),4326)))))* -- works on Mercator only
CASE
WHEN width ~ '^\d{1,3}(\.\d+)?$' THEN width::real
ELSE LEAST(GREATEST(ST_Length(st_transform(way,4326)::geography)/50,12.0),75.0)
END,
'endcap=flat join=round'
),
highway, railway, aeroway, z_order, ST_Length(way)*ST_Length(way) AS way_area FROM planet_osm_line
WHERE aeroway IN ('runway')
UNION ALL
SELECT -- taxiways with width either tagged or guessed
ST_Buffer(
way,
-- more generic estimation for scale factor on arbitrary projections would be:
-- 0.5*(St_Distance(ST_StartPoint(way), ST_EndPoint(way))/St_Distance_Sphere(ST_Transform(ST_StartPoint(way), 4326), ST_Transform(ST_EndPoint(way), 4326)))*
(0.5 / cos(radians(ST_y(st_transform(st_centroid(way),4326)))))* -- works on Mercator only
CASE
WHEN width ~ '^\d{1,3}(\.\d+)?$' THEN width::real
ELSE 6
END,
'endcap=flat join=round'
),
highway, railway, aeroway, z_order, ST_Length(way)*ST_Length(way) AS way_area FROM planet_osm_line AS tline
WHERE aeroway IN ('taxiway')
SELECT -- features mapped as polygons
way,
COALESCE(
('highway_' || (CASE WHEN highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'cycleway', 'living_street', 'track', 'path', 'platform', 'services') THEN highway ELSE NULL END)),
('railway_' || (CASE WHEN railway IN ('platform') THEN railway ELSE NULL END)),
('aeroway_' || (CASE WHEN aeroway IN ('taxiway', 'helipad') THEN aeroway ELSE NULL END))
) AS feature,
z_order, way_area FROM planet_osm_polygon
WHERE (highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'living_street', 'track', 'path', 'platform', 'services')
OR railway IN ('platform')
OR aeroway IN ('taxiway', 'helipad'))
AND way && !bbox!
UNION ALL
SELECT -- aeroway lines, converted to areas
way, feature, z_order, ST_Area(way) AS way_area
FROM
(SELECT
ST_Transform(
ST_Buffer(
ST_Transform( -- Use a projection that allows accurate buffering
way,
_ST_BestSRID(ST_Transform(way, 4326)::geography) -- Find the SRID to use
),
0.5 * CASE -- Buffer by the half-width
WHEN width ~ '^\d{1,3}(\.\d+)?$' -- Validate the width tag
THEN LEAST(width::real, 150) -- Place a maximum on the width
WHEN aeroway = 'runway' -- No valid width, so estimate from length if a runway
THEN LEAST(GREATEST(ST_Length(ST_Transform(way,4326)::geography)/50,12.0),75.0)
ELSE --taxiway
6
END,
'endcap=flat join=round'
),
ST_SRID(way)
) AS way,
'aeroway_' || aeroway AS feature,
z_order FROM planet_osm_line
WHERE aeroway IN ('runway', 'taxiway')
AND way && -- extend bounding box by maximum buffer width
CASE WHEN ST_Perimeter(ST_Transform(!bbox!,4326)) >= 360 THEN !bbox!
ELSE ST_Transform(
ST_Expand(
ST_Transform(
!bbox!,
_ST_BestSRID(ST_Transform(!bbox!,4326)::geography)),
150),
ST_SRID(!bbox!))
END
) AS p
) AS features
ORDER BY z_order, way_area desc
) AS highway_area_fill
Expand Down

0 comments on commit c8fcb23

Please sign in to comment.