November 28, 2011
Maperitive Beta: Subpixel Accuracy

Even though most of Maperitive work I’m doing lately is done in a separate branch that will come out as a brand new Maperitive 2.0 release some time in the beginning of 2012, I do occasionally implement some quick enhancements to the currently “unofficially” released Maperitive beta. I’ve just uploaded a new beta version with a couple of neat features, one of which I will describe in this post (the other will have to wait for the next post).

Subpixel Accuracy

This is an important, although probably not very well known feature Mapnik provides. What is subpixel accuracy? Simply put, it is the ability to set the thickness of the line in fractions of a pixel (image stolen from AGG’s site):

Up until now this was not really possible in Maperitive. Well, you could specify the thickness as, say, 1.3 pixels, but it would be rendered as a line with thickness of one pixel, ignoring the fraction. The reason is simple: Maperitive uses GDI+ library for rendering, which doesn’t do subpixel accuracy (it does support antialiasing, but that’s not enough). Mapnik, on the other hand, uses superior Anti-Grain Geometry (AGG) library (you can read more about it in AGG’s Introduction page, which is very interesting).

Why is subpixel accuracy important? Certain map features require delicacy. In his Cartographic Relief Presentation book Eduard Imhof gives very precise recommendations for elevation contour lines thicknesses. 0.05 to 0.08 mm for black normal contours for map scale 1 : 50,000, as an example. Without subpixel accuracy it is very difficult to come even close to such measures and then you end up with both normal and index contours (the thicker ones) having the same thickness in the rendering:

So given that I cannot directly render lines with subpixel accuracy and using AGG in Maperitive is not a practical solution because of various technical reasons I won’t go into, I’ve more or less given up on this.

The Solution

… Until I came up with a simple but effective trick to achieve subpixel accuracy: render the whole map scaled to (say) three times and then downsample the whole image back to the “normal” scale. Before I delve into details, here’s how the same map looks like using this technique:

I think the difference is obvious: you can now see two distinctive contour line types. Index lines are 1.25 wide, while normal lines have a width of 0.65 pixels.Don’t worry about these numbers, subpixel accuracy is not that precise, but it is precise enough.

The Details

Subpixel accuracy can be tuned for three Maperitive commands:

  • export-bitmap
  • export-3d
  • generate-tiles

All of them have a new subpixel parameter which accepts a positive integer value. This value is used as a scaling factor when rendering. Once the rendering is done, Maperitive uses Supersampling algorithm to resample (downsample actually) the rendering to the scale factor of 1. So for example if you want to generate tiles using subpixel accuracy, you type in something like

generate-tiles minzoom=10 maxzoom=12 subpixel=3

Caveats

What is the best value for subpixel parameter, you may ask? I’ve been experimenting with the value of 3. You could try larger values, although I doubt there will be a noticeable increase in the quality of rendering. The downside of larger values is that Maperitive takes longer to render. This could considerably slow down your tiles generation, so there is a trade-off between the quality and speed (isn’t there always?). Measurements of tile generation speed show that by increasing subpixel value by 1 halves the speed of tile generation. In future this should be mitigated by allowing Maperitive to render tiles using multiple processors.

You should also be aware that if you intend to use subpixel accuracy for exporting large bitmaps, Maperitive has to actually allocate a much bigger bitmap in the process of rendering. So for example if you want to create a 4000x4000 bitmap using subpixel=3, Maperitive will want to allocate a 12000x12000 bitmap in the process and will probably fail due to limitations of GDI+ bitmap size. So there is no free lunch (at least until I figure a way around this problem ;) ).

One final note: interactive map does not use subpixel accuracy since this would make the map rendering pretty slow. In future versions Maperitive will provide some kind of “map quality” / “level of detail” setting, so you’ll be able to control this.

Enjoy!

October 19, 2011
Maperitive: 3D Export

