I ran some code with a feature class that had X, Y, Z and M units to get lengths from the I3DCurve interface. I ran a test on a feature using a Projected Coordinate System where my initial X, Y and Z units were all in Feet_US and got the expected 3D length value. Then I modified the feature class to change the Z Units to meters, but I left the X/Y coordinate units in Feet_US. When I reran the code the 3D length reported by the I3DCurve interface did not change from the previous run when I had the Z units in feet. I made sure that the polyline I supplied to the interface had been assigned the feature class' Spatial Reference and made sure the Z values I tested were much greater than the change in X/Y so the difference in Z units would have an obvious impact, but that had no effect on the length that the I3DCurve reported.Here is my main loop code (variables are correctly Dimensioned to the correct types outside the loop) that produced no change in the reported length after I changed my Spatial Reference Z Units from Feet_US to meters. Am I missing something about how my code should be written to get the I3DCurve interface to recognize the change I made to the Spatial Reference of the Z units? If I am not than it seems that this interface either has a bug or an undocumented (and unexpected) behavior for its method of calculating the 3D length of the curve when a feature class has mixed X/Y and Z units.' Assume a Polyline Feature that is Z and M Aware is assigned to pFeat, which is an IFeature
Dim pSpatialRef As ISpatialReference = pFeat.Shape.SpatialReference
If Not TypeOf pSpatialRef Is IProjectedCoordinateSystem5 Then
' Currently not able to process Geographic Coordinate System or Unknown
MsgBox("Spatial Reference Is Not A Projected Coordinate System")
Return
End If
pPolyline = New Polyline
pPolyline.SpatialReference = pSpatialRef ' Make sure Polyline has Spatial Reference
pPolyline = pFeat.Shape ' Assign geometry to Polyline
pCurve3D = pPolyline
pPointColl = pFeat.ShapeCopy ' Assign to pointCollection
pEnumVert = pPointColl.EnumVertices
pInPoint = New Point ' Reinitialize Input Point
pInPoint.SpatialReference = pSpatialRef
pEnumVert.Reset()
pEnumVert.QueryNext(pInPoint, lPart, lVert)
LastPoint = New Point ' Reinitialize Input Point
i = 1
Do While Not pInPoint Is Nothing
' For lPtCnt = 0 To pPointColl.PointCount - 1 ' For loop to access all curve points
If lPart = 0 And lVert = 0 Then
LastPoint = pInPoint
GapAdd = 0
End If
' pInPoint = pPointColl.Point(lPtCnt) ' Assign Input successive input Points
pCurve3D.QueryPointAndDistance3D(ESRI.ArcGIS.Geometry.esriSegmentExtension.esriNoExtension, pInPoint, False, pOutPoint, distAlong, distFrom)
If lVert = 0 And Not Ignore_Gaps Then
GapAdd = (Math.Sqrt((pInPoint.X - LastPoint.X) ^ 2 + (pInPoint.Y - LastPoint.Y) ^ 2 + ((pInPoint.Z - LastPoint.Z) * ZUnitFactor) ^ 2)) * Measure_Factor + GapAdd
End If
pEnumVert.put_M(distAlong + GapAdd) ' Modify M to be 3D distance along curve
' pPointColl.ReplacePoints(lPtCnt, 1, 1, pInPoint) ' Replace the point with its new M version'
If pEnumVert.IsLastInPart And pPointColl.PointCount <> i Then
LastPoint = pInPoint
pEnumVert.QueryNext(pInPoint, lPart, lVert)
ElseIf Not pEnumVert.IsLastInPart Then
pEnumVert.QueryNext(pInPoint, lPart, lVert)
Else
pInPoint = Nothing
End If
' pInPoint = Nothing
' Next lPtCnt
i += 1
Loop
pFeat.Shape = pPointColl
pFCursor.UpdateFeature(pFeat) ' Update the cursor