| 1 | #!/usr/bin/perl -w |
| 2 | |
| 3 | # Our database |
| 4 | $dbname = 'osm'; |
| 5 | |
| 6 | # Default verbosity level? Can be increased with -v, decreased with -q |
| 7 | $verblev = 0; |
| 8 | |
| 9 | # The area which we cover |
| 10 | $x1 = 11.01; |
| 11 | $y1 = 49.56; |
| 12 | $x2 = 11.04; |
| 13 | $y2 = 49.58; |
| 14 | |
| 15 | # There should be no need to touch anything below this line. |
| 16 | # --------------------------------------------------------------------------- |
| 17 | |
| 18 | use DBI; |
| 19 | use POSIX qw(strftime mktime); |
| 20 | use Pg::hstore; |
| 21 | |
| 22 | # Par. 0: Level on which this gets printed |
| 23 | # Par. 1: Text |
| 24 | sub printlev($$) { |
| 25 | unless (defined($printlev_atbeginofline)) { $printlev_atbeginofline = 1; } |
| 26 | if ($verblev >= $_[0]) { |
| 27 | if ($printlev_atbeginofline) { |
| 28 | print(strftime("[%Y%m%d-%H%M%S] ", localtime(time()))); |
| 29 | } |
| 30 | print($_[1]); |
| 31 | if ($_[1] =~ m/\n$/) { |
| 32 | $printlev_atbeginofline = 1; |
| 33 | } else { |
| 34 | $printlev_atbeginofline = 0; |
| 35 | } |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | # Par. 0: default value to return if nothing is defined |
| 40 | # Par. 1: the hashref containing our variables. |
| 41 | # Par. 2: variables to query. The LAST one that exists will be returned. |
| 42 | sub fetchlastofhr($$@) { |
| 43 | my $res; my $hr; my @vns; |
| 44 | ($res, $hr, @vns) = @_; |
| 45 | for (my $i = 0; $i < @vns; $i++) { |
| 46 | my $vn = $vns[$i]; |
| 47 | if (defined($hr->{$vn})) { |
| 48 | $res = $hr->{$vn}; |
| 49 | } |
| 50 | } |
| 51 | return $res; |
| 52 | } |
| 53 | |
| 54 | # ---------------------------------------------------------------------------- |
| 55 | # main() |
| 56 | # ---------------------------------------------------------------------------- |
| 57 | |
| 58 | # Parse commandline |
| 59 | foreach $a (@ARGV) { |
| 60 | if ($a eq '-q') { |
| 61 | $verblev--; |
| 62 | } elsif ($a eq '-v') { |
| 63 | $verblev++; |
| 64 | } else { |
| 65 | print("Unknown parameter: $a\n"); |
| 66 | print("Syntax: $0 [-q] [-v]\n"); |
| 67 | print(" -q decreases verbosity, -v increases verbosity.\n"); |
| 68 | exit(1); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | unless ($dbh = DBI->connect("dbi:Pg:dbname=$dbname","","")) { |
| 73 | print(STDERR "Failed to open database. Please try again later.\n"); exit(1); |
| 74 | } |
| 75 | |
| 76 | $tx1 = $dbh->selectrow_array("select ST_X(ST_transform(ST_GeomFromText('POINT($x1 $y1)', 4326), 900913))"); |
| 77 | $ty1 = $dbh->selectrow_array("select ST_Y(ST_transform(ST_GeomFromText('POINT($x1 $y1)', 4326), 900913))"); |
| 78 | $tx2 = $dbh->selectrow_array("select ST_X(ST_transform(ST_GeomFromText('POINT($x2 $y2)', 4326), 900913))"); |
| 79 | $ty2 = $dbh->selectrow_array("select ST_Y(ST_transform(ST_GeomFromText('POINT($x2 $y2)', 4326), 900913))"); |
| 80 | my $cntr = 0; |
| 81 | print("// Note: this file has been autogenerated by $0\n"); |
| 82 | print("var FAUGeoJSON = {\n"); |
| 83 | print(" \"type\": \"FeatureCollection\",\n"); |
| 84 | print(" \"features\": [\n"); |
| 85 | foreach $table ('planet_osm_line', 'planet_osm_polygon') { |
| 86 | my $sth = $dbh->prepare("select osm_id, way, building, 'tower:type', name, tags" |
| 87 | . " from $table where" |
| 88 | . " (building is not null or (tags->'building:part') is not null)" |
| 89 | . " and way && ST_MakeEnvelope($tx1, $ty1, $tx2, $ty2)"); |
| 90 | unless ($sth->execute()) { |
| 91 | print(STDERR "Sorry, database query exploded.!\n"); |
| 92 | exit(1); |
| 93 | } |
| 94 | my $sth2 = $dbh->prepare("select ST_X(points) as x, ST_Y(points) as y" |
| 95 | . " from (select ST_astext((ST_dumppoints(ST_transform(?, 4326))).geom) as points) as points"); |
| 96 | while ($row = $sth->fetchrow_hashref()) { |
| 97 | my $hstoredec; |
| 98 | if (defined($row->{'tags'})) { |
| 99 | $hstoredec = Pg::hstore::decode($row->{'tags'}); |
| 100 | } |
| 101 | my $height = fetchlastofhr(1, $hstoredec, 'levels', 'building:levels'); |
| 102 | $height = $height * 2.5; |
| 103 | $height = fetchlastofhr($height, $hstoredec, 'height', 'building:height'); |
| 104 | $height = sprintf("%.1f", $height); |
| 105 | my $minheight = fetchlastofhr(0, $hstoredec, 'min_levels', 'building:min_levels'); |
| 106 | $minheight = $minheight * 2.5; |
| 107 | $minheight = fetchlastofhr($minheight, $hstoredec, 'min_height', 'building:min_height'); |
| 108 | $minheight = sprintf("%.1f", $minheight); |
| 109 | my $wallcolor = fetchlastofhr(undef, $hstoredec, 'building:color', 'building:colour'); |
| 110 | my $roofcolor = fetchlastofhr(undef, $hstoredec, |
| 111 | 'roof:color', 'roof:colour', 'building:roof:color', 'building:roof:colour'); |
| 112 | my $roofshape = fetchlastofhr(undef, $hstoredec, 'roof:shape', 'building:roof:shape'); |
| 113 | my $roofheight = fetchlastofhr(undef, $hstoredec, 'roof:height', 'building:roof:height'); |
| 114 | $cntr++; |
| 115 | print(" {\n"); |
| 116 | print(" \"type\": \"Feature\",\n"); |
| 117 | print(" \"id\": $cntr,\n"); |
| 118 | print(" \"geometry\": {\n"); |
| 119 | print(" \"type\": \"Polygon\",\n"); |
| 120 | print(" \"coordinates\": [[\n"); |
| 121 | unless ($sth2->execute($row->{'way'})) { |
| 122 | print(STDERR "Sorry, decoding the way data exploded.\n"); |
| 123 | exit(1); |
| 124 | } |
| 125 | my ($onex, $oney); |
| 126 | while (($onex, $oney) = $sth2->fetchrow_array()) { |
| 127 | print(" [ $onex, $oney ],\n"); |
| 128 | } |
| 129 | print(" ]]\n"); |
| 130 | print(" },\n"); |
| 131 | print(" \"properties\": {\n"); |
| 132 | print(" \"height\": $height,\n"); |
| 133 | print(" \"min_height\": $minheight,\n"); |
| 134 | if (defined($wallcolor)) { |
| 135 | print(" \"wallColor\": \"$wallcolor\",\n"); |
| 136 | } |
| 137 | if (defined($roofcolor)) { |
| 138 | print(" \"roofColor\": \"$roofcolor\",\n"); |
| 139 | } |
| 140 | if (defined($roofshape)) { |
| 141 | print(" \"roofShape\": \"$roofshape\",\n"); |
| 142 | } |
| 143 | if (defined($roofheight)) { |
| 144 | $roofheight = sprintf("%.1f", $roofheight); |
| 145 | print(" \"roofHeight\": \"$roofheight\",\n"); |
| 146 | } |
| 147 | print(" }\n"); |
| 148 | print(" },\n"); |
| 149 | } |
| 150 | $sth2->finish(); |
| 151 | undef($sth2); |
| 152 | $sth->finish(); |
| 153 | undef($sth); |
| 154 | } |
| 155 | print(" ]\n"); |
| 156 | print("};\n"); |