The latest Maperitive beta (download it from here) now contains a new command called export-3d, which generates a 3D mesh using the digital elevation model and places the map texture on top of it. The 3D model is exported into a COLLADA format, which can be imported into various 3D programs (Google SketchUp is the one I mostly used, it’s free).

Quick How-To

The quickest/easiest way to generate a 3D export is to move the map to the area you’re interested in and simply select the Tools | Export To 3D menu command. Maperitive will then generate files in the output/Maperitive3D directory of your Maperitive installation. If you do not load your own OSM vector layer, Maperitive will use OSM tiles, the same ones used to show tne OSM web map.

NOTE: be careful to keep the map area fairly small, otherwise you’ll end up with a 3D model that you won’t be able to import into other software, especially if you don’t have a top-of-the-line computer at your disposal.

Importing Into SketchUp

After opening SketchUp, choose **File | Import…” menu command. NOTE: Before browsing for the file, click on the Options… button and make sure Validate COLLADA file is turned off:

Validation should be disabled because it makes importing unbearably slow, especially for larger models. After you’ve done this, browse to your generated Maperitive3D.dae file and open it.

Depending on the size of your model, you might have to wait for some time for the importing to finish. Sometimes I even have to resort to killing the SketchUp process and regenerating a simpler model.

Configuring SketchUp

After the model has been successfully imported, you may want to tweak a few settings in SketchUp to make the rendering look better:

  • View | Edge Style | Edge - uncheck this so the edges of surfaces are not shown.
  • View | Face Style - choose Shaded With Textures to get the best effect.
  • View | Shadows - check this to turn on the sun shadows.

Tweaking The 3D Model

export-3d command provides additional parameters we can tweak. Type in help-command export-3d into the command prompt and you’ll get the list of those parameters:

COMMAND NAME: export-3d 
DESCRIPTION: generates a 3D map from the current map view and saves it to the disk 
PARAMETERS: 
  output-dir=<the directory where output files will be saved> (text, optional)
  mesh-points=<the maximum number of points the terrain TIM mesh should have> (integer, optional)
  tin-error=<the maximum allowed elevation difference (in meters) when simplifying the terrain TIN mesh (default is 1 meter)> (real number, optional)
  width=<bitmap width> (value, optional)
  height=<bitmap height> (value, optional)
  map-scale=<map scale to use when exporting> (value, optional)
  scale=<graphics scale to use when exporting> (value, optional)
  dpi=<DPI to use when exporting> (value, optional)
  zoom=<zoom level to use when exporting> (value, optional)

Better Bitmap Texture

By setting various bitmap parameters you can increase the resolution of the bitmap and/or the zoom level of the underlying OSM bitmap.

TIN Tweaks

To increase performance, Maperitive uses Garland-Heckbert’s TIN simplification algorithm to simplify the terrain triangulated irregular network (TIN). There are two command parameters that affect the simplification process:

  • tin-error: this is the maximum error (tolerance) allowed between the actual DEM elevation and the generated model, in meters. The default value is 1 meter and if your model becomes too big to handle, I suggest increasing the tolerance value.

  • mesh-points: this is the maximum number of points (vertices) the TIN should have. The simplification algorithm starts from a very simple model (just two triangles) and incrementally adds new points to it. Upon reaching the maximum number of points, the algorithm stops (regardless of the tin-error setting). This is a safeguard against the model going wild with too many points. So I suggest experimenting with those two values to get something workable for your case.

Setting The Map Area More Precisely

Instead of relying on the map window to act as your area of interest, you can specify printing bounds (right click on the map) and move them to an exact position of your choice.

Final Notes

This 3D export function is by no means of the same quality as some other OSM 3D projects - you don’t get any 3D objects apart from the terrain model, so don’t expect to see any 3D buildings, trees etc. It is, however, a very simple tool to use (I hope) and it produces an output in a fairly open standard (COLLADA) which can then be tweaked with other software.

