Follow us on Twitter

Programming the new MapFeatures in MapPoint 2010

Share:

One of the most notable and asked-for additions to MapPoint 2010, is the ability to switch different map features on or off. A dozen or so different features can have their graphical representations (aka ‘symbols’) and/or labels switched on (default), off, or to display additional detail. The ability to switch labels on or off has been frequently requested, but this new feature goes further and provides a much finer level of control than was expected. This new functionality is also implemented in the API using the MapFeatures property and collection in the MapPoint Map object. This is covered in the documentation, although some of the documentation is incomplete. This article describes how to use this MapFeatures collection, and describes a couple of pitfalls. Examples are given using C#.

Calling MapPoint 2010 from C#

The example code (see below) is implemented in a series of functions. These are called with a test harness, implemented as a standard C# console application. When creating this console project, you must add a reference to the MapPoint COM object model. MapPoint 2010’s object model is version 17.0. The reference dialog box will use the name “Microsoft MapPoint 17.0 Object Library (North America)“.

Additional “using” references should also be added to the System.IO and System.Collections .NET libraries. These are only required for my demonstration code and are not required by MapPoint.

The test harness is below. This will be very familiar to anyone who has programmed previous versions of MapPoint with C#, and much of it should be familiar to programmers of other languages. It creates an Application object, displays MapPoint, gets a reference to the Map object; runs the test code; then shuts MapPoint down.

The only line of code which is new for MapPoint 2010, is the MapPoint.MapFeatures line. This obtains a reference to the MapFeatures collection using the Map object’s new MapFeatures property. This reference is passed to each individual test routine.

Accessing the MapFeatures Collection

Most if not all of MapPoint’s collections can be accessed using C#’s foreach statement. Our first test routine demonstrates that the same applies to the MapFeatures collection:

All this routine does, is to iterate through the collection querying every MapFeature object. Each map feature’s index and name is displayed.

The foreach construct can also be used to set all map features to the same setting – eg. All on, all off, or extra detail for everything. See the commented code for a sample of how to do this using the DetailedLevel property. This property uses a new enumeration called MapPoint.GeoMapDetail. Use GeoMapDetail.geoNeverDisplay to switch the feature
off. Use GeoMapDetail.geoDefault to switch the feature on at the default level. Use GeoMapDetail.geoMoreDetail if you wish to display additional detail. The final example in this article uses this last option to show extra river detail.

The DetailedLevel property could also be used to query feature visibilities (e.g. to serialize all map feature visibilities).

Obtaining an Alphabetical List of Map Feature Names

The following example is very similar to the above example, except the map feature names are displayed in alphabetical order:

Rather than using a .NET Dictionary object which keeps its contents sorted on the fly, an ArrayList is used instead. This is only sorted once after all the names have been added. This approach can be considerably faster for a simple “load/read” sequence like this.

Accessing Individual MapFeature Objects

The MapFeatures collection has an Item method which can be used to access individual MapFeature objects. As with other MapPoint collections, this appears in C# as the get_Item() method and expects an object reference as the parameter. This allows the calling application to refer to an object in the collection by its index or by its name. The downside is that it complicates the interface in C#. This is because the index (an integer) or the name (a string) has to be boxed as an object, and a reference has to be passed. This typically requires at least one extra line of code, so I have implemented two new functions which automate the process. These take an integer or a string, and return a reference to the resulting MapFeature object:

GetMapFeatureByIndex works as expected. Unfortunately, GetMapFeatureByName does not work if you pass the name (e.g. “Boundaries – Country – Symbols”) of the required MapFeature object. An ‘index not found’ exception is thrown. This method can be made to work, but only if you pass the required index as a string, eg. “8” instead of “Boundaries – Country – Symbols”! Therefore the string implementation is of little use for this collection, and developers should use the integer index instead.

Here are the map feature indexes for MapPoint 2010:

  1. Miscellaneous – Water Features – Symbols
  2. Miscellaneous – Parks and Reserves – Symbols
  3. Miscellaneous – All Other – Symbols
  4. Populated Places – Town/Other Place (0 – 99,999) – Symbols
  5. Populated Places – Minor City (100,000 – 499,999) – Symbols
  6. Populated Places – City (500,000 – 999,999) – Symbols
  7. Populated Places – Major City (1,000,000+) – Symbols
  8. Boundaries – Country – Symbols
  9. Boundaries – State or Province – Symbols
  10. Boundaries – County – Symbols
  11. Transportation – Highways – Symbols
  12. Transportation – Local Roads – Symbols
  13. Transportation – Railroads – Symbols
  14. Boundaries – Postal Code – Symbols
  15. Miscellaneous – Points of Interest – Symbols
  16. Miscellaneous – Water Features – Labels
  17. Miscellaneous – Parks and Reserves – Labels
  18. Miscellaneous – All Other – Labels
  19. Populated Places – Town/Other Place (0 – 99,999) – Labels
  20. Populated Places – Minor City (100,000 – 499,999) – Labels
  21. Populated Places – City (500,000-999,999) – Labels
  22. Populated Places – Major City (1,000,000+) – Labels
  23. Boundaries – Country – Labels
  24. Boundaries – State or Province – Labels
  25. Boundaries – County – Labels
  26. Transportation – Highways – Labels
  27. Transportation – Local Roads – Labels
  28. Boundaries – Postal Code – Labels
  29. Miscellaneous – Points of Interest – Labels
  30. Boundaries – Commune – Symbols
  31. Boundaries – Commune – Labels
  32. Transportation – Toll Roads – Symbols
  33. Transportation – Toll Roads – Labels
  34. Boundaries – 3 digit Postal Code – Symbols
  35. Boundaries – 3 digit Postal Code – Labels

The integer index might pose problems in the future. There is nothing in the documentation to say that these numbers will remain the same. A conscientious developer should write code that checks the MapFeature names are what the developer expects. The alternative is code that might break or behave in an unexpected manner when a new version of MapPoint is released with new MapFeatures or different index codes.

Here is some example code which uses GetMapFeatureByIndex (and to a lesser extent GetMapFeatureByName) to change a number of feature visibility settings:

This code switches all roads, railroads, and smaller cities off. Rivers and parks are switched on with “additional detail”. This produces the display below. As can be seen, “additional detail” adds a number of additional park icons, but it also adds a lot of additional smaller rivers and lakes.

Note that the above methods return references which could also be used to query the visibility of individual map features.

Example screenshot (click for larger image)

Conclusions

The new map feature functionality implements a much-requested feature, and includes more capabilities than anyone was expecting. It should greatly enhance MapPoint’s utility in producing presentation maps.

The programming interface has a few quirks. The documentation could be more complete, and the get_Item() function could implement names. Or better still, it would be great if MapFeature objects could be queried using an enumeration. A correctly implemented enumeration should be immune to any future changes or additions to the available map features.

1 comment to Programming the new MapFeatures in MapPoint 2010

  • Matt

    Thank You, Thank You, Thank You. If I did eventually figure this out it would have taken forever. It’s unfortunate for MapPoint devs that MS will never migrate this product to be a full .net citizen. But we’ll make the best of it until they stop supporting it all together!

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">