Beispiel #1
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);

            bool   found  = false;
            double radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Radius", out found);

            if (!found)
            {
                Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the radius of this circle", false);
                return;
            }

            try
            {
                Curve = Arc.Create(Position.Origin, radius, 0, 2.0 * Math.PI, Position.BasisX, Position.BasisY);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("too small"))
                {
                    string lengthAsString = UnitFormatUtils.Format(IFCImportFile.TheFile.Document.GetUnits(), UnitType.UT_Length, radius, true, false);
                    Importer.TheLog.LogError(Id, "Found a circle with radius of " + lengthAsString + ", ignoring.", false);
                    Curve = null;
                }
                else
                {
                    Importer.TheLog.LogError(Id, ex.Message, false);
                }
                Curve = null;
            }
        }
Beispiel #2
0
        override protected void Process(IFCAnyHandle ifcBlock)
        {
            base.Process(ifcBlock);

            bool found = false;

            XLength = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcBlock, "XLength", out found);
            if (!found)
            {
                Importer.TheLog.LogError(ifcBlock.StepId, "Cannot find the X length of this block.", false);
                return;
            }

            YLength = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcBlock, "YLength", out found);
            if (!found)
            {
                Importer.TheLog.LogError(ifcBlock.StepId, "Cannot find the Y length of this block.", false);
                return;
            }

            ZLength = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcBlock, "ZLength", out found);
            if (!found)
            {
                Importer.TheLog.LogError(ifcBlock.StepId, "Cannot find the Z length of this block.", false);
                return;
            }
        }
Beispiel #3
0
        protected override void Process(IFCAnyHandle ifcMaterialLayer)
        {
            base.Process(ifcMaterialLayer);

            IFCAnyHandle ifcMaterial = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcMaterialLayer, "Material");

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterial))
            {
                Material = IFCMaterial.ProcessIFCMaterial(ifcMaterial);
            }

            bool found = false;

            LayerThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcMaterialLayer, "LayerThickness", out found);
            if (!found)
            {
                return;
            }

            // GetOptionalLogicalAttribute defaults to Unknown.  We want to default to false here.
            IsVentilated = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcMaterialLayer, "IsVentilated", out found);
            if (!found)
            {
                IsVentilated = IFCLogical.False;
            }
        }
Beispiel #4
0
        private void ProcessIFCOffsetCurve3D(IFCAnyHandle ifcCurve)
        {
            IFCAnyHandle basisCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", false);

            if (basisCurve == null)
            {
                return;
            }

            bool   found    = false;
            double distance = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Distance", out found);

            if (!found)
            {
                distance = 0.0;
            }

            try
            {
                IFCCurve ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve);
                if (ifcBasisCurve.Curve != null)
                {
                    Curve = ifcBasisCurve.Curve.CreateOffset(distance, XYZ.BasisZ);
                }
                else if (ifcBasisCurve.CurveLoop != null)
                {
                    CurveLoop = CurveLoop.CreateViaOffset(ifcBasisCurve.CurveLoop, distance, XYZ.BasisZ);
                }
            }
            catch
            {
                IFCImportFile.TheLog.LogError(ifcCurve.StepId, "Couldn't create offset curve.", false);
            }
        }
        override protected void Process(IFCAnyHandle solid)
        {
            base.Process(solid);

            // We will not fail if the direction is not given, but instead assume it to be normal to the swept area.
            IFCAnyHandle direction = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "ExtrudedDirection", false);

            if (direction != null)
            {
                Direction = IFCPoint.ProcessNormalizedIFCDirection(direction);
            }
            else
            {
                Direction = XYZ.BasisZ;
            }

            bool found = false;

            Depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(solid, "Depth", out found);
            if (!found || MathUtil.IsAlmostZero(Depth))
            {
                string depthAsString = IFCUnitUtil.FormatLengthAsString(Depth);
                Importer.TheLog.LogError(solid.StepId, "extrusion depth of " + depthAsString + " is invalid, aborting.", true);
            }

            if (Depth < 0.0)
            {
                // Reverse depth and orientation.
                Depth     = -Depth;
                Direction = -Direction;
                Importer.TheLog.LogWarning(solid.StepId, "negative extrusion depth is invalid, reversing direction.", false);
            }
        }
        // TODO: this function should be moved to IFCBoundingBox.cs now that they are fully supported.
        static private BoundingBoxXYZ ProcessBoundingBox(IFCAnyHandle boundingBoxHnd)
        {
            IFCAnyHandle lowerLeftHnd = IFCAnyHandleUtil.GetInstanceAttribute(boundingBoxHnd, "Corner");
            XYZ          minXYZ       = IFCPoint.ProcessScaledLengthIFCCartesianPoint(lowerLeftHnd);

            bool   found = false;
            double xDim  = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(boundingBoxHnd, "XDim", out found);

            if (!found)
            {
                return(null);
            }

            double yDim = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(boundingBoxHnd, "YDim", out found);

            if (!found)
            {
                return(null);
            }

            double zDim = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(boundingBoxHnd, "ZDim", out found);

            if (!found)
            {
                return(null);
            }

            XYZ            maxXYZ      = new XYZ(minXYZ.X + xDim, minXYZ.Y + yDim, minXYZ.Z + zDim);
            BoundingBoxXYZ boundingBox = new BoundingBoxXYZ();

            boundingBox.set_Bounds(0, minXYZ);
            boundingBox.set_Bounds(1, maxXYZ);
            return(boundingBox);
        }
