Archive for the 'OpenStreetMap' Category

Published by breki on 18 Sep 2010

Maperitive Gets A New Home Page

I’ve finally taken some time to redesign Maperitive’s home page. Not a masterpiece, but I think it’s decent enough for a non-web designer like me. Just don’t ask how much time it took.

Maperitive gets a new home page

Now I’m off to fix some bugs.

Published by breki on 12 Sep 2010

Maperitive: Update Bug

I’m in the middle of releasing a new version of Maperitive, but I have to warn all users that if you are currently using the latest build (982), automatic update will fail. This is due to an undetected bug in 982 which prevents exiting the application normally.

Manual update is pretty simple: download the new ZIP file (when it arrives) and simply overwrite old Maperitive files with the ones from the ZIP file. I’m sorry about this, but it happens sometimes.

Published by breki on 06 Sep 2010

Random Thoughts

I feel I’ve been neglecting my blog lately and it’s a shame. It is not that I don’t have stuff to write, it’s just that I’m so immersed into developing various projects (mostly Maperitive) that I don’t seem to find the time and energy to take some time to write something interesting.

Yes, I know one of the first rules in writing blogs is not to apologize for not writing. But anyway, I’ve decided I should write something more regularly but deliver it in smaller packages. This way writing shouldn’t look so intimidating and it should make it easier for me to write.

How’s Maperitive

There has been a lot going on behind the scenes in Maperitive. I’ve been opening many different fronts, but I’ve mostly worked on improving the GUI. Maperitive started out as a (more or less) command line application and now I’m slowly trying to improve its usability. Right now the GUI is still too intimidating for a non-technical user and a lot of work is still needed to improve this.

Like the most of other code in Maperitive, the GUI framework has been written mostly from scratch, with some reusing of the existing code of Kosmos. I had to reinvent the wheel on each step, since there aren’t many good WinForms GUI frameworks out there (in fact I only know of one which is a beast and I didn’t feel the urge to invest a huge amount of time to try to learn it). The advantage of this is that it forced me to get to know the problems I’m trying to solve and not just sweep them under the rug using some 3rd party library.

All in all I’m quite satisfied with the new architecture. One of the main reasons I decided to pull the plug on Kosmos and start with clean code was to ensure the new architecture allows me to add new features more easily and to make the whole code base more manageable. I think I’ve achieved this, mostly by sticking to dependency injection and using Windsor Castle, an inversion of control container.

The application framework being built for Maperitive is generic enough to be reusable for other desktop applications, which could come in handy if I find the time to work on anything else. But right now I have so many ideas for new features in Maperitive that I doubt I’ll run out of work in the next year (or more).

Published by breki on 06 Aug 2010

Maperitive: Enhanced Usability & Scripting Support

Maperitive running scripts

For the last week or so I’ve been busting my fingers with one of the harder things to implement in a desktop GUI: application responsiveness when executing longer-running tasks. By longer-running I mean something that takes more than a couple of seconds.

Simple desktop applications tend to run everything synchronously: when the user presses a button, the action gets run. After the action finishes, the control is given back to the user. Simple, but totally crappy. The problem is that the action gets run on the same thread that services the GUI, so until the action finishes, the application will not be able even to refresh itself or respond in any meaningful way to user clicks or key presses. And since there is no refresh, you cannot show any progress indicators to the user. I know I wouldn’t want to wait half an hour for something to finish without some reassurance that the application is still alive and not waiting for the electricity to run out.

Maperitive already had a lot of responsiveness code implemented, but it was still an “under the construction” design. The additional complication was the fact I want Maperitive to have a good script runner and scripts can take a very long time (downloading OSM data, generating tiles etc.). After a lot of trials and errors I finally managed to implement the whole thing in a consistent package. And believe me when I say it was not easy.

So what is new:

  • When running scripts (or longer tasks), Maperitive draws an indicator on the map (see the screenshot above) and launches a “sort of modal” mode – most of GUI controls are disabled so the script doesn’t get confused by some inadvertent user action. However, the application is still responsive: you can view the progress of the script in the command log.
  • Aborting scripts: as the indicator says, you can press the escape key to abort the script. If you prefer torturing your mouse instead of your keyboard, there’s an “Abort task” button in the bottom right corner which does the same thing.

Not all of running tasks have been switched to the new system. Loading OSM files is one example of a task that will still block the GUI, but I will gradually improve these things.

You can download the latest release at http://maperitive.net/download/

Enjoy!

Published by breki on 25 Jul 2010

Maperitive: Tile Generator

Maperitive Tile Generator

I’ve just released Maperitive build 924 which has two new commands:

Eastern Alps

Published by breki on 13 Jul 2010

Maperitive Has Menus!

Maperitive Got Its First Menus

DOWNLOAD LINK: http://maperitive.net/download/Maperitive-907.zip

Four months after the first public release, Maperitive has finally received some improvements to the GUI: menus. Right now menus cover only non-interactive commands, but in near future I will add dialogs which I guess will make all command line haters very happy.

