Lesson 6: Selecting DatumShifts

Overview

GeoCalc provides multiple methods for getting DatumShifts.  If you know exactly what DatumShift you need, you can get it using the DataSource:;GetDatumShift method as described above in Lesson 4, or you can get it using the ObjectPicker or DataSourcePicker as described in Lesson 5.  Often, it is not known exactly which DatumShifts are needed, so the DataSource provides two methods to help you find the necessary DatumShifts.  These methods are called EstablishDatumShift and GetValidDatumShifts.  GeoCalc also provides a graphical way to find DatumShifts in the form of  the DatumShiftPicker dialog.  This dialog can be used to find all of the valid DatumShifts and select the best ones.

We will first need to create and load a DataSource, since this is what contains all of the DatumShift definitions we will want to select.  For more information about using the DataSource, see Lesson 4.  

[VB6]

Dim gcDataSource As New DataSource

gcDataSource.LoadFile ("c:\bmg\GeoCalcCOM\data\geocalc.xml")

 

[Delphi 7]

var

  gcDataSource : DataSource;

begin

  gcDataSource := CoDataSource.Create;

  gcDataSource.LoadFile('c:\bmg\GeoCalcCOM\data\geocalc.xml');

 

Method #1 - EstablishDatumShift

This method will allow you to specify some properties about the necessary DatumShifts, and then it will find some set of DatumShifts that satisfy these properties.  This method requires two arguments: a CoordTransform object and a DatumShiftPreferences object.  First, let's construct the CoordTransform.  We will go into more depth about CoordTransforms in Lesson 7 and Lesson 8, but here we will just set the SourceCoordSys and TargetCoordSys properties, which indicate the input and output systems of the coordinate transformation.

[VB6]

Dim ct As New CoordTransform

ct.SourceCoordSys = gcDataSource.GetProjectedCoordSys("BMG", "ME-27E")

ct.TargetCoordSys = gcDataSource.GetGeodeticCoordSys("BMG", "WGS84_coordinate_system")

 

[Delphi 7]

var

  ct : CoordTransform;

begin

  ct := CoCoordTransform.Create;

  ct.SourceCoordSys := gcDataSource.GetProjectedCoordSys('BMG', 'ME-27E');

  ct.TargetCoordSys := gcDataSource.GetGeodeticCoordSys('BMG', 'WGS94_coordinate_system');

Here, we have constructed a CoordTransform that will convert coordinates from the US State Plane 27 Maine East system to the WGS84 geodetic system.  Since these systems use different HorizontalDatums, we will need some DatumShifts in order to convert points.  Before we use the EstablishDatumShift method to get a set of DatumShifts, we must create a DatumShiftPreferences object that describes some properties about the necessary DatumShifts.  Suppose we want a set of DatumShifts that uses the Molodensky method, we don't care if the DatumShifts go through an intermediate HorizontalDatum, and we don't care about checking whether Envelopes match up.  Then we would construct the DatumShiftPreferences object like this:

[VB6]

Dim prefs As New DatumShiftPreferences

prefs.Method = dsMolodensky

prefs.Options = slDirect Or slViaIntermediary Or slIgnoreArea

 

[Delphi 7]

var

  prefs : DatumShiftPreferences;

begin

  prefs := CoDatumShiftPreferences.Create;

  prefs.Method := dsMolodensky;

  prefs.Options := slDirect or slViaIntermediary or slIgnoreArea;

Now we are ready to get our DatumShifts with a call to the EstablishDatumShift method:

[VB6]

If Not gcDataSource.EstablishDatumShift(ct, prefs) Then

    MsgBox ("EstablishDatumShift failed")

End If

 

[Delphi 7]

if not gcDataSource.EstablishDatumShift(ct, prefs) then

begin

  ShowMessage('EstablishDatumShift failed');

end;

If this method succeeds, then the CoordTransform::DatumShifts property will be populated with some DatumShifts that satisfy the properties described in the DatumShiftPreferences object and will shift from the SourceCoordSys to the TargetCoordSys of the CoordTransform.

 

Method #2 - GetValidDatumShifts

This method will find all sets of DatumShifts that satisfy our requirements and then let us decide which set will work best.  It requires four arguments, the first of which is the source ICoordSys for the desired DatumShifts, the second of which is the target ICoordSys for the DatumShifts, the third of which is a DatumShiftPreferencesEx object that describes the nature of the desired DatumShifts, and the fourth of which is a DatumShiftInfoSetCollection object that will hold information about the DatumShifts that fit our requirements.  Let's start by constructing a CoordTransform in the same way we did above.  Once again, we will go into more depth about the CoordTransform object in Lesson 7 and Lesson 8.

[VB6]

Dim ct As New CoordTransform

ct.SourceCoordSys = gcDataSource.GetProjectedCoordSys("BMG", "ME-27E")

ct.TargetCoordSys = gcDataSource.GetGeodeticCoordSys("BMG", "WGS84_coordinate_system")

 

[Delphi 7]

var

  ct : CoordTransform;

begin

  ct := CoCoordTransform.Create;

  ct.SourceCoordSys := gcDataSource.GetProjectedCoordSys('BMG', 'ME-27E');

  ct.TargetCoordSys := gcDataSource.GetGeodeticCoordSys('BMG', 'WGS84_coordinate_system');

Now we must construct a DatumShiftPreferencesEx object that describes the nature of the DatumShifts that we want.  Let's suppose we are interested in DatumShifts that use either the Molodensky or Bursa-Wolfe method, and that we don't care if the DatumShifts use an intermediate HorizontalDatum, or if the Envelopes match.  Then we would define our DatumShiftPreferencesEx like this:

[VB6]

Dim prefsEx As New DatumShiftPreferencesEx

prefsEx.BitFlags = dsbMolodensky Or dsbBursaWolfe

prefsEx.OnlyGoThruIntermediate = False

 

[Delphi 7]

var

  prefsEx : DatumShiftPreferencesEx;

begin

  prefsEx := CoDatumShiftPreferencesEx.Create;

  prefsEx.BitFlags := dsbMolodensky or dsbBursaWolfe;

  prefsEx.OnlyGoThruIntermediate := false;

There is one more step we must take before we will be ready to use the GetValidDatumShifts method: we must construct a DatumShiftInfoSetCollection object to hold the result of the method:

[VB6]

Dim shiftSets As New DatumShiftInfoSetCollection

 

[Delphi 7]

var

  shiftSets : DatumShiftInfoSetCollection;

begin

  shiftSets := CoDatumShiftInfoSetCollection.Create;

Now we are ready to find our DatumShifts:

[VB6]

If Not gcDataSource.GetValidDatumShifts(ct.SourceCoordSys, ct.TargetCoordSys, prefsEx, shiftSets) Then

    MsgBox ("GetValidDatumShifts failed")

End If

 

[Delphi 7]

if not gcDataSource.GetValidDatumShifts(ct.SourceCoordSys, ct.TargetCoordSys, prefsEx, shiftSets) then

begin

  ShowMessage('GetValidDatumShifts failed');

end;

We now have a DatumShiftInfoSetCollection that is full of some number of DatumShiftInfoSets, each of which is full of some number of DatumShiftInfo objects.  Each DatumShiftInfoSet represents a complete set of DatumShifts that will shift from our CoordTransform's SourceCoordSys to its TargetCoordSys.  Each DatumShiftInfo object contains all of the information necessary to get a DatumShift from the DataSource.  We are now presented with the task of determining which DatumShiftInfoSet should be used to populate our CoordTransform::DatumShifts property, and this task is outside the scope of this tutorial.  For this lesson, let's just use the first DatumShiftInfoSet in the collection:

[VB6]

ct.DatumShifts.Clear

Dim dsiSet As DatumShiftInfoSet

Dim dsi As DatumShiftInfo

Set dsiSet = shiftSets.Item(0)

Dim i As Integer

For i = 0 To dsiSet.Count - 1

    Set dsi = dsiSet.Item(i)

    Dim ds As DatumShift

    Set ds = gcDataSource.GetDatumShift("GC", dsi.Code)

    ds.ReverseUsage = dsi.ReverseUsage

    Set ds = ct.DatumShifts.InsertBack(ds)

Next

 

[Delphi 7]

var

  dsiSet : DatumShiftInfoSet;

  dsi : DatumShiftInfo;

  ds : DatumShift;

  index : integer;

begin

  ct.DatumShifts.Clear;

  dsiSet := shiftSets.Item[0];

  for index := 0 to dsiSet.Count - 1 do

  begin

    dsi := dsiSet.Item[index];

    ds := gcDataSource.GetDatumShift('GC', dsi.Code);

    ds.ReverseUsage := dsi.ReverseUsage;

    ds := ct.DatumShifts.InsertBack(ds);

  end;

Our CoordTransform now has all of the DatumShifts it will need to perform the transformation.  For more information about using CoordTransforms, see Lesson 7 and Lesson 8.

 

Method #3: DatumShiftPicker Dialog

The DatumShiftPicker dialog provides a graphical interface that accomplishes the same task as the GetValidDatumShfits method.  You supply the dialog with the source and target ICoordSys objects as well as a DatumShiftPreferencesEx object, and it finds all of the DatumShifts that meet those criteria.  Once the DatumShifts are found, they are displayed to the users so that the user can select which ones will work best.  The selected DatumShift objects are then put into a DatumShiftCollection for use by the user.

As with the previous methods, let's start by constructing a CoordTransform object.  We will go into more depth about the CoordTransform object in Lesson 7 and Lesson 8.

[VB6]

Dim ct As New CoordTransform

ct.SourceCoordSys = gcDataSource.GetProjectedCoordSys("BMG", "ME-27E")

ct.TargetCoordSys = gcDataSource.GetGeodeticCoordSys("BMG", "WGS84_coordinate_system")

 

[Delphi 7]

var

  ct : CoordTransform;

begin

  ct := CoCoordTransform.Create;

  ct.SourceCoordSys := gcDataSource.GetProjectedCoordSys('BMG', 'ME-27E');

  ct.TargetCoordSys := gcDataSource.GetGeodeticCoordSys('BMG', 'WGS84_coordinate_system');

Now we must construct a DatumShiftPreferencesEx object that describes the nature of the DatumShifts that we want.  Let's suppose we are interested in DatumShifts that use either the Molodensky or Bursa-Wolfe method, and that we don't care if the DatumShifts use an intermediate HorizontalDatum, or if the Envelopes match.  Then we would define our DatumShiftPreferencesEx like this:

[VB6]

Dim prefsEx As New DatumShiftPreferencesEx

prefsEx.BitFlags = dsbMolodensky Or dsbBursaWolfe

prefsEx.OnlyGoThruIntermediate = False

 

[Delphi 7]

var

  prefsEx : DatumShiftPreferencesEx;

begin

  prefsEx := CoDatumShiftPreferencesEx.Create;

  prefsEx.BitFlags := dsbMolodensky or dsbBursaWolfe;

  prefsEx.OnlyGoThruIntermediate := false;

We now have enough information to construct the DatumShiftPicker dialog.  After the object has been constructed, several properties must be set before the dialog can be displayed, including the DataSource property, the SourceCoordSys property, the TargetCoordSys property, and the DatumShiftPrefs property.  Here is how we will construct our DatumShiftPicker

[VB6]

Dim picker As New DatumShiftPicker

picker.DataSource = gcDataSource

picker.SourceCoordSys = ct.SourceCoordSys

picker.TargetCoordSys = ct.TargetCoordSys

picker.DatumShiftPrefs = prefsEx

 

[Delphi 7]

var

  picker : DatumShiftPicker;

begin

  picker := CoDatumShiftPicker.Create;

  picker.DataSource := gcDataSource;

  picker.SourceCoordSys := ct.SourceCoordSys;

  picker.TargetCoordSys := ct.TargetCoordSys;

  picker.DatumShiftPrefs := prefsEx;

Once it has been constructed, the DatumShiftPicker will not be displayed until we call the Show method.  The Show method requires a single argument, which is the DatumShiftCollection that will hold the DatumShifts that the user selects, and it returns a member of the DialogState enumeration that indicates the result of showing the dialog.  Here is how we show the dialog:

[VB6]

Dim retVal As DialogState

Dim selectedShifts As New DatumShiftCollection

retVal = picker.Show(selectedShifts)

If retVal = drsSuccess Then

    ct.SetDatumShifts selectedShifts

End If

 

[Delphi 7]

var

  selectedShifts : DatumShiftCollection;

  retVal : DialogState;

begin

  selectedShifts := CoDatumShiftCollection.Create;

  retVal := picker.Show(IDatumShiftCollection(selectedShifts));

  if retVal = drsSuccess then

  begin

    ct.SetDatumShifts(selectedShifts);

  end;

Here is an example of the appearance of the DatumShiftPicker dialog:

If the return value is either drsNoShiftNeeded or drsNoChoices, then the dialog was not ever shown.  The return value drsNoShiftNeeded indicates that the dialog was not shown because there was no DatumShift required to perform the CoordTransform.  This can occur when both the SourceCoordSys and the TargetCoordSys use the same HorizontalDatum.  The return value drsNoChoices indicates that a DatumShift is required for the CoordTransform, but a suitable DatumShift could not be found in the DataSource.  This can occur if the SourceCoordSys and TargetCoordSys use user-defined HorizontalDatum for which there are not DatumShifts.  If the return value is drsCancel, then the user clicked the Cancel button.  If the return value is drsSuccess, then the dialog was displayed, the user selected some DatumShifts, and the selected DatumShifts were put into the DatumShiftCollection passed to the Show method.

The DatumShiftPicker dialog also provides the option of choosing to not to apply any DatumShifts to the CoordTransform.  This option can be selected by choosing "None" in the Category Pane of the DatumShiftPicker.  Users should be aware that some coordinate shift may occur when shifting between ProjectedCoordSys' even though no DatumShift is being used.  This can be occur if the source and target HorizontalDatums use different Ellipsoids.