Beispiel #7
0
        private void ProcessIFCCircle(IFCAnyHandle ifcCurve, Transform transform)
        {
            bool   found  = false;
            double radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Radius", out found);

            if (!found)
            {
                return;
            }

            Curve = Arc.Create(transform.Origin, radius, 0, 2.0 * Math.PI, transform.BasisX, transform.BasisY);
        }
        override protected void Process(IFCAnyHandle ifcCylindricalSurface)
        {
            base.Process(ifcCylindricalSurface);

            bool found = false;

            Radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCylindricalSurface, "Radius", out found);
            if (!found)
            {
                Importer.TheLog.LogError(ifcCylindricalSurface.StepId, "Cannot find the radius of this cylindrical surface", true);
                return;
            }
        }
Beispiel #9
0
        /// <summary>
        /// Converts an IfcVector into a UV or XYZ value.
        /// </summary>
        /// <param name="vector">The handle to the IfcVector.</param>
        /// <returns>An XYZ value corresponding to the value in the file.  There are no transformations done in this routine.
        /// If the return is an XY point, the Z value will be set to 0.</returns>
        public static XYZ ProcessScaledLengthIFCVector(IFCAnyHandle vector)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(vector))
            {
                Importer.TheLog.LogNullError(IFCEntityType.IfcVector);
                return(null);
            }

            if (!IFCAnyHandleUtil.IsValidSubTypeOf(vector, IFCEntityType.IfcVector))
            {
                Importer.TheLog.LogUnexpectedTypeError(vector, IFCEntityType.IfcVector, false);
                return(null);
            }

            XYZ xyz;
            int stepId = vector.StepId;

            if (IFCImportFile.TheFile.XYZMap.TryGetValue(stepId, out xyz))
            {
                return(xyz);
            }

            IFCAnyHandle direction = IFCImportHandleUtil.GetRequiredInstanceAttribute(vector, "Orientation", false);

            if (direction == null)
            {
                return(null);
            }

            bool   found     = false;
            double magnitude = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(vector, "Magnitude", out found);

            if (!found)
            {
                magnitude = 1.0;
            }

            XYZ directionXYZ = IFCPoint.ProcessIFCDirection(direction);

            if (directionXYZ == null)
            {
                return(null);
            }

            xyz = directionXYZ * magnitude;
            AddToCaches(stepId, IFCEntityType.IfcVector, xyz);
            return(xyz);
        }
