The CartoType core library is written in C++. To use it to draw maps you need to create various class objects. All CartoType functionality is accessed by calling member functions of those objects.
C++ programming conventions
In the CartoType C++ API, nearly all public identifiers use Pascal Case, which means that each word of a compound name starts with a capital letter. Examples: Framework, BitmapView (classes), Rotation, DisplayRoute (functions), X, Y (data members). Everything is in the CartoType namespace, which you can use either by putting the 'CartoType::' qualifier before the names, or putting 'using namespace CartoType;' at the start of your source files.
There are some complications to the naming convention.
M classes are 'mixins' or interfaces or abstract classes. Example: MPath.
Formal arguments (parameters) of functions start with a small a, for 'argument'. Example: Result Framework::LoadFont(const String& aFontFileName).
Numeric constants start with K: for example, KDarkBlue, KDegreesToRadiansDouble.
Indenting and bracketing follow the Whitesmiths style.
These conventions are documented for your convenience in understanding CartoType APIs. Naturally you are free to use your own preferred style in your code.
Error codes, not exceptions
In general, exceptions are not thrown by the CartoType C++ SDK. It uses exceptions internally but they are trapped and an error code is returned to the caller using the CartoType::Result type, which is convertible to an integer. The value 0 (KErrorNone) indicates success.
Construction using a 'New' function
Some classes have constructors that might fail for some other reason than running out of memory. In those cases the constructor is made private, and instead of using the constructor you call a static function called New, which returns a smart pointer to a fully constructed object; the pointer will be null if construction fails. For example, you can call
static std::unique_ptr<CFramework> New(Result& aError,const Framework::Param& aParam)
to create the CartoType framework object. If construction fails, the returned unique pointer is null and the error code is placed in aError. If construction succeeds, aError will have the value 0 (KErrorNone).
The C++ language
CartoType is written in C++14.
Here is how you initialize CartoType.
Create a framework object
The framework object (CartoType::Framework) manages the resources and objects you need to draw a map: the CartoType engine, the fonts, the data sources and the map itself.The normal system is to create just one framework object. Keep the framework for the duration of your application: it is best to make it a data member of your main application object.
You supply map data, a style sheet and a font to create a framework. Later on you can add more map data and load extra fonts if necessary. You need:
- A CTM1 file containing your map.
- A style sheet: an XML document telling CartoType how to draw the map. This sample code loads CartoType's OSM style sheet, designed for displaying OpenStreetMap data
- A font. You can load any TrueType, OpenType or PostScript Type 1 font. This sample code loads Deja Vu Sans from the Deja Vu family.
// declaration of the CFramework object in your application class std::unique_ptr<CartoType::Framework> m_framework; // desired width and height of your map in pixels (example values) int view_width = 800; int view_height = 600; // code in your application class's initialization function CartoType::Result error; m_framework = CartoType::Framework::New(error, "/CartoType/src/test/data/ctm1/santa-cruz.ctm1", "/CartoType/src/style/standard.ctstyle", "/CartoType/src/font/DejaVuSans.ttf", view_width,view_height);
Optionally load some more fonts
You have loaded one font, but it's a good idea to load some more so that the maps look more attractive. The standard style sheet uses more than one typeface. You can load any TrueType, OpenType or PostScript Type 1 fonts you like. In this example some more fonts are loaded from the popular and versatile Deja Vu family. The other is Droid Sans Fallback, which provides Chinese and other scripts not supported by the Deja Vu fonts.
if (!error) error = m_framework->LoadFont("/CartoType/src/font/DejaVuSans-Bold.ttf"); if (!error) error = m_framework->LoadFont("/CartoType/src/font/DejaVuSerif.ttf"); if (!error) error = m_framework->LoadFont("/CartoType/src/font/DejaVuSerif-Italic.ttf"); if (!error) error = m_framework->LoadFont("/CartoType/src/font/DroidSansFallback.ttf");
In this example, for simplicity, the fonts are taken from their standard location in the CartoType sources. In production code you would need to obtain a path to the fonts from somewhere or create it relative to the application's path.
Drawing the map
In these steps you draw the map and handle user interface events, allowing the user to pan, zoom and rotate the map. This functionality happens in your application framework's event handling system, which differs from one platform to another.
This example uses MFC (Microsoft Foundation Classes). The full source code of a working Windows demo using this code can be found in the CartoType public repository. The code relies on the OpenGL ES 2.0 libraries, which are supplied with the evaluation CartoType Windows SDK.
Create a map renderer object
// declaration of the map renderer in your application class std::unique_ptr<CartoType::MapRenderer> m_map_renderer; // code in your application class's initialization function m_map_renderer = std::make_unique<CartoType::MapRenderer>(*m_framework,m_hWnd);
That's all you need to do. The map renderer object draws the map continuously at 30 frames per second.
See the source code of the C# demo app.
See the source code of the Android demo app.
See the source code of the Swift demo app.