[Talk-de] [patch] Breite von Flüssen :)

Sven Geggus lists at fuchsschwanzdomain.de
Sa Jul 5 17:56:18 UTC 2008


Hallo zusammen,

so, jetzt kann ich endlich teilweise das anbieten, was ich eigentlich
schon länger haben wollte aber bisher mangels xslt Kenntnisse nicht
realisieren konnte.

Prinzipiell bin ich zwar auch kein Perl Hacker sondern meine
Scriptsprachen sind eher Python und Tcl, aber trotzdem liegt
mir die prozedurale Welt wohl doch besser als xslt.

Langer Rede kurzer Sinn! Ich hab trotzdem für orp einen patch gebaut,
der die Breite von Flüssen berücksichtig, wenn ein with=X Tag an den
Weg angehängt ist. X ist die Breite des Flusses in Meter.

Weiterhin kann man folgende Tags im Header der jeweiligen
osm-map-features-z17.xml angeben:

minLineWidth="1"
maxLineWidth="100"
honorWidth="waterway-river-core waterway-river-casing"
meter2px="0.1375"

Diese Werte sind die defaults, die auch verwendet werden, falls in
der Styledatei nichts angegeben wurde.

minLineWidth und maxLineWidth sind die min/max Werte für die Breite
in Meter. meter2px ist der Skalierungsfaktor über den die angegebenen
Werte von Metern in px umgerechnet werden. honorWidth sind die
Klassen aus der Map-Features Datei, bei denen ein width Tag angewandt
wird. 

Ich möchte das ganze jedoch erst ins svn einchecken wenn es jemand
ausprobiert und für funktioniell befunden hat.

Meine Flüsse hier in der Gegend muss ich auch erst noch messen gehn :)

Den patch findet ihr unten oder unter
http://home.geggus.net/osm/orp-river-width.diff

Gruss

Sven

P.S.: Falls das jemand in die xslt Variante von osmarender einbauen
möchte, nur zu!

--schnipp--
--- orp-drawing.pm	(Revision 8751)
+++ orp-drawing.pm	(Arbeitskopie)
@@ -78,15 +78,57 @@
 {
     my ($linenode, $layer, $way, $class) = @_;
 
+    # explicit way specific style
+    my $style="";
+
     # convenience variables
     my $id = $way->{"id"};
     my $nodes = $way->{"nodes"};
 
     return unless(scalar(@$nodes));
 
+    # this is a special hack for rivers we honor a with=something tag in
+    # this case to generate rivers of different width.
+    # This is done by an explizit specification of a
+    # style="stroke-width:..px" tag in the generated SVG output
+
+    if (defined($way->{"tags"}->{"width"})) {
+
+      # get all classes where width should be honored
+      my @honorWidth=split(/ /, get_variable("honorWidth","waterway-river-core waterway-river-casing"));
+      
+      # check if the list of honored classes contains the current class
+      my %cClass=map{ $_ => 1 } split(/ /,$class);
+
+      my $cname="";
+      foreach my $c (@honorWidth){
+	if($cClass{$c}) {
+	  $cname=$c;
+	  last;
+	}
+      }
+      if ($cname ne "") {
+	my $width = $way->{"tags"}->{"width"};
+	$width =~ s/m$//;
+	my $f = get_variable("meter2px","0.1375");
+	my $w;
+	# make shure, that width is a numeric value
+	{ no warnings; $w = $f*$width if 0+$width;}
+
+	if (defined($w)) {
+	  # make shure that width is inside the desired range
+	  my $maxw = $f*get_variable("maxLineWidth","100");
+	  my $minw = $f*get_variable("minLineWidth","1");
+	  if ($w > $maxw) {$w = $maxw;}
+	  if ($w < $minw) {$w = $minw;}
+	  $style = "stroke-width:${w}px";
+	}
+      }
+    }
+
     # first draw middle segment if we have more than 2 nodes
     draw_path($linenode, "way_mid_$id", 
-        "osmarender-stroke-linecap-butt osmarender-no-marker-start osmarender-no-marker-end") 
+        "osmarender-stroke-linecap-butt osmarender-no-marker-start osmarender-no-marker-end", $style) 
         if (scalar(@$nodes)>2);
 
     # count connectors on first and last node
@@ -116,32 +158,32 @@
 
     if ($first_node_connection_count == 1)
     {
-        draw_path($linenode, "way_start_$id", "osmarender-no-marker-end");
+        draw_path($linenode, "way_start_$id", "osmarender-no-marker-end", $style);
     } 
     elsif ($first_node_lower_layer_connection_count > 0)
     {
         draw_path($linenode, "way_start_$id", 
-            "osmarender-stroke-linecap-butt osmarender-no-marker-end");
+            "osmarender-stroke-linecap-butt osmarender-no-marker-end", $style);
     }
     else
     {
         draw_path($linenode, "way_start_$id",
-            "osmarender-stroke-linecap-round osmarender-no-marker-end");
+            "osmarender-stroke-linecap-round osmarender-no-marker-end", $style);
     }
 
     if ($last_node_connection_count == 1)
     {
-        draw_path($linenode, "way_end_$id", "osmarender-no-marker-start");
+        draw_path($linenode, "way_end_$id", "osmarender-no-marker-start", $style);
     } 
     elsif ($last_node_lower_layer_connection_count > 0)
     {
         draw_path($linenode, "way_end_$id", 
-            "osmarender-stroke-linecap-butt osmarender-no-marker-start");
+            "osmarender-stroke-linecap-butt osmarender-no-marker-start", $style);
     }
     else
     {
         draw_path($linenode, "way_end_$id", 
-            "osmarender-stroke-linecap-round osmarender-no-marker-start");
+            "osmarender-stroke-linecap-round osmarender-no-marker-start", $style);
     }
 }
 
@@ -719,17 +761,18 @@
 }
 
 # -------------------------------------------------------------------
-# sub draw_path($rulenode, $path_id, $class)
+# sub draw_path($rulenode, $path_id, $class, $style)
 #
 # draws an SVG path with the given path reference and style.
 # -------------------------------------------------------------------
 sub draw_path
 {
-    my ($rulenode, $path_id, $addclass) = @_;
+    my ($rulenode, $path_id, $addclass, $style) = @_;
 
     my $mask_class = $rulenode->getAttribute("mask-class");
     my $class = $rulenode->getAttribute("class");
     my $extra_attr = [];
+
     if ($mask_class ne "")
     {
         my $mask_id = "mask_".$path_id;
@@ -752,11 +795,17 @@
         $writer->endTag("mask");
         $extra_attr = [ "mask" => "url(#".$mask_id.")" ];
     }
-
-    $writer->emptyTag("use", 
-        "xlink:href" => "#$path_id",
-        @$extra_attr,
-        "class" => defined($addclass) ? "$class $addclass" : $class);
+    if (defined($style) and $style ne "") {
+      $writer->emptyTag("use", 
+			"xlink:href" => "#$path_id", "style" => "$style",
+			@$extra_attr,
+			"class" => defined($addclass) ? "$class $addclass" : $class);
+    } else {
+      $writer->emptyTag("use", 
+			"xlink:href" => "#$path_id",
+			@$extra_attr,
+			"class" => defined($addclass) ? "$class $addclass" : $class);
+    }
 }
--schnapp--

-- 
"Software is like sex; it's better when it's free"
	                              (Linus Torvalds)

/me is giggls at ircnet, http://sven.gegg.us/ on the Web




Mehr Informationen über die Mailingliste Talk-de