Beispiel #10
0
        override protected void Process(IFCAnyHandle solid)
        {
            base.Process(solid);

            IFCAnyHandle directrix = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "Directrix", true);

            Directrix = IFCCurve.ProcessIFCCurve(directrix);

            bool found = false;

            Radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(solid, "Radius", out found);
            if (!found || !Application.IsValidThickness(Radius))
            {
                Importer.TheLog.LogError(solid.StepId, "IfcSweptDiskSolid radius is invalid, aborting.", true);
            }

            double innerRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(solid, "InnerRadius", 0.0);

            if (Application.IsValidThickness(innerRadius))
            {
                if (!Application.IsValidThickness(Radius - innerRadius))
                {
                    Importer.TheLog.LogError(solid.StepId, "IfcSweptDiskSolid inner radius is too large, aborting.", true);
                }
                InnerRadius = innerRadius;
            }

            StartParameter = IFCImportHandleUtil.GetOptionalDoubleAttribute(solid, "StartParam", 0.0);
            if (StartParameter < MathUtil.Eps())
            {
                StartParameter = 0.0;
            }

            double endParameter = IFCImportHandleUtil.GetOptionalDoubleAttribute(solid, "EndParam", -1.0);

            if (!MathUtil.IsAlmostEqual(endParameter, -1.0))
            {
                if (endParameter < StartParameter + MathUtil.Eps())
                {
                    Importer.TheLog.LogWarning(solid.StepId, "IfcSweptDiskSolid swept curve end parameter less than or equal to start parameter, ignoring both.", true);
                    StartParameter = 0.0;
                }
                else
                {
                    EndParameter = endParameter;
                }
            }
        }
        override protected void Process(IFCAnyHandle ifcSurface)
        {
            base.Process(ifcSurface);

            IFCAnyHandle extrudedDirection = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcSurface, "ExtrudedDirection", true);

            ExtrudedDirection = IFCPoint.ProcessNormalizedIFCDirection(extrudedDirection);

            bool found = false;

            Depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcSurface, "Depth", out found);
            if (!found)
            {
                Importer.TheLog.LogError(Id, "IfcSurfaceOfLinearExtrusion has no height, ignoring.", true);
            }
        }
Beispiel #12
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);

            IFCAnyHandle basisCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", false);

            if (basisCurve == null)
            {
                return;
            }

            IFCAnyHandle dir = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "RefDirection", false);

            bool   found    = false;
            double distance = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Distance", out found);

            if (!found)
            {
                distance = 0.0;
            }

            IFCCurve ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve);
            XYZ      dirXYZ        = (dir == null) ? ifcBasisCurve.GetNormal() : IFCPoint.ProcessNormalizedIFCDirection(dir);

            try
            {
                if (ifcBasisCurve.Curve != null)
                {
                    SetCurve(ifcBasisCurve.Curve.CreateOffset(distance, XYZ.BasisZ));
                }
                else
                {
                    CurveLoop baseCurveLoop = ifcBasisCurve.GetTheCurveLoop();
                    if (baseCurveLoop != null)
                    {
                        SetCurveLoop(CurveLoop.CreateViaOffset(baseCurveLoop, distance, XYZ.BasisZ));
                    }
                }
            }
            catch
            {
                Importer.TheLog.LogError(ifcCurve.StepId, "Couldn't create offset curve.", false);
            }
        }
        protected override void Process(IFCAnyHandle ifcMaterialLayerSetUsage)
        {
            base.Process(ifcMaterialLayerSetUsage);

            IFCAnyHandle ifcMaterialLayerSet =
                IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcMaterialLayerSetUsage, "ForLayerSet", true);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterialLayerSet))
            {
                MaterialLayerSet = IFCMaterialLayerSet.ProcessIFCMaterialLayerSet(ifcMaterialLayerSet);
            }

            string directionAsString = IFCAnyHandleUtil.GetEnumerationAttribute(ifcMaterialLayerSetUsage, "LayerSetDirection");

            if (directionAsString == null)
            {
                Direction = IFCLayerSetDirection.Axis3;
                IFCImportFile.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No LayerSetDirection defined, defaulting to Axis3.", false);
            }
            else
            {
                Direction = (IFCLayerSetDirection)Enum.Parse(typeof(IFCLayerSetDirection), directionAsString, true);
            }

            string directionSenseAsString = IFCAnyHandleUtil.GetEnumerationAttribute(ifcMaterialLayerSetUsage, "DirectionSense");

            if (directionSenseAsString == null)
            {
                DirectionSense = IFCDirectionSense.Positive;
                IFCImportFile.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No DirectionSense defined, defaulting to Positive.", false);
            }
            else
            {
                DirectionSense = (IFCDirectionSense)Enum.Parse(typeof(IFCDirectionSense), directionSenseAsString, true);
            }

            bool found = false;

            Offset = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcMaterialLayerSetUsage, "OffsetFromReferenceLine", out found);
            if (!found)
            {
                IFCImportFile.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No Offset defined, defaulting to 0.", false);
            }
        }
Beispiel #14
0
        private void ProcessIFCEllipse(IFCAnyHandle ifcCurve, Transform transform)
        {
            bool   found   = false;
            double radiusX = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis1", out found);

            if (!found)
            {
                return;
            }

            double radiusY = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis2", out found);

            if (!found)
            {
                return;
            }

            Curve = Ellipse.Create(transform.Origin, radiusX, radiusY, transform.BasisX, transform.BasisY, 0, 2.0 * Math.PI);
        }
