Revit has three reference points for coordinates: the internal origin, a survey point, and a project base point. The project base point may have an angle to true north set. When you export to IFC, an
IfcSite is created. Both elements have coordinates and data. However, are these coordinates correct? Are they complete? And can we use them reliably in other software? Let’s investigate.
Coordinate systems defined by
Let’s talk about what we want the results to be. According to the IFC specification,
IfcProject provides the following information:
- the project coordinate system
- the coordinate space dimension
- the precision used within the geometric representations
- optionally the indication of the true north
- optionally the map conversion between the project coordinate system and the geospatial coordinate reference system.
This information is provided using the
RepresentationContexts relationship of the
IfcProject. This relationship will contain one or more
IfcGeometricRepresentationContext elements. Each will typically have a
CoordinateSpaceDimension of 3, to show a 3D model, and the
Precision attribute shows the model precision.
The actual project coordinate system is defined by the
HasCoordinateOperation relationship. This holds an
IfcMapConversion element, which in turn references an
IfcProjectedCRS. Let’s go through the attributes of
IfcProjectedCRS first, as knowing the Coordinate Reference System (CRS) of the project is the most critical aspect of geeoreferencing:
EPSGcode for the CRS. In Sydney, (i.e. GDA94 / MGA Zone 56) this would be
EPSG:28356. This should be the only value you need to fill out if the EPSG number has a complete definition of the Projected CRS. If the EPSG number is not known, you can enter in
WKTas a value here, and full out the subsequent attributes. Just for the sake of example, let’s assume we wanted to describe
Description: this would be the description of the CRS, such as “GDA94 / MGA Zone 56”. Note: to reiterate, this, and all subsequent attributes are optional if you have specified an EPSG number with a full definition.
GeodeticDatum: following our example above, we can specify it to be
VerticalDatum: in Australia, this would be set to
EPSG:5111, which represents AHD (Australian Height Datum)
MapProjection: in our example it will be
MapZone: this will be zone
56, following our Sydney example.
MapUnit: the standard states it is in meters, so we will specify an
IFCSIUNIT (*, .LENGTHUNIT., $, .METRE.).
- It can also nest a
HasCoordinateOperation, but you really shouldn’t unless you want insanity to occur
Now that the projected CRS is defined, we need to define whether or not there are any map conversions between our model’s local coordinate system and the map coordinate system. Typically for horizontal construction projects, such as roads, rail, and other linear infrastructure, there would be no map conversion, and the local coordiante system will directly use Eastings and Northings of the map coordinate system. However, for vertical construction projects, such as buildings, there will almost always be a map conversion converting from small, local, XYZ coordinates, to map eastings, northings, and height coordinates. Here are the attributes of the
SourceCRS: refers back to the
IfcProjectto establish the inverse relationship
TargetCRS: refers to the CRS used in the project. This will hold an
IfcCoordinateReferenceSystem, or its subtype
IfcProjectedCRS. It has a bit of data:
0,0,0origin will correlate to this number. In Sydney, if your building is the Sydney Opera House, this’ll be something like
334902.775. If you have specified a
ProjectedCRSyou should use that unit (e.g. meters). Otherwise, you should use the project units (e.g. millimeters).
Northings: same as
Eastings, but for the Y axis. For the Sydney Opera House, it’ll be something like
OrthogonalHeight: continuing our example, this’ll be the AHD of our world origin. Wikipedia says it is 4m in elevation, so I guess it’ll be something like
4. In this case, we keep the same units as
Northings, so that we can apply a uniform scale afterwords.
XAxisAbscissa: specifies the local X axis vector along the easting to determine rotation of the local coordinates. If there is no rotation, this will be
XAxisOrdinate: specifies the local X axis vector along the northing to determine rotation of the local coordinates. If there is no rotation, this will be
Scale: This is the average combined scale factor across the small site such that a local surface distance multiplied by this value equals a map distance. This will typically be something very close to
1, but not quite (such as
0.99996). Your surveyor can calculate the actual value.
IfcProjectedCRS element of the
IfcGeometricRepresentationContext holds all of the georeferencing information that we require. These attributes contains all of the parameters required to perform a “Helmert transformation”, which is a fancy way of saying how to offset, rotate, and scale local project coordinates to a globally positioned coordinate system. For your surveyor to provide these transformation parameters properly, they will need multiple surveyed points (a minimum of two), ideally taken at extremes across the site, in both your local coordinates, as well as their equivalents in the target CRS. They will also need to know your desired building orientation (i.e. project north) to calculate the X axis abcissa and ordinate, and a nominated false origin to set the Eastings and Northings. The more points that are surveyed, the more accurate this
IfcMapConversion will become.
With all of the information defined above, to convert from local coordinates
(X, Y, Z), to map grid coordinates
(X', Y', Z'), you can use these relationships:
Credits go to BuildingSmart Australasia who has done great work in clarifying these concepts. Note that I have clarified the argument order of the
atan2 function is
y, x, which is more common in programming languages.
After all of this information is recorded, it’s interesting to note that the
IfcGeometricRepresentationContext additionally has a
TrueNorth attribute. Assuming the
IfcMapConversion is already provided, there is actually no need for a
TrueNorth attribute, and so if it is provided, it is merely duplicate data and there for convenience. IFC readers should not parse it and should not apply the same rotation twice. The
IfcMapConversion takes priority over the
IfcGeometricRepresentationContext of the
IfcProject also has a
WorldCoordinateSystem attribute. Usually, this will be set to
(0, 0, 0), and represents the origin of the virtual world. In other words, any element in a project usually inherit the local relative placement of its parent, all the way up to
IfcSite, but somewhere, it needs to end in an absolute coordinate. This
WorldCoordinateSystem is the final absolute coordinate that is not relative to anything else. It can therefore be used to offset everything in your project, should you want to. The
IfcMapConversion we just described, will then be used to convert our virtual world into the real world.
Coordinate system inheritance
IfcSite is spatially contained in the
IfcProject. However, the spatial containment is not the determining factor for how coordinates are inherited. Instead, the
IfcSite has an
ObjectPlacement and a
Representation attribute. These are the important attributes to pay attention to.
ObjectPlacement attribute positions the
IfcSite element relative to other objects. We will discuss about different placements below, but suffice to say that it merely deals with relative offsets of coordinates.
Representation attribute, however, contains an
IfcRepresentationContext chosen from the list of contexts defined at the
IfcProject level. It is this particular selection of the
IfcRepresentationContext that allows the
IfcSite to inherit a particular
MapConversion attribute defined at the
I would like to emphasize that the inheritance of coordinate transformation is not done due to spatial containment, but instead due to the selection of
IfcRepresentationContext. This allows different
IfcSite elements to have a different
IfcRepresentationContext, and therefore have a different
MapConversion. This is useful if you are working on a small town or any geographically large projects, as different sites will likely require different Helmert transformations. That said, I have heard talk that the
IfcMapConversion could be moved to be defined at the
IfcSite level, instead of the
In fact, any IFC product that has a representation can select its own context. This means that an
IfcWall can have one map conversion, and have an
ObjectPlacement to another IFC element which has a different map conversion. Although technically possible, it is bad practice and seasoned GIS professionals will tell you to never mix different CRSes on one map unless you want to be more artistic than useful.
Coordinate systems defined by
In addition to ordinary coordinates, the
RefElevation attributes. As the prefix “Ref” suggests, this is a latitude and longitutde provided only for reference. It is not sufficient for proper geolocation and if there is a discrepancy between the
IfcMapConversion and the data provided in
IfcMapConversion takes priority.
Note that these
RefLongitude values are recorded in integers that are separated by a full stop to represent degrees, minutes, seconds, and an optional millionths of a second. West and south locations are negative, and east and north locations are positive.
In a real project, a project may contain multiple
IfcSite objects. Each
IfcSite has a
Representation, which may include terrain, for example. For most projects, there is a site boundary, such as a cadastral boundary which denotes the legal plot of land. The
ObjectPlacement of the
IfcSite is therefore likely to be a corner of the site boundary which is a point that has been surveyed.
Coordinate systems defined by
IfcBuilding contains a
Representation of the building. It also contains an
IfcObjectPlacement, which is relative to the
IfcSite. This would place your building on your site model. The rotation of this placement also sets out the project north of the building. If your building has multiple wings, it may also define the individual project norths of each wing.
IfcBuilding additionally contains two attributes:
ElevationOfRefHeight: as one steps into your building, the finish floor level will be seen as the building’s internal reference height of +0.00. This attribute will record this “+0.00 reference height” in terms of the absolute values of elevation above sea level.
ElevationOfTerrain: this is the height in absolute values of elevation above sea level of the terrain immediately surrounding the perimeter of the building. If the terrain slopes, it is taken to be the lowest point.
Just like the reference point values in
IfcSite, these are also duplications of data. It is not explicitly mentioned, but I believe that should there be a discrepancy, the derived coordinate from the
IfcMapConversion takes priority.
ElevationOfTerrain, apart from being a reference value, also provides a datum to measure the
EavesHeight and the
Height (total height) of the building which is recorded in the
If your object has an
IfcObjectPlacement, it usually uses an
IfcLocalPlacement which has a
PlacementRelTo, thus inheriting the parent’s placement. If you omit the
PlacementRelTo, it does not inherit any more parent coordinates, and ends up being an absolute coordinate. An absolute coordinate is defined as only relative to the
WorldCoordinateSystem of the
A common example for this is the
IfcSite element which is the immediate child of the
IfcProject. Because its only parent coordinate is the
WorldCoordinateSystem, it is known as an absolute placement.
You can also omit the
IfcObjectPlacement altogether, and it will therefore also be treated as an absolute placement which is equal to the
WorldCoordinateSystem of the
Omission of the
IfcObjectPlacement is a quick and easy way to say that your
IfcSite, are all at the
WorldCoordinateSystem. This behaviour has been noted in some software, such as Revit in some circumstances.
Keep in mind that this behaviour is technically possible but it is not endorsed by buildingSMART. For more information, see this ISG implementation agreement CV-2x3-143 agreement on having the containment tree and the relative placement tree identical for spatial elements. It is only mentioned out of completeness.
Coordinate systems and
Grids are by convention (i.e. described not enforced by the IFC specification) placed relative to the local placement of its container. Grids can be contained by
IfcBuildingStorey. As an alternative to a relative and absolute placements, coordinates can also be specified constrained to a grid system. This is as simple as using
IfcGridPlacement for the
IfcGridPlacement allows you to specify an object’s placement using the intersection of two grid lines, or
IfcVirtualGridIntersection, and a direction. The details will not be described here, but using grids does not change the fundamental concept of site coordinates. Any object placed this way will still resolve to a local
(X, Y, Z) which can be translated using the
It is therefore possible to have an
IfcGrid spatially contained by an
IfcBuilding could then have a placement aligning with the grid. This makes intuitive sense to lay a building out relative to a grid placed on the site, but it breaks the ISG agreement where containment tree and relative placement tree should be identical.
Spatial Composition and coordinates
For the objects that we’ve described so far, they usually use the Spatial Composition concept to relate to one another. Keep in mind that spatial decomposition and inheritance of coordinates are two separate concepts. Just because something is spatially contained in a parent container does not mean that it inherits its coordinates.
However, that being said, a convention is endorsed by the specification’s documentation of
IfcLocalPlacement to place objects relative to the same container that it is spatially contained in. I’ve linked the page for you to read the details of the relationships that are endorsed.
Coordinate systems created by Revit
Now that we know what should be defined and how they should be defined in an ideal world, let’s take a Revit project as an example. We will be exporting using the open source Revit exporter as an IFC4 file.
Revit provides an
IfcProject as expected, and this has one
IfcGeometricRepresentationContext. Unfortunately, our luck ends here, as no
IfcMapConversion is provided. Therefore, all that great stuff we talked about where we could record a CRS, its datums and projections, and so on, are not available.
Let’s see what information we do have in the
Precision: this is set to 0.01 of a millimeter in my metric scenario.
WorldCoordinateSystem: this is set to
(0, 0, 0). As far as I have observed, this never changes, regardless of the placement of any of Revit’s origins.
TrueNorth: this represents a vector of the “Angle to True North” value that you have set for your project base point. For example, if your project has no rotation, it will be the vector
(0, 1). If your true north is set to 45 degrees (i.e. top left of your building), then it will be the vector
(-Pi/4, Pi/4)(in the second quadrant). And so on.
IfcSite is also provided with the following information.
RefLatitude: this value is taken from your Revit project’s “Location” latitude, and has no relationship to the survey point or project base point. There are a few quirks to watch out for: it is comma and space separated instead of using a full stop separator, and it records to a degree of precision that may return different results if you are using other programs that do not share the same degree of precision.
RefLongitude: same as latitude, but for longitude instead.
RefElevation: this value is set to the
Elevfield of the Revit Project Base Point.
The final information we can extract is the
ObjectPlacement attribute of the
IfcSite element. This has a location and a direction. The direction is identical to the
TrueNorth value described above, but has a Z dimension too. The Z dimension may be set to the
Elev field of the Revit Project Base Point, if the “Include IFCSITE elevation in the site local placement origin” option is checked in the “Advanced” tab of the IFC export settings. If the option is not checked, it is set to
Credits to Niel Simmonds for clarifying the behaviour of elevation data.
Location of the
IfcSite, however, is a bit of a tricky one. It is a 3D coordinate, with the Z ordinate always set to
0. The X and Y ordinates have a relationship to the project base point (PBP) as shown below. Revit further complicates things by having a project base point that can be represented by eastings and northings that are relative to either the survey point, or the project’s invisible internal origin point. These are denoted with the subscript
IfcBuilding is always set to a relative placement of
(0, 0, 0), and therefore fully inherits the location of the
IfcSite. However, I have seen elevation data at the
IfcBuildingStorey level, set in its
Location Z ordinate (X and Y are hardcoded at
0, 0). In particular, this Z value will not be the value you set in your Revit level schedule. Instead, it will be your Revit level value plus the
Elev value of your Project Base Point. As a result, your building will always have “absolute” height values in its IFC export, even though it may not be inherited or stored at the location recommended by the IFC spec. I should note that the
Elev value set on your Revit Survey Point has no impact whatsoever on the IFC export.
It should be noted that Revit does not know what a building or site is and so it is not possible to have multiple buildings, building portions, sites, or sub-sites. All files automatically generate and contain all of their contents inside a single site and single building.
Knowing this information is extremely important. Because Revit does not specify a CRS conversion, many people put their local CRS eastings and northings coordinates into the project base point and the survey point. As most of these values are very large in magnitude, the
IfcSite local placement will too be extremely far off in space.
This far site placement is inherited by every single object spatially contained by the site. Any program which then parses the IFC to extract the geometry will have to deal with this, and the inability to deal with such large transformation magnitudes is a well known problem in the 3D industry. As a result, geometry gets unnecessarily “broken” and imports are unreliable. You can experience this yourself by importing an IFC into Blender which has CRS coordinates, or even attempting to import an IFC back into Revit: it won’t be able to handle its own creation.
As a workaround, you can simply modify the
IfcLocalPlacement of the
IfcSite in a text editor before importing the IFC. After the import, you can then specify using native GIS features of your application how the origin point translates to a target CRS. Knowing the relationship of the
IfcSite coordinates above will help you specify the origin correctly. I tend to simply reset the value such that the origin point corresponds with the project base point. In simple scenarios this is
(0, 0, 0), but sometimes it may have a further offset which you can calculate using the formula above. An alternative, simpler way is by finding the difference in coordinates between the
IfcSite and Revit’s project base point, and making that the new
IfcSite local placement
This article should clarify all coordinate related concepts in BIM and Revit, and hopefully you can now use IFCs a bit more reliably across other software other than Revit.