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 an
IfcGeometricRepresentationContext. This 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, with all sorts of useful attributes. Let’s go through them below:
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:
Name: It is the
EPSGnamespace for the CRS. In Sydney, (i.e. MGA56) this would be
Description: some informal description if required.
GeodeticDatum: usually, the
Namewould unambiguously define the related geodetic datum. Otherwise, following our example above, we can specify it to be
VerticalDatum: again, in Australia, this would be set to
- It can also nest a
HasCoordinateOperation, but you really shouldn’t unless you want insanity to occur
MapProjection: this is a little bit of repetition, but 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.).
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. Notice this value is in meters, as per the convention of MGA56, even though
IfcLengthMeasuresays lengths should typically be in mm.
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: Our local (source) coordinate system is usually in millimeters, and the target coordinate system (MGA56) is in meters, so the scale conversion will be something around
0.001. Keep in mind that it is unlikely to be exactly
0.001. This is because the scale isn’t primarily about units, it is the scaling factor of the Helmert transformation, which takes into account curvature of the Earth and local site topograpy. Your surveyor can calculate the actual value.
IfcMapConversion element of the
IfcGeometricRepresentationContext holds all of the CRS conversion information that we require. However, the values for this
MapConversion aren’t exactly as straightforward as its made out above. It isn’t simply a matter of an offset and rotation on a planar axis. It actually contains all of the parameters required to perform a Helmert transformation. This transformation mathematically maps all local project coordinates to a globally positioned coordinate system. To calculate these transformation parameters properly, it requires multiple surveyed points (a minimum of two) in your local coordinates, as well as their equivalents in the target CRS. The more points that are surveyed, the more accurate this
IfcMapConversion will become. Your surveyor will be qualified to calculate these parameters.
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 systems defined by
IfcSite is spatially contained in the
IfcProject and therefore inherits the
IfcProject map transformation as well as the
WorldCoordinateSystem attribute. Because its only parent coordinate is the
WorldCoordinateSystem, it is known as an absolute placement.
RefElevation attributes. As the prefix “Ref” suggests, this is purely a reference for convenience, and is in fact a duplication of data. 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.
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.
In the current state of affairs, no matter how many sites and sub-sites you have in your project, they all inherit the same
IfcMapConversion from the
IfcProject. If you are working on a small town or any geographically large projects, different sites will likely require different Helmert transformations. At the moment, the only solution is to split your file into
IfcProjects. In the future, it is likely that the
IfcMapConversion will be defined at the
IfcSite level, instead of the
IfcProject to overcome this limitation.
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 values in
IfcSite, these are also purely for reference. 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
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
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 always
0, no matter what.
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, set to
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
Finally, let’s talk about where the absolute elevation is stored. As stated above, the
RefElevation of the
IfcSite, as well as the Z ordinate of the
IfcSite is always
IfcBuilding is always set to a relative placement of
(0, 0, 0), and therefore fully inherits the location of the
IfcSite. The elevation data only comes in at the
IfcBuildingStorey level, set in its
Location Z ordinate (X and Y are hardcoded at
0, 0). However, 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.