Beispiel #15
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);
            bool   found   = false;
            double radiusX = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis1", out found);

            if (!found)
            {
                Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the attribute SemiAxis1 of this curve", true);
            }

            double radiusY = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis2", out found);

            if (!found)
            {
                Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the attribute SemiAxis2 of this curve", true);
            }

            Curve = Ellipse.CreateCurve(Position.Origin, radiusX, radiusY, Position.BasisX, Position.BasisY, 0, 2.0 * Math.PI);
        }
Beispiel #16
0
        override protected void Process(IFCAnyHandle solid)
        {
            base.Process(solid);

            // We will not fail if the direction is not given, but instead assume it to be normal to the swept area.
            IFCAnyHandle direction = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "ExtrudedDirection", false);

            if (direction != null)
            {
                Direction = IFCPoint.ProcessNormalizedIFCDirection(direction);
            }
            else
            {
                Direction = XYZ.BasisZ;
            }

            bool found = false;

            Depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(solid, "Depth", out found);
            if (found && Depth < 0.0)
            {
                // Reverse depth and orientation.
                if (Application.IsValidThickness(-Depth))
                {
                    Depth     = -Depth;
                    Direction = -Direction;
                    IFCImportFile.TheLog.LogWarning(solid.StepId, "negative extrusion depth is invalid, reversing direction.", false);
                }
            }

            if (!found || !Application.IsValidThickness(Depth))
            {
                string depthAsString = UnitFormatUtils.Format(IFCImportFile.TheFile.Document.GetUnits(), UnitType.UT_Length, Depth,
                                                              true, false);
                IFCImportFile.TheLog.LogError(solid.StepId, "extrusion depth of " + depthAsString + " is invalid, aborting.", true);
            }
        }
Beispiel #17
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);

            bool   found  = false;
            double radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Radius", out found);

            if (!found)
            {
                Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the radius of this circle", false);
                return;
            }

            if (!IFCGeometryUtil.IsValidRadius(radius))
            {
                Importer.TheLog.LogError(ifcCurve.StepId, "Invalid radius for this circle: " + radius, false);
                return;
            }

            try
            {
                SetCurve(Arc.Create(Position.Origin, radius, 0, 2.0 * Math.PI, Position.BasisX, Position.BasisY));
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("too small"))
                {
                    string lengthAsString = IFCUnitUtil.FormatLengthAsString(radius);
                    Importer.TheLog.LogError(Id, "Found a circle with radius of " + lengthAsString + ", ignoring.", false);
                }
                else
                {
                    Importer.TheLog.LogError(Id, ex.Message, false);
                }
                SetCurve(null);
            }
        }
        protected override void Process(IFCAnyHandle ifcMaterialLayerSetUsage)
        {
            base.Process(ifcMaterialLayerSetUsage);

            IFCAnyHandle ifcMaterialLayerSet =
                IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcMaterialLayerSetUsage, "ForLayerSet", true);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterialLayerSet))
            {
                MaterialLayerSet = IFCMaterialLayerSet.ProcessIFCMaterialLayerSet(ifcMaterialLayerSet);
            }

            Direction = IFCEnums.GetSafeEnumerationAttribute(ifcMaterialLayerSetUsage, "LayerSetDirection", IFCLayerSetDirection.Axis3);

            DirectionSense = IFCEnums.GetSafeEnumerationAttribute(ifcMaterialLayerSetUsage, "DirectionSense", IFCDirectionSense.Positive);

            bool found = false;

            Offset = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcMaterialLayerSetUsage, "OffsetFromReferenceLine", out found);
            if (!found)
            {
                Importer.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No Offset defined, defaulting to 0.", false);
            }
        }
