Example #1
0
        /// <summary>
        /// Processes an IFC unit in the property.
        /// </summary>
        /// <param name="ifcSimpleProperty">The simple property.</param>
        /// <param name="simplePropertyHandle">The simple property handle.</param>
        static protected void ProcessIFCSimplePropertyUnit(IFCSimpleProperty ifcSimpleProperty, IFCAnyHandle simplePropertyHandle)
        {
            IFCAnyHandle ifcUnitHandle = IFCImportHandleUtil.GetOptionalInstanceAttribute(simplePropertyHandle, "Unit");
            IFCUnit      ifcUnit       = (ifcUnitHandle != null) ? IFCUnit.ProcessIFCUnit(ifcUnitHandle) : null;

            if (ifcUnit == null)
            {
                if (ifcSimpleProperty.IFCPropertyValues.Count > 0)
                {
                    IFCPropertyValue propertyValue = ifcSimpleProperty.IFCPropertyValues[0];
                    if (propertyValue != null && propertyValue.HasValue() &&
                        (propertyValue.Type == IFCDataPrimitiveType.Integer) || (propertyValue.Type == IFCDataPrimitiveType.Double))
                    {
                        string   unitTypeName;
                        UnitType unitType = IFCDataUtil.GetUnitTypeFromData(propertyValue.Value, UnitType.UT_Undefined, out unitTypeName);
                        if (unitType != UnitType.UT_Undefined)
                        {
                            ifcUnit = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(unitType);
                        }
                        else
                        {
                            Importer.TheLog.LogWarning(simplePropertyHandle.StepId, "Unhandled unit type: " + unitTypeName, true);
                        }
                    }
                }
            }

            ifcSimpleProperty.m_IFCUnit = ifcUnit;
        }
Example #2
0
        /// <summary>
        /// Processes an IFC physical simple quantity.
        /// </summary>
        /// <param name="ifcPhysicalQuantity">The IfcPhysicalSimpleQuantity object.</param>
        /// <returns>The IFCPhysicalSimpleQuantity object.</returns>
        override protected void Process(IFCAnyHandle ifcPhysicalSimpleQuantity)
        {
            base.Process(ifcPhysicalSimpleQuantity);

            IFCAnyHandle unit = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcPhysicalSimpleQuantity, "Unit");

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unit))
            {
                IFCUnit = IFCUnit.ProcessIFCUnit(unit);
            }

            // Process subtypes of IfcPhysicalSimpleQuantity here.
            string attributeName = ifcPhysicalSimpleQuantity.TypeName.Substring(11) + "Value";

            Value        = ifcPhysicalSimpleQuantity.GetAttribute(attributeName);
            BaseUnitType = IFCDataUtil.GetUnitTypeFromData(Value, UnitType.UT_Undefined);

            if (BaseUnitType == UnitType.UT_Undefined)
            {
                // Determine it from the attributeName.
                if (string.Compare(attributeName, "LengthValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Length;
                }
                else if (string.Compare(attributeName, "AreaValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Area;
                }
                else if (string.Compare(attributeName, "VolumeValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Volume;
                }
                else if (string.Compare(attributeName, "CountValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Number;
                }
                else if (string.Compare(attributeName, "WeightValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Mass;
                }
                else if (string.Compare(attributeName, "TimeValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Number; // No time unit type in Revit.
                }
                else
                {
                    Importer.TheLog.LogWarning(Id, "Can't determine unit type for IfcPhysicalSimpleQuantity of type: " + attributeName, true);
                    BaseUnitType = UnitType.UT_Number;
                }
            }


            if (IFCUnit == null)
            {
                IFCUnit = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(BaseUnitType);
            }
        }
Example #3
0
        /// <summary>
        /// Processes a project unit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        /// <returns>The Unit object.</returns>
        public IFCUnit ProcessIFCProjectUnit(IFCAnyHandle unitHnd)
        {
            IFCUnit unit = IFCUnit.ProcessIFCUnit(unitHnd);

            if (unit != null)
            {
                m_ProjectUnitsDictionary[unit.Spec] = unit;
            }

            return(unit);
        }
Example #4
0
        /// <summary>
        /// Processes a conversion based unit.
        /// </summary>
        /// <param name="convUnitHnd">The unit handle.</param>
        void ProcessIFCConversionBasedUnit(IFCAnyHandle convUnitHnd)
        {
            IFCAnyHandle measureWithUnitHnd = IFCAnyHandleUtil.GetInstanceAttribute(convUnitHnd, "ConversionFactor");

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(measureWithUnitHnd))
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Missing required attribute ConversionFactor.");
            }

            IFCUnit measureWithUnit = IFCUnit.ProcessIFCUnit(measureWithUnitHnd);

            if (measureWithUnit == null)
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Invalid base ConversionFactor, aborting.");
            }

            CopyUnit(measureWithUnit);

            // For some common cases, get the units correct.
            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(convUnitHnd, "UnitType");

            if (string.Compare(unitType, "LENGTHUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Length;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "FOOT", true) == 0 ||
                    string.Compare(name, "FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_FEET_FRACTIONAL_INCHES;
                    UnitSymbol = UnitSymbolType.UST_NONE;
                }
                else if (string.Compare(name, "INCH", true) == 0 ||
                         string.Compare(name, "INCHES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_FRACTIONAL_INCHES;
                    UnitSymbol = UnitSymbolType.UST_NONE;
                }
            }
            else if (string.Compare(unitType, "PLANEANGLEUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Angle;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "GRAD", true) == 0 ||
                    string.Compare(name, "GRADIAN", true) == 0 ||
                    string.Compare(name, "GRADS", true) == 0 ||
                    string.Compare(name, "GRADIANS", true) == 0)
                {
                    UnitSystem = UnitSystem.Metric;
                    UnitName   = UnitName.DUT_GRADS;
                    UnitSymbol = UnitSymbolType.UST_GRAD;
                }
                else if (string.Compare(name, "DEGREE", true) == 0 ||
                         string.Compare(name, "DEGREES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_DECIMAL_DEGREES;
                    UnitSymbol = UnitSymbolType.UST_DEGREE_SYMBOL;
                }
            }
            else if (string.Compare(unitType, "AREAUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Area;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "SQUARE FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE_FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE FEET", true) == 0 ||
                    string.Compare(name, "SQUARE_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_SQUARE_FEET;
                    UnitSymbol = UnitSymbolType.UST_FT_SUP_2;
                }
            }
            else if (string.Compare(unitType, "VOLUMEUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Volume;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "CUBIC FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC_FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC FEET", true) == 0 ||
                    string.Compare(name, "CUBIC_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_CUBIC_FEET;
                    UnitSymbol = UnitSymbolType.UST_FT_SUP_3;
                }
            }
            else if (string.Compare(unitType, "THERMODYNAMICMEASUREUNIT", true) == 0)
            {
                UnitType = UnitType.UT_HVAC_Temperature;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if ((string.Compare(name, "F", true) == 0) ||
                    (string.Compare(name, "FAHRENHEIT", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_FAHRENHEIT;
                    UnitSymbol = UnitSymbolType.UST_DEGREE_F;
                }
                else if ((string.Compare(name, "R", true) == 0) ||
                         (string.Compare(name, "RANKINE", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_RANKINE;
                    UnitSymbol = UnitSymbolType.UST_DEGREE_R;
                }
            }
        }
Example #5
0
        /// <summary>
        /// Processes an IfcDerivedUnit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd)
        {
            List <IFCAnyHandle> elements =
                IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements");

            IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >();

            foreach (IFCAnyHandle subElement in elements)
            {
                IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false);
                IFCUnit      subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd);
                if (subUnit != null)
                {
                    bool found;
                    int  exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found);
                    if (found)
                    {
                        derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent));
                    }
                }
            }

            // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit.
            // The IList allows for possible different interpretations.  For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time).
            IList <DerivedUnitExpectedTypes> expectedTypesList = new List <DerivedUnitExpectedTypes>();

            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType");

            if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_Velocity;
                UnitSystem = UnitSystem.Metric;

                // Support only m / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_METERS_PER_SECOND, UnitSymbolType.UST_M_PER_S);
                expectedTypes.AddExpectedType(1, UnitType.UT_Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_CoefficientOfHeatTransfer;
                UnitSystem = UnitSystem.Metric;

                // Support W / (K * m^2) or kg / (K * s^3)
                DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
                expectedTypesWinvKinvM2.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvM2.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
                expectedTypesWinvKinvM2.AddExpectedType(-2, UnitType.UT_Length);
                expectedTypesList.Add(expectedTypesWinvKinvM2);

                DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
                expectedTypesWinvKinvArea.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
                expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_Area);
                expectedTypesList.Add(expectedTypesWinvKinvArea);

                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
                expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                expectedTypes.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
                expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_Airflow;
                UnitSystem = UnitSystem.Metric;

                // Support L / s or m^3 / s in the IFC file.

                // L / s
                DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitName.DUT_LITERS_PER_SECOND, UnitSymbolType.UST_L_PER_S);
                expectedTypesLPerS.AddExpectedType(1, UnitType.UT_Volume);
                expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypesLPerS);

                // m^3 / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_CUBIC_METERS_PER_SECOND, UnitSymbolType.UST_CU_M_PER_S);
                expectedTypes.AddExpectedType(3, UnitType.UT_Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "MASSDENSITYUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_MassDensity;
                UnitSystem = UnitSystem.Metric;

                // Support kg / m^3 in the IFC file.

                // kg / m^3.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_KILOGRAMS_PER_CUBIC_METER, UnitSymbolType.UST_KG_PER_CU_M);
                expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                expectedTypes.AddExpectedType(-3, UnitType.UT_Length);
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "USERDEFINED", true) == 0)
            {
                // Look at the sub-types to see what we support.
                string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null);
                if (!string.IsNullOrWhiteSpace(userDefinedType))
                {
                    if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0)
                    {
                        UnitType   = UnitType.UT_Electrical_Efficacy;
                        UnitSystem = UnitSystem.Metric;

                        // Support only lm / W.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_LUMENS_PER_WATT, UnitSymbolType.UST_LM_PER_W);
                        expectedTypes.AddExpectedType(-1, UnitType.UT_Mass);
                        expectedTypes.AddExpectedType(-2, UnitType.UT_Length);
                        expectedTypes.AddCustomExpectedType(3, "TIMEUNIT");
                        expectedTypes.AddExpectedType(1, UnitType.UT_Electrical_Luminous_Flux);
                        expectedTypesList.Add(expectedTypes);
                    }
                    else if (string.Compare(userDefinedType, "Friction Loss", true) == 0)
                    {
                        UnitType   = UnitType.UT_HVAC_Friction;
                        UnitSystem = UnitSystem.Metric;

                        // Support only Pa / m.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_PASCALS_PER_METER, UnitSymbolType.UST_PASCAL_PER_M);
                        expectedTypes.AddExpectedType(-2, UnitType.UT_Length);
                        expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                        expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT");
                        expectedTypesList.Add(expectedTypes);
                    }
                }
            }

            foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList)
            {
                double scaleFactor = 1.0;
                if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor))
                {
                    // Found a match.
                    UnitName    = derivedUnitExpectedTypes.UnitName;
                    UnitSymbol  = derivedUnitExpectedTypes.UnitSymbol;
                    ScaleFactor = scaleFactor;
                    return;
                }
            }

            Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType);
        }
Example #6
0
        /// <summary>
        /// Processes a conversion based unit.
        /// </summary>
        /// <param name="convUnitHnd">The unit handle.</param>
        void ProcessIFCConversionBasedUnit(IFCAnyHandle convUnitHnd)
        {
            IFCAnyHandle measureWithUnitHnd = IFCAnyHandleUtil.GetInstanceAttribute(convUnitHnd, "ConversionFactor");

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(measureWithUnitHnd))
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Missing required attribute ConversionFactor.");
            }

            IFCUnit measureWithUnit = IFCUnit.ProcessIFCUnit(measureWithUnitHnd);

            if (measureWithUnit == null)
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Invalid base ConversionFactor, aborting.");
            }

            CopyUnit(measureWithUnit);

            // For some common cases, get the units correct.
            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(convUnitHnd, "UnitType");

            if (string.Compare(unitType, "LENGTHUNIT", true) == 0)
            {
                Spec = SpecTypeId.Length;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "FOOT", true) == 0 ||
                    string.Compare(name, "FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.FeetFractionalInches;
                    Symbol     = new ForgeTypeId();
                }
                else if (string.Compare(name, "INCH", true) == 0 ||
                         string.Compare(name, "INCHES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.FractionalInches;
                    Symbol     = new ForgeTypeId();
                }
            }
            else if (string.Compare(unitType, "PLANEANGLEUNIT", true) == 0)
            {
                Spec = SpecTypeId.Angle;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "GRAD", true) == 0 ||
                    string.Compare(name, "GRADIAN", true) == 0 ||
                    string.Compare(name, "GRADS", true) == 0 ||
                    string.Compare(name, "GRADIANS", true) == 0)
                {
                    UnitSystem = UnitSystem.Metric;
                    Unit       = UnitTypeId.Gradians;
                    Symbol     = SymbolTypeId.Grad;
                }
                else if (string.Compare(name, "DEGREE", true) == 0 ||
                         string.Compare(name, "DEGREES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.Degrees;
                    Symbol     = SymbolTypeId.Degree;
                }
            }
            else if (string.Compare(unitType, "AREAUNIT", true) == 0)
            {
                Spec = SpecTypeId.Area;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "SQUARE FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE_FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE FEET", true) == 0 ||
                    string.Compare(name, "SQUARE_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.SquareFeet;
                    Symbol     = SymbolTypeId.FtSup2;
                }
            }
            else if (string.Compare(unitType, "VOLUMEUNIT", true) == 0)
            {
                Spec = SpecTypeId.Volume;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "CUBIC FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC_FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC FEET", true) == 0 ||
                    string.Compare(name, "CUBIC_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.CubicFeet;
                    Symbol     = SymbolTypeId.FtSup3;
                }
            }
            else if (string.Compare(unitType, "THERMODYNAMICMEASUREUNIT", true) == 0)
            {
                Spec = SpecTypeId.HvacTemperature;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if ((string.Compare(name, "F", true) == 0) ||
                    (string.Compare(name, "FAHRENHEIT", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.Fahrenheit;
                    Symbol     = SymbolTypeId.DegreeF;
                }
                else if ((string.Compare(name, "R", true) == 0) ||
                         (string.Compare(name, "RANKINE", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.Rankine;
                    Symbol     = SymbolTypeId.DegreeR;
                }
            }
        }
Example #7
0
        /// <summary>
        /// Processes an IfcDerivedUnit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd)
        {
            List <IFCAnyHandle> elements =
                IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements");

            IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >();

            foreach (IFCAnyHandle subElement in elements)
            {
                IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false);
                IFCUnit      subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd);
                if (subUnit != null)
                {
                    bool found;
                    int  exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found);
                    if (found)
                    {
                        derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent));
                    }
                }
            }

            // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit.
            // The IList allows for possible different interpretations.  For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time).
            IList <DerivedUnitExpectedTypes> expectedTypesList = new List <DerivedUnitExpectedTypes>();

            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType");

            if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0)
            {
                Spec       = SpecTypeId.HvacVelocity;
                UnitSystem = UnitSystem.Metric;

                // Support only m / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.MetersPerSecond, SymbolTypeId.MPerS);
                expectedTypes.AddExpectedType(1, SpecTypeId.Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.HeatTransferCoefficient;
                UnitSystem = UnitSystem.Metric;

                // Support W / (K * m^2) or kg / (K * s^3)
                DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K);
                expectedTypesWinvKinvM2.AddExpectedType(1, SpecTypeId.HvacPower); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvM2.AddExpectedType(-1, SpecTypeId.HvacTemperature);
                expectedTypesWinvKinvM2.AddExpectedType(-2, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypesWinvKinvM2);

                DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K);
                expectedTypesWinvKinvArea.AddExpectedType(1, SpecTypeId.HvacPower); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvArea.AddExpectedType(-1, SpecTypeId.HvacTemperature);
                expectedTypesWinvKinvArea.AddExpectedType(-1, SpecTypeId.Area);
                expectedTypesList.Add(expectedTypesWinvKinvArea);

                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K);
                expectedTypes.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes.AddExpectedType(-1, SpecTypeId.HvacTemperature);
                expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.AirFlow;
                UnitSystem = UnitSystem.Metric;

                // Support L / s or m^3 / s in the IFC file.

                // L / s
                DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitTypeId.LitersPerSecond, SymbolTypeId.LPerS);
                expectedTypesLPerS.AddExpectedType(1, SpecTypeId.Volume);
                expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypesLPerS);

                // m^3 / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CubicMetersPerSecond, SymbolTypeId.MSup3PerS);
                expectedTypes.AddExpectedType(3, SpecTypeId.Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "MASSDENSITYUNIT", true) == 0)
            {
                Spec       = SpecTypeId.MassDensity;
                UnitSystem = UnitSystem.Metric;

                // Support kg / m^3 in the IFC file.

                // kg / m^3.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilogramsPerCubicMeter, SymbolTypeId.KgPerMSup3);
                expectedTypes.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes.AddExpectedType(-3, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "LINEARFORCEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.LinearForce;
                UnitSystem = UnitSystem.Metric;

                // Support N / m in the IFC file.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerMeter, SymbolTypeId.NPerM);
                expectedTypes.AddExpectedType(1, SpecTypeId.LinearForce);
                expectedTypesList.Add(expectedTypes);

                // Support N / m in basic units
                DerivedUnitExpectedTypes expectedTypes2 = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerMeter, SymbolTypeId.NPerM);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Length);
                expectedTypes2.AddCustomExpectedType(-2, "TIMEUNIT");
                expectedTypes2.AddExpectedType(-1, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypes2);
            }
            else if (string.Compare(unitType, "PLANARFORCEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.AreaForce;
                UnitSystem = UnitSystem.Metric;

                // Support N / m^2 in the IFC file.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerSquareMeter, SymbolTypeId.NPerMSup2);
                expectedTypes.AddExpectedType(1, SpecTypeId.AreaForce);
                expectedTypesList.Add(expectedTypes);

                // Support N / m in basic units
                DerivedUnitExpectedTypes expectedTypes2 = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerSquareMeter, SymbolTypeId.NPerMSup2);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Length);
                expectedTypes2.AddCustomExpectedType(-2, "TIMEUNIT");
                expectedTypes2.AddExpectedType(-2, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypes2);
            }
            else if (string.Compare(unitType, "USERDEFINED", true) == 0)
            {
                // Look at the sub-types to see what we support.
                string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null);
                if (!string.IsNullOrWhiteSpace(userDefinedType))
                {
                    if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0)
                    {
                        Spec       = SpecTypeId.Efficacy;
                        UnitSystem = UnitSystem.Metric;

                        // Support only lm / W.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.LumensPerWatt, SymbolTypeId.LmPerW);
                        expectedTypes.AddExpectedType(-1, SpecTypeId.Mass);
                        expectedTypes.AddExpectedType(-2, SpecTypeId.Length);
                        expectedTypes.AddCustomExpectedType(3, "TIMEUNIT");
                        expectedTypes.AddExpectedType(1, SpecTypeId.LuminousFlux);
                        expectedTypesList.Add(expectedTypes);
                    }
                    else if (string.Compare(userDefinedType, "Friction Loss", true) == 0)
                    {
                        Spec       = SpecTypeId.HvacFriction;
                        UnitSystem = UnitSystem.Metric;

                        // Support only Pa / m.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM);
                        expectedTypes.AddExpectedType(-2, SpecTypeId.Length);
                        expectedTypes.AddExpectedType(1, SpecTypeId.Mass);
                        expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT");
                        expectedTypesList.Add(expectedTypes);
                    }
                }
            }

            foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList)
            {
                double scaleFactor = 1.0;
                if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor))
                {
                    // Found a match.
                    Unit        = derivedUnitExpectedTypes.Unit;
                    Symbol      = derivedUnitExpectedTypes.Symbol;
                    ScaleFactor = scaleFactor;
                    return;
                }
            }

            Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType);
        }
