Release date: 21st April 2017

Previous release: 4.2, 12th December 2016

Major changes since the previous release

Added a new routing system, turn-expanded A-star, which allows routes to pass through the same junction or road segment twice.

Added functions to set and get the preferred routing system and find out what the actual current routing system is.

Improved the system for allowing routes to pass along private highways at start and end, which was formerly unreliable and could cause slow route calculation.

The CFramework functions GeoCodeSummary and GetAddress no longer take a locale parameter. They use the locale set by CFramework::SetLocale; analogous changes have been made to the Android, .NET, and iOS SDKs.

Changes affecting the C++ API only

Abolished the CartoType-specific array classes CArray, CPointerArray, CNonOwningPointerArray, TFixedSizeArray. Standard library std::vector and std::array classes are now used instead of them.

Added functions CFramework::AbbreviatePlacename and ExpandStreetName.

Added the string class TWritableText, mostly for internal use.

The TTextLiteral macro now causes no code to be executed at run-time.

Changes affecting the .NET API only

The Geometry class now has functions to get the number of contours, number of points in any contour, the coordinates of a point, and whether the object is empty.

Changes affecting the IOS API only

The CartoTypeGeometry class now has functions to get the number of contours, number of points in any contour, and the coordinates of a point.

Changes to makemap

Many more projections are supported by the /project option, allowing you to use (for example) Lambert Equal Area with default parameters by simply using /project=laea instead of having to supply the full set of proj.4 options. The names are the same as those used in proj.4. The following projections are now supported: merc, cea, eqc, tmerc, tcea, cass, sinu, moll, eck1...eck6, goode, hatano, mbtfpp, mbtfpq, mbtfps, putp2, putp5, quau, winkl, boggs, collg, dense, parab, poly, hammer, wag7, aitoff, wintri, loxim, bonne, lcc, eqdc, pconic, aea, leac, rpoly, stere, sterea, gnom, ortho, airy, laea, aeqd.

A better memory allocation system gives about a 13% speed improvement when creating a CTM1 file from OSM data.

Some parallellization gives a further small speed improvement on multi-core computers; e.g., 3% on four physical cores.

Release 4.2 makes relatively few API changes. Its purpose is mainly to merge in a large number of internal changes from the main development branch.

Changes affecting all platforms

ReverseRoutes function

The new ReverseRoutes or reverseRoutes function reverses current routes, replacing them with new routes from the former end to the former start.

Changes to the C++ API


The CBaseMapObject class has been abolished. The public map object class is now CMapObject. 


There is a convenience declaration, CMapObjectArray, defined as std::vector<std::unique_ptr<CMapObject>> CMapObjectArray, which is used when returning map objects from Find functions. It replaces all former uses of CPointerArray<CBaseMapObject>. The use of unique pointers clarifies ownership and makes the objects easier to manage.


CBitmap functions which create modified bitmaps now return CBitmap objects, not std::unique_ptr<CBitmap>. There is no loss of performance because move operations are used internally.

Indication of turn-off

The TTurn class now has a member iTurnOff indicating whether is a turn off, defined as a turn on to a lower-status road.

Changes to the .NET API


There is a new class, MapObjectList, defined as System.Collections.Generic.List<CartoType.MapObject>, which is used when returning map objects from Find functions. It replaces all former uses of List<MapObject>. One advantage of this change is that it allows documentation for Find functions to be shown in the Visual Studio Object Browser. Formerly, the presence of < and > signs in the C++/CLI type List<MapObject^>^ prevented in-source documentation for the Find functions from being created during compilation.

Changes to the Android API

Licensing functions

Two new functions, Framework.license and Framework.licensee, allow you to supply a license key and get the licensee name respectively.


The new deleteRoutes function deletes all current routes.


Changes affecting all APIs

Gradients can be used in routing

You can add gradients to route data using the makemap command-line options /route=ag (A-star routing with gradients) or /route=cg (contraction hierarchy routing with gradients). For this to work you have to load the elevation data from USGS .hgt files using the /usgs option. For more details about the /usgs option see the main article about creating maps.

If you add gradients, one of eight gradients (flat or slight, gentle, steep and very steep, each in an uphill or downhill varient) is stored for every route segment. You can add speed weightings and bonuses to the route profile for the gradients, and specify which road types the gradient weightings apply to.

Loading and saving routes

Route objects now contain the route profile used to create them, which means you no longer have to specify a profile when saving a route. You can now load or save routes in files or strings, and you can load routes from GPX files, in which case the GPX track is converted to a legal route. All route loading and saving functions allow you to use either .ctroute or GPX format.

Layer names

You can get all the layer names in a single array using a new LayerNames or layerNames function.

Changes to the C++ API

Smart pointers

