You are here: > ESRI Forums > arcgis desktop discussion forums > Thread Replies

ArcGIS Desktop Discussion Forums

ArcGIS Desktop - ArcObjects Visual Basic for Application (VBA) forum

ArcView 3.2 Distance Calculation between tw...   Vsunkara Sunkara Jul 01, 2002
Re: ArcView 3.2 Distance Calculation betwee...   srivatsava sunkara Jul 01, 2002
Re: ArcView 3.2 Distance Calculation betwee...   Vsunkara Sunkara Jul 02, 2002
Re: ArcView 3.2 Distance Calculation betwee...   Vsunkara Sunkara Jul 02, 2002
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject ArcView 3.2 Distance Calculation between two theme points - Need help desperately 
Author Vsunkara Sunkara 
Date Jul 01, 2002 
Message Hi VBA experts,

I desperately need help converting the distance.apr avenue script to VBA. Basically, what I am trying to do is find the distance between two point themes in ArcMap and populate the attribute table with the distance field(Exactly what the measure dialog does in ArcView Gis 3.2 to calculate distance To and From two theme points)

Has anyone written similar code in VBA or has an approach to do the same in ArcMap? Please advise. I'm new to VBA and would truly appreciate any help.

Below is the avenue script from ArcView 3.2

Thanks,
Vasanthi. 
 
'This script is a variation of the calcdist.ave sample script.  Calcdist.ave 
'calculates distances from every selected point in one point point theme to every point
'in another point theme. 
'
'This script will only calculate distances between points that have a common id value. 
'
'Before running this script, make sure you know what point themes you are calculating 
'distances FROM and TO. The distance values will be added to the TO theme. 
'
'If the FROM theme has features selected, then calculations will be made from only 
'the selected FROM features. If no features are selected, then calculations will be
'made for all FROM features.
'
'Keep in mind that the two themes have to have common ID values, or else no 
'caluculations will be made

theThemeList = av.GetActiveDoc.GetThemes.Clone
newThemeList = {}

