Running an Openstreetmap-Tileserver with “readable” names

Standard tile layer rendered with Latin localization.

For most westerners the standard tile layer is basically unreadable in regions of the world where Latin script is not the norm. For this reason German style has been using localization for years.

Unfortunately for some people this has been implemented in a somewhat incompatible way regarding standard tile layer which would require changes to the style itself to get localized names.

Fortunately I changed this now and this has hopefully simplified a lot for people using standard tile layer or German style.

Now, if all you want to have is standard tile layer with localized names what you have to do is using openstreetmap-carto-flex-l10n.lua from German style for database import instead of the one from standard tile layer. This will still require the installation of osml10n but once you have done this it is possible to localize names during database import (or update) easily.

Likely this comes especially handy if your target language ist not German but something like English, French oder Spanish and thus just using our tile-servers providing German style is not an option.

If you also want German road colors in addition to localized names, then just go for German style as before which now also uses the upstream database layout. It is now even possible to render German style without localized names easily, but I doubt that this is something anybody will want to do.

Technically all of this localization stuff works by modifying the name tag of OpenStreetMap objects to the names we want to see in the map during database imports. Probably I should add an option to keep an unmodified version of the name in the hstore columns of the database.

Tags:

A simple way to localize (latinize) an Openstreetmap style

Based on a request on the german mailinglist back in july, I thought about how the perfect localization of the german mapnik style would look like and finaly implemented something which comes close. Unfortunately up till now I did not document it.

However Reading about a map in manx today, I came to the conclusion, that I really need to do this.

First of all I came up with the following assumptions (valid for all languages using latin script IMO):

  • always prefer mapped names over automated transliteration
  • prefer name:<yourlang> over any other name tags (name:de in my case)
  • prefer int_name over non-latin script
  • prefer name:en over non-latin script if int_name has not been specified
  • transliterate non-latin script as a last resort

So how has this been implemented?

I decided to do it inside the SQL-query. This way it is independent of the rendering Software. It will certainly work at least with mapnik, mapserver and geoserver. Even the proprietary ESRI rendering stuff should actually work 🙂

Basically any rendering system using a PostgreSQL backend can be easily adapted. Of course your database must provide all the required name columns.

So how would one enable rendering a latin name insead of just the generic name tag?

Assume your style uses something like this for rendering a street-name:

SELECT name
FROM planet_osm_line;

Now just replace this by the following:

SELECT get_localized_name(name,"name:de",int_name,"name:en") as name
FROM planet_osm_line;

Quite easy isn’t it?

Well, here comes the (slightly) more complicated stuff…

Of course PostgreSQL does not provide a get_localized_name function out of the box, we have to install it first. So here is how to do this in two steps:

The get_localized_name function has been implemented in PL/pgSQL and is available at http://svn.openstreetmap.org/applications/rendering/mapnik-german/views/get_localized_name.sql.

So first add this function to your database using the following command:
psql -f get_localized_name.sql <your_database>

Second add the transliterate function available at http://svn.openstreetmap.org/applications/rendering/mapnik-german/utf8translit/.

To compile and install it on GNU/Linux (sorry, I don’t care about Windows) do the following:

  • svn co http://svn.openstreetmap.org/applications/rendering/mapnik-german/utf8translit
  • Install the Server dev package (On Debian/Ubuntu this would be called postgresql-server-dev-x.y, postgresql-server-dev-9.2 in my case)
  • Install the libicu-dev package
  • compile and install calling make; make install
  • On Debian/Ubuntu you would be better off using dpkg-buildpackage and install the resulting package instead of using the make install procedure.

Now enable the function from the shared object using the following SQL command (from a postgresql admin account):

CREATE FUNCTION transliterate(text)RETURNS text
AS '$libdir/utf8translit', 'transliterate' LANGUAGE C STRICT;


Here is how to check if this works:
mydb=> select transliterate('Москва́');
transliterate
---------------
Moskvá
(1 row)

Well that’s it, I hope that this will be useful for some people.

Unfortunately this stuff has currently (at least) two problems:

  • Transliteration of Thai Language uses ISO 11940 instead of the RTGS system
  • Transliteration of japanese Kanji characters end up with a chinese transliteration (e.g. dōng jīng instead of Tōkyō for 東京)

If anybody has some suggestions on how to solve these please post them here!

Tags: