Introduction

The MicroStationAPI provides an API for developers wanting to create custom applications for MicroStation® from Bentley Systems.

We usually create a MicroStation application as a DLL, written using C++ and built with the Microsoft C++ compiler and linker. You can choose whether to use Microsoft Visual Studio or the Bentley Systems make (bmake) tools.

This example uses the MicroStationAPI in a C++ project. The project is built using Bentley make (bmake) or Visual Studio. It uses the C++ compiler and linker provided by Visual Studio.

What is Unit Conversion?

A MicroStation user creates a DGN model in 2D or 3D space. Metrics in that space are defined by the design units, which are sized to fit the user's familiar measurements. Distances may be measured in metres, feet, or miles and areas measured in square metres, square feet. Area metrics include acres and hectares.

Unit conversions are, on the face of it, simple. For example, 1 yard = 0.9144 metre. However, for a programmer who does not know the system currently in use, it's not so clear. For example, suppose I want to calculate the area of a field in acres, but I don't know the current DGN settings.

Bentley::DgnPlatform::UnitDefinition

The MicroStationAPI provides the UnitDefinition class. It's purpose is to let the programmer establish an identity for a particular system of units. For example, you might create a metric UnitDefinition for units in metres, or an Imperial UnitDefinition for units in feet.

The UnitDefinition lets us create a set of unit systems or derive one from the current DGN settings. We can compare one UnitDefinition against another, and obtain a conversion factor (CF) that lets us convert a distance in one system to an alternative system.

UnitConverter Class

Here's the formal definition of a UnitConverter class …

struct UnitConverter
{
    ///  A static initialiser obtains its definition from the active DGN model.
    static Bentley::DgnPlatform::UnitDefinition  GetMasterUnitDefinition ();
    ///  The UnitDefinition of the active model at the point of creation.
    const Bentley::DgnPlatform::UnitDefinition  masterUnitSystem_;
    ///  Return the UnitDefinition of the active DGN model.
    const Bentley::DgnPlatform::UnitDefinition&  MasterUnitDefinition ()  const { return masterUnitSystem_; }
    ///  The UnitDefinition of a metric system.
    const Bentley::DgnPlatform::UnitDefinition  metricUnitSystem_;
    ///  Return the UnitDefinition of a metric system.
    const Bentley::DgnPlatform::UnitDefinition&  MetricUnitDefinition ()  const { return metricUnitSystem_; }
    ///  Conversion factor from active DGN model to metric.
    double  ConvertActiveToMetric ()  const;
    ///  Conversion factor from another UnitSystem to metric.
    double  ConvertToMetric (UnitDefinitionCR  ud)  const;
    //  Construction
    UnitConverter ();
};

Here's the implementation of UnitConverter …

// static
Bentley::DgnPlatform::UnitDefinition  UnitConverter::GetMasterUnitDefinition ()
{
  DgnModelP      model { ISessionMgr::GetActiveDgnModelP () };
  ModelInfoCR    info  { model->GetModelInfo () };
  return info.GetMasterUnit ();
}
//  Constructor
UnitConverter::UnitConverter ()
  :   masterUnitSystem_  (GetMasterUnitDefinition ()),
      metricUnitSystem_  (Bentley::DgnPlatform::UnitBase::Meter, Bentley::DgnPlatform::UnitSystem::Metric, 1., 1., L"m")
{
}

Calculate the conversion factor from the active DGN model to a metric system based on metres …

double  UnitConverter::ConvertActiveToMetric ()  const
{
  double d { 0.0 };
  if (SUCCESS != metricUnitSystem_.GetConversionFactorFrom (d, masterUnitSystem_))
  {
    const WString  alert (L"UnitConverter::ConvertActiveToMetric failed");
    mdlOutput_messageCenter (Bentley::DgnPlatform::OutputMessagePriority::Warning, alert.c_str (), alert.c_str (), Bentley::DgnPlatform::OutputMessageAlert::Balloon);
  }
  return d;
}

Calculate the conversion factor from a programmer-defined UnitConverter to a metric system based on metres …

double  UnitConverter::ConvertToMetric (UnitDefinitionCR  ud)  const
{
  double d  { 0.0 };
  if (SUCCESS != metricUnitSystem_.GetConversionFactorFrom (d, ud))
  {
    const WString  alert (L"UnitConverter::ConvertToMetric failed");
    mdlOutput_messageCenter (Bentley::DgnPlatform::OutputMessagePriority::Warning, alert.c_str (), alert.c_str (), Bentley::DgnPlatform::OutputMessageAlert::Balloon);
  }
  return d;
}

UnitConverter Class

Using this class is straightforward …

UnitConverter converter;  //  Constructor creates data from your active DGN model
//	Convert from active DGN units to metric
double	conversionFactor = converter.ConvertActiveToMetric ();
//  Create an Imperial UnitDefinition for comparison
UnitDefinition unitDef (Bentley::DgnPlatform::UnitBase::Meter, Bentley::DgnPlatform::UnitSystem::English, 0.3048, 1., L"ft");
double	cf_feetToMetres = converter.ConvertToMetric (unitDef);

Return to MicroStationAPI articles index.