Returning results from ShowFindDialog

mbdunkin
08-15-2005, 10:58 AM
Let me preface this by saying I'm BRAND new when it comes to developing code that interacts with MapPoint, so forgive me if my question is "obvious" to those more experienced. :)

At any rate, I have written a small C# app that takes a street address, city, state, and ZIP as input from a user. When the user clicks a button, the app goes out and finds the location in MapPoint, opens and plots the location on a map, and returns the Lat/Long of the location to the app.

If MapPoint finds an exact match for the location as input by the user, then it returns the Lat/Long values fine. However, if it doesn't find an exact match, I have it opening the 'ShowFindDialog' box. At this point, the user may click on an address in the returned list. What I'm having problems with at this point is having it return the Lat/Long of the selected address to my app.

Basically, I don't know how to get the results of what the user selected in the Dialog Box and do my Lat/Long calculation.

Below is the snippet of code that I'm using to calculate the Lat/Long ...


if ( MapPoint.GeoFindResultsQuality.geoFirstResultGood == oResults.ResultsQuality)
{
IEnumerator at = oResults.GetEnumerator();
if ( !at.MoveNext())
{
return null;
}
oLocate = (MapPoint.Location) at.Current;
}
else
{
//If no exact match found, open Dialog box
oMap.ShowFindDialog(strAddress, new MapPoint.GeoFindState(), (int)this.Handle, false);

return null;
}


oLocate.GoTo();
int x;
int y;
double dblLat;
double dblLon;
double l;
double d;

x = oMap.LocationToX(oLocate);
y = oMap.LocationToY(oLocate);

MapPoint.FindResults oContext;
oContext = oMap.ObjectsFromPoint( x, y);

MapPoint.Location obj;

if ( locNorthPole == null )
{
locNorthPole = oMap.GetLocation( 90, 0, 1 );
locSantaCruz = oMap.GetLocation( 0, -90, 1 );

// Compute distance between north and south poles == half earth circumference
dblHalfEarth = oMap.Distance( locNorthPole, oMap.GetLocation(-90, 0, 1) );

// Quarter of that is the max distance a point may be away from locSantaCruz and still be in western hemisphere
dblQuarterEarth = dblHalfEarth / 2;
}

// Compute latitude from distance to north pole
dblLat = 90 - 180 * oMap.Distance(locNorthPole, oLocate) / dblHalfEarth;

d = oMap.Distance(oMap.GetLocation(dblLat, 0, 1), oLocate);

// convert latitude to radian
l = (dblLat / 180) * Math.PI;

// Compute Longitude from great circle distance
dblLon = 180 * Math.Acos((Math.Cos((d * 2 * Math.PI) / (2 * dblHalfEarth)) - Math.Sin(l) * Math.Sin(l)) / (Math.Cos(l) * Math.Cos(l))) / Math.PI;

//Correct longitude sign if located in western hemisphere
if ( oMap.Distance(locSantaCruz, oLocate) < dblQuarterEarth )
dblLon = -dblLon;

oPin = oMap.AddPushpin(oLocate, strAddress);
oPin.Highlight = true;
oPin.Symbol = 17;
oPin.BalloonState = MapPoint.GeoBalloonState.geoDisplayBalloon;
txtLat.Text = dblLat.ToString();
txtLong.Text = dblLon.ToString();



Thanks in advance for any help on this!!

Wilfried
08-15-2005, 01:52 PM
Hi,