Functions creating objects (e.g., New functions, LoadMapObject) now return std::unique_ptr, not a raw pointer. This makes it much easier to manage their lifetimes.

String properties

String properties like Name, Locale and Proj4Param that were formerly returned as const char* are now returned as std::string, making it easier to write safe code.

Setting camera parameters in perspective view

The new SetPerspective overload takes a TPerspectiveParam object which allows you to set camera height, angle, rotation, field of view and other parameters.

Framework observers

Framework observers are now supported, primarily for use by CartoType GL.

Multiple framework observers are now supported: AddObserver and RemoveObserver replace SetObserver.

Changes to the Android Java API

Framework observers

Framework observers are now supported, primarily for use by CartoType GL.

CartoType release 4.0
and how it differs from release 3

Changes affecting all APIs

The Legend API

The new Legend API allows you to create consistent, good-looking and flexible legends (scale bars and keys to symbols) as separate images which can be overlaid on the map or drawn elsewhere.

Consistent argument order for the Find functions

The many Find functions now order their arguments consistently. The destination array always comes first, followed by the maximum object count if applicable, and so on. These changes also affect the non-C++ APIs.


Moving to C++11

The main theme of the changes is a move to modern C++. C++11 is supported on all major platforms, including Windows (VS2015), iOS (Xcode), the Android NDK (gcc), and Linux (gcc).

Memory allocation failure throws an exception

CartoType's builds formerly disabled exceptions and handled out-of-memory conditions by using a memory allocator which returned null when out of memory. The error KErrorNoMemory was then propagated back up the stack. CartoType 4.0 uses exceptions, and throws std::bad_alloc when an allocation fails. Other errors like failing to open a file are still handled using error codes.

Arrays are std::vector objects

CartoType's main two array classes are now publicly derived from std::vector:

template<class T> class CArray: public std::vector<T>
template<class T> class CPointerArray: public std::vector<T*>

That means you can now use all the std::vector functions and algorithms. Of course, because memory allocation failure now throws an exception, array functions no longer return error codes.

Sample code showing the use of range for with a CartoType array:

CPointerArray<CBaseMapObject> found_objects;
for (const auto p : found_objects)

size_t everywhere

Many argument and return types have changed from int32 to size_t to avoid warnings when using the new array classes based on std::vector.


CartoType::CString now has value semantics, which means you can assign strings to each other, pass them as function arguments, return them from functions, and create arrays of them. A CString still holds UTF-16 text, but can now be constructed from null-terminated 8-bit strings, and also from std::string. You can even construct a string from nullptr, which makes it easy to have default CString arguments: void myfunc(CString aText = nullptr). All this means that…

String arguments are simpler

Most functions taking string arguments now take CString or const CString&. Overloads taking const char* no longer exist. But thanks to the new CString constructors you can pass 8-bit string literals or std::string objects if you like.

So you can call CFramework::LoadMap in these different ways:

std::string map_name1("wales.ctm1");
CString map_name2("scotland.ctm1");

Observer interface: MFrameworkObserver

The new observer interface allows you to provide an observer object to a CartoType::CFramework object. The observer receives notifications of changes to the framework state. It is intended for the use of higher-level GUI objects which need to update their display after framework state has been changed programmatically. For example, if a route is created, dynamic map objects need to be redrawn.

British national grid functions

There are some new functions to convert back and forth between British national grid references and other position formats. They are useful when comparing CartoType maps of Great Britain with Ordnance Survey maps.

CT_IMPORT and CT_EXPORT have gone

The macros CT_IMPORT and CT_EXPORT were used in older versions of CartoType to declare functions as exported from DLLs. The C++ SDK is no longer built or shipped as a DLL, therefore these macros have been abolished.

Simpler functions to set and get string attributes

The functions to set and get string attributes have been simplified. For example, where you formerly wrote:

CString key; key.Set("addr:street");
TText street;

you can now write

CString street = my_map_object->GetStringAttribute("addr:street");

The makemap tool

No more support for old-style import scripts

Two obsolete import script formats are no longer supported. They are the old OSM rule format with the extension .osm_to_ctm1_rules, and the old shapefile rule format with the extension xml. The new .makemap format replaces them both.

In particular, when you import coastlines from shapefile data you should use a coastlines.makemap file with this content (adjusting the filename as necessary):

<?xml version="1.0" encoding="UTF-8"?>
        <file name='\coastlines-complete\land_polygons.shp'>
                <commit layer='outline'/>

The .makemap import rules format is described here: .


Release date: 26th June 2015

Previous release: 3.3, 13th May 2015


Release date: 13th May 2015

Changeset: 4926 (efa659079cbf)

Previous release: 3.2, 26th January 2015


Release date: 9th September 2015

Previous release: 3.4, 26th June 2015