fix my double-escape-FAIL
[osmrrze.git] / scripts / osmbuildings-json-generator.pl
index 16ad1c373857b29fc74ec8a02b805d3a3e3812fb..6970699dcd23c09258168a243cf4f31d37414521 100755 (executable)
@@ -18,6 +18,7 @@ $y2 = 49.58;
 use DBI;
 use POSIX qw(strftime mktime);
 use Pg::hstore;
+use JSON;
 
 # Par. 0: Level on which this gets printed
 # Par. 1: Text
@@ -86,6 +87,18 @@ sub ProjectF
   return $Y;
 }
 
+# print that drops whitespace when not in verbose mode.
+sub printwows($) {
+  my $res = $_[0];
+  if ($verblev > 0) {
+    print($res); return;
+  }
+  $res =~ s/^\s+//g;
+  $res =~ s/"\s*:\s*/":/g;
+  $res =~ s/[\r\n]//g;
+  print($res);
+}
+
 # ----------------------------------------------------------------------------
 # main()
 # ----------------------------------------------------------------------------
@@ -110,7 +123,10 @@ foreach $a (@ARGV) {
 
 if (defined($ENV{'REQUEST_URI'})) {
   $iscgi = 1;
-  print("Content-type: application/json\n\n");
+  print("Content-type: application/json; charset=utf-8\n");
+  print("Access-Control-Allow-Origin: *\n");
+  print("Cache-Control: public, max-age=3600\n");
+  print("\n");
   unless ($ENV{'REQUEST_URI'} =~ m!(\d+)/(\d+)/(\d+)\.json$!) {
     print("{\n\"_comment\": \"Sorry, query parameters not understood.\"\n}\n");
     exit(0);
@@ -135,12 +151,12 @@ $ty2 = $dbh->selectrow_array("select ST_Y(ST_transform(ST_GeomFromText('POINT($x
 my $cntr = 0;
 if ($iscgi == 0) {
   print("// Note: this file has been autogenerated by $0\n");
-  print("var FAUGeoJSON = {\n");
+  printwows("var FAUGeoJSON = {\n");
 } else {
-  print("{\n");
+  printwows("{\n");
 }
-print("  \"type\": \"FeatureCollection\",\n");
-print("  \"features\": [\n");
+printwows("  \"type\": \"FeatureCollection\",\n");
+printwows("  \"features\": [\n");
 foreach $xtable ('planet_osm_polygon1', 'planet_osm_polygon2', 'planet_osm_line') { # 'planet_osm_polygon', 'planet_osm_line'
   my $querypart1 = " ((tags->'building:part') is not null)";
   my $table = 'planet_osm_polygon'; 
@@ -174,35 +190,43 @@ foreach $xtable ('planet_osm_polygon1', 'planet_osm_polygon2', 'planet_osm_line'
       $hstoredec = Pg::hstore::decode($row->{'tags'});
     }
     my $levels = fetchlastofhr(1, $hstoredec, 'levels', 'building:levels');
-    my $height = fetchlastofhr($height, $hstoredec, 'height', 'building:height');
-    unless ($height =~ m/^[0-9.]+$/) { undef($height); }
+    my $height = fetchlastofhr(undef, $hstoredec, 'height', 'building:height');
+    unless ((defined($height)) && ($height =~ m/^[0-9.]+$/)) {
+      undef($height);
+    }
     my $minlevel = fetchlastofhr(0, $hstoredec,
                                  'min_levels', 'building:min_levels', 'min_level', 'building:min_level');
-    my $minheight = fetchlastofhr($minheight, $hstoredec, 'min_height', 'building:min_height');
-    unless ($minheight =~ m/^[0-9.]+$/) { undef($minheight); }
+    my $minheight = fetchlastofhr(undef, $hstoredec, 'min_height', 'building:min_height');
+    unless ((defined($minheight)) && ($minheight =~ m/^[0-9.]+$/)) {
+      undef($minheight);
+    }
+    my $shape = fetchlastofhr(undef, $hstoredec, 'building:shape');
+    my $material = fetchlastofhr(undef, $hstoredec,
+                                 'building:material', 'building:facade:material', 'building:cladding');
     my $wallcolor = fetchlastofhr(undef, $hstoredec, 'building:color', 'building:colour');
     my $roofcolor = fetchlastofhr(undef, $hstoredec,
                                   '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');
+    my $roofmaterial = fetchlastofhr(undef, $hstoredec, 'roof:material', 'building:roof:material');
     if ($cntr != 0) {
-      print(",\n");
+      printwows(",\n");
     }
     $cntr++;
-    print("  {\n");
-    print("    \"type\": \"Feature\",\n");
+    printwows("  {\n");
+    printwows("    \"type\": \"Feature\",\n");
     if (defined($row->{'osm_id'})) {
-      print("    \"id\": " . $row->{'osm_id'} . ",\n");
+      printwows("    \"id\": " . $row->{'osm_id'} . ",\n");
     } else {
-      print("    \"id\": $cntr,\n");
+      printwows("    \"id\": $cntr,\n");
     }
     if (defined($row->{'name'})) {
       $row->{'name'} =~ s/"//g;
-      print("    \"name\": \"" . $row->{'name'} . "\",\n");
+      printwows("    \"name\": \"" . $row->{'name'} . "\",\n");
     }
-    print("    \"geometry\": {\n");
-    print("      \"type\": \"Polygon\",\n");
-    print("      \"coordinates\": [[\n");
+    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);
@@ -213,51 +237,68 @@ foreach $xtable ('planet_osm_polygon1', 'planet_osm_polygon2', 'planet_osm_line'
       if ($firstcoord == 1) {
         $firstcoord = 0;
       } else {
-        print(",\n");
+        printwows(",\n");
       }
-      printf("        [ %.5f, %.5f ]", $onex, $oney);
+      printwows(sprintf("        [ %.5f, %.5f ]", $onex, $oney));
     }
-    print("\n");
-    print("      ]]\n");
-    print("    },\n");
-    print("    \"properties\": {\n");
+    printwows("\n");
+    printwows("      ]]\n");
+    printwows("    },\n");
+    printwows("    \"properties\": {\n");
     if (defined($height)) {
-      print("       \"height\": $height,\n");
+      printwows("       \"height\": $height,\n");
     }
-    if (defined($min_height)) {
-      print("       \"min_height\": $minheight,\n");
+    if (defined($minheight)) {
+      printwows("       \"minHeight\": $minheight,\n");
     }
     if (defined($levels)) {
-      print("       \"levels\": $levels,\n");
+      printwows("       \"levels\": $levels,\n");
     }
     if (defined($minlevel)) {
-      print("       \"minLevel\": $minlevel,\n");
+      printwows("       \"minLevel\": $minlevel,\n");
+    }
+    if (defined($shape)) {
+      $shape = JSON->new->allow_nonref->encode($shape);
+      printwows("       \"shape\": $shape,\n");
+    }
+    if (defined($material)) {
+      $material = JSON->new->allow_nonref->encode($material);
+      printwows("       \"material\": $material,\n");
     }
     if (defined($wallcolor)) {
-      print("       \"wallColor\": \"$wallcolor\",\n");
+      $wallcolor = JSON->new->allow_nonref->encode($wallcolor);
+      printwows("       \"wallColor\": $wallcolor,\n");
     }
     if (defined($roofcolor)) {
-      $roofcolor =~ s/"//g;
-      print("       \"roofColor\": \"$roofcolor\",\n");
+      $roofcolor = JSON->new->allow_nonref->encode($roofcolor);
+      printwows("       \"roofColor\": $roofcolor,\n");
     }
     if (defined($roofshape)) {
-      $roofshape =~ s/"//g;
-      print("       \"roofShape\": \"$roofshape\",\n");
+      if ($roofshape eq 'pyramidal') { $roofshape = 'pyramid'; }
+      $roofshape = JSON->new->allow_nonref->encode($roofshape);
+      printwows("       \"roofShape\": $roofshape,\n");
+    }
+    if (defined($roofmaterial)) {
+      $roofmaterial = JSON->new->allow_nonref->encode($roofmaterial);
+      printwows("       \"roofMaterial\": $roofmaterial,\n");
     }
     if (defined($roofheight)) {
       $roofheight = sprintf("%.1f", $roofheight);
-      print("       \"roofHeight\": \"$roofheight\",\n");
+      printwows("       \"roofHeight\": \"$roofheight\",\n");
     }
-    print("       \"dummy\": \"void\"\n");
-    print("    }\n");
-    print("  }");
+    # 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("  }");
   }
   $sth2->finish();
   undef($sth2);
   $sth->finish();
   undef($sth);
 }
-print("\n  ]\n");
+printwows("\n  ]\n");
 if ($iscgi == 0) {
   print("};\n");
 } else {
This page took 0.059751 seconds and 4 git commands to generate.