Beispiel #19
0
        /// <summary>
        /// Processes IfcProject attributes.
        /// </summary>
        /// <param name="ifcProjectHandle">The IfcProject handle.</param>
        protected override void Process(IFCAnyHandle ifcProjectHandle)
        {
            IFCAnyHandle unitsInContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcProjectHandle, "UnitsInContext", false);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unitsInContext))
            {
                IList <IFCAnyHandle> units = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitsInContext, "Units");

                if (units != null)
                {
                    m_UnitsInContext = new HashSet <IFCUnit>();

                    foreach (IFCAnyHandle unit in units)
                    {
                        IFCUnit ifcUnit = IFCImportFile.TheFile.IFCUnits.ProcessIFCProjectUnit(unit);
                        if (!IFCUnit.IsNullOrInvalid(ifcUnit))
                        {
                            m_UnitsInContext.Add(ifcUnit);
                        }
                    }
                }
                else
                {
                    Importer.TheLog.LogMissingRequiredAttributeError(unitsInContext, "Units", false);
                }
            }

            var application  = IFCImportFile.TheFile.Document.Application;
            var projectUnits = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length);

            IFCImportFile.TheFile.VertexTolerance     = application.VertexTolerance;
            IFCImportFile.TheFile.ShortCurveTolerance = application.ShortCurveTolerance;
            Importer.TheProcessor.PostProcessProject(projectUnits?.ScaleFactor, projectUnits?.Unit);

            // We need to process the units before we process the rest of the file, since we will scale values as we go along.
            base.Process(ifcProjectHandle);

            // process true north - take the first valid representation context that has a true north value.
            HashSet <IFCAnyHandle> repContexts = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcProjectHandle, "RepresentationContexts");

            bool   hasMapConv = false;
            XYZ    geoRef     = XYZ.Zero;
            string geoRefName = null;
            double trueNorth  = 0.0;

            if (repContexts != null)
            {
                foreach (IFCAnyHandle geomRepContextHandle in repContexts)
                {
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(geomRepContextHandle) &&
                        IFCAnyHandleUtil.IsSubTypeOf(geomRepContextHandle, IFCEntityType.IfcGeometricRepresentationContext))
                    {
                        IFCRepresentationContext context = IFCRepresentationContext.ProcessIFCRepresentationContext(geomRepContextHandle);
                        if (TrueNorthDirection == null && context.TrueNorth != null)
                        {
                            // TODO: Verify that we don't have inconsistent true norths.  If we do, warn.
                            TrueNorthDirection = new UV(context.TrueNorth.X, context.TrueNorth.Y);
                        }

                        if (WorldCoordinateSystem == null && context.WorldCoordinateSystem != null && !context.WorldCoordinateSystem.IsIdentity)
                        {
                            WorldCoordinateSystem = context.WorldCoordinateSystem;
                        }

                        // Process Map Conversion if any
                        HashSet <IFCAnyHandle> coordOperation = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(geomRepContextHandle, "HasCoordinateOperation");
                        if (coordOperation != null)
                        {
                            if (coordOperation.Count > 0)
                            {
                                if (IFCAnyHandleUtil.IsSubTypeOf(coordOperation.FirstOrDefault(), IFCEntityType.IfcMapConversion))
                                {
                                    hasMapConv = true;
                                    IFCAnyHandle mapConv  = coordOperation.FirstOrDefault();
                                    bool         found    = false;
                                    double       eastings = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "Eastings", out found);
                                    if (!found)
                                    {
                                        eastings = 0.0;
                                    }
                                    double northings = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "Northings", out found);
                                    if (!found)
                                    {
                                        northings = 0.0;
                                    }
                                    double orthogonalHeight = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "OrthogonalHeight", out found);
                                    if (!found)
                                    {
                                        orthogonalHeight = 0.0;
                                    }
                                    double xAxisAbs = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "XAxisAbscissa", 1.0);
                                    double xAxisOrd = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "XAxisOrdinate", 0.0);
                                    trueNorth = Math.Atan2(xAxisOrd, xAxisAbs);
                                    //angleToNorth = -((xAxisAngle > -Math.PI / 2.0) ? xAxisAngle - Math.PI / 2.0 : xAxisAngle + Math.PI * 1.5);
                                    double scale = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "Scale", 1.0);
                                    geoRef = new XYZ(scale * eastings, scale * northings, scale * orthogonalHeight);

                                    // Process the IfcProjectedCRS
                                    IFCAnyHandle projCRS = IFCAnyHandleUtil.GetInstanceAttribute(mapConv, "TargetCRS");
                                    if (projCRS != null && IFCAnyHandleUtil.IsSubTypeOf(projCRS, IFCEntityType.IfcProjectedCRS))
                                    {
                                        geoRefName = IFCImportHandleUtil.GetRequiredStringAttribute(projCRS, "Name", false);
                                        string       desc          = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "Description", null);
                                        string       geodeticDatum = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "GeodeticDatum", null);
                                        string       verticalDatum = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "VerticalDatum", null);
                                        string       mapProj       = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "MapProjection", null);
                                        string       mapZone       = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "MapZone", null);
                                        IFCAnyHandle mapUnit       = IFCImportHandleUtil.GetOptionalInstanceAttribute(projCRS, "MapUnit");

                                        Document    doc         = IFCImportFile.TheFile.Document;
                                        ProjectInfo projectInfo = doc.ProjectInformation;

                                        // We add this here because we want to make sure that external processors (e.g., Navisworks)
                                        // get a chance to add a container for the parameters that get added below.  In general,
                                        // we should probably augment Processor.AddParameter to ensure that CreateOrUpdateElement
                                        // is called before anything is attempted to be added.  This is a special case, though,
                                        // as in Revit we don't actually create an element for the IfcProject.
                                        Importer.TheProcessor.CreateOrUpdateElement(Id, GlobalId, EntityType.ToString(), CategoryId.IntegerValue, null);

                                        Category category = IFCPropertySet.GetCategoryForParameterIfValid(projectInfo, Id);
                                        IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.Name", geoRefName, Id);
                                        if (!string.IsNullOrEmpty(desc))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.Description", desc, Id);
                                        }
                                        if (!string.IsNullOrEmpty(geodeticDatum))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.GeodeticDatum", geodeticDatum, Id);
                                        }
                                        if (!string.IsNullOrEmpty(verticalDatum))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.VerticalDatum", verticalDatum, Id);
                                        }
                                        if (!string.IsNullOrEmpty(mapProj))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapProjection", mapProj, Id);
                                        }
                                        if (!string.IsNullOrEmpty(mapZone))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapZone", mapZone, Id);
                                        }
                                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(mapUnit))
                                        {
                                            IFCUnit mapUnitIfc = IFCUnit.ProcessIFCUnit(mapUnit);
                                            string  unitStr    = UnitUtils.GetTypeCatalogStringForUnit(mapUnitIfc.Unit);
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapUnit", unitStr, Id);
                                            double convFactor = UnitUtils.Convert(1.0, mapUnitIfc.Unit, IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length).Unit);
                                            eastings         = convFactor * eastings;
                                            northings        = convFactor * northings;
                                            orthogonalHeight = convFactor * orthogonalHeight;
                                            geoRef           = new XYZ(eastings, northings, orthogonalHeight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                ProjectLocation projectLocation = IFCImportFile.TheFile.Document.ActiveProjectLocation;
                ProjectPosition projectPosition;
                if (projectLocation != null)
                {
                    if (hasMapConv)
                    {
                        projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth);
                        projectLocation.SetProjectPosition(XYZ.Zero, projectPosition);

                        if (!string.IsNullOrEmpty(geoRefName))
                        {
                            IFCImportFile.TheFile.Document.SiteLocation.SetGeoCoordinateSystem(geoRefName);
                        }
                    }
                    else
                    {
                        // Set initial project location based on the information above.
                        // This may be further modified by the site.
                        trueNorth = 0.0;
                        if (TrueNorthDirection != null)
                        {
                            trueNorth = -Math.Atan2(-TrueNorthDirection.U, TrueNorthDirection.V);
                        }

                        // TODO: Extend this to work properly if the world coordinate system
                        // isn't a simple translation.
                        XYZ origin = XYZ.Zero;
                        if (WorldCoordinateSystem != null)
                        {
                            geoRef = WorldCoordinateSystem.Origin;
                            double angleRot = Math.Atan2(WorldCoordinateSystem.BasisX.Y, WorldCoordinateSystem.BasisX.X);

                            // If it is translation only, or if the WCS rotation is equal to trueNorth, we assume they are the same
                            if (WorldCoordinateSystem.IsTranslation ||
                                MathUtil.IsAlmostEqual(angleRot, trueNorth))
                            {
                                WorldCoordinateSystem = null;
                            }
                            else
                            {
                                // If the trueNorth is not set (=0), set the trueNorth by the rotation of the WCS, otherwise add the angle
                                if (MathUtil.IsAlmostZero(trueNorth))
                                {
                                    trueNorth = angleRot;
                                }
                                else
                                {
                                    trueNorth += angleRot;
                                }

                                WorldCoordinateSystem = null;
                            }
                        }

                        projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth);
                        projectLocation.SetProjectPosition(XYZ.Zero, projectPosition);
                    }
                }
            }
        }