A common problem reported on various MapPoint programming forums including MapForums; is that of MapPoint’s “Find” methods resulting in exceptions and fatal crashes. These problems are actually due to the misuse of MapPoint’s API, and are seen with the following multiple-result “Find” methods:
FindPushpin only returns a single pushpin and is not susceptible to the same problem.
The crash is produced by search code like the following VB6:
Dim sName as String sName = oMap.FindAddressResults("One Microsoft Way", "Redmond", , "WA", , geoCountryUnitedStates).Item(1).Name
The problem is not a problem with MapPoint but is due to a mis-understanding of these methods. The crashes are caused by two related assumptions:
- MapPoint will always find one valid result
- These methods return a simple array collection
First, MapPoint is not guaranteed to produce a single correct location. Due to inadequate search information, it may not be able to find an address or location — or the results may be ambiguous. Therefore assuming the collection contains at least one valid result can produce unreliable behavior, or even an exception if no results are returned.
Second, these methods all return the FindResults collection. This is not a simple array, but a class that inherits from a collection. As well as the standard MapPoint collection methods and properties, the FindResults collection implements the ResultsQuality property. This is a GeoFindResultsQuality enumeration with the following values:
|geoAllResultsValid||0||All returned results match the method criteria. Used only for results obtained from the FindNearby and ObjectsFromPoint methods, where all results match the criteria.|
|geoAmbiguousResults||2||At least the first two results are good matches, but it is not clear which one was intended.|
|geoFirstResultGood||1||The first result is a good match to the method criteria.|
|geoNoGoodResult||3||None of the results is a good match to the method criteria, but the results are the best available.|
|geoNoResults||4||No results are returned.|
Therefore the ResultsQuality property should be tested first before any of the returned locations are read. Typically, values of 0 (“All Valid”) or 1 (“First Result Good”) will be acceptable, and the other values should result in error warnings or other actions. For example, if a value of 2 (“Ambiguous Results”) is returned, then the application could present the full list of ambiguous results to the user for selection.
Here is an improved version of the above code:
Dim sName as String Dim results as MapPoint.FindResults Set results = oMap.FindAddressResults("One Microsoft Way", "Redmond", , "WA", , geoCountryUnitedStates) If (results.ResultsQuality = MapPoint.GeoFindResultsQuality.geoAllResultsValid Or results.ResultsQuality = MapPoint.GeoFindResultsQuality.geoFirstResultGood) Then sName = results.Item(1).Name Else sName = "Results were ambiguous or could not be found" End If
The documentation that ships with every copy of MapPoint is pretty clear with respect to these methods and the above assumptions. The problems appear to be due to lazy “cut and paste” coding based on poor code examples. Unfortunately some of these examples are in the official documentation.