Build Real-Time Web Images
Use Microsoft's TerraService and MapPoint Web Services to start your own VS.NET-based mapping projects.
Technology Toolbox: VB.NET, XML, Visual Studio .NET 2003, XML Web services
Location-based Web services will play an increasingly important role as handheld devices gain carrier-based and GPS positioning capabilities. You can expect Microsoft, other map providers, and cellular carriers to offer an expanding array of geocoded imaging Web services. Now's the time to start exploring new VS.NET mapping applications.
Existing production Web services mostly deliver character-based XML datasuch as ADO.NET DataSetsbetween server endpoints. Not many commercial services interact with desktop clients yet. Consequently, you rarely see Web services that deliver base64Encoded bitmap data you can display in a Web or Windows client.
User demand is growing for image delivery, however, and developers who hear the call are starting to discover what they can do with VS.NET 2003's Add Web Reference dialog. This dialog makes it easy to create proxies for Web services that return encoded images. True, it isn't a walk in the park to write VB.NET or C# code for specifying geographic image coordinates and displaying them in a WinForm or Web Form appespecially if you haven't mastered the members of the .NET Framework 1.1's System.Drawing.Imaging and System.Drawing.Printing namespaces.
I'll give you a head start by describing two WinForm imaging apps that consume mapping Web services. I'll provide highlights of the VB.NET code required to acquire, display, and navigate aerial photographs and annotated topograpic maps. You can download the complete source code for both VS.NET 2003 projects.
The first project, TerraService.sln, connects to Microsoft Research's ASP.NET TerraService and LandmarkService (see Additional Resources). TerraService provides direct access to the 3.5 terabyte (TB) TerraServer SQL Server 2000 database of satellite and U.S. Geological Survey (USGS) aerial photographs, along with scanned images of USGS paper topographic maps. The TerraServer project started in 1997 as a SQL Server 7.0 scalability demonstration. Public Web access to 1.5 GB of TerraServer images commenced in 1998, and is currently in version 6.0. Microsoft Research added TerraService Web services in 2001.
TerraService delivers images as Simple Object Access Protocol (SOAP) response documents containing base64Encoded bitmaps of 200-by-200-pixel tiles, specified by theme, scale, scene, and X and Y indexes (see Listing 1). Available members of the theme enumeration are Photo (1), Topo (2), or Relief (3). The scale enum specifies the resolution of the tile in meters per pixel (m/px). The base resolution of the tiles is 1 m/px and ranges downward to 2,048 km/px, but 256 m/px is the lowest resolution that delivers a useful image.
A scene (integer) is one of 60 Universal Transverse Mercator (UTM) zones of the earth; scenes 10 and 11 show America's West Coast, with the East Coast in scenes 17, 18, and 19. Indexes are related to the integer UTM eastings (X) and northings (Y) of the tile. Photo tiles are JPEG gray-scale images in 8-bit indexed format; topo map tiles are 24-bit RGB or 8-bit indexed GIF color images. Typical size of a TerraService GetTile method SOAP response document is about 10K for photos and 24K for topo maps. Fortunately, the Web service proxy code converts base64Encoded byte arrays to the appropriate binary encoding automatically. Also, imaging namespace members make it easy to handle JPEG, GIF, PNG, TIFF, and BMP format translation.
Draw a Photo or Map on the Form
You display photos or topo map images of reasonable size by assembling multiple tiles. The projects' 640-by-480-pixel active display area below the main form's title and menu bars requires from 12 to 20 tiles, depending on the relationship of the image's latitude/longitude centerpoint coordinates to the centerpoint of the central tile. You express the coordinates in pixels as XOffset and YOffset. Pass the centerpoint coordinates as a LatLonPt. Add that to the theme, scale, and bitmap width and height as arguments of the GetAreaFromPt Web method. The system then returns an AreaBoundingBox type. This type's members define the range of tile indexes required and the XOffset and YOffset values.
You invoke the GetTile method to return each tile. It takes about four to eight seconds to acquire the 12 to 20 tiles needed for a 640-by-480-pixel image, assuming a medium-speed DSL connection. You generate the final display bitmap with code that stitches together multiple adjacent tile images that are cropped by XOffset and YOffset values (see Listing 2). Displaying the image on the form's active area requires a MyBase.Invalidate instruction to invoke an overridden Form.OnPaint event handler. The handler refreshes the image and optionally adds tile gridlines (see Listing 3 and Figure 1).
End users aren't likely to know the lat/lon coordinates of the image they want. Consequently, the sample apps provide a city menu displaying 16 m/px images of seven arbitrarily chosen cities. TerraService's ConvertPlaceToLatLonPt returns the centerpoint coordinates of major U.S. cities, airports, and other well-known points of interest. The Places List | New Selection menu choice opens a dialog (Places.vb) that lets users specify a city name and state. Clicking on Get Places returns a list of available place coordinates. Double-clicking on or selecting a list item and clicking on Get Map displays the default photo or topo map image at a scale appropriate to the place type (see Figure 2).
Users can change the scale and navigate north, east, west, or south by one tile. Pressing Ctrl-C copies the bitmap to the Clipboard by executing a Clipboard.SetDataObject(bmpImage, True) statement. Users can save images to files in JPEG, GIFF, PNG, TIFF, or BMP format, but can open and display files only as JPEGs. Displaying a saved file disables most main menu choices, because the image centerpoint coordinates aren't included in the file.
Right-clicking on the form opens the Image Data dialog that shows a raft of information about the currently displayed image (see Figure 3). The most significant data are the west-east and north-south image distances in kilometers. Functions in PublicVars.vb use trigonometric functions from System.Math to compute the distances from the longitude and latitude of the top-left, bottom-left, and bottom-right corners of the image.
The only documentation for TerraServer's LandmarkService is its WSDL document. That means you'll need to do some experimentation in your code to determine the types and number of landmarks within the current image rectangle. There are many landmark types, but only a few return Shape.Point (LatLonPt) types; types such as Parks and Recreation Areas return Shape.Polygon or Polyline types for overlays on images. A large rectangle that surrounds an entire city can return several hundred landmarks. You can create an array of valid landmark types by activating the Landmarks.vb dialog, which calls the GetLandmarkTypes method and then the CountOfLandmarkPointsByRect method. This method populates a checked listbox with the names and counts of LandmarkTypes that return LatLonPt objects. Users mark the types to return and click on Get Selected Landmarks to fill the Landmarks list by invoking the GetLandmarkPointsByRect method (see Figure 4).
Even a medium-size citysuch as Oakland, Calif., at 16 m/pxhas 306 point landmarks, though many are of historical interest only. Strangely, New York City at 32 m/px returns only 233 landmark items. The online help file for both projects illustrates both applications' menu-based feature sets.
Add Images and Address Lookup
MapPoint Web Service provides a broad range of Web services for displaying maps using a multitude of methods. Microsoft offers a free Web service evaluation agreement good for 45 days' use of the MapPoint staging server. Better yet, MSDN subscribers can sign up for a one-year subscription to the staging and production servers. I used this plan to add a MapPoint theme and address lookup feature to my original TerraService project. MapPoint bitmaps derive from vector-based images, making them clearer and more attractive than the scanned USGS paper topo maps.
The new MapPoint Web Service SDK 3.5 provides several ASP.NET Web Forms that demonstrate the service's extensive capabilities and give you a starting point for map-based projects. I based the MapPoint code in the second TerraServiceMP.sln project on the MapWithNavigationButton and FindAddress samples in the ...\CoreFunctionality\VB folder. It required about one programmer day to add basic MapPoint functionality to the original app.
You have more options for displaying MapPoint maps than for TerraService topo maps (see Figure 5). I chose ViewByScale for the MapPoint View type. This requires a LatLon centerpoint definition and Integer MapScale to return the image. The ViewByScale option lets you clone GetTileImage with the GetMapPointImage function to enable all TerraService menu choices when users select MapPoint images (see Listing 4). MapPoint's Scale property is the ratio of the display's physical dimensions (at the most common 96 px/inch resolution) to those of a corresponding rectangle on the earth. Interestingly, a MapPoint Scale value of 60,000 generates maps with nearly identical coverage as photos and topo maps at TerraService's 16 m/px scale.
Users expect address lookup with most commercial mapping applications, and they'll feel cheated if they can't display photos and maps centered onor close totheir residence address. The MapPoint Web Service includes a FindServicesSoap.FindAddress method that returns the centerpoint coordinates of postal addresses in the MapPoint database closest to the address you type in the projects' Enter U.S. Postal Address dialog (Address.vb). Click on the Get Address button to populate the textboxes with the address data returned from the Web service call; click on Get Map to display the default 2 m/px image centered on the coordinates (see Figure 6).
Download the source code for the two VB.NET sample project versions, get a MapPoint evaluation account or MSDN subscription, and give them a test drive. Working with mapping lets you gain useful experience with Web services that return complex encoded image and related XML Schema types. You can sharpen your WinForm or Web Form graphics and math skills by displaying map images and adding custom annotations. Microsoft announced a new MapPoint Location Server integrated with the MapPoint Web Service in March, and you'll be able to take advantage of this once you've gone through the exercises I've discussed here.
Roger Jennings is an independent data-oriented .NET developer and computer book author. He's also a Visual Studio Magazine contributing editor and the author of oakleafblog.blogspot.com