City of Gävle in 3D
From fmepedia
In FME 2010, our 3D support got a big push. One of the most interesting examples prepared by our core development team is based on data we got from the City of Gävle (http://en.wikipedia.org/wiki/G%C3%A4vle). The example includes several interesting things including new functionality as well as some tricks that helped us to generate a 3D data that looks as follows:
For the examples on this page, the source files came from a variety of formats including Shape, JPEG, TIF, Sketchup and others. In one workspace I wrote out to 3D PDF, and in another workspace I wrote to Geodatabase. It's interesting to note that people who want to browse parts of 3D cityscapes in ESRI ArcCatalog don't need to write translate data into Geodatabase however, as FME 2010 now extends the browsing capabilities of ArcCatalog such that users can simply view 3D data from a variety of formats without translating it.
Most of these examples showcase the new texture support for 3D objects being introduced in FME 2010, but it's valuable to know that the new release will offer support for a whole new list of 3D formats including 3ds, Sketchup, AutoCAD Civil 3D and Collada. You can view the listing of the formats supported in the current release of FME at: www.safe.com/Formats.
The workspace that writes out to 3D PDF consists of several parts, let's go through some of them:
| Table of contents |
Making Background
When our PDF 3D writer writes rasters, it replaces them with faces using raster as a texture. This replacement can also be done with the the updated FaceReplacer transformer. This makes the creation of backgrounds for 3D models really easy (as long as the terrain is flat and when the raster is georeferenced).
The screenshot shows a custom transformer within the main workspace that generates the surface. We also use Clipper here to reduce the original TIFF image. If the source image is too big, the PDF writer as well as other writers may hit their limits. For example, I wasn't able to use a texture bigger than ~9200*9200 pixels. In this case, you may use one or more of the following options:
- Clip only the portion of the image you need;
- Reduce image size by resampling (RasterResampler)
- Use RasterTiler to make several tiles of a smaller size.
Creating Roofs
The buildings provided by the City of Gävle contained two attributes that helped us to generate 3D roofs - the maximum (HOJD_TAKNO) and the minimum (HOJD_TAKFO) roof elevations. Using CenterlineReplacer, we generate axes that will represent roof ridges.
The building footprints are elevated to the minimum roof elevation, and roof ridges are brought to the maximim roof elevation. After that, we can use this data in TINGenerator to make surfaces for each roof.
Building footprints also serve as clippers for the source image so that after Clipper we get multiple images representing building roofs.
Now, having roof surfaces and roof textures, we simply combine them together with AppearanceAdder, and roofs are ready.
Ideally, roof ridges should come from some real source, for example, as a result of image digitizing. Our algorithm cannot always predict the true roof ridge orientation, although in our example we sometimes do pretty good job:
Adding Textures to Walls
Unfortunately, we don't have real textures for the City of Gävle, so we had to come up with some technique of random texture assignment. Using building area sizes and heights, we separated them into three groups representing commercial, apartment and low-rise residential real estate. Based on that, we generated two texture parameters, which control how many times each texture should appear horizontally and vertically.
We also set up our texture reader (JPEG reader) in such a way, that it reads and uses everything available in the respective folders under texture folder - \commercial, \residential, and \apartments. You can place your own images in these folders, and they will be used in your output. For each texture, we generate texture_id attribute with the Counter transformer - there are three ranges of those ids - starting from 0 for residential, from 1000 - for commercial, and from 2000 - for apartments.
Depending of building type (commercial, apartment, or residential), we generate random _texture_id on buildings also in three ranges.
Generate_walls custom transformer takes building footprints, chops them into two-vertex lines, makes walls by extruding these lines to minimum roof elevation, and assigns textures to walls using texture_id as a Group By attribute.
Replacing Texture on a SketchUp model
The Gävle Goat (http://en.wikipedia.org/wiki/G%C3%A4vle_goat), as tells us Wikipedia, is a giant figure of a traditional Swedish Yule Goat. This straw goat is known be a target of arson attacks, and this is why Dale asked me to take a SketchUp model fot he goat, and replace straw texture with fire.
Very reluctantly I agreed to commit this act of virtual vandalism, but eventually, it served us well - as you can see, our textures are placed on each face separately, whereas the original goat has textures going across several faces. This is how Goat on fire helped us to find a problem rather earlier than later:
| Original | Replaced Textures |
|---|---|
![]() |
![]() |
Making a Tour to the Goat
Two more exciting features in FME 2010 are combined in this demo. Now we can find shortest path with ShortestPathFinder and make an animated tour along a linear feature (for example, along shortest path) with KMLTourBuilder.
The workspace takes the road network, and two points - one for the beginning of the path, and another - for its end. It finds the shortest path, assembles its components into a single linear feature with LineJoiner and simplifies it with Generalizer:
Then, the shortest path is converted to a tour feature, which is autmatically recognized and saved as a tour by KML Writer:
Results can be seen either in Google Earth, or as |a movie on FMEGuru Channel (http://www.youtube.com/user/FMEGuru#p/u/6/uL0P_e04UGE) or with your favorite program that can read MP4 files.
Conclusion and Downloads
Many thanks to the City of Gävle for providing us with this dataset. Thanks to our development team for their efforts in making FME 3D capable, and for creating the workspace.
I didn't go through all the details of the workspace, feel free to contact me (mailto:dmitri.bagh@safe.com) in case you have any questions, or if you would like to set up a similar workspace with your data. Here is the list of what is needed for such a demo:
- Orthophotos for roof textures;
- building footprints for walls and roofs;
- either roof ridge and roof eave elevations as attributes or their vector representations;
- photos of the walls for textures with some way of identifying to which side each texture belongs.
- DEM (if terrain is important)
- Models of the features that you would like to see - poles, trees, bus shelters, fences, etc.
Downloads:
The output Geodatabase (~65 mb);
The workspace writing to PDF 3D;
The workspace writing to Geodatabase;
The archive contains buildings, textures, orthophoto, and the goat;
The short movie showing results produced with ShortestPathFinder and KMLTourBuilder;
The workspace making KML tour, the source dataset (roads), and KML file with the tour.


