[Talk-de] osmosis schema mit mapnik nutzen Was: Import von Planet.osm?
Florian Lohoff
flo at rfc822.org
Di Dez 15 17:24:09 UTC 2009
On Tue, Dec 15, 2009 at 03:49:52PM +0100, Sarah Hoffmann wrote:
> > Hier ein Beispiel:
> >
> > drop view powerlineview;
> > create view powerlineview AS
> > SELECT ways.id,
> > voltage.v as voltage,
> > ways.linestring as geom
> > from ways left outer join (
> > select way_id,v from way_tags
> > where k='voltage') voltage on ( ways.id = voltage.way_id ),
> > way_tags wt
> > where wt.k = 'power'
> > and wt.v = 'line'
> > and wt.way_id = ways.id;
>
> Diese Anfrage stellst du aber nicht auf einer Datenbank, die den kompletten
> Planeten enthält, oder? Wenn ich den SELECT-Teil auf meinem
> (zugegebenermassen etwas schwachbrüstigen) Rechner laufen lasse, braucht
> die Anfrage knapp 15 Minuten. (Das ist natürlich immernoch wesentlich
> günstiger als ein 8-Stunden-osm2psql-Tagesupdate, weswegen ich gerade
> in diese Richtung experimentiere.)
Ich habe nen bischen mehr indexe als das standard osmosis schema - IIRC
sieht osmosis auf way_tags keinen index ausser auf way_id vor - ich habe
da noch nen index auf "k"
osm=> \d way_tags
Table "public.way_tags"
Column | Type | Modifiers
--------+--------+-----------
way_id | bigint | not null
k | text | not null
v | text |
Indexes:
"idx_way_tag_k" btree (k)
"idx_way_tags_way_id" btree (way_id)
Ausserdem natuerlich entsprechend indexe auf den ways.linestring - somit
durchsuche ich sowieso nur entsprechend die NRW linestrings.
Wenn man da nur ein "bischen" mit den indexen schludert kommt da schnell
mal ein full table scan bei raus und dann brauchen wir auch mal 15 minuten:
osm=> explain SELECT ways.id,
voltage.v as voltage,
ways.linestring as geom
from ways left outer join (
select way_id,v from way_tags
where k='voltage') voltage on ( ways.id = voltage.way_id ),
way_tags wt
where wt.k = 'power'
and wt.v = 'line'
and wt.way_id = ways.id and inborder(ways.linestring, 62761);
QUERY PLAN
----------------------------------------------------------------------------------------------
Nested Loop Left Join (cost=924.00..92653.20 rows=7 width=807)
-> Nested Loop (cost=924.00..90614.49 rows=7 width=797)
-> Bitmap Heap Scan on way_tags wt (cost=924.00..90385.79 rows=22 width=8)
Recheck Cond: (k = 'power'::text)
Filter: (v = 'line'::text)
-> Bitmap Index Scan on idx_way_tag_k (cost=0.00..924.00 rows=42267 width=0)
Index Cond: (k = 'power'::text)
-> Index Scan using pk_ways on ways (cost=0.00..10.38 rows=1 width=797)
Index Cond: (ways.id = wt.way_id)
Filter: inborder(ways.linestring, 62761)
-> Index Scan using idx_way_tags_way_id on way_tags (cost=0.00..291.23 rows=1 width=18)
Index Cond: (ways.id = way_tags.way_id)
Filter: (way_tags.k = 'voltage'::text)
Und das inborder dingelchen ist sowas:
osm=> \df+ inborder
List of functions
Schema | Name | Result data type | Argument data types | Volatility | Owner | Language | Source code | Description
--------+----------+------------------+---------------------+------------+-------+----------+----------------------------------------------------------------------------------------------+-------------
public | inborder | boolean | geometry, integer | immutable | flo | sql | SELECT _ST_Intersects($1,(select border from completeborders where completeborders.id = $2)) |
completeborders wiederum enthaelt vorher praeparierte multipolygon geometrien fuer die entsprechenden
relations die ich so zusammenbaue:
osm=> \d completeborders
Table "public.completeborders"
Column | Type | Modifiers
------------+-------------------+-----------
id | bigint |
name | character varying |
complete | integer |
adminlevel | integer |
border | geometry |
path | character varying |
Check constraints:
"enforce_dims_border" CHECK (ndims(border) = 2)
"enforce_srid_border" CHECK (srid(border) = 4326)
insert into completeborders ( id, adminlevel, name, border )
select border.id,
border.adminlevel::integer,
border.name,
ST_BuildArea(ST_Collect(linestring)) as geom
from (
select rm.id, rm.adminlevel, rm.name, w.linestring
from ways w, (
select rm.relation_id as id,
rm.member_id as wayid,
rt1.v as adminlevel,
rt2.v as name
from relation_members rm,
relation_tags rt1,
relation_tags rt2
where rm.member_type = 'W'
and rm.relation_id in ( 62761, 62771, 62607, 73347 )
and rm.relation_id = rt1.relation_id
and rm.relation_id = rt2.relation_id
and rt1.k = 'admin_level'
and rt2.k = 'name'
order by id
) rm
where w.id = rm.wayid
and ST_NumPoints(w.linestring)>1
) as border
group by border.id, border.adminlevel, border.name;
osm=> select id,name,complete,adminlevel,path from completeborders where id = 62761;
id | name | complete | adminlevel | path
-------+---------------------+----------+------------+------
62761 | Nordrhein-Westfalen | | 4 |
Das mit dem "inborder" als funktion habe ich nur deshalb gemacht weil mapnik zu bloede ist
sauber joins auseinanderzuhalten - d.h. mapnik geht sofort baden wenn im query mehr als
eine geometry column auftaucht - Das kann man via function relativ gut verstecken ...
Flo
--
Florian Lohoff flo at rfc822.org
"Es ist ein grobes Missverständnis und eine Fehlwahrnehmung, dem Staat
im Internet Zensur- und Überwachungsabsichten zu unterstellen."
- - Bundesminister Dr. Wolfgang Schäuble -- 10. Juli in Berlin
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : signature.asc
Dateityp : application/pgp-signature
Dateigröße : 189 bytes
Beschreibung: Digital signature
URL : <http://lists.openstreetmap.org/pipermail/talk-de/attachments/20091215/5c47f604/attachment.sig>
Mehr Informationen über die Mailingliste Talk-de