OpenStreetMap

GSoC 2019 - Font rendering for traffic sings with custom text - OSM2World

Posted by JasonManoloudis on 11 June 2019 in English (English)

Introduction

This is the very first entry regarding the official work on this year’s Google Summer of Code! As seen in the subject line, the first task was about implementing the ability to render traffic signs that “require” custom text in their definition upon mapping them. This is preferred compared to the alternative of having a different texture stored in the textures folder for every traffic signs available, for obvious reasons (e.g. huge number of textures) as well as for scalability purposes. As the available time for each task is limited and a number of existing traffic signs are rarely mapped (tested with overpass), this first implementation showcases 2 widely used sign types, those of DE:274 (speed limit) and DE:1001-31 . So, let’s take a look on the changes of the past 2 weeks:

Restructuring

Material objects use a list of TextureData objects to define the data necessary in case a texture was going to be applied to a material. Each TextureData entry in this list represents a texture layer to be applied. Up until now, these layers always referred to an already stored image. So if we were going to implement the ability to render an image with text “on the go”, this had to be changed. Therefore the first step was to introduce a TextTextureData class and define the following hierarchy:

Abstract class First implementation Second implementation
TextureData TextTextureData ImageTextureData

A getFile() method was added to each of these classes with the purpose of

  • Generating and saving an appropriate temporary image with text rendered, when it comes to TextTextureData
  • Returning this.file when it comes to ImageTextureData

With that, the lists that previously accepted the “default” ImageTextureData are now able to accept layers of TextTextureData type as well.
That pretty much sums up the restructuring part so let’s move on to additions/changes on existing parts of the codebase.

Other additions/changes

Materials.java

As a next step, it was deemed essential that the TextTextureData layers could be configured via a .properties file, just like the Image ones already do. That required

  1. To decide the format of the new .properties entries
  2. To refactor the ConfigureMaterials(Config) method, defined in Materials.java that handles exactly that part

The attribute that would declare the beginning of TextTextureData fields definitions was decided to be that of type = text . With that said, here is an example of a definition of some of the TextTextureData fields, for the SIGN_DE_1001_31 material:

material_SIGN_DE_1001_31_texture1_type = text
material_SIGN_DE_1001_31_texture1_font = Interstate,20
material_SIGN_DE_1001_31_texture1_topOffset = 60

TrafficSignModule.java

That was arguably the class with the most changes necessary.
First of all, the TrafficSignType enumeration was replaced with a TrafficSignType.java class, containing exact same fields and constructor. This might seem a rather small change but it opened the way for 2 major changes to take place:

  1. A different material can be now used to define each TrafficSignType instance. Prior to that, each enumeration constant had its material already defined (e.g. the first argument in DE_101(SIGN_DE_101, 1, 2)) meaning that, if a change to a TextureData layer had to be made for only 1 sign of DE_101 type, all other DE_101 type signs present in the .osm input file, would also be affected by that change.
  2. The concept of “non-supported” traffic sign has now a different meaning. With a few additional lines of code, a “non-supported” sign is now a sign with no texture layers defined for it. In such a case, a default white traffic sign will be rendered. Prior to that, a “non-supported” sign would be one that was not included in the enumeration constants and in that case, no sign would have been rendered at all.

To make use of the first newly available potential, the configureMaterial(ConfMaterial originalMaterial, String value) method was introduced. The originalMaterial parameter represents the already defined material for the appropriate sign. Ultimately, configureMaterial() generates and returns a new ConfMaterial object, identical to the originalMaterial one with the only difference found in the TextureDataList. A new list is used in the returned object that has the appropriate TextTextureData layer changed to one with the correct text value , taken from the .osm input file tag. That generated material is later used in the TrafficSignType definition.

Conclusion

There are of course more smaller changes in other parts of the codebase as well as a lot of bug resolving that were not listed here but the above should sum up all the major ones for this task. Changes can be found in this branch of my fork of OSM2World. It is likely that I continue to make small modifications on it in the following days, in order to reach a mergable state. Depending on their importance, I may include a brief of them in the next diary post.
Until then, thank you for following the updates! I look forward to posting the next one

Png output of current results

png output

Coming up: Human-readable traffic sign values

GSoC Application document: https://github.com/JayGhb/GSoC-2019-Application

Login to leave a comment