Yoiur code snipped is very long. :( Also Ido not understeand what exacly the problem is. Canyou elaorae ?>

mbdunkin
08-15-2005, 02:40 PM
When the user types in a street address, city, and state in my app, if MapPoint finds an EXACT match, it runs through the lat/long calculation and returns the Latitude and Longitude to two text fields in my application (txtLat and txtLong). The 'oLocate' variable is being set to the current location on the map and from that point the latitude/longitude calculations are being done.

However, if MapPoint does NOT find an exact match, then it opens the "ShowFindDialog" box with a list of potential matches. If the user selects one of these addresses from the "ShowFindDialog" box, it does NOT return the Latitude/Longitude values to my app. The reason is because I don't know how to set my 'oLocate' variable to the results of the address that the user is selecting from the list. As a result, 'oLocate' is never being set and therefore latitude/longitude can't be calculated.

Does that help any?

Thanks so much!!

calv1ns
08-15-2005, 09:39 PM
Hey mbdunkin

I do not know if this is the most beautiful approach but this is what I'd do:

'Get some unclear results and add a pushpin
Set objPin = myobj.ShowFindDialog("4950 Hamilton Ave, , California", geoFindAddress)

'use the pushpin to get a Location Object
set oLocA = objPin.Location

Then use a version of the code provided by Chris @ Crime Analysis.net in this article:

http://www.mp2kmag.com/a9--gebhardt.lat.lon.mappoint.html

Change the Subroutine parameter from string of address to a MapPoint.Location.

Sorry all this is in VB6 but a smart C# guy like you will figure it out.

Here's my/Chris's test code hacked out to see if it works.
<pre>
Sub GetLatLong()
'Latitude/Longitude Discovery Module (v1.0, June 5, 2001)
'Created by Christopher S. Gebhardt Chris @ Crime Analysis.net
' Crime Analysis Associates www.CrimeAnalysis.net

'This code is hereby released into the public domain. Please forward any suggestions
'or additions to the author. If you decide to use this code snippet, leave this
'header information intact to give credit to the author!
'MOD: Terry Calvin FleetScan Solutions www.fleetscan.com
' 15-Aug-2005
' Converted version to work off of a location object.

Dim oPush, oPushA As MapPoint.Pushpin
Dim oLoc, oLocA, oLocB As MapPoint.Location
Dim PointX, PointY As MapPoint.Location
Dim measure, percision As Double
Dim zLat, zLong, DistX, DistY, DistZ As Double
Dim myapp As New MapPoint.Application
Dim myobj As MapPoint.Map
Dim objPin As MapPoint.Pushpin

'Set up the application
' wk_istat2 = Open_Map("C:\Documents and Settings\Terry58\My Documents\test.ptm")
Set myobj = myapp.ActiveMap
myapp.Visible = True
myapp.UserControl = True

'Get some unclear resutls
Set objPin = myobj.ShowFindDialog("4950 Hamilton Ave, , California", geoFindAddress)

'myLat and myLong are a known point. In this case, Wichita, Kansas
myLat = 37.70212
myLong = -97.31775

'Initially, set zLat and zLong equal to the known point
zLat = myLat
zLong = myLong

'Measure is used to adjust the starting distance. In this case, start off with 750 miles.
'Measure is made smaller in the Do While loop below but it is a good idea to start off
'with a large number
'A Mile = 0.01471 Degrees of Lat/Long, a Half mile = 0.007355
measure = 0.01471 * 750
'Percision of 20ft
percision = (0.01471 / 5280) * 20

'Create two points: oLoc as the reference point and oLocA your address for which you need lat/long
'In a real work example pass objPin.Location into the subroutine as a Location Object
Set oLoc = myobj.GetLocation(myLat, myLong)
Set oLocA = objPin.Location
X = 0

'Create a loop that will continue until your desired precision. As indicated below
'this loop will repeat until the lat/long is found to be within 20 feet.
Do While measure > percision

X = X + 1
'Create two other reference points: PointX is one Measure off oLoc's Lattitude
' PointY is one Measure off oLoc's Longitude
Set PointX = myobj.GetLocation(zLat + measure, zLong)
Set PointY = myobj.GetLocation(zLat, zLong + measure)

'Measure the distances from each of the three reference points to our main address (oLocA)
DistX = oLocA.DistanceTo(PointX)
DistY = oLocA.DistanceTo(PointY)
DistZ = oLocA.DistanceTo(oLoc)

'Determine which reference point is closer to oLocA, our main address
If DistX < DistY And DistX < DistZ Then
'Make the master reference point oLoc equal to PointX since PointX was the closest to
'our main address
Set oLoc = myobj.GetLocation(zLat + measure, zLong)
zLat = zLat + measure 'Don't forget to add the Measure to zLat for the next iteration
End If
If DistY < DistX And DistY < DistZ Then
Set oLoc = myobj.GetLocation(zLat, zLong + measure)
zLong = zLong + measure
End If
If DistZ < DistX And DistZ < DistY Then
'The main reference point is closer than PointX or PointY.
'PointX and PointY were too far away by ADDING a Measure, so here we need
'to subtract a measure from both the Latitude and the Longitude
Set oLoc = myobj.GetLocation(zLat - measure, zLong - measure)
zLat = zLat - measure
zLong = zLong - measure
End If

'Here is where Measure gets adjusted. Check to see if the distance between the new
'reference point is smaller than Measure. If so, reduce Measure by half.
'Don't forget that Measure is in degrees of Lat/Long while the distance will be
'in miles. To convert degrees to miles, multiply by .01471, the number of degrees
'in a mile.
If oLocA.DistanceTo(oLoc) < measure / 0.01471 Then
measure = measure / 2
End If
' Set oPush = myobj.addpushpin(myobj.GetLocation(zLat, zLong), "Point: " & Str(X))
' oPush.Location.Goto
' oPush.BalloonState = geoDisplayBalloon 'Turn on the balloon state so we can see the lat/long
' Debug.Print "Iteration is " & Str(X) & " and Measure is " & Str(measure)

Loop

'Create a PushPin with the new location that matches our address
'Add how many iterations of the loop it took (x) and the the Latitude, Longitude
Set oPush = myobj.addpushpin(oLoc, Str(X) & ": " & Str(zLat) & ", " & Str(zLong))
oPush.Location.Goto

Debug.Print "The Lat/Long of your address is " & zLat & ", " & zLong & _
Chr(13) & "It was found in " & X & " iterations."

'The next four lines are just for presentation. Uncomment them if you like
oPush.BalloonState = geoDisplayBalloon 'Turn on the balloon state so we can see the lat/long
oPush.Highlight = True 'Highlight the pushpin so we really see it
myobj.DataSets.ZoomTo 'Zoom the map to the individual pushpin

'myobj.Saved = True
End Sub
</pre>

 
Web mp2kmag.com
mapforums.com