Automating MapPoint in C++ With Built In GPS Features Enabled
Jonathan Oppelaar shows how he used techniques to overcome limitations in the MapPoint API to make MapPoint a better
navigation platform for Project54, a in-car law enforcement system currently in use in over 1,000 vehicles.
Project54 is currently developing a GPS Navigation application to be used in police cruisers. This navigation application is using MapPoint 2006 as its routing and mapping engine. MapPoint 2006 has an SDK which gives developers software control of MapPoint. With this SDK Project54 developers are able to integrate MapPoint into the Project54 system. However, there are a few limitations to MapPoints SDK that need to be resolved before MapPoint can be installed in a car. The first limitation is that there are no API calls to turn GPS Tracking on or off. GPS Tracking is a MapPoint feature that reads data from a GPS receiver and displays your current position on the map. This feature also has the ability to rotate the map, which cannot be done via APIs.
Driving Guidance is another MapPoint feature that cannot be controlled by the SDK. Driving Guidance displays turn by turn directions while a user is driving along a route. These directions are also presented to the user through speech. A status bar is shown to keep the user up to date with progress on a certain road segment.
These limitations must be overcome if we want to use MapPoint as the navigation backbone in the Project54 system. This article is about my workaround to MapPoints SDK that allows developers to enable MapPoints GPS Tracking and Driving Guidance.
I chose to develop a solution in C++ because I am most familiar with that language and Project54 applications are written using C++. Unfortunately for C++ developers, almost all resources for MapPoint are given in C# and VB. Since Project54 is COM based it would have been possible to write an application using C# or VB and incorporate it into Project54 but, that is not as clean of a solution and would require more work.
After researching my problem on the Internet I was able to find an article (1) that discusses how to use Windows messages to control MapPoint. In this article Paul Larson describes his API that can control MapPoints window panes as well as the check boxes in the panes which enables the GPS Tracking and Driver Guidance. I also found an article (2) that gives an example on how to automate MapPoint in C++.
With the combination of these two articles and other resources (3, 4, 5) I was able to write an application that integrates MapPoint into Project54. Unfortunately, even after enabling the Driving Guidance by help of Paul Larsons code, the turn by turn directions would not update. The only message given by the guidance was "Proceed to Route". This seemed odd to me because the turn by turn direction update perfectly when I would run MapPoint.exe outside of Project54.
This led me to try something different than what is the suggested way to start MapPoint. Every example I have come across initializes MapPoint using the CreateInstance (LPSTR clsid) (in C++) function call. This returns a COM pointer to the MapPoint application. You need this pointer in order to call any of MapPoints APIs. My approach was to use CreateProcess (LPSTR path) to open MapPoint.exe and then get a pointer to the application that is already running. I am able to do this by calling the GetActiveObject (LPSTR clsid) function. This function returns the application pointer to an active COM object.
Now that MapPoint is initialized differently, the Driving Guidance works perfectly. Also, no other code has to be altered. I cannot tell you why the driving directions did not work with the original solution but, I can tell you that when the new method is applied there are no issues enabling the GPS Tracking and Driving Guidance by windows messages. Figure 1 shows a screenshot of my application running with turn by turn direction working.