Here are answers to some questions frequently asked about CartoType.

Will CartoType run on any platform?

Yes, as long as, for that platform, there is a way of building C++ code using a compiler which supports C++14.

Can I add my own data to the map?

Yes, you can add your own points, lines and polygons; in fact you can add any type of map object at run-time (except bitmap objects, which are used for terrain shading and similar things); objects can be added to any layer, or you can create new layers.You can add extra styles for these objects, either at run-time, or by adding them to your custom style sheet.

Why is a CTM1 file twice the size of a PBF file?

A CTM1 file is a file in CartoType's own map file format. A PBF file contains OpenStreetMap data encoded compactly using the protocol buffer system.

A CTM1 file is normally about twice the size of a PBF file. The actual main data (layer data) is roughly the same size as the PBF file, but there are several other tables necessary to make things work, or speed things up. The main ones are

  • the low-resolution layer data: when you zoom right out you don't want to incur the cost of loading detailed polygons like (say) the entire eastern coastline of the USA. The lower resolution copies remove any features which would be less than a pixel in size when drawn. Turn this off using /lowreslayers=no as a makemap argument, at the cost of slower drawing.
  • the full-text index; turn it off using /textindex=no, at the cost of poor or slow address searching.
  • the route network; turn it off using /route=no, at the cost of slow first route creation; CartoType has to build the route table at run-time if it's not in the CTM1 file.

Here's an example of how things break down, using a map of the eastern part of the US state of Virginia. I obtained the data using the ctm1_info tool, which you can download: http://www.cartotype.com/assets/downloads/ctm1_info.exe.

east_virginia.pbf = 253Mb

east_virginia.ctm1 = 424Mb

extract from ctm1_info report:

table 0: global information (166 bytes, 0.00Mb)
table 1: layer data (266637835 bytes, 254.29Mb)
table 4: projection table (99 bytes, 0.00Mb)
table 5: table of compressed strings (776336 bytes, 0.74Mb)
table 6: low-resolution layer data (41879150 bytes, 39.94Mb)
table 8: index used for text searching (57499012 bytes, 54.84Mb)
table 10: routing network (A*) (56946763 bytes, 54.31Mb)
table 12: extra information for the routing network (A*) (9493 bytes, 0.01Mb)

I want to create maps of countries including parts of bordering countries

If you want to create a map of a European country (for example) with a bounding box in degrees which contains parts of bordering countries, it's not practical to download the OSM data for the whole of Europe, then use the /extent parameter with makemap, because makemap loads all the data before clipping it to the bounds; and that takes a long time and about 100Gb of RAM. Here is what you should do instead:

1. Download the OpenStreetMap data for the entire planet in PBF format. It is currently (in September 2022) about 56Gb in size. You can then keep it updated using osmupdate.

2. Extract rectangular or polygonal regions using osmconvert on planet.pbf. The best thing to do is to ask it to write the extracts as PBF files, which are more compact than OSM files.

3. Run makemap on the PBF files you have extracted. You can use osmconvert to convert to OSM format and pipe the output to makemap, like this:

osmconvert denmark.pbf | makemap -project=laea -.osm denmark.ctm1

The special input filename _.osm tells makemap to read from standard input.

Can I use CartoType with Qt?

Yes. In fact our multi-platform Maps App is written in Qt, using the CartoType C++ API. The source code is availble for your use under the MIT license.

Using the CartoType Windows SDK, link your app with bin\17.0\x64\ReleaseDLL\cartotype.lib and bin\17.0\x64\ReleaseDLL\CartoTypeQtMapRenderer.lib.

Using the CartoType Linux SDK, link your app with bin/libcartotype.a and bin/libCartoTypeQtMapRenderer.a.

Please contact us if you would like to use CartoType with Qt on other platforms.

How can I set the color of a map object when I insert it using InsertMapObject()?

Lines and polygons

You can give every map object that is a line or a polygon its own main color and border color, overriding any colors set in the style sheet. Formerly (before CartoType 7.4) that was possible only for icons. The new feature is principally useful when inserting map objects at run time ('dynamic map objects') but can be used when building the CTM1 file by inserting appropriate logic in the .makemap rules.

The colors are set using the map object attributes _color and _border_color. Colors can use any color expression that is valid in a style sheet. For example: 'blue', 'orange+0.25white', '#A00', '#08123456'. A color expression consists of one or more sections separated by plus signs. The format of a section is

{ '+' { blend-ratio } } hex-color | color-name

where blend-ratio is an optional number; if it's between 0 and 1 inclusive it's treated as a fraction, otherwise as a number of 255ths; and hex-color is either #RGB, #RGBA, #RRGGBB or #RRGGBBAA. The plus sign and blend-ratio are legal only if there is a previous color to blend with.

Icons

You can set the color of an icon using the _color attribute. It sets the overall color of an icon by 'colorising' it: converting it to grey-scale then drawing it in the selected color. For best results when setting icon colors in this way use monochrome black icons.

Can I rotate an icon to point in any direction?

You can draw icons along a line object using the repeatedSymbol element in a layer. The documentation (also see this article) is the same as for <oneWayArrow>, but <oneWayArrow> works only for one-way streets, while <repeatedSymbol> works for all linear objects. Note that gap='0' causes a single element only to be drawn.

If you need to insert a point object with a rotated icon you can do that by inserting a short line segment that is not actually drawn. For example, you might want to show an icon representing a drone and show which way the drone is pointing. 

Here's what you need to do. The following example uses an SVG icon called drone-icon.

Create a style sheet layer for the drone position. Let's call it drone/vector because it's job is to indicate a vector or direction, not just a position:

<layer name='drone/vector'>
<repeatedSymbol gap='0' ref='drone-icon'/>
</layer>

Ensure that the definition of 'drone-icon' specifies the desired size. For example, you could scale the drone icon to 25 map metres, with a minimum size of 3mm, by defining it like this:

<icon id='drone-icon' width='25m,3mm'>
<svg ... >
...
</svg>
</icon>

Get the drone's position in degrees long/lat, and the direction it is pointing in (the azimuth) as an angle in degrees (North = 0, East = 90, etc.).

This data must be supplied by your application.

Get a point 100 metres from the drone's position, in the direction of the azimuth, using this function (in the C++ API: other APIs are similar):

CartoType::PointFP p = CartoType::PointAtAzimuth(drone_position,drone_azimuth,100);

Insert a line object with its start at the drone's position and its end at p.

CartoType::Geometry(CartoType::CoordType::Degree,false);
g.AppendPoint(drone_position.X,drone_position.Y);
g.AppendPoint(p.X,p.Y);
long id = 0;
my_framework->InsertMapObject(0,"drone/vector",g,"",nullptr,id,true);