Example #8
0
        /// <summary>
        /// Processes an IfcDerivedUnit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd)
        {
            List <IFCAnyHandle> elements =
                IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements");

            IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >();

            foreach (IFCAnyHandle subElement in elements)
            {
                IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false);
                IFCUnit      subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd);
                if (subUnit != null)
                {
                    bool found;
                    int  exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found);
                    if (found)
                    {
                        derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent));
                    }
                }
            }

            ISet <Tuple <int, UnitType, string> > expectedTypes = new HashSet <Tuple <int, UnitType, string> >();

            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType");

            if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_CoefficientOfHeatTransfer;
                UnitSystem = UnitSystem.Metric;
                UnitName   = UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN;

                // Support only kg / (K * s^3).
                expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(1, UnitType.UT_Mass, null));
                expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-1, UnitType.UT_HVAC_Temperature, null));
                expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-3, UnitType.UT_Custom, "TIMEUNIT"));
            }
            else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_Airflow;
                UnitSystem = UnitSystem.Metric;
                UnitName   = UnitName.DUT_CUBIC_METERS_PER_SECOND;

                // Support only m^3 / s.
                expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(3, UnitType.UT_Length, null));
                expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-1, UnitType.UT_Custom, "TIMEUNIT"));
            }
            else if (string.Compare(unitType, "USERDEFINED", true) == 0)
            {
                // Look at the sub-types to see what we support.
                string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null);
                if (!string.IsNullOrWhiteSpace(userDefinedType))
                {
                    if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0)
                    {
                        UnitType   = UnitType.UT_Electrical_Efficacy;
                        UnitSystem = UnitSystem.Metric;
                        UnitName   = UnitName.DUT_LUMENS_PER_WATT;

                        // Support only lm / W.
                        expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-1, UnitType.UT_Mass, null));
                        expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-2, UnitType.UT_Length, null));
                        expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(3, UnitType.UT_Custom, "TIMEUNIT"));
                        expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(1, UnitType.UT_Electrical_Luminous_Flux, null));
                    }
                }
            }

            double scaleFactor = 1.0;

            if (derivedElementUnitHnds.Count == expectedTypes.Count)
            {
                foreach (KeyValuePair <IFCUnit, int> derivedElementUnitHnd in derivedElementUnitHnds)
                {
                    int dimensionality = derivedElementUnitHnd.Value;
                    Tuple <int, UnitType, string> currKey = new Tuple <int, UnitType, string>(dimensionality, derivedElementUnitHnd.Key.UnitType, derivedElementUnitHnd.Key.CustomUnitType);
                    if (expectedTypes.Contains(currKey))
                    {
                        expectedTypes.Remove(currKey);
                        scaleFactor *= Math.Pow(derivedElementUnitHnd.Key.ScaleFactor, dimensionality);
                    }
                    else
                    {
                        break;
                    }
                }

                // Found all supported units.
                if (expectedTypes.Count == 0)
                {
                    ScaleFactor = scaleFactor;
                    return;
                }
            }

            IFCImportFile.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType);
        }
Example #9
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);
                    }
                }
            }
        }