Re: [OSM-talk] Osm2pgsql/TileMill - how to detect whether way is in a route?

2013-03-19 Thread Phil! Gold
* Steve Bennett stevag...@gmail.com [2013-03-19 10:52 +1100]:
 One way to fudge this is to render the way, then render the route
 relation over the top, obscuring it. But that doesn't work if you want
 to use line smoothing (eg, line-smooth:0.6). The route relation will
 form a smooth bezier curve the intersection of two ways, but the way
 rendering will form a sharp point.
 
 So I'm just wondering if there is a way around this - some setting in
 osm2pgsql, some SQL magic I could play with.

I do something very similar with my highway shield rendering, which is
driven by route relations.  I go through the planet_osm_rels table that's
created by osm2pgsql's slim mode, which is considered cheating in some
circles.

My rendering has code at https://launchpad.net/osm-shields , but the meat
of what you're interested in is the following two functions:

-- osm2pgsql stores tags in PostgreSQL arrays, where even-numbered array
-- members are tags and odd-numbered members are the tags' values.  This
-- is a convenience function to go through such an array and retrieve the
-- value for a given tag.
CREATE OR REPLACE FUNCTION osm_get_tag_value(tags TEXT[], tag TEXT)
RETURNS TEXT
IMMUTABLE
RETURNS NULL ON NULL INPUT
LANGUAGE plpgsql
AS $$
DECLARE
  tag_index INTEGER;
BEGIN
  SELECT i INTO tag_index
FROM (SELECT generate_subscripts(tags, 1) AS i) AS indices
WHERE i % 2 = 1 AND tags[i] = tag;
  RETURN tags[tag_index + 1];
END;
$$;

CREATE OR REPLACE FUNCTION 
shields_get_route_memberships(planet_osm_rels.id%TYPE)
RETURNS fullref[]
STABLE
RETURNS NULL ON NULL INPUT
COST 5000
LANGUAGE SQL
AS $$
  SELECT 
shields_replace_groups(array_agg(ROW(shields_sanitize_text(network), 
shields_sanitize_text(ref))::fullref))
FROM (SELECT osm_get_tag_value(tags, 'route') route,
 UPPER(osm_get_tag_value(tags, 'network')) network,
 UPPER(COALESCE(NULLIF(osm_get_tag_value(tags, 'ref'), ''), 
osm_get_tag_value(tags, 'name'))) AS ref
FROM planet_osm_rels
WHERE parts  ARRAY[$1]
  AND parts[way_off:array_upper(parts, 1)]  ARRAY[$1]) AS 
ref_inner
WHERE route = 'road' AND network IS NOT NULL AND ref IS NOT NULL;
$$;

There's a lot of shield-rendering-specific code in there.  A more succinct
query might be the following (where $1 is the OSM ID of the way for which
you want to determine route membership):

SELECT *
  FROM (SELECT osm_get_tag_value(tags, 'route') route,
   osm_get_tag_value(tags, 'network') network,
   osm_get_tag_value(tags, 'ref') ref,
   osm_get_tag_value(tags, 'name') name
  FROM planet_osm_rels
  WHERE parts  ARRAY[$1]
AND parts[way_off:array_upper(parts, 1)]  ARRAY[$1]) AS 
ref_inner
  WHERE route IS NOT NULL;

Obviously, you can add your own parameters in the statement.

___
talk mailing list
talk@openstreetmap.org
http://lists.openstreetmap.org/listinfo/talk


Re: [OSM-talk] Osm2pgsql/TileMill - how to detect whether way is in a route?

2013-03-18 Thread Frederik Ramm

Hi,

On 19.03.2013 00:52, Steve Bennett wrote:

So I'm just wondering if there is a way around this - some setting in
osm2pgsql, some SQL magic I could play with.


It will be very slow magic, but two things come to mind:

One would use the line geometry table and ask for routes in the vicinity 
to be subtracted from the way geometry; if the resulting geometry is 
empty then your way was part of a route. In pseudo SQL something like


select way,attribute,attribute,attribute,st_isempty(st_difference(way, 
(select way from planet_osm_roads t2 where t2.osm_id0 and 
t2.has_mtb_route_tags and t2.way  way) as in_mtb_route from 
planet_osm_ways...


The other would be using the planet_osm_rels table that only exists ins 
slim mode and from there get a list of all relations the way in question 
is a member of, check those relations for mtb routes...


The only *efficient* way I can think of is extending osm2pgsql so that 
it sets an extra flag for ways that are part of a route relation.


Bye
Frederik

--
Frederik Ramm  ##  eMail frede...@remote.org  ##  N49°00'09 E008°23'33

___
talk mailing list
talk@openstreetmap.org
http://lists.openstreetmap.org/listinfo/talk