Este é o código que criei usando um tipo Vector3 . Não está exatamente no local, mas está perto o suficiente para cálculos adicionais:
public static LatLon GetOrthographicProjecten(LatLon start, LatLon end, LatLon offsetpoint)
{
#region Start node conversion
var sLat = DegreesToRadians(start.Lat);
var sLon = DegreesToRadians(start.Lon);
var sX = EarthRadius * Math.Cos(sLat) * Math.Cos(sLon);
var sY = EarthRadius * Math.Cos(sLat) * Math.Sin(sLon);
var sZ = EarthRadius * Math.Sin(sLat);
#endregion
#region End node conversion
var eLat = DegreesToRadians(end.Lat);
var eLon = DegreesToRadians(end.Lon);
var eX = EarthRadius * Math.Cos(eLat) * Math.Cos(eLon);
var eY = EarthRadius * Math.Cos(eLat) * Math.Sin(eLon);
var eZ = EarthRadius * Math.Sin(eLat);
#endregion
#region Offsetpoint conversion
var oLat = DegreesToRadians(offsetpoint.Lat);
var oLon = DegreesToRadians(offsetpoint.Lon);
var oX = EarthRadius * Math.Cos(oLat) * Math.Cos(oLon);
var oY = EarthRadius * Math.Cos(oLat) * Math.Sin(oLon);
var oZ = EarthRadius * Math.Sin(oLat);
#endregion
// Create vectors
var p1 = new Vector3(sX, sY, sZ);
var p2 = new Vector3(eX, eY, eZ);
var o = new Vector3(oX, oY, oZ);
// Calculate
var u = p2 - p1;
var po = o - p1;
var w2 = po - (u * Vector3.DotProduct(po, u) / Math.Pow(u.Magnitude, 2));
var point = o - w2;
// Convert to latlon
var rlat = RadiansToDegrees(Math.Asin(point.Z / EarthRadius));
var rlon = RadiansToDegrees(Math.Atan2(point.Y, point.X));
return new LatLon(rlat, rlon);
}