Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

Mapping, Web Services, & C++

February, 2005: Mapping, Web Services, & C++

Neil Roodyn is an independent software consultant and author who can be contacted at http://www.Roodyn.com/ or [email protected].

Signing Up for MapPoint Web Services

The Microsoft MapPoint web service [1] provides methods for looking up addresses, rendering maps, calculating routes, and a number of other useful mapping functions. I was recently asked to examine the possibility of helping a client get an application up and running on a Microsoft Smartphone, a cell phone with built-in PDA-like capabilities [2] that utilizes the MapPoint web service. The client wanted the phone screen to display a map of an address that was entered. I initially thought the .NET Compact Framework would be a good place to start, but it turned out that the client had already deployed a number of Smartphone 2002 devices, which unfortunately don't support the .NET Framework. Consequently, the only way to write applications for them is using embedded Visual C++ [3].

In this article, I describe what's involved in building client applications for the MapPoint web service in C++. To fully implement the techniques and code I present here, you must have MapPoint developer credentials. To sign up for credentials, see the accompanying text box "Signing Up for MapPoint Web Services."

Mobile devices such as the Smartphone present challenges above and beyond a normal C++-based web-service client, namely:

  • Keeping the application as small as possible.
  • Dealing with a sometimes-connected environment.
  • Calling an authenticated web service (MapPoint).

As an extreme programmer, I always start with a couple of spikes (experiments) to get the lay of the land. The idea is to get a thin slice of the functionality working. In this case, I wanted to create a small C++ application that calls the web service and returns some information.

Before writing any code, however, I considered whether a toolkit would help since a couple of years ago, I investigated several C++ toolkits for creating and using web services. In particular, I used RogueWave's LEIF (short for "Lightweight Enterprise Integration Framework") toolkit [4] to help a client connect a legacy C++ application through to newer .NET clients. At the same time, I also looked at gSOAP [5] and PocketSOAP [6]. However, the problem with toolkits is that they all carry some baggage. While small, the baggage is still there and embedded solutions demand the least-possible amount of baggage. Every kilobyte counts and any general solution adds a few more KBs.

Luckily, web services such as MapPoint are easy to use—essentially, they're HTTP calls that send and return text files—so I decided a toolkit would be overkill for this project. In the time it would take to learn to use the toolkit, I could have written most of the solution.

For example, the first spike I implemented was a console application that used the Win32 WinInet functions to open a connection, set up a session, and make a request. Conveniently, WinInet methods are available on the Smartphone, making life easier. Listing 1, for instance, calls the GetVersionInfo method on the web service, thereby validating that the code is working.

When you run this program, you see the output in Figure 1. The version number in the XML you have retrieved is and you don't need to write the code here to extract that. Again, the point of this exercise was to see how easy it is to call the authenticated MapPoint web service.

How do you know what the XML to build the SOAP request should look like? The Web Service Description Language (WSDL) file provides everything you need to work this out. This WSDL can be found at http://staging.mappoint.net/standard-30/mappoint.wsdl. The description of the GetVersionInfoSoapIn message defines the parameters that are expected in the body of the SOAP when the call is made to the operation. In this case, the parameters are described in the GetVersionInfo element (Example 1). As you can see in the WSDL, the GetVersionInfo element is empty, so no parameters need to be embedded in the SOAP. Of course, this is a simple call. Sticking to the desktop console application (thereby letting you do this without a Smartphone), I'll expand this code to find the latitude and longitude of an address using the MapPoint web service.

First you create a FindAddress method that you can call with an Internet session handle and an address. In Listing 2, I have extracted from the main method the functionality that opens the HTTP session, sets up the headers, and sends the request. I have also added a call to a method called BuildFindAddressSoapRequest.

The BuildFindAddressSoapRequest method is similar to the BuildSoap method. You need to work out what the SOAP body needs to contain. This time it is somewhat more complicated than the GetVersionInfo operation. The WSDL describes the FindAddressSoapIn, which takes a FindAddress element. The FindAddress element consists of a FindAddressSpecification. The FindAddressSpecification contains the DataSourceName (a string), an Address type, and FindOptions.

