Here is the Bobcat Video I told you about:
Back to Programming...
Here is how you calculate the distance between points on the earth. You also need to know EarthRadiusInMiles = 3956.0;
/// <summary>
/// Calculate the distance between two geocodes. Defaults to using Miles.
/// </summary>
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2)
{
return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
}
/// <summary>
/// Calculate the distance between two geocodes.
/// </summary>
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m)
{
double radius = GeoCodeCalc.EarthRadiusInMiles;
if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
return radius * 2 * Math.Asin(Math.Min(1, Math.Sqrt((Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0)))));
}
I created a Marker class to mark the end points of the distance calculation. To show the user that they are in distance calculation mode, I have also changed the cursor on the map control. In this case, I alternate between the arrow and the pointing finger.
PointsOfInterest m_oMarkers = new PointsOfInterest();
void cbMeasure_Checked(object sender, RoutedEventArgs e)
{
Map1.Cursor = Cursors.Hand;
m_oMarkers.Clear();
}
void cbMeasure_Unchecked(object sender, RoutedEventArgs e)
{
Map1.Cursor = Cursors.Arrow;
if ( m_oMarkers.Count > 1 )
AddLine(m_oMarkers,.5);
}
The code for collecting the user's selection of points is here:
void Map1_MouseClick(object sender, MapMouseEventArgs e)
{
var oLocation = Map1.ViewportPointToLocation(e.ViewportPoint);
PointOfInterest oPOI = null;
if (cbMeasure.IsChecked == true)
{
oPOI = new Marker() { Loc = oLocation };
m_oMarkers.Add(oPOI);
}
else
{
oPOI = new PointOfInterest() { Loc = oLocation };
m_oList.Add(oPOI);
}
RenderPoint(oPOI);
if (cbDraw.IsChecked == true)
try
{
double dRadius = double.Parse(txtRadius.Text);
AddCircle(oLocation, dRadius, .5);
}
catch( Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Using a polyline and a tool tip is great way to report the distance:
double DistanceInMiles(LocationCollection oLocs)
{
double dDistance = 0.0;
for (int i = 0; i < oLocs.Count() - 1; i++)
dDistance += DistanceInMiles(oLocs[i], oLocs[i + 1]);
return dDistance;
}
double DistanceInMiles(Location Loc1, Location Loc2)
{
double dMiles = GeoCodeCalc.CalcDistance(Loc1.Latitude, Loc1.Longitude, Loc2.Latitude, Loc2.Longitude);
return dMiles;
}
LocationCollection RenderLine(List<PointOfInterest> oList)
{
var oPOIs = (from oPOI in oList
where oPOI is Marker
select oPOI).ToList<PointOfInterest>();
var oLocs = new LocationCollection();
foreach (var oPOI in oPOIs)
oLocs.Add(oPOI.Loc);
return oLocs;
}
void AddLine(List<PointOfInterest> oList, double dOpacity)
{
MapPolyline polyline = new MapPolyline();
polyline.Stroke = new SolidColorBrush(Colors.Red);
polyline.StrokeThickness = 1;
polyline.Opacity = dOpacity;
//this works in miles
LocationCollection oLocs = RenderLine(oList);
polyline.Locations = oLocs;
Map1.AddChild(polyline);
double dDist = DistanceInMiles(oLocs);
ToolTipService.SetToolTip(polyline, string.Format("{0:0.0} mi \n {1:0.00} yd", dDist, dDist * 5280.0 / 3.0));
}
1 comment:
Great job, this is interesting and useful for distance determination. I have been trying to measure the heights of street trees from Bird's eyeview and wonder if there is a way. There is no measure tool in Bird's eyeview, and even if there is, there are issues with scale for each photo tile. However, I am sure that it should be possible. If you know of a way to measure tree heights in Bird's eyeview, I'll be delighted to know.
My contact is tningal@gmail.com.
Thanks and cheers
Tine
UCD, Dublin, Ireland
Post a Comment