The next logical step would be to include the things like roads and buildings as actual 3D objects, but I will leave that for the future since my task list already very full with other features.

Please send me feedback if you find this feature useful (or indeed if you find it crappy). Since all this is beta, expect to find bugs. Also, if you’re more of an expert in 3D field than me, a question for you: can you recommend any (preferably free) tool for raytracing which can consume COLLADA files generated by Maperitive?

September 21, 2011
Maperitive Beta Update

DOWNLOAD LINK: http://maperitive.net/beta/Maperitive-1.1.2001.zip

I’ve just released an update of the Maperitive beta (it’s the same download link and build number).

This update has a few nasty bugs fixed and a couple of new features.

Label Collision Detection

Maperitive now detects if two or more labels overlap. In case of overlaps the label with lower priority is removed. Priority is determined by the order of the features and rules in the rules file - rules near the beginning of the file have a higher priority than the ones near the end.

A sample rendering of UK cities and towns (the first image is from the old Maperitive and the second was generated using the latest beta):

This is a very simple system and it covers only horizontal labels (so street names can still overlap). A better system will be implemented in the future.

TileJSON

generate-tiles command now generates an accompanying TileJSON file. TileJSON is an invention of MapBox developers and it is used to hold some basic information about the generated tiles, like:

  • map name, description and attribution,
  • minimum and maximum zoom,
  • map boundaries.

The benefit of this file is that certain JavaScript mapping libraries (like Wax) can read it and automatically configure themselves based on its data. Compare that to the last step in my web map tutorial where you needed to do it manually.

Here’s a sample TileJSON file generated by Maperitive:

// Generated by Maperitive v1.1.2001
// For more information about TileJSON format, visit https://github.com/mapbox/tilejson#readme
// TODO: Update the 'tiles' to reflect your actual path on the Web server
// TODO: Update the default map location (longitude, latitude, zoom)
{
    "tilejson":"1.0.0", 
    "name":"Maperitive Web Map", 
    "description":"Maperitive Web Map", 
    "attribution":"Map data © OpenStreetMap (and) contributors, CC-BY-SA", 
    "tiles":
    [
            "tiles/{z}/{x}/{y}.png"
    ], 
    "minzoom":9, 
    "maxzoom":13, 
    "bounds":
    [
        -1.2254669867114432, 
        51.041883339771708, 
        1.5044914337393456, 
        52.076449581817052
    ], 
    "center":
    [
        0.13951222351395121, 
        51.55916646079438, 
        9
    ]
}

Note the “TODO”s: make sure you have the proper values before uploading the file to your web server.

UPDATE: there was a bug in the generated TileJSON files, “tiles” is actually an array (thanks to @kkaefer for pointing this out). I’ve updated the beta release.

September 18, 2011
New Maperitive Beta Release

DOWNLOAD LINK: http://maperitive.net/beta/Maperitive-1.1.2001.zip

A new release of Maperitive (branded as build 2001) is finally here - albeit in beta form. I wanted to release the new stuff I was working on since May, but I didn’t want to wait for everything to be totally finished. But let’s start with some…

Notes about this release you should be aware of

NOTE 1: This beta release will not appear as an update when running the “standard” Maperitive release. It will also not be possible to later auto-update it with a new release when it arrives. I’m working on a revamped auto-updating system and the old updating mechanism has been turned off in beta (that’s why it’s beta). So you will have to download the beta manually, unzip it somewhere, and run Maperitive.exe (on Windows) or Maperitive.sh (on Linux/Mac). I do not recommend overwriting the previous installation, so keep that as your backup.

NOTE 2: there have been some changes in certain Maperitive script commands, so you may need to update your scripts. The changes are mostly in how the bounds are specified when exporting bitmaps or SVGs. More on that later.

NOTE 3: there wasn’t any major bug fixing done for this release. You can see the list of open bugs (it’s not the full list, some old bugs are reported in other places - I will migrate/fix those soon).