All the functionality will still be available through the command line. Menus will cover only the most commonly used functions and settings.

Published by breki on 20 Jun 2010

Rewriting Code

I’m working on some new Maperitive commands and they require a bit of an extension of the command-line interface. I’ve tried to extend the existing command-line parser code, but it feels like tearing off fingernails. The funny thing is that I’ve rewritten this part of the code a couple of months ago, but it still smells. It’s a typical case of having to extend some functionality slowly bit by bit and not doing it properly, and the crappy code piles up.

So after considering all the options, I’ve decided to do a new rewrite of this code. It’s going to take some time, but it will make me feel better – and that’s the most important thing.

Luckily I have a dozen of existing unit tests which will be very helpful in making the new code run correctly. This is one of the best reasons to write unit tests, people!

Published by breki on 22 May 2010

Maperitive’s New Text Formatting Features

Maperitive Text Formatting

I’m in the middle of implementing new features for formatting text in Maperitive. The above map shows just some of them:

  • Word wrapping: a new text-max-width property specifies the maximum width of the text. Everything else will be moved to a new line.
  • Alignment: text-align-horizontal and text-align-vertical are the new properties for this.
  • Offsetting: you will be able to move the text horizontally (text-offset-horizontal) or vertically (text-offset-vertical) from the original point. This enables showing icons for peaks and their names pushed below to prevent overlapping.
  • Some other text-related stuff I haven’t yet implemented, but let’s leave this as a surprise.

The new version will probably be released sooner than planned because I decided to leave the SVG exporting work for another release.

Published by breki on 22 Apr 2010

Kerning Or How To Outfox GDI+

500px-Metal_type_kerning.svg[1] (image taken from Wikipedia)

I’m working on a text-on-path algorithm for Maperitive to be able to render things like street names. GDI+ does not have a built-in function for drawing texts on a path, so I’m stuck with writing my own.

Although there are a lot of implementations of such an algorithm out there, they all miss one important thing: kerning. Kerning is basically telling a character to move a bit closer to its neighbor if there is enough space for them to huddle together:

Kerning[1] (image taken from Wikipedia)

Since the path can consist of several line segments (and even curves), you need to render each character (glyph to be more precise) separately to be able to rotate it using the angle of the line segment it will be drawn on. The problem is determining how far from the previous character to place the next character. GDI+ offers a method called MeasureString, but calling it on a single isolated character returns a character width value without any kerning taken into account, so characters like V and A can appear too spread apart. There is another method, MeasureCharacterRanges, which can measure each individual character width for a given text, but it has a practical limit of 32 characters and is pretty processor- and resource-intensive. I’ve used it for the text-on-path algorithm for Kosmos but the results weren’t very satisfactory.

From my (basic) understanding of how kerning usually works on computer typography, a font which has kerning information stores kerning offsets for character pairs. So, for example, V and A will have a different (usually stronger) kerning than say, character pair V and T. The problem with GDI+ is that you don’t really have access to this information.

One option would be to use old GDI’s font and text functions to fetch the information about the kerning pairs, but these need to be P/invoked and thus will probably not work on Mono, which makes them unusable for Maperitive – I’m really trying to make Maperitive run on multiple platforms.

So after spending a day in brainstorming, I got an idea on how to handle kerning myself. It’s really simple: I will calculate the kerning myself (using the mentioned MeasureString method). The formula is simple:

<character kerned width> = <character non-kerned width> – (<character pair non-kerned width> – <character pair kerned width>)

I can get all of the three values on the right of the equation using the MeasureString: first I’ll measure each character’s individual (non-kerned) width and then I’ll measure the width when they are drawn together. The difference between these is the actual kerning, which is then used to calculate the kerned width of the first character.

The added twist to this tale is that I’ll keep this information in a cache, to keep the expensive calls to the MeasureString method to the minimum. This cache could even be persisted to the disk. Of course, each font family and font style dictates its own kerning, so the cache needs to be extended with this information.

One potential problem is how to handle kerning information for different font heights. Since Maperitive supports continuous zooming levels, the number of different font heights used is (almost) limitless. I’ve decided to cut some corners here: the kerning will be calculated (and stored) for some nominal font height (say 100 em) and then interpolated for any needed height. We’ll see how that goes… next time.

Published by breki on 17 Apr 2010

Maperitive Hillshading

Just a quick post about the latest Maperitive release: it can now do hillshading. I’ve improved the hillshading algorithm previously used in Kosmos so it now better handles missing SRTM elevations (no more “hellholes’”). I’ve also added a few additional parameters to the hillshading command.

Here’s a sample hillshading of Swiss Alps around Engandin:

Engandin

I’ve selected this area (and the blue tint shade) because I wanted to make a small tribute to Eduard Imhof’s Relief of Switzerland:

o13[1] 

It doesn’t come close to his beautiful work, but I guess that’s the way it should be.

« Prev - Next »