private void ReCalculateLength(IPolyline trackLine)
{
double fixedLength = 0.0;
double fixedLengthKil = 0.0;
double totalLength = 0.0;
double totalLengthKil = 0.0;
string unitDescriptor = "";
esriUnits unit = m_HookHelper.FocusMap.MapUnits;
if (trackLine != null && (trackLine as IPointCollection).PointCount > 2)
{
IPolyline fixedLine = (trackLine as IClone).Clone() as IPolyline;
(fixedLine as IPointCollection).RemovePoints((fixedLine as IPointCollection).PointCount - 1, 1);
fixedLength = GetPolylineLength(fixedLine);
fixedLengthKil = ConvertLengthToKilometers(fixedLine, unit, out unitDescriptor);//ConvertLengthToKilometers(fixedLine, unit, out unitDescriptor);
}
totalLength = (trackLine != null) ? GeometryWrapper.GetPolylineLength(trackLine) : 0;
totalLengthKil = (trackLine != null) ? UnitConvert.ConvertLengthToKilometers(trackLine, unit, out unitDescriptor) : 0; //ConvertLengthToKilometers(trackLine, unit, out unitDescriptor) : 0;
string fixedLengthString = string.Format("{0:N2}{1},\n约为:{2:N2}公里。", fixedLength, unitDescriptor, fixedLengthKil);
_measureTooltipForm.CurrentValue = fixedLengthString;
string totalLengthString = string.Format("{0:N2}{1},\n约为:{2:N2}公里。", totalLength, unitDescriptor, totalLengthKil);
_measureTooltipForm.AllValue = totalLengthString;
}
/// <summary>
/// 获取折线的长度
/// </summary>
/// <param name="pGeometry"></param>
/// <returns>如果错误,返回-1;否则返回折线的长度</returns>
public static double GetPolylineLength(IGeometry pGeometry) {
if (pGeometry is IPolyline) {
IPolyline pPolyline = pGeometry as IPolyline;
if (pPolyline == null) return -1;
return pPolyline.Length;
}
return -1;
}
/// <summary>
/// 地图线长度转换为公里
/// </summary>
/// <param name="polyline">计算的线</param>
/// <param name="esriUnit">地图单位</param>
/// <param name="unitDescript">单位中文描述</param>
/// <returns></returns>
public static double ConvertLengthToKilometers(IPolyline polyline, esriUnits esriUnit, out string unitDescriptor)
{
unitDescriptor = "";
double length = 0.0;
if (polyline == null)
{
return length;
}
IPolyline line = (polyline as IClone).Clone() as IPolyline;
length = GeometryWrapper.GetPolylineLength(line);
switch (esriUnit)
{
// "未知单位";
case esriUnits.esriUnknownUnits:
unitDescriptor = "未知单位"; break;
// "英寸";
case esriUnits.esriInches:
length = length * 0.3048 / 1000;
unitDescriptor = "英寸"; break;
//"像素点";
case esriUnits.esriPoints:
length = length * 0.3528 / 1000 / 1000;
unitDescriptor = "像素点"; break;
// "英尺";
case esriUnits.esriFeet:
length = length * 0.3048 / 1000;
unitDescriptor = "英尺"; break;
// "码";
case esriUnits.esriYards:
length = length * 0.9144 / 1000;
unitDescriptor = "码"; break;
// "英里";
case esriUnits.esriMiles:
length = length * 1609.344 / 1000;
unitDescriptor = "英里"; break;
//"海里";
case esriUnits.esriNauticalMiles:
length = length * 1852 / 1000;
unitDescriptor = "海里"; break;
// "毫米";
case esriUnits.esriMillimeters:
length = length / 1000 / 1000;
unitDescriptor = "毫米"; break;
// "厘米";
case esriUnits.esriCentimeters:
length = length / 100 / 1000;
unitDescriptor = "厘米"; break;
// "公里";
case esriUnits.esriKilometers:
unitDescriptor = "公里"; break;
// "十进制度";
case esriUnits.esriDecimalDegrees:
length = Sphere_GetPolylineLength(line) / 1000;
unitDescriptor = "十进制度"; break;
//"分米";
case esriUnits.esriDecimeters:
length = length / 10 / 1000;
unitDescriptor = "分米"; break;
//"米"
case esriUnits.esriMeters:
length = length / 1000;
unitDescriptor = "米"; break;
}
return length;
}
/// <summary>
/// 获取球面折线的长度,单位米
/// </summary>
/// <param name="pGeometry"></param>
/// <returns>如果错误,返回-1;否则返回折线的长度</returns>
public static double Sphere_GetPolylineLength(IGeometry pGeometry) {
if (pGeometry is IPolyline) {
IPointCollection pointCollection = pGeometry as IPointCollection;
if (pointCollection == null) return -1;
double totalDistance = 0;
for (int i = 0; i < pointCollection.PointCount - 1; i++) {
IPoint pt1 = pointCollection.get_Point(i);
IPoint pt2 = pointCollection.get_Point(i + 1);
totalDistance += Sphere_DistanceOfTwoPoints(pt1.X, pt1.Y, pt2.X, pt2.Y);
}
return totalDistance;
}
return -1;
}
private static double Sphere_DistanceOfTwoPoints(double lng1, double lat1, double lng2, double lat2) {
double radLat1 = Rad(lat1);
double radLat2 = Rad(lat2);
double a = radLat1 - radLat2;
double b = Rad(lng1) - Rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * 6378137.0; //以wgs84椭球为例
s = Math.Round(s * 10000) / 10000;
return s;
}
private static double Rad(double d) {
return d * Math.PI / 180.0;
}