2

I have Road (polyline) feature class and I wish to find those roads whose length are greater than 500 kilometre.

The feature class projection is in GCS_WGS_1984 and I do not want to change the projection.

Is there anyway to calculate length in kilometre through programming without changing projection?

1

This is in many ways, a simple problem if you know the specifics. If you know the area in which a Polyline will fall, you can project the polyine to an appropriate Projection, and then find the length.

A few years back, I had a problem where the Line could be anywhere. This called for a general solution. For this purpose, I had made the following functions. The GetLength function will iterate over each segment of the line, and calculate the length of each segment using Haversine's formula. This function works for multipart lines without any problems.

/// <summary>
/// Gets the length of a given Polyline. This function assumes that the Line is WGS84 Lat-Long
/// </summary>
/// <param name="polyLine">Input Polyline</param>
/// <returns>Length in KM</returns>
internal static double GetLength(IPolyline polyLine)
{
    Double Distance = 0;
    //first check the Geometry's SR
    ISpatialReference SR = polyLine.SpatialReference;
    int FactoryCode = SR.FactoryCode;
    if (FactoryCode == 4326)//this is in WGS 84 Lat long
    {
        //iterate over the parts of the PolyLine
        IGeometryCollection GeomColl = (IGeometryCollection)polyLine;
        for (int i = 0; i < GeomColl.GeometryCount; i++)
        {
            IGeometry Geom = GeomColl.get_Geometry(i);
            if (Geom.GeometryType == esriGeometryType.esriGeometryPath)
            {
                //Now that we have a Path, we need to find the individual Segments
                ISegmentCollection SegColl = (ISegmentCollection)Geom;
                for (int j = 0; j < SegColl.SegmentCount; j++)
                {
                    ISegment Segment = SegColl.get_Segment(j);
                    if (Segment.GeometryType == esriGeometryType.esriGeometryLine)
                    {
                        //Calculate the length of the segment and add it to running total
                        Distance += GetHaverSineDistance(Segment);
                    }
                }
            }
        }

    }
    else
    {
        throw new Exception("Polyline is not in EPSG:4326");
    }

    return Distance;
}

/// <summary>
/// Returns the distance in kilometers of a segment
/// It's based on the code present at: http://megocode3.wordpress.com/2008/02/05/haversine-formula-in-c/
/// </summary>
/// <param name="seg"> The ISegment whose Length is to be calculated</param>
/// <returns>The length in KM</returns>
private static double GetHaverSineDistance(ISegment seg)
{
    Double R = 6371;
    Double dLat = toRadian(seg.ToPoint.Y - seg.FromPoint.Y);
    Double dLong = toRadian(seg.ToPoint.X - seg.FromPoint.X);

    double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
        Math.Cos(toRadian(seg.FromPoint.Y)) * Math.Cos(toRadian(seg.ToPoint.Y)) *
        Math.Sin(dLong / 2) * Math.Sin(dLong / 2);
    double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
    double d = R * c;

    return d;
}

/// <summary>
/// Convert to Radians.
/// </summary>
/// <param name="val">The angle is degrees</param>
/// <returns>Angle in Radians</returns>
private static double toRadian(double val)
{
    return (Math.PI / 180) * val;
}
  • it wont be very slow if i have features in lakhs and i want length in kilometre. – sudoku Jan 10 '14 at 8:08
  • You should test it out: If you know the area of the location of the line, you could project it to an appropriate projection. My gut feeling is that it would be slightly faster, but not by an order of magnitude. – Devdatta Tengshe Jan 10 '14 at 8:29
  • thanx a ton!!! its working.Only slight difference in length exists when i calculated manually on arcmap for example if length calculated manually is 18.36 then through program its coming 18.76 rest its fine.Thanx devdatta – sudoku Jan 10 '14 at 10:33
  • @sudoku: The difference could be due to the projection that you have selected in ArcMap. The Havesine forumla is usually accurate within an order of cm. What projection have you used in ArcMap? – Devdatta Tengshe Jan 10 '14 at 10:43
  • ..Used projected coordinate system ..WGS_1984_World Mercator for calculating length through calculate geometry option in arcmap – sudoku Jan 10 '14 at 10:53
1

You can use GeometryServer coclass with IGeometryServer3 interface (in 10.1). See GetLengthsPreserveShape and GetLengthsGeodesic. Both methods allow to specify units of length and do calculation on the spheroid. The geodesic method will replace all polyline segments with geodesics. While "preserve shape" one will calculate the true geographic length of the polyline as you see it on the screen (as if you densified the polyline first and then calculated geodesic length of it).

  • hey i have to use it for arcgis desktop. – sudoku Jan 10 '14 at 8:07
  • @sudoku The GeometryServer class is a regular COM class. Create it and use it on Desktop. It will not start any real servers. – 0kcats Jan 10 '14 at 17:04
0

If you are not willing to change projection for calculation (without saving) - that is what i do. Try this: Haversine Formula.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.