Darstellung der Straßennamen im extra Layer

Aus kvwmap
Wechseln zu: Navigation, Suche

--Boldt 16:48, 13. Mär 2006 (CET)

Wir hatten das Problem der Abfrage in data für den layer Straßennamen, wenn die Namen und die Geometrie aus den Tabellen alkobj_t_pkt und alkobj_t_line herausgenommen werden sollen. Hilfe erhielten wir von Markus und Herrn Korduan, wobei wir hier die Information von Herrn Korduan mal an Allle weitergeben möchten. Herr Korduan hat ein SQL-Statement geschrieben, welches ermöglicht, in einen Layer die Straßennamen aus zwei unterschiedlichen Geometrietabellen (Punkt und Linie) darzustellen.

Prinzipiell kann MapServer in einem Layer nur eine Art von Geometrie anzeigen. Aber Dank PostGIS können wir da was machen. Hier ein Statement, mit dem aus der Punktgeometrie eine Liniengeometrie gemacht wird. Das Statement haben wir in Data zu unserem layer Straßenname geschrieben. Es entstehen Linien der Länge 10m mit der Richtung von winkel.

the_geom FROM
(SELECT t.objnr AS oid,t.label AS label,t.winkel AS winkel,
        t.objart AS objart,t.folie AS alkfolie,
        MakeLine (t.the_geom,SetSRID(MakePoint(X(t.the_geom)+(cos(t.winkel*PI()/180)*10),
                                               Y(t.the_geom)+(sin(t.winkel*PI()/180)*10)),2398))
        AS the_geom 
 FROM alkobj_t_pkt AS t
 WHERE t.objart >= 5100 and t.objart <= 5299 AND t.folie = '022'
 UNION SELECT l.objnr AS oid,l.label AS label,
              '0' AS winkel,l.objart AS objart,l.folie AS alkfolie,
              l.the_geom AS the_geom FROM alkobj_t_lin AS l 
 WHERE l.objart >= 5100 and l.objart <= 5299 AND l.folie = '022')
 as foo using unique oid using srid=2398

Wobei man das ganze Where auch weglassen kann und in class packen kann. Je nach dem ob man die Beschriftung der Gebäude und Strassen in einem Layer anzeigen will oder verschiedenen. Das Weglassen der Where Klausel kann aber den Bildaufbau wesentlich verzögern, weil die Abfrage länger dauert.

Zum Ausrichten der Texte muss man nun nicht mehr lableangleitem = winkel verwenden, sondern in der Tabelle labels: angle=AUTO und autoangle=1 einstellen. Das bewirkt die Ausrichtung des Textes an der Linie. Der Layer muss dann auch vom Type Line sein also in tabelle Layer Datentype=1. Passen Sie auch den Style des Layers neu an.

Die Class Expression für den layer Straßenname lautet:

('[objart]' >= '5100' AND '[objart]' <= '5299' AND '[alkfolie]' eq '022')

Bei uns funktioniert das jetzt wunderbar.

--Heinz Schmidt 07:26, 10. Jul 2006 (CEST)
Eine andere Möglichkeit besteht darin in pgAdmin III eine Sicht strassennamen anzulegen und diese als Layer einzubinden. Hierzu in pgAdmin folgendes Statement ausführen:

CREATE OR REPLACE VIEW strassennamen 
AS SELECT t.objnr AS oid, t.objnr AS id, t.label, t.winkel, t.objart, t.folie AS alkfolie, 
          makeline(t.the_geom, setsrid(makepoint(x(t.the_geom) + cos(t.winkel * pi() / 180) * 10,
                                       y(t.the_geom) + sin(t.winkel * pi() / 180) * 10), 2398)) 
AS the_geom FROM alkobj_t_pkt t
WHERE t.objart >= 5100 AND t.objart <= 5299 AND t.folie::text = '022'::text
UNION SELECT l.objnr AS oid, l.objnr AS id, ::text || l.label::text AS label, '0' AS winkel, 
l.objart, l.folie AS alkfolie, l.the_geom
FROM alkobj_t_lin l
WHERE l.objart >= 5100 AND l.objart <= 5299 AND l.folie::text = '022'::text;
ALTER TABLE strassennamen OWNER TO kvwmap;

Im Feld data der Layertabelle steht dann nur:

the_geom from strassennamen as foo using unique oid using srid=2398

Diese Methode hat bei mir gleich geklappt, im Gegensatz zum oben beschriebenen Verfahren.
Vielen Dank an Hendrik Reissland für den Tip :-)


--HolgerR 09:42, 16. Aug 2006 (CEST) Statt der oben beschriebenen Verfahrensweise, die Punkte aus der Tabelle 'alkobj_t_pkt' in Linien zu transformieren, gibt es die umgekehrte Variante, mittels Postgisfunktionen aus den Linien der Tabelle 'alkobj_t_lin' die Richtung zu bestimmen und einen Punkt zu erzeugen, an dem der Text dann platziert wird. Das ganze sieht dann wie folgt aus:

SELECT objnr, folie, objart, artinfo, objkartyp, label, 
  90-degrees(azimuth(startpoint(the_geom),endpoint(the_geom))) AS winkel, 
  line_interpolate_point(the_geom,0.5) AS the_geom 
FROM alkobj_t_lin 
WHERE folie = '022' AND objart BETWEEN 5000 AND 5299
UNION SELECT DISTINCT ON (label, winkel) objnr, folie, objart, artinfo, objkartyp, 
                                         label, winkel, the_geom 
FROM alkobj_t_pkt 
WHERE folie = '022' AND objart BETWEEN 5000 AND 5299

Mit azimuth(startpoint(the_geom),endpoint(the_geom) wird der Winkel aus der Linie zw. Anfangspunkt und Endpunkt in Radiant berechnet.

Die Funktion degree() wandelt den Winkel in Grad um (PostgreSQL-Funktion). Das Ganze muss von 90° subtrahiert werden, damit die Richtung stimmt.

Mit der Funktion line_interpolate_point(the_geom,0.5) wird von der Linie ein Punkt interpoliert, der in diesem Fall auf der Hälfte der Länge dieser Linie liegt.

Da bei mir momentan die Übergabe der Winkel über phpMapscript aus den MySQL-Tabellen nicht funktioniert, ist die Anzeige der Straßennamen über ein WMS ins kvwmap eingebunden.