spacer1
spacer2 1_1 1_2
2_1
 Subscribe
 The MP2K Update!
 
 
 
 Magazine
Front Cover
What's New
Articles
News
Sample Data
Gallery
Advertise
About
 Features
MapPoint 2013
Press Releases
MapPoint Forums
Companies
Link to MP2Kmag
Wish List
MapPoint Trial
Authors
 Earlier Content
Past News Items
Past What's New Announcements
 Sponsors
 Order

MapPoint 2013

Programming MapPoint in .NET

MapPoint Book

  Spatial Community
SVG Tutorials
MapPoint

Map Visitors

  ARTICLES  


Finding the Starting Point of a Route

Nico Bontenbal shares a method for determining the starting point of a route by examining the pixels in the map image using Window API calls

For some time I have tried to find a way to determine the coordinates of the starting point of route segments. I want to be able to send these coordinates to my basic Garmin GPS. I've written code that sends the points of a polyline to my GPS, but I always have to trace a route by hand because MapPoint only returns the middle of a route segment and not the start.

The 'Reverse geocoding, another method' article gave me hope that by using the extrapolation technique I would be able to find the starting points of all the route segments. This works for rather straight route segments, but on a roundabout this does not work; the middle of the route isn't in the middle of the start and end of the segment. While exploring this technique I came up with a completely different solution. I found out that when you select a route segment, a label with the instruction appears on the map at the start of the segment as shown in the images below.

Route Starting Point

On an enlargement you can see the individual pixels of the map:

Route Starting Point Enlarged

I found out that by using the GetPixel and GetBitmapBits API calls I could analyze the map bitmap and find the location of this label and therefore the starting point of a route segment. There are many disadvantages to this technique. It is slow and the different maps are 'flashing' over the screen. Also I have to improve the technique further because it is not working 100%. Nonetheless, because I saw in the forum that I'm not the only one who wanted to solve this problem, I decided to share the technique.

When you use this code:

    objmap.ActiveRoute.Directions(intSegment).Select
    objmap.ActiveRoute.Directions(intSegment).Location.GoTo
    objmap.Altitude = objmap.Altitude * 2
MapPoint wil display a map something like the one in the example above. By using quite a complicated set of API-calls it is possible to scan this map for the location of the label. By using the XYToLocation function these coordinates can be transferred into a Mappoint location object.

I've written a GetRouteSegmentStartLocation function (download code) that does just this. It accepts a MapPoint map object and the number of the route segment and displays the route segment on screen. The function then uses the GetBitmapBits API-call (along with some others) to transfer the map into an array. After this it is easy to retrieve the colours of the individual pixels of the map.

The map is 'traced' for the 'signature' of the top of a label. I've defined the signature as: a black pixel with a white pixel 1 and 14 pixels below it, and a black pixel 15 pixels below it. This is a very simple definition of the 'signature' but it works most of the times. Improving the signature is one of the areas of the technique that needs improvement. When the top of a label is found the function scans the bitmap to the left to find the left border of the caption. When it finds the left border the start of the route segment (white dot) is 4 pixels to the left and 4 pixels to the top of the upper left corner of the label.

For performance reasons the bitmap is not scanned line by line. I found that most of the time the label is near the middle of the map so the map is first scanned at the middle. If a caption is not found there, the map it scanned at 3/4 and 1/4 of it’s width, then at 7/8, 5/8, 3/8 and 1/8 etc. until the label is found.

When you put all this together you get the code example you see at the end of this article. The Main procedure loops through all the segments of a route and puts a pushpin at the start of all of them.

To use this example copy the code into a VB(A) project and set a reference to MapPoint. Then start Mappoint and create a route. After this the Main procedure in the code can be run. Ideveloped and test the code in the European version of MapPoint, and it works with the US version as well.

As I said before, the signature of the label needs improvement. This can be done by adding more rules to the signature. For instance, when scanning to the left to find the left border all pixels in between should be whiteor at least 10 pixels to the left or to the right of the top of the label should be black (with white pixels below), etc.

I found that sometimes when the route is selected, the label is not displayed on the map. This is why the GetRouteSegmentStartLocation function stops scanning the map after it has scanned 64 lines;after this it assumes there is no label on the map.

When the selected route segment is large, the map is zoomed out to show the entire segment. This way the XYToLocation function is getting less accurate. This can be improved by scanning the map again after the (inaccurate) location is found, but this time at maximum zoom.

If anyone improves this example, please report these improvements back to MP2Kmag. I hope together we can make this code really useable (perhaps even in a production environment).

Also I can imagine other uses for the 'scan the map pixel by pixel technique' such as the ability to trace a complete route, a road, or a postal code area.

Discuss this story in the forum.

Author: Nico Bontenbal
Email: nico(AT)xsoffice.nl
URL: http://www.xsoffice.nl
Nico Bontenbal has developed MS Access applications for the last 10 years. Many of these applications use a link to MS Word and MS Excel. When he bought a Garmin Etrex GPS half a year ago MS MapPoint caught his attention. Just for fun he tried to link the GPS to MapPoint so he could plan a route in MapPoint and send it to the GPS, and project the trace log of the GPS on a MapPoint map. But he found out MapPoint can also be used with the MS Access applications he develops. For example to plot the locations of addresses in a database on a map.

Nico works as a contractor under the name XS-Office (www.xsoffice.nl, links to a site in Dutch). He lives and works (in that order) in Alphen aan den Rijn, Netherlands (52.1185 4.6560).



Google
 
MP2Kmag Internet


 Recent Discussion
 Resources
Browse GIS books and periodicals
Find a MapPoint Partner or Consultant
Real Estate Thornbrook Homes for Sale
Excellent Great Loop Travel Guide


Want Your Site To Appear Here?

   © 1999-2012 MP2K. Questions and comments to: website@mp2kmag.com
  Microsoft and MapPoint 2002/2004/2006/2009/2010/2011/2013 are either trademarks or registered trademarks of Microsoft.