Extrude 2D polygons to 3D
Creating a 3D city model
You can create a 3D city model easily in GRASS GIS even if building heights are not available using v.extrude. We'll just assume a constant building height (otherwise you can use individual heights stored in the attribute table for the respective building).
Here an example with OpenStreetMap (OSM) data:
# first reproject OSM data from LatLong to metric projection, e.g. UTM32N:
ogr2ogr -t_srs epsg:32632 polygons_UTM32.shp polygons.shp
OSM map import and building extraction into new map
Import into a metric GRASS location (here: UTM32N), extract the buildings and extrude them to 3D:
v.in.ogr polygons_UTM32.shp out=oberursel2D
# extract the buildings into a new map (use db.connect -p to see which driver you are using):
### statement for DBF driver:
v.extract oberursel2D out=oberursel2D_small where="tags LIKE 'building'"
### statement for SQLite driver:
v.extract oberursel2D out=oberursel2D_small where="tags LIKE LIKE '%building%'"
We see that a lot of buildings are actually NOT tagged as buildings. You may fix that at http://www.openstreetmap.org/
Alternative: use v.db.addcol to add an "area double precision" column and upload the area sizes in (square)meters with v.to.db. Then use v.extract to extract all areas over, say, 200 m^2. However, better fix the OSM map!
Extruding building polygons to 3D
# extrude 2D building polygons to 3D, here with a constant height:
v.extrude oberursel2D_small out=oberursel3D height=20
# check that the 'areas' have become type 'faces':
v.info oberursel3D
Ready! Note that you can make use of individual heights when stored in the attribute table for the respective building since v.extrude supports also that.
Visualization
Now we can visualize them:
# set computation region to map:
g.region vect=oberursel3D
# generate a pseudo-DEM (if you have a real DEM, use the 'elevation=' parameter in v.extrude above):
r.mapcalc "mydem = 0.0"
# visualize in 3D:
nviz elevation=mydem vect=oberursel3D