# How do I obtain the longitude and latitude of the current location using the Mappoint 2010 Map Control

I have been asked to complete an application on behalf of a programmer who has left the Company.  The application is a fleet management system and ises Mappoint 2010 ( Europe ) for location and mapping.

I can find a location using the mappoint [FindPlaceResults] procedure but inorder to identify the nearest current ehicle I need to query the sql table which uses lat/longs to keep track of vehicle location.

Idealliy I would like to be able to find the Lat/Long of the current location returned by using the [FindPlaceResults] procedure.  I am only taking the top entry from the procedure so there will only be ever one location returned.  As the map centres on the location found I had hoped the the lat/long could be obatined.
###### Who is Participating?

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
Sorry I cannot help much with Mappoint, but I know a bit about Google Maps and its API.  I have an article here at EE that may be helpful.

Proximity information can be calculated with reasonable accuracy using either plane geometry or the Haversine formula.
http://en.wikipedia.org/wiki/Haversine_formula

Haversine is more accurate over longer distances.  Neither geometry takes into account physical limitations -- if you want to go from point A to point B and there is a river in between, your closest result may take you across the river whether there is a bridge there or not!  You can probably use Google Maps and Waypoints to get a more accurate travel distance.

When I've done proximity matching for large numbers of clients, I have used a "down-select" from the tables to capture only a small number of locations.  I create a temporary table (engine = memory) with the closest locations based on a plus-or-minus difference in latitude and longitude, then compute the distances for only those closest points.  After that, I can select from the temporary table and ORDER BY distance to find the nearest locations.

Here is a function that computes distance.
``````<?php // RAY_compute_distance.php
error_reporting(E_ALL);
echo "<pre>\n";

// COMPUTE THE DISTANCE BETWEEN TWO LAT/LON PAIRS

// MAN PAGE: http://en.wikipedia.org/wiki/Haversine_formula
function compute_distance(\$from_lat, \$from_lon, \$to_lat, \$to_lon, \$units='KM')
{
// CHOOSE A UNIT OF MEASURE BY THE FIRST CHARACTER
\$units = strtoupper(substr(trim(\$units),0,1));

// ENSURE THAT ALL COORDINATES ARE FLOATING POINT VALUES
\$from_lat = floatval(\$from_lat);
\$from_lon = floatval(\$from_lon);
\$to_lat   = floatval(\$to_lat);
\$to_lon   = floatval(\$to_lon);

// IF THE SAME POINT THE DISTANCE IS ZERO.  HAVERSINE FAILS ON THIS INSTANCES
if ( (\$from_lat == \$to_lat) && (\$from_lon == \$to_lon) )
{
return 0.0;
}

// COMPUTE THE DISTANCE WITH THE HAVERSINE FORMULA
\$distance
= acos
)
;

// DISTANCE IN MILES AND KM - ADD OTHERS IF NEEDED
\$miles = (float) \$distance * 69.0;
\$km    = (float) \$miles * 1.61;

// RETURN MILES
if (\$units == 'M') return round(\$miles,1);

// RETURN KILOMETERS = MILES * 1.61
if (\$units == 'K') return round(\$km,2);

// UNITS NOT UNDERSTOOD
return('INVALID FIFTH ARGUMENT - USE MILES OR KM');
}

// SHOW THE FUNCTION IN ACTION
if (!empty(\$_GET))
{
\$distance = compute_distance(\$_GET["a_lat"], \$_GET["a_lon"], \$_GET["b_lat"], \$_GET["b_lon"], \$_GET["units"]);
echo \$distance . ' ' . \$_GET["units"] . '<br/>' . PHP_EOL;
}