NOTE 4: the new GUI features like map elements selection and editing may be a little bit buggy. A lot of time has been invested in making them work as there were some fundamental problems that needed to be solved. Users running Maperitive on Linux/Mac may especially notice certain problems, due to the fact that Maperitive is running through Mono. In any case, please report any problems if you see them and I will do my best to fix them.

New Features

First let me say there aren’t any revolutionary new features in this beta. Most of the work I did was done on the infrastructure code, which will help me introduce cool new things in next releases.

What is new is the way how bounds are specified (bounds specify the geographical extents of Maperitive commands). Up until now, there was only one bounds parameter, but from now on you have geometry bounds and printing bounds.

Geometry Bounds

These are more or less the “old” bounds - you use them to specify the map area to download OSM data for (as an example). Geometry bounds are defined in terms of “min longitude, min latitude, max longitude, max latitude” coordinates. They are shown as a red rectangle with diagonal hatching (see the screenshot above).

Maperitive commands that act on geometry bounds have been renamed to dump-geo-bounds, geo-bounds-use-source, reset-geo-bounds, set-geo-bounds. I haven’t updated the Maperitive documentation for these yet, but you can still use help-command to get the list of supported arguments, like:

help-commands set-geo-bounds

Printing Bounds

Printing bounds are used by export-bitmap and export-svg commands to control the exported map area. What is cool about the printing bounds is that you can specify them in terms of paper size, paper orientation, paper margins, map scale and DPI resolution. This was one of the most requested features - to be able to export a map in terms of physical paper dimensions.

Printing bounds work in two modes: fixed paper mode and free-size mode. In free-size mode you are not bound to a particular paper size, so you can define the bounds in the old way (just like geometry bounds).

Printing bounds are shown as blue dashed rectangle:

New printing bounds commands are set-print-bounds-geo, set-print-bounds-paper and set-print-bounds-view. There is also a new command for setting the paper properties: set-paper.

Why Two Boundary Types?

It may seem a bit complicated two introduce two types of boundaries, but it is necessary precondition for me to be able to introduce map rotation in Maperitive (and support for different map projections). Why? Because once you rotate the map, the geometry bounds rotate, too, so they are useless for any kind of printing boundaries (which need to be rectangles parallel with the screen).

Editing Bounds Visually

There is no need to specify bounds using the command line interface, because there are a couple of new GUI features (which gave me the greatest headache). More on that follows.

Map Context Menu

Yes, the map now has a context menu (finally). So if you want to specify printing bounds, simply right-click on the map and choose Place Printing Bounds Here. Now you have printing bounds placed on the map and selected

Selecting And Manipulating Map Elements

If you click on the geometry or printing bounds, you can select them - small yellow selection handles appear. You can drag the handles to resize the bounds. If you hold the Shift key, the resizing will maintain the aspect ratio. Hold the Control key and you will be able to resize while maintaining the center point.

Move the mouse a little bit more inside the bounds box and you will be able to move the whole bounds across the map.

Properties Window

The last major new GUI “thingy” is the Properties window. If you right-click on the printing bounds and choose Properties, a tool window will appear that lets you edit the properties. This means you don’t need to mess with command line to specify the paper size, for example.

What Comes Next

As I’ve already mentioned, Maperitive is getting a new updating system. The next “official” release will start using semantic versioning, like 2.4.2 and the old build numbering will be consigned to history. This will enable a more transparent updating system - users will be able to choose whether they want to install unstable releases or wait for the next stable/tested one.

Of course, I plan to fix some bugs too (including the ones that I’m sure you’ll report for this beta release).

Next major features: a better labeling mechanism (collision and duplicates detection, abbreviations…) and maperipy, the Python API and integrated Python scripting.

That’s really. I hope you’ll try the new beta and enjoy it. And don’t hesitate to send me your feedback (positive and/or negative)!

Liked posts on Tumblr: More liked posts »