You are not logged in.
- Topics: Active | Unanswered
Announcement
Please create new topics on the new site at community.openstreetmap.org. We expect the migration of data will take a few weeks, you can follow its progress here.***
#1 2013-05-03 20:46:57
- cziehr
- Member
- Registered: 2013-04-04
- Posts: 241
Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Hallo,
wie ich ja in letzter Zeit schon geschrieben habe bin ich gerade dabei eine spezielle Hydrantenkarte für eine Feuerwehr zu erstellen. Ich habe dafür Mapnik2 auf einem Ubuntu-Server laufen.
Ich habe die OpenFireMap-Quellen erhalten und angefangen den Kartenstil etwas zu modifizieren bzw. zu erweitern (in Zoomstufe 18 soll außerdem der Druck und die Durchflussrate angegeben werden), aber irgendwie funktioniert es nicht so wirklich. Hier ein Auszug des Inhalts meiner osm.xml:
[...]
<Style name="hydrants">
[...]
<Rule>
&maxscale_zoom18;
&minscale_zoom18;
<Filter>[fh_t] = 'underground'</Filter>
<PointSymbolizer file="&symbols;/hydrant_u_17.png" allow-overlap="true"/>
<TextSymbolizer allow-overlap="true" fontset-name="bold-fonts" size="9" fill="#ff0000" dy="9" halo-radius="1" wrap-width="0">H[fh_d] \n [fh_p] bar \n [fh_f]</TextSymbolizer>
</Rule>
</Style>
<Layer name="hydrants" status="on" srs="&osm2pgsql_projection;">
<StyleName>hydrants</StyleName>
<Datasource>
<Parameter name="table">
(select way,name,emergency,amenity,ref,
coalesce("fire_hydrant:type",'_') as fh_t,replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') as fh_d,
"fire_hydrant:pressure" as fh_p,
case when "fire_hydrant:flow_capacity" similar to '[[:digit:]]+' then
round(cast("fire_hydrant:flow_capacity" as numeric)*60) || ' l/min' else null end as fh_f
from &prefix;_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants
</Parameter>
&datasource-settings;
</Datasource>
</Layer>
[...]Das \n erzeugt laut Dokumentation einen Zeilenumbruch (wie auch in "richtigen" Programmiersprachen). Ich habe es auch schon ohne probiert, aber auch da funktioniert es nicht.
Wenn ich renderd mit der Option -f starte bekomme ich folgenden Fehler ausgegeben:
renderd[29494]: An error occurred while loading the map layer 'default': Failed to parse expression: "H[fh_d]" in TextSymbolizer in style 'hydrants' in map '/etc/mapnik-osm-data/osm.xml'Anscheinend kann ich also bei <TextSymbolizer> nur eine Variable angeben, z.B. [fh_d] (so war es auch in der ursprünglichen OpenFireMap-Datei).
Kann mir jemand einen Tipp geben wo ich ansetzen muss damit ich die Sache zum Laufen kriege?
Vielen Dank schonmal,
Christoph
Offline
#2 2013-05-03 20:57:41
- wambacher
- Member

- From: Schlangenbad/Wambach, Germany
- Registered: 2009-12-16
- Posts: 16,769
- Website
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
glaube schon: formuliere deine Abfrage etwa so:
(select way,
name,
emergency,
amenity,
ref,
'H' || coalesce("fire_hydrant:type",'_') || '\n' ||
replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') ||
"fire_hydrant:pressure" ||
case
when "fire_hydrant:flow_capacity" similar to '[[:digit:]]+' then
round(cast("fire_hydrant:flow_capacity" as numeric)*60) || ' l/min'
else
null
end as fh_full
from &prefix;_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants;
<TextSymbolizer allow-overlap="true"
fontset-name="bold-fonts"
size="9"
fill="#ff0000"
dy="9"
halo-radius="1"
wrap-width="0">
[fh_full]
</TextSymbolizer>Knackpunt ist, dass Postgresql EIN Feld fh_full zurückgibt, das dann im textsymbolizer verwendet wird.
es könnten noch 1-2 tippfehler drin sein, aber das Prinzip sollte klar sein.
Gruss
walter
Last edited by wambacher (2013-05-03 21:35:32)
Offline
#3 2013-05-05 16:47:17
- cziehr
- Member
- Registered: 2013-04-04
- Posts: 241
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Hallo Walter,
vielen Dank schonmal für deine Arbeit!
Allerdings hab ich jetzt noch das Problem, dass [fh_t] dafür benutzt wurde zu unterscheiden welche Grafik für den jeweiligen Hydranten angezeigt wird (Unterscheidung in der Bauform unterirdisch <-> oberirdisch). Ich dachte dann dass ich einfach beide Stile drinlasse, denn ich wollte in Zoomstufe 17 nur die Bauart und den Durchmesser und in Zoomstufe 18 komplett alles anzeigen lassen. Mein Lösungsansatz
<Rule>
&maxscale_zoom17;
&minscale_zoom17;
<Filter>[fh_t] = 'underground'</Filter>
<PointSymbolizer file="&symbols;/hydrant_u_17.png" allow-overlap="true"/>
<TextSymbolizer allow-overlap="true" fontset-name="bold-fonts" size="9" fill="#ff0000" dy="9" halo-radius="1" wrap-width="0">[fh_d]</TextSymbolizer>
</Rule>
<Rule>
&maxscale_zoom18;
&minscale_zoom18;
<Filter>[fh_t] = 'underground'</Filter>
<PointSymbolizer file="&symbols;/hydrant_u_17.png" allow-overlap="true"/>
<TextSymbolizer allow-overlap="true" fontset-name="bold-fonts" size="9" fill="#ff0000" dy="9" halo-radius="1" wrap-width="0">[fh_full]</TextSymbolizer>
</Rule>
<Layer name="hydrants_17" status="on" srs="&osm2pgsql_projection;">
<StyleName>hydrants</StyleName>
<Datasource>
<Parameter name="table">
(select way,name,emergency,amenity,ref,
coalesce("fire_hydrant:type",'_') as fh_t,replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') as fh_d
from &prefix;_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants
</Parameter>
&datasource-settings;
</Datasource>
</Layer>
<Layer name="hydrants_18" status="on" srs="&osm2pgsql_projection;">
<StyleName>hydrants</StyleName>
<Datasource>
<Parameter name="table">
(select way,
name,
emergency,
amenity,
ref,
'H' || coalesce("fire_hydrant:type",'_') || '\n' ||
replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') ||
"fire_hydrant:pressure" ||
case
when "fire_hydrant:flow_capacity" similar to '[[:digit:]]+' then
round(cast("fire_hydrant:flow_capacity" as numeric)*60) || ' l/min'
else
null
end as fh_full
from &prefix;_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants
</Parameter>
&datasource-settings;
</Datasource>
</Layer>(es sind noch weitere Regeln vorhanden die eigentlich alle gleich aufgebaut sind, die habe ich aber aufgrund der Übersichtlichkeit ausgeblendet)
hat dann aber irgendie nicht funktioniert - ich bekomme beim Aufruf von renderd die Fehlermeldung
ERROR: column "fh_d" does not exist
LINE 1: SELECT AsBinary("way") AS geom,"fh_d","fh_t" from
^
Full sql was: 'SELECT AsBinary("way") AS geom,"fh_d","fh_t" from
(select way,
name,
emergency,
amenity,
ref,
'H' || coalesce("fire_hydrant:type",'_') || '\n' ||
replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') ||
"fire_hydrant:pressure" ||
case
when "fire_hydrant:flow_capacity" similar to '[[:digit:]]+' then
round(cast("fire_hydrant:flow_capacity" as numeric)*60) || ' l/min'
else
null
end as fh_full
from planet_osm_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants
WHERE "way" && SetSRID('BOX3D(890185.6314091616 6364299.849080344,892937.36442743 6367051.582098612)'::box3d, 900913)'Weist du hier vielleicht auch noch einen Rat?
Viele Grüße und nochmal Danke!
Christoph
Last edited by cziehr (2013-05-05 16:49:37)
Offline
#4 2013-05-05 18:09:45
- wambacher
- Member

- From: Schlangenbad/Wambach, Germany
- Registered: 2009-12-16
- Posts: 16,769
- Website
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Weist du hier vielleicht auch noch einen Rat?
Full sql was: 'SELECT AsBinary("way") AS geom,"fh_d","fh_t" from
(select way,
name,
emergency,
amenity,
ref,
abc as fh_d, <------------------- hier
xyz as fh_t, <------------------- erweitern
'H' || coalesce("fire_hydrant:type",'_') || '\n' ||
replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') ||
"fire_hydrant:pressure" ||
case
when "fire_hydrant:flow_capacity" similar to '[[:digit:]]+' then
round(cast("fire_hydrant:flow_capacity" as numeric)*60) || ' l/min'
else
null
end as fh_full
from planet_osm_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants
WHERE "way" && SetSRID('BOX3D(890185.6314091616 6364299.849080344,892937.36442743 6367051.582098612)'::box3d, 900913)'jo, etwas unhübsch, aber: hole dir fh_d,fh_t und fh_full von der db ab. abc und xyz natürlich ähnlich wie bei fh_full anpassen.
irgendwie doppelt gemoppelt aber was besseres fällt mir auf die schnelle auch nicht ein.
Last edited by wambacher (2013-05-05 18:10:47)
Offline
#5 2013-05-05 19:11:44
- cziehr
- Member
- Registered: 2013-04-04
- Posts: 241
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Danke für die Antwort. Ich hab noch ein bisschen umgebaut, und jetzt ist es (fast) perfekt:
<Layer name="hydrants" status="on" srs="&osm2pgsql_projection;">
<StyleName>hydrants</StyleName>
<Datasource>
<Parameter name="table">
(select way,
name,
emergency,
amenity,
ref,
"fire_hydrant:type" as fh_t,
'H' || replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') as fh_d,
'H' || replace(replace("fire_hydrant:diameter",'fixme',' '),'FIXME',' ') || ' ' ||
floor(cast("fire_hydrant:pressure" as numeric)*10)*0.1 || ' bar' || ' ' ||
floor(cast("fire_hydrant:flow_capacity" as numeric)*60*0.01)*100 || ' l/min'
as fh_full
from &prefix;_point
where ( emergency='fire_hydrant' or amenity='fire_hydrant' )
) as hydrants
</Parameter>
&datasource-settings;
</Datasource>
</Layer>als Karte sieht es dann so aus:
http://ffebg.no-ip.org:911/osm/slippyma … layers=0B0 (rechts oben den Layer "FF Ebg externer Zugriff" wählen, hab nur die Daten für unseren Landkreis und noch etwas Gebiet drumrum auf dem Server da dieser schon etwas älter ist. Also nicht wundern wenn der eigene Ort nicht auf der Karte erscheint)
Vielen Dank nochmal an wambacher für die schnelle und kompetente Hilfe!
Zum "(fast) perfekt": Gibt es eine Möglichkeit einer if-else-abfrage? In den ersten Posts hatte ich ja noch einer "when "fire_hydrant:flow_capacity" similar to '[[:digit:]]+' then"-Abfrage drin, aber die funktioniert irgendwie nicht... Ich will einfach nur prüfen ob z.B. der Druck des Hydranten angegeben ist und wenn nicht dann diesen nicht verwenden. Ansonsten wird nämlich nur das Symbol gezeichnet, aber Der Leitungsdurchmesser und die Durchflussrate werden nicht angezeigt, auch wenn diese vorhanden sind und halt nur der Druck nicht.
Viele Grüße,
Christoph
Last edited by cziehr (2013-05-05 19:18:32)
Offline
#6 2013-05-05 20:06:39
- wambacher
- Member

- From: Schlangenbad/Wambach, Germany
- Registered: 2009-12-16
- Posts: 16,769
- Website
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Zum "(fast) perfekt": Gibt es eine Möglichkeit einer if-else-abfrage?
wenn es um Mapnik geht, muß ich passen. ich "spreche" nur Sql ![]()
in sql gibt es kein if sondern das wird alles mit case erledigt - aber das ist jetzt wohl nicht dein Problem.
Gruss
walter
Offline
#7 2013-05-05 20:09:53
- cziehr
- Member
- Registered: 2013-04-04
- Posts: 241
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Zeiter Satz aus deinem Link:
The SQL CASE expression is a generic conditional expression, similar to if/else statements in other programming languages
Ok, damit wäre das geklärt. Dann muss ich mit CASE experimentieren. Das wird aber gegenüber der vorherigen Probleme die leichteste Übung sein.
Danke nochmal!
Offline
#8 2013-05-05 20:16:10
- wambacher
- Member

- From: Schlangenbad/Wambach, Germany
- Registered: 2009-12-16
- Posts: 16,769
- Website
Re: Mapnik: Erzeugen von kombinierter Beschriftung aus mehreren Feldern
Danke nochmal!
Keine Ursache.
Wie sagten wir früher: "Danksagungen bitte in schriftlicher Form an unseren Chef - Fehlermeldungen und Beschwerden bitte in mündlicher Form an unseren Hausmeister" ![]()
Offline