// END OF PHP - PUT UP THE FORM TO RECEIVE INPUT
?>
TEST IT HERE:
<form>
POINT A LAT <input name="a_lat" value="38.898047"> LON <input name="a_lon" value="-77.036562" />
POINT B LAT <input name="b_lat" value="39.737554"> LON <input name="b_lon" value="-77.464943" />
<input type="radio" name="units" value="miles" checked="checked" />Miles
<input type="submit" />
</form>
``````

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
In semi-related news, here is my teaching example of how to call the major geocoder APIs.  Give them an address and they can give you back the Lat/Lon pair in a decimal number, suitable for use in the Haversine formula.  Google has recently revised and extended its geocoder to make it perform reverse geo-coding.  You can give it a Lat/Lon pair and it will give you the nearest address.  How cool is that!

Please let me know if you have further questions or if I can help with anything else about the theory and practice of proximity calculation.  As I said, I do not know Mappoint, but the principles and geometry are going to be the same no matter what software you choose.  Best, ~Ray
``````<?php // RAY_class_SimpleGeoCoder.php
error_reporting(E_ALL);
echo "<pre>" . PHP_EOL;

// API KEYS, ETC., IF REQUIRED
// require_once('local_data.php');

// A FREEFORM NAMED LOCATION STATEMENT IS OPTIONAL - PROCESSED FIRST
if (!empty(\$_GET["n"]))
{
\$location = trim(\$_GET["n"]);
}
// ADDRESS, CITY, STATE, ZIP ARE OPTIONAL - PROCESSED IF FREEFORM LOCATION IS NOT PRESENT
else
{
\$location = '';
if (!empty(\$_GET["a"])) { \$location .= \$_GET["a"] . ' '; }
if (!empty(\$_GET["c"])) { \$location .= \$_GET["c"] . ' '; }
if (!empty(\$_GET["s"])) { \$location .= \$_GET["s"] . ' '; }
if (!empty(\$_GET["z"])) { \$location .= \$_GET["z"] . ' '; }
\$location = trim(\$location);
}

// IF WE HAVE A LOCATION STRING, RUN THE GEOCODERS
if (\$location)
{
// PREPARE THE SIMPLE GEO-CODER
\$demo = new SGC;

// TEST THE YAHOO! GEOCODER
\$demo->YGC(\$location);
echo PHP_EOL . "YAHOO! ";
print_rr(\$demo);

\$demo->GGC(\$location);
print_rr(\$demo);
}
// ALL DONE PROCESSING THE INPUT, PUT UP THE FORM
?>
<html>
<body>
<form method="get">
Try using a full or partial address.
Addr: <input type="text" name="a" autocomplete="off" />
City: <input type="text" name="c" autocomplete="off" />
ST:   <input type="text" name="s" autocomplete="off" size="2" />
Zip:  <input type="text" name="z" autocomplete="off" size="8" />
<input type="submit" value="GeoCode This Address" />

Or use the name of a location.
Name: <input type="text" name="n" autocomplete="off" />
<input type="submit" value="GeoCode This Location Name" />
</form>
</body>
</html>