From this WSDL (see Example 2) and the help available on the MSDN MapPoint web site [1], you can create the BuildFindAddressSoapRequest method in Listing 3. In the main method, you can call the FindAddress method with an address, as in Listing 4.

When you run this application, you can see that the latitude and longitude are returned in the body of the XML SOAP envelope (Figure 2). You should probably think about extracting the latitude and longitude from the XML; see Listing 5. You can then call that method from the FindAddress method when you have read the response (Listing 6).

Granted, this is simplistic—but that's the point! If you were doing this with a SOAP toolkit such as gSOAP, LEIF, or PocketSOAP, you would get structures generated for each of the custom types exposed by the web service. For example, the FindAddressSpecification structure might look like this:

struct FindAddressSpecification 
TCHAR* DataSourceName;
Address* InputAddress;
FindOptions* Options;

As you have this structure, you would need the Address and FindOptions structures:

struct Address 
TCHAR* AddressLine;
TCHAR* PrimaryCity;
TCHAR* SecondaryCity;
TCHAR* Subdivision;
TCHAR* PostalCode;
TCHAR* CountryRegion;
TCHAR* FormattedAddress;

These structures add to the overhead mentioned earlier, and you don't need them just to get a latitude and longitude. If you are using a small subset of what is provided by a web service, then you can write simple code that gets what you want from the web service without using a toolkit. Or when you are writing a client application that uses only a small number of calls, you can get away without the toolkit. However, the toolkits are great for when you are using a large number of methods from a web service.

The requirements for the client application I am presenting here is to display a map of an address. This requires two method calls—one to get the latitude and longitude, and another to get the map.

Using the WSDL, you can work out what you need to pass in the SOAP body to get a map from a latitude and longitude. You can build this SOAP envelope in a method similar to the BuildFindAddressSoapRequest method (Listing 7). This BuildGetMapSoapRequest can be called from a method that opens the HTTP session and sends the request. Similar to the FindAddress method, this new GetMap method calls an operation on the MapPoint web service (Listing 8). Notice that the endpoint has changed from /Find-30/FindService.asmx to /Render-30/RenderService.asmx.

How did I know this was the endpoint for this operation? From the WSDL, which describes the service that supports the GetMap method:

<wsdl:service name="RouteService">
	. . . 
 <wsdl:port name="RouteServiceSoap" binding="tns:RouteServiceSoap">
  <soap:address location=
   "http://routev3.staging.mappoint.net/Route-30/RouteService.asmx" /> 

You can also see that not only the endpoint has changed, but the server is also different. This means you cannot use the same Internet session for the GetMap call that you used for the FindAddress call. To call the GetMap method, you need to call InternetConnect again with the server name (Listing 9).

To get the map image (see Figure 3), you need to extract the image bits from the response you get in the GetMap method. For this experiment, I can save the image to a file. This SaveMapBitmap (Listing 10) can be called from the GetMap method.

Porting this code from the console to the Smartphone involves two other issues:

  • Because the Smartphone doesn't support Digest Authentication by default, you need to either find or write a Digest Authentication library for the Smartphone.
  • The Base64Decode method I used in the experiment is not available on the Smartphone platform. This is a simpler issue that can easily be resolved with a small method.


[1] http://msdn.microsoft.com/MapPoint.

[2] http://www.microsoft.com/windowsmobile/smartphone/default.mspx.

[3] http://www.microsoft.com/downloads/details.aspx?FamilyID=1dacdb3d-50d1-41b2-a107-fa75ae960856&displaylang=en.

[4] http://www.roguewave.com/products/leif/.

[5] http://www.cs.fsu.edu/~engelen/soap.html.

[6] http://www.pocketsoap.com/.

[7] http://blogs.msdn.com/cthota.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.