for each thm in theThemeList
  if (thm.getftab.findfield("shape").gettype = #FIELD_ShapePOINT) then
    newThemeList.add(thm)
  end
end   

thePrj = av.GetActiveDoc.GetProjection

'  Use these lines to prompt the user for input parameters...
theFromTheme = (MsgBox.List(newThemeList,"to calculate the distance FROM.","Please select a point theme..."))
if (theFromTheme = nil) then exit end 
theFromFtab = theFromTheme.GetFTab
newThemeList.RemoveObj(theFromTheme)   
theToTheme = (MsgBox.List(newThemeList,"to calculate the distance TO.","Please select a point theme..."))
if (theToTheme = nil) then exit end  
theToFtab = theToTheme.GetFTab
theFromIDField = MsgBox.ListAsString(theFromFtab.GetFields,"containing the point identifier.","From Theme: Please select a field...")
  if (theFromIDField = nil) then
    exit
  end 
theToIDField = MsgBox.ListAsString(theToFtab.GetFields,"containing the point identifier.","To Theme: Please select a field...")
  if (theToIDField = nil) then
    exit
  end                                                          

theFromShapeField = theFromFTab.FindField("Shape")            
theToShapeField = theToFtab.FindField("Shape")

theToFtab.SetEditable(true)

theNewFieldName = msgbox.input("WARNING: If the field name already exists in the table, its values will get overwritten","Input a field name for your new distance field:","dist_2_id(x)")
  
' If a distance field doesn't exist, add it...
if (theToFtab.FindField(theNewFieldName) = nil) then
  
'   Choose the field size commensurate with the view's projection.
  if (thePrj.IsNull) then
    theDistanceField = field.make(theNewFieldName,#field_decimal,16,4)
  else
    theDistanceField = field.make(theNewFieldName,#field_decimal,18,4)
  end
      
    theToFtab.addfields({theDistanceField})
' If a distance field does exist, clear it...    
else
  if (theToFtab.FindField(theNewFieldName).IsTypeString = true) then
    MsgBox.Info("Your input field name cannot be overwritten with number values","Please start over and select a different field name...")
    exit
  end  
  theToFtab.Calculate("0",theToFtab.FindField(theNewFieldName))
  theDistanceField = theToFTab.FindField(theNewFieldName)  
end 

if (theFromFtab.GetSelection.Count = 0) then
  theRecordsToCalc = theFromFtab
  numRecs = theFromFtab.GetNumRecords
else
  theRecordsToCalc = theFromFtab.GetSelection
  numRecs = theRecordsToCalc.Count
end

for each f in theRecordsToCalc
  av.ShowMsg("Calculating Distance Values")
  av.SetStatus( (f / numRecs) * 100 )
' Get the point location you are measuring FROM. 
' If the view is projected, get the the point location in projected units.
  theID = theFromFtab.ReturnValue(theFromIDField,f)
  theFromShape = theFromFTab.ReturnValue(theFromShapeField,f)
  if (thePrj.IsNull.Not) then
    theFromShape = theFromShape.ReturnProjected(thePrj)
  end  
  
  for each t in theToFtab
    theToID = theToFtab.returnvalue(thetoidfield,t)
    'msgbox.info("thetoid",thetoid.asstring)
      if (thetoid = theid) then
        '  Get the point location you are measuring TO.
        '  Get it in projected units, if the view is projected.
        theToShape = theToFTab.ReturnValue(theToFtab.FindField("Shape"),t)
          if (thePrj.IsNull.Not) then
            theToShape = theToShape.ReturnProjected(thePrj)
          end
      
        ' Calculate the distance between the two points.
        ' Add the value to the output (TO) branch table.    
        theDistance = theFromShape.Distance(theToShape)
        theToFtab.SetValue(theDistanceField,t,theDistance)
      end
  end
  
end  

av.ClearMsg
av.ClearStatus 

theToFtab.SetEditable(false)

av.ShowMsg("Distance calculation complete") 
    
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: ArcView 3.2 Distance Calculation between two theme points - Need help desperately 
Author srivatsava sunkara 
Date Jul 01, 2002 
Message Try IProximityOperator::ReturnDistance

Use Basic Trignometry to get the distance between the points.

but if you need great circle distance , here is a sample below ,modify it according to your needs

Description:

This sample contains VB wrappers for two geodesic functions that are in the Projection Engine library. The geoddist function returns the geodesic (shortest) distance between two geographic points on a spheroid. The geodcoord function returns a geographic point at a defined distance and azimuth from the input point.

A geodesic distance is calculated on a spheroid. A great circle distance is calculated on a sphere. If you want the great circle distance, set the a parameter to the radius of the sphere and set e2 to zero in the SetSpheroid subroutine.

You need to update the Projection Engine library locations and change the geographic coordinate system. The Projection Engine library is located in the bin directory and is called peXX.dll where XX is the ArcGIS version. Check the comments in the code for more information.



How to use:
Add these functions to your Visual Basic project.

' Converts decimal degrees to radians.
' Divide radians by DDtoRAD to convert back to decimal degrees.
Public Const DDtoRAD = 3.14159265358979 / 180#
Public a As Double, e2 As Double

' Change the library path if necessary. The geoddist function provides
' access to the pe_geodesic_distance function in the Projection Engine
' library, pe82.dll. The function inputs are:
'
' a = semimajor axis of a spheroid
' e2 = eccentricity, e2 = f*(2-f) where f = flattening
' lam1 = longitude of the first point in radians
' phi1 = latitude of the first point in radians
' lam2 = longitude of the second point in radians
' phi2 = latitude of the second point in radians
'
' The function returns:
'
' distance = geodesic distance between the two points in meters
' az12 = geodetic azimuth from point 1 to point 2 in radians
' az21 = geodetic azimuth from point 2 to point 1 in radians
'
' The returned distance is a geodesic distance. A great circle distance
' is on a sphere. The geodesic is on a spheroid/ellipsoid. If you wish
' the great circle distance, make sure that the geographic coordinate
' system uses a sphere. Ex: esriSRGeoCS_Authalicsphere (R = 6371000 m)
'
Private Declare Function geoddist Lib "d:\arcgis\arcexe82\bin\pe82.dll" _
Alias "pe_geodesic_distance" (ByVal a As Double, ByVal e2 As Double, _
ByVal lam1 As Double, ByVal phi1 As Double, _
ByVal lam2 As Double, ByVal phi2 As Double, _
distance As Double, azi12 As Double, azi21 As Double) As Long

' Change the library path if necessary. The geodcoord function provides
' access to the pe_geodesic_coordinate function in the Projection Engine
' library, pe82.dll. The function inputs are:
'
' a = semimajor axis of a spheroid
' e2 = eccentricity, e2 = f*(2-f) where f = flattening
' lam1 = longitude of the first point in radians
' phi1 = latitude of the first point in radians
' distance = geodesic distance between the two points in meters
' az12 = geodetic azimuth from point 1 to point 2 in radians
'
' The function returns:
'
' lam2 = longitude of the second point in radians
' phi2 = latitude of the second point in radians
'
' The returned coordinate is based on a geodesic distance. A great circle
' is on a sphere. The geodesic is on a spheroid/ellipsoid. If you wish
' to use a great circle distance, make sure that the geographic coordinate
' system uses a sphere. Ex: esriSRGeoCS_Authalicsphere (R = 6371000 m)
'
Private Declare Function geodcoord Lib "d:\arcgis\arcexe82\bin\pe82.dll" _
Alias "pe_geodesic_coordinate" (ByVal a As Double, ByVal e2 As Double, _
ByVal lam1 As Double, ByVal phi1 As Double, _
ByVal distance As Double, ByVal azi12 As Double, _
lam2 As Double, phi2 As Double) As Long

Public Sub main()

' By default, these functions calculate the geodesic distance or coordinate.
' A geodesic distance is calculated on a spheroid. A great circle distance
' is calculated on a sphere. If you want the great circle distance, set
' the a parameter to the radius of the sphere and set e2 to zero.

geodesic_distance
geodesic_coordinate

End Sub

Public Sub geodesic_distance(ByVal lon1 As Double, ByVal lat1 As Double, _
ByVal lon2 As Double, ByVal lat2 As Double, _
dist As Double, a12 As Double, a21 As Double)

' Initialization of variables needed by the geoddist function.
Dim lam1 As Double, phi1 As Double
Dim lam2 As Double, phi2 As Double
Dim distance As Double
Dim azi12 As Double, azi21 As Double

' Defining the geographic coordinate system.
' SetSpheroid retrieves the spheroid parameters. Change the
' geographic coordinate system in the SetSpheroid subroutine.
SetSpheroid a, e2

' Definition of two input points and conversion to radians.
lam1 = lon1 * DDtoRAD
phi1 = lat1 * DDtoRAD
lam2 = lon2 * DDtoRAD
phi2 = lat2 * DDtoRAD

' The function is called.
geoddist a, e2, lam1, phi1, lam2, phi2, distance, azi12, azi21
dist = distance
a12 = azi12 / DDtoRAD
a21 = azi21 / DDtoRAD

' Print or store the results. The azimuths are converted back to
' decimal degrees.
' Debug.Print distance
' Debug.Print azi12 / DDtoRAD
' Debug.Print azi21 / DDtoRAD

End Sub

Public Sub geodesic_coordinate(ByVal lon1c As Double, ByVal lat1c As Double, _
ByVal distc As Double, ByVal azi12c As Double, _
lon2c As Double, lat2c As Double)

' Initialization of variables needed by the geodcoord function.
Dim lam1 As Double, phi1 As Double
Dim lam2 As Double, phi2 As Double
Dim distance As Double
Dim a12 As Double

' Defining the geographic coordinate system.
' SetSpheroid retrieves the spheroid parameters. Change the
' geographic coordinate system in the SetSpheroid subroutine.
SetSpheroid a, e2

' Convert the input point and azimuth to radians.
lam1 = lon1c * DDtoRAD
phi1 = lat1c * DDtoRAD
a12 = azi12c * DDtoRAD

' Assign the distance
distance = distc

' The function is called.
geodcoord a, e2, lam1, phi1, distance, a12, lon2c, lat2c

' Print or store the results. The second point is converted back to
' decimal degrees.
lon2c = lon2c / DDtoRAD
lat2c = lat2c / DDtoRAD

End Sub

Public Sub SetSpheroid(a As Double, e2 As Double)
Dim f As Double

Dim pSpatialReferenceEnv As SpatialReferenceEnvironment
Set pSpatialReferenceEnv = New SpatialReferenceEnvironment

' Defining the geographic coordinate system.
' Change esriSRGeoCSType enumeration to the appropriate geographic
' coordinate system.
Dim pGCS As IGeographicCoordinateSystem
Dim pSpatialReference As ISpatialReference
Set pGCS = pSpatialReferenceEnv.CreateGeographicCoordinateSystem(esriSRGeoCS_NAD1983)

' This section retrieves the spheroid parameters from the geographic
' coordinate system.
Dim pDatum As IDatum
Dim pSpheroid As ISpheroid
Set pDatum = pGCS.Datum
Set pSpheroid = pDatum.Spheroid
a = pSpheroid.SemiMajorAxis
f = pSpheroid.Flattening
e2 = f * (2# - f)

End Sub

This is a sample under Geodesic Functions
This should help,
Sri 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: ArcView 3.2 Distance Calculation between two theme points - Need help desperately 
Author Vsunkara Sunkara 
Date Jul 02, 2002 
Message Hi Sri,

Thank you so much for taking the time to write back with possible solutions to my problem. I have tried to use the IProximity Operator to Return Distance, but I was only able to use it with one set of points at a time.

What I am basically trying to do is simply measure the distance to and from two point themes on ArcMap, probably like a Button Click event that would bring up the dialog like in ArcView3.2 and just populate it into the attribute table.

Thanks again for your thoughts,
Vasanthi Sunkara. 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: ArcView 3.2 Distance Calculation between two theme points - Need help desperately 
Author Vsunkara Sunkara 
Date Jul 02, 2002 
Message Sri, Just a quick question, does the geodesic_distance function measure the distance? I am confused with the calculation/conversion that it's doing.

Vasanthi.