<?php
// SIMPLE GEOCODER CLASS
class SGC
{
// DECLARE THE WORKING DATA
private \$precis;

// DECLARE THE OUTPUT DATA
public \$latitude;
public \$longitude;
public \$precision;
public \$warning;
public \$error;
public \$geocoder;

// DECLARE THE CONSTRUCTOR
public function __construct()
{
\$this->latitude  = 0.0;
\$this->longitude = 0.0;
\$this->precision = FALSE;  // WANT A VALUE OF 5 OR HIGHER, HIGHER IS BETTER, 8 IS ON THE ROOFTOP
\$this->warning   = '';
\$this->geocoder  = '';
\$this->error     = '';
unset(\$this->precis);
}

// DECLARE THE DATA-CLEANUP
private function _cleanup(\$str)
{
\$str = preg_replace('/[^\' a-zA-Z0-9&!#\$%()"+:?\/@,_\.\-]/', '', \$str);
return trim(preg_replace('/\s\s+/', ' ', \$str));
}

// DECLARE THE YAHOO! VERSION OF THE WORKHORSE
public function YGC(\$location)
{
\$loc = \$this->_cleanup(\$location);
if (empty(\$loc))
{
\$this->error = "LOCATION DATA IS EMPTY";
return FALSE;
}
if (!defined('YAHOO_API')) define('YAHOO_API', 'YAHOO_API');
\$this->geocoder = 'Yahoo!';
\$yahooUrl = "http://local.yahooapis.com/MapsService/V1/geocode?&appid=" . YAHOO_API;
\$yahooUrl .= "&location=" . urlencode(\$loc);

// EXECUTE YAHOO GEOCODER QUERY
// NOTE - USE ERROR SUPPRESSION OR IT WILL BARK OUT THE YAHOO API KEY - ON FAILURE RETURNS HTTP 400 BAD REQUEST
if (\$yfp = @fopen(\$yahooUrl, 'r'))
{
\$yahooResponse = '';
while (!feof(\$yfp))
{
\$yahooResponse .= fgets(\$yfp);
}
fclose(\$yfp);
}
// IF SOMETHING IS SICK AT YAHOO
else
{
\$this->error = "UNABLE TO OPEN \$yahooUrl";
return FALSE;
}

// EXAMINE THE RESULT
if (\$yahooResponse != '') // NOT EMPTY, WE GOT DATA
{
\$ydata = new SimpleXMLElement(\$yahooResponse);

// CHECK FOR ANY ERROR MESSAGE, IF NONE, EXTRACT THE DATA POINTS
\$yerror = \$ydata->Message;
if (\$yerror == '')
{
\$this->precis    = (string)\$ydata->Result["precision"];
\$this->warning   = (string)\$ydata->Result["warning"];
\$this->latitude  = (string)\$ydata->Result->Latitude;
\$this->longitude = (string)\$ydata->Result->Longitude;

// THESE STATEMENTS CAN BE USED TO RETURN NORMALIZED ADDRESS
\$this->city      = (string)\$ydata->Result->City;
\$this->state     = (string)\$ydata->Result->State;
\$this->zip       = (string)\$ydata->Result->Zip;

// SET PRECISION TO A NUMBER VALUE
if (\$this->precis == 'zip')     { \$this->precision = "5"; }
if (\$this->precis == 'street')  { \$this->precision = "6"; }
if (\$this->precis == 'address') { \$this->precision = "8"; }
}
else
{
\$this->error = "ERROR: \$yahooUrl SAYS \$yerror";
return FALSE;
}
}

// NO RESULT - SOMETHING IS SICK AT YAHOO
else
{
\$this->error = "NO DATA RETURNED FROM \$yahooUrl";
return FALSE;
}
return TRUE;
} // END function geocodeYahoo

// DECLARE THE GOOGLE VERSION OF THE WORKHORSE
public function GGC(\$location)
{
\$loc = \$this->_cleanup(\$location);
if (empty(\$loc))
{
\$this->error = "LOCATION DATA IS EMPTY";
return FALSE;
}

{
while (!feof(\$gfp))
{
}
fclose(\$gfp);
}
else
{
\$this->error = "UNABLE TO OPEN \$googleUrl";
return FALSE;
}

// EXTRACT THE DATA FROM THE CSV STRING
if (\$gdata[0] != '200') // RESPONSE CODE SHOULD BE '200' -- IF 602 - BAD ZIP CODE OR UNUSABLE ADDRESS
{
\$this->error = "ERROR CODE {\$gdata[0]} FROM \$googleUrl";
return FALSE;
}
\$this->precision = \$gdata[1]; // GEOCODE ACCURACY - ZIP CODE = 5, HIGHER NUMBERS ARE BETTER
\$this->latitude  = \$gdata[2];
\$this->longitude = \$gdata[3];
return TRUE;

} // END class SimpleGeocoder

// UNRELATED FUNCTION TO MAKE THE OUTPUT SHOW THE PUBLIC INFORMATION ONLY
function print_rr(\$thing)
{
\$str = print_r(\$thing, TRUE);
\$arr = explode(PHP_EOL, \$str);
foreach (\$arr as \$ptr => \$txt)
{
if (preg_match('/:private]/', \$txt))
{
unset(\$arr[\$ptr]);
}
}
echo implode(PHP_EOL, \$arr);
}
``````
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.