From e044730af3cbe276d3c2dce40bd2170c8b822f44 Mon Sep 17 00:00:00 2001 From: Michael 'PoempelFox' Meier Date: Thu, 6 Aug 2015 14:45:29 +0200 Subject: [PATCH] redo my quick weekend hack with perls JSON module. --- scripts/osmbuildings-json-generator.pl | 118 +++++++++++-------------- 1 file changed, 51 insertions(+), 67 deletions(-) diff --git a/scripts/osmbuildings-json-generator.pl b/scripts/osmbuildings-json-generator.pl index 6970699..5cd216f 100755 --- a/scripts/osmbuildings-json-generator.pl +++ b/scripts/osmbuildings-json-generator.pl @@ -52,19 +52,15 @@ sub fetchlastofhr($$@) { return $res; } -# Helper functions for the CGI variant. Taken from the openstreetmap-Wiki. +# Helper functions for the CGI variant. Taken from the openstreetmap-Wiki, +# which in turn is almost a direct copy of a GPL'd script included in (amongst +# others) the mapnik sourcecode. -> GPL code use Math::Trig; -sub Project { +sub Project($$$) { my ($X, $Y, $Zoom) = @_; my $Unit = 1 / (2 ** $Zoom); my $relY1 = $Y * $Unit; my $relY2 = $relY1 + $Unit; - - # note: $LimitY = ProjectF(degrees(atan(sinh(pi)))) = log(sinh(pi)+cosh(pi)) = pi - # note: degrees(atan(sinh(pi))) = 85.051128.. - #my $LimitY = ProjectF(85.0511); - - # so stay simple and more accurate my $LimitY = pi; my $RangeY = 2 * $LimitY; $relY1 = $LimitY - $RangeY * $relY1; @@ -75,17 +71,14 @@ sub Project { my $Long1 = -180 + $X * $Unit; return ($Lat2, $Long1, $Lat1, $Long1 + $Unit); # S,W,N,E } -sub ProjectMercToLat($){ - my $MercY = shift; - return rad2deg(atan(sinh($MercY))); +sub ProjectMercToLat($) { + return rad2deg(atan(sinh($_[0]))); } -sub ProjectF -{ - my $Lat = shift; - $Lat = deg2rad($Lat); - my $Y = log(tan($Lat) + sec($Lat)); - return $Y; +sub ProjectF($) { + $Lat = deg2rad($_[0]); + return (log(tan($Lat) + sec($Lat))); } +# ----- end of copied helper functions ----- # print that drops whitespace when not in verbose mode. sub printwows($) { @@ -148,6 +141,16 @@ $tx1 = $dbh->selectrow_array("select ST_X(ST_transform(ST_GeomFromText('POINT($x $ty1 = $dbh->selectrow_array("select ST_Y(ST_transform(ST_GeomFromText('POINT($x1 $y1)', 4326), 900913))"); $tx2 = $dbh->selectrow_array("select ST_X(ST_transform(ST_GeomFromText('POINT($x2 $y2)', 4326), 900913))"); $ty2 = $dbh->selectrow_array("select ST_Y(ST_transform(ST_GeomFromText('POINT($x2 $y2)', 4326), 900913))"); +# Why do crappy perl libraries always insist on using an "Object Oriented" interface +# for things where this does not make any sense at all? +my $crappyjsonoo = JSON->new()->latin1(); # Note: has to be latin1 instead of utf8 +# for now, because the strings we get from the DB are WTF8, but are not marked +# as such. Therefore, we must not tell the JSON module to do utf8(), because +# otherwise it would encode the WTF8 twice. +# This will change with DBI::Pg modules >3 where UTF8 is properly handled. +if ($verblev > 0) { + $crappyjsonoo = $crappyjsonoo->pretty(); +} my $cntr = 0; if ($iscgi == 0) { print("// Note: this file has been autogenerated by $0\n"); @@ -178,9 +181,9 @@ foreach $xtable ('planet_osm_polygon1', 'planet_osm_polygon2', 'planet_osm_line' while ($row = $sth->fetchrow_hashref()) { if ($xtable eq 'planet_osm_polygon1') { my $hassubparts = $dbh->selectrow_array("select count(*)" - . " from planet_osm_line" - . " where ((tags->'building:part') is not null)" - . " and (ST_Covers(" . $dbh->quote($row->{'way'}) . ", way) = true)"); + . " from planet_osm_line" + . " where ((tags->'building:part') is not null)" + . " and (ST_Covers(" . $dbh->quote($row->{'way'}) . ", way) = true)"); # The subparts usually cover the whole building, so we do NOT draw the # whole building but only the subparts. if ($hassubparts > 0) { next; } @@ -208,90 +211,71 @@ foreach $xtable ('planet_osm_polygon1', 'planet_osm_polygon2', 'planet_osm_line' 'roof:color', 'roof:colour', 'building:roof:color', 'building:roof:colour'); my $roofshape = fetchlastofhr(undef, $hstoredec, 'roof:shape', 'building:roof:shape'); my $roofheight = fetchlastofhr(undef, $hstoredec, 'roof:height', 'building:roof:height'); + unless ((defined($roofheight)) && ($roofheight =~ m/^[0-9.]+$/)) { + undef($roofheight); + } my $roofmaterial = fetchlastofhr(undef, $hstoredec, 'roof:material', 'building:roof:material'); if ($cntr != 0) { printwows(",\n"); } $cntr++; - printwows(" {\n"); - printwows(" \"type\": \"Feature\",\n"); - if (defined($row->{'osm_id'})) { - printwows(" \"id\": " . $row->{'osm_id'} . ",\n"); - } else { - printwows(" \"id\": $cntr,\n"); - } + my $jso = { "type" => "Feature" }; + $jso->{'id'} = (defined($row->{'osm_id'}) ? $row->{'osm_id'} : $cntr); if (defined($row->{'name'})) { - $row->{'name'} =~ s/"//g; - printwows(" \"name\": \"" . $row->{'name'} . "\",\n"); + $jso->{'name'} = $row->{'name'}; } - printwows(" \"geometry\": {\n"); - printwows(" \"type\": \"Polygon\",\n"); - printwows(" \"coordinates\": [[\n"); unless ($sth2->execute($row->{'way'})) { print(STDERR "Sorry, decoding the way data exploded.\n"); exit(1); } my ($onex, $oney); - my $firstcoord = 1; + my @geomarr1 = (); while (($onex, $oney) = $sth2->fetchrow_array()) { - if ($firstcoord == 1) { - $firstcoord = 0; - } else { - printwows(",\n"); - } - printwows(sprintf(" [ %.5f, %.5f ]", $onex, $oney)); + my @onecoord = ( sprintf("%.5f", $onex), sprintf("%.5f", $oney)); + push (@geomarr1, \@onecoord); } - printwows("\n"); - printwows(" ]]\n"); - printwows(" },\n"); - printwows(" \"properties\": {\n"); + my @geomarr2 = (\@geomarr1); + my $geomhsh = { "type" => "Polygon", + "coordinates" => \@geomarr2 }; + $jso->{'geometry'} = $geomhsh; + my $prophsh = { }; if (defined($height)) { - printwows(" \"height\": $height,\n"); + $prophsh->{'height'} = $height; } if (defined($minheight)) { - printwows(" \"minHeight\": $minheight,\n"); + $prophsh->{'minHeight'} = $minheight; } if (defined($levels)) { - printwows(" \"levels\": $levels,\n"); + $prophsh->{'levels'} = $levels; } if (defined($minlevel)) { - printwows(" \"minLevel\": $minlevel,\n"); + $prophsh->{'minLevel'} = $minlevel; } if (defined($shape)) { - $shape = JSON->new->allow_nonref->encode($shape); - printwows(" \"shape\": $shape,\n"); + $prophsh->{'shape'} = $shape; } if (defined($material)) { - $material = JSON->new->allow_nonref->encode($material); - printwows(" \"material\": $material,\n"); + $prophsh->{'material'} = $material; } if (defined($wallcolor)) { - $wallcolor = JSON->new->allow_nonref->encode($wallcolor); - printwows(" \"wallColor\": $wallcolor,\n"); + $prophsh->{'wallColor'} = $wallcolor; } if (defined($roofcolor)) { - $roofcolor = JSON->new->allow_nonref->encode($roofcolor); - printwows(" \"roofColor\": $roofcolor,\n"); + $prophsh->{'roofColor'} = $roofcolor; } if (defined($roofshape)) { if ($roofshape eq 'pyramidal') { $roofshape = 'pyramid'; } - $roofshape = JSON->new->allow_nonref->encode($roofshape); - printwows(" \"roofShape\": $roofshape,\n"); + $prophsh->{'roofShape'} = $roofshape; } if (defined($roofmaterial)) { - $roofmaterial = JSON->new->allow_nonref->encode($roofmaterial); - printwows(" \"roofMaterial\": $roofmaterial,\n"); + $prophsh->{'roofMaterial'} = $roofmaterial; } if (defined($roofheight)) { - $roofheight = sprintf("%.1f", $roofheight); - printwows(" \"roofHeight\": \"$roofheight\",\n"); + $prophsh->{'roofHeight'} = $roofheight; } - # this line is completely useless, but we need it to guarantee JSON has - # no trailing comma. osmbuildings will accept JSON with trailing commas - # just fine when you give it static, but NOT when requesting it dynamically. - printwows(" \"K9\": \"\"\n"); - printwows(" }\n"); - printwows(" }"); + $jso->{'properties'} = $prophsh; + # Now dump it all. + print($crappyjsonoo->encode($jso)); } $sth2->finish(); undef($sth2); -- 2.25.1