From c8fcb239a6c8ec6915777c57c3729739e7d02bd4 Mon Sep 17 00:00:00 2001 From: imagico Date: Mon, 21 Sep 2015 21:19:43 +0200 Subject: [PATCH] move to more generic method of buffering --- project.mml | 2 +- project.yaml | 91 +++++++++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/project.mml b/project.mml index b7e8f837fc..1cf2017784 100644 --- a/project.mml +++ b/project.mml @@ -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": "", diff --git a/project.yaml b/project.yaml index 98b233a51a..75e5fcb8d2 100644 --- a/project.yaml +++ b/project.yaml @@ -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