OpenStreetMap

JasonManoloudis's Diary

Recent diary entries

Wrapping up GSoC 2019 - The current state of OSM2World

Posted by JasonManoloudis on 26 August 2019 in English (English). Last updated on 13 November 2019.

Introduction

So, this is the final entry of a what has come to be a 6 entries series, regarding this year’s Google Summer of Code project and the work that has been done on the 3D Renderer OSM2World. This post will summarize the last 2 tasks that did not get their own separate entries as well as give an overview of the whole summer work, starting from the latest. The two tasks in question are those of Rendering Destination Signs and Guessing the positions of non-explicitly defined signs, as stated in the application document, which have proved to be particularly challenging to say the least; we will go through them later on this post.
So without further ado, let’s present what has been done so far in this Summer of Code, in a chronological order:

  1. Font rendering for signs with custom text: https://github.com/tordanik/OSM2World/pull/147
  2. Human readable traffic sign values: This particular task does not have a pull request of its own as its TODOs, mentioned in the application document, where gradually being implemented as parts of the other tasks (a good example of this can be found in this entry)
  3. SVG texture support: https://github.com/tordanik/OSM2World/pull/151
  4. Traffic sign catalogues: https://github.com/tordanik/OSM2World/pull/153
  5. Destination signs: https://github.com/tordanik/OSM2World/pull/154
  6. Guessing the positions of non-explicitly defined signs: https://github.com/tordanik/OSM2World/pull/155 (may be changed)

A summary is available for each of the first 4 tasks, in their corresponding diary entries, listed below in the same order:

  1. Font rendering for signs with custom text
  2. Human Readable traffic sign values
  3. SVG texture support
  4. Traffic sign catalogues

Let’s now see what the remaining 2 tasks are all about!

Rendering of Destination signs

Destination signs was the first time it was required to take into account something other than explicitly defined nodes for rendering traffic signs, as the information about them is found in “type” = “destination_sign” relations. Destination sign relations include ways & nodes around junctions, as this also tends to be the places you find such signs in real life.
It would be useful to break down the important (to this project) members of such relations, at this point, before moving forward:

  • From: The (usually) way before coming to the junction
  • To: The (usually) way after the junction
  • Intersection: The node of the junction
  • Sign: The point where the sign is

I would also like to make clear that by “destination signs” we refer to this type of signs: Destination sign 1 Destination sign 2

As one can tell, destination signs could not really “fit” into the existing mechanism for traffic sign rendering; they are a type on their own. That translates into a new private class, in TrafficSignModule

private final class DestinationSign extends NoOutlineNodeWorldObject
			implements RenderableToAllTargets

that of course has its own renderTo() method (although one can find similarities with TrafficSign’s renderTo()).
The concept for this task is as follows:
First of all, such sign’s textures consist of 2 texture layers, an image type background and a text type. The coloring of the signs makes use of the colorable mechanism, which essentially “paints” the bottom texture layer with the material’s color. In our case, the material’s color is extracted from the colour:back tag of the relation (indicates the sign’s background color) and is set to the corresponding material using the newly introduced, for the needs of this task, method

        /**
	 * returns a material that is the same as this one,
	 * except with a different color
	 */
	public Material withColor(Color color)

in Material.java .
What differentiates the signs and allows the application to know which material to use every time is the color of the arrow around each sign, tagged with colour:arrow in the relation. So a relation with

“colour:back” = “white”
“colour:arrow” = “black”

would result in the first of the 2 signs pictured above while

“colour:back” = “yellow”
“colour:arrow” = “black”

would result in the second one.
The text depicted on the signs is extracted from the “destination =’’ and *“distance =” tags of the relation, using the renewed

private static Material configureMaterial(ConfMaterial originalMaterial, Map<String, String> map, MapElement element)

method of TrafficSignModule, as updated to cover the needs of the previous, Traffic sign catalogues, task while the text color is extracted from the “colour:text” = relation tag and is set in the appropriate text texture layer using the also newly introduced

/**
 * returns a copy of {@code material} with its {@link TextTextureData} layer
 * No. {@code numberOfTextLayer} changed with a replica with textColor={@code color}
 */
public Material withTextColor(Color color, int numberOfTextLayer)

method, of Material.java .
The result of the above, for 4 “type” = “destination_sign” relations around the same intersection & sign nodes (and dummy text for demonstration purposes) is this:

Destination signs sample

The facing side of each sign on the pole is calculated using the direction angle of the relation’s from member while the pointing sides take the into account the position of the relation’s to member, checking whether is it to the right or left of from .
Material variants for left & right pointing sides are now available in Germany’s traffic sign catalogue configuration file and the materials are being defined and parsed in a Traffic sign catalogues task way!

Guessing the positions of non-explicitly defined signs

That brings us to the last, and arguably GSoC’s hardest, task of this summer.
The context of this task is as follows:
Traffic signs can be mapped on openstreetmap in 3 different ways + one special case:

  • Mapped on explicitly defined nodes usually next to ways, where the node’s positions indicate the actual positions of the signs
  • Mapped as tags on ways in a manner of maxspeed=50 or traffic_sign=De;101-11 which indicates that the sign’s rules apply to the whole extend of this way
  • Mapped on nodes that are part of ways where the actual position of the sign is to the right/left of this node
  • Special cases highway=give_way & highway=stop where a number of specific rules apply to them

Up until now only the 1st of those cases was supported in OSM2World and it was the goal of this task to support the remaining 3.
What justifies this task as GSoC’s hardest is the large number of rules that has to be followed for the positions and facing directions of the signs, as many cases equals many lines of code, making it quite hard to keep everything in mind while avoiding code duplication. Those rules are:

  • For signs mapped as tags on a way:

    1. If the sign is tagged as “traffic_sign:forward = “ or “traffic_sign:backward = “ , only 1 sign is rendered, that faces the defined direction.
      If the sign is simply tagged as “traffic_sign” = , 2 signs are rendered, one at the beginning and one at the end of the way, which face opposite directions.
    2. If side=left/right is defined on the way, it indicates the side of the way the sign is placed on
    3. If the way is oneway, only one sign is required, at the beginning of the road.
    4. If a way that is an extension of the one we are working with, also contains the exact same traffic sign mapped on it, then the sign must not be rendered in between them.
  • For traffic signs mapped on a way node:

    1. side=left/right/both again applies. If side=both then 2 signs are rendered, on each side of the node
    2. traffic_sign:forward/backward also applies
  • For the special cases

    1. Their facing direction is extracted by finding the closest intersection to the node they are mapped on. To not confuse anyone any further, here is their wiki documentation

To make things easier, a TrafficSignModel class is introduced that represents a sign with all its traffic sign types on it (a pole can have more than one signs).
TrafficSignModule’s applyToNode() method was also restructured and now has the following shape:

@Override
protected void applyToNode(MapNode node) {

  /* if sign is a destination sign */

  isDestinationSign(node);

  /* if "traffic_sign = *" or any of the human-readable signs (maxspeed|overtaking|maxwidth|maxweight|maxheight) are mapped as a way tag */

		
  isTagOnWay(node, signsOnWaysState);
		

  /* hardcoded special cases highway=give_way & highway=stop */

  isSpecialCase(node);

  /* if sign is a simple traffic sign mapped on a node (not a destination sign or a human-readable value mapped on a way) */

  isMappedOnNode(node);

}

with method names that speak for themselves.
An example of maxspeed=30 sign extracted from way tags can be seen below, with it’s counterpart facing the opposite direction at the other end of the way visible at the distant end of the road

signs from way tags

What is left to be done

The links provided at the beginning of this entry will change in the following days as the last 2 tasks are changing towards their final form. That mostly means writing tests for some relatively complex methods created during GSoC and putting some final touches where this is required.
There are of course things that could be done under the scope of supporting traffic signs in OSM2World, like rendering of street name signs based on name=* tags and signs derived from routing-related tags like oneway and access but for now, this is as far as this Summer of Code project goes! It would be great though to continue being a contributor to OSM2World, now that I have an understanding of it up to a point, and maybe implement these tasks without being under the pressure of time and I am pretty sure many students would feel like now that their own GSoC projects are also coming to an end!

Conclusion

From my perspective, GSoC has definitely been a unique experience, different from what I’ve come across so far work-wise, thus the reason I craved to take part in it, and of course with its ups and downs, as pretty much everything has (?)
It may sound somewhat “childish” but one of the biggest satisfactions the Summer of Code has given me is actually being a contributor to a large scale project used by a lot of people, giving meaning, in a way, to my presence on GitHub as well as to code I’ve written! It is also a nice opportunity to get a taste of what working remotely might be like and get to know if that work/life style actually suits you.
To conclude and also give two well deserved shout-outs , I honestly was glad to be participating with OpenStreetMap in this initiative as well as with this specific project and mentor!

Application document

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

Introduction

The completion of the Traffic sign catalogues task brings a long-desirable feature in OSM2World: being able to define and configure materials solely through the configuration file, without the need for them to exist in Materials.java!
During this main feature’s implementation, the Human Readable Traffic sign Values task also came to a more complete state by adding lines of code related to it, while progressing, to cover needs that came up.
This entry will be split into 3 parts, separately covering Human Readable (H-R) values-related additions to avoid possible confusion. It is worth mentioning that there are of course more changes than the ones explained here but as changes are being constantly made it would be practically impossible to include every detail that has changed since the last diary entry. Plus, it would turn out to be boring for the readers.
That being said, sample sign images with the material definitions/configurations that create them included can be found by the end of this entry!
Let’s get started:

I will try to keep things short and briefly present only the most important points as this is not the main focus of this entry:

  • A clear distinction between H-R values and non H-R values is now taking place in TrafficSignModule.java. Its simple implementation may seem obvious at first but it had to be validated by looking through a lot of Overpass data with a query like

[out:csv(traffic_sign;false)];
nwr[“traffic_sign”][traffic_sign~”:”]({{bbox}});
out;

that looks for traffic sign values that include “ : “ in their name i.e. are country prefix - sign ID pairs like DE:267 . Using that, one can see that there were no cases where a sign contained both a country-prefixed value and a human-readable one together (e.g. v=’DE:254, maxheight’ ) so the code below was deemed to be the way to go:


if(tagValue.contains(":")) { //if country prefix is used
    String[] countryAndSigns = tagValue.split(":", 2);
    if(countryAndSigns.length !=2) return;
    country = countryAndSigns[0];
    signs = countryAndSigns[1].split("[;,]");

    } else { //human-readable value

   signs = tagValue.split("[;,]");
   }

  • The trafficSign_signName_material = * property is now supported The above property will map a H-R sign name to its corresponding material definition for the specified country. Properties like that will be loaded into a separate configuration file, unique for every traffic sign catalogue, which will be loaded together with the catalogue & the main configuration file. These 3 lines (in the main config file) are enough to produce this result for the catalogue of Germany:
locale = Germany

include = ${locale}TrafficSignCatalogue.properties
include = ${locale}HumanReadableSigns.properties

The same principle can be applied for any other catalogue. Following the same syntax, trafficSign_signName_numPosts = * and
trafficSign_signName_defaultHeight = *
are also supported to define the corresponding TrafficSignType values for a sign.

Traffic Sign catalogues

The first thing that had to be done was to make the application able to handle non-predefined materials parsed from a configuration file:

/* If material is not defined in Materials.java, create new material
and add it to externalMaterials map */

if (material == null) {
	material = new ConfMaterial(Interpolation.FLAT, Color.white);
	externalMaterials.put(materialName, material);
}

The externalMaterials Map that can be seen here stores exactly what its name implies. It is also used in getMaterial(String fieldName) in Materials.java for this method to be able to also return the external ones.

Next up is the addition of a core method in TrafficSignModule, mapSignAttributes . Remember the trafficSign_signName_ values mentioned above? This is the method to parse and return them, if they exist, as they are essential for the creation of the sign. As for now, this function returns a Map containing the results of the parsing plus a couple of necessary values more, as Strings; a situation that might be later improved by having the method return a TrafficSignType instance. As this function is relatively large to be included here, only its brief javadoc is presented below:

/**
 * Parses configuration files for the traffic sign-related keys
 * trafficSign_NAME_numPosts|defaultHeight|material
 * 
 * @param country The sign country prefix, if it exists; empty string otherwise
 * @param sign The sign name (without country prefix and subtype/brackettext value)
 * @return A HashMap containing the above values if found | Empty map in case of "fatal" error
 */
private Map<String, String> mapSignAttributes(String country, String sign)


Wrapping this section up, are some final noteworthy points:

  • In both the material definitions (when it comes to traffic signs) and the trafficSign_signName_ keys it was deemed necessary to follow a single convention for the signName representation. That convention is the already used “ SIGN_countryPrefix_ID “ . So, to configure some attributes for the German sign 625-11 one could use:
material_SIGN_DE_625_11_transparency = BINARY
trafficSign_SIGN_DE_625_11_numPosts = 2
  • Global values for traffic sign height and a sign’s pole radius can be defined (preferably) at the beginning of each catalogue like this:
# Global values
defaultTrafficSignHeight = 2.6
standardPoleRadius = 0.038

However the presence of the trafficSign_signName_defaultHeight = * key for a specific sign will of course overwrite the global value for this sign only.

  • 2 more necessary configurable fields are added in TextTextureData. Those are textColor and relativeFontSize .
    textColor defines the text’s color, as its name implies, by parsing hexademical values from the configuration file. Its value defaults to #000000 (black).
    relativeFontSize is a way of configuring the text’s size in relation to the overall size of the image. The smaller the value the smaller the text size. Its use is showcased in the outputs below.

PNG outputs of signs defined solely in the German traffic sign catalogue configuration file

The depicted signs are generated using the following material definitions respectively:

material_SIGN_DE_266_transparency = BINARY
material_SIGN_DE_266_texture0_file = ./textures/signs-DE/regulation_signs/266.svg
material_SIGN_DE_266_texture0_width = 0.84
material_SIGN_DE_266_texture0_height = 0.84
material_SIGN_DE_266_texture1_type = text
material_SIGN_DE_266_texture1_text = %{traffic_sign.subtype}m
material_SIGN_DE_266_texture1_font = DIN 1451 Mittelschrift,PLAIN
material_SIGN_DE_266_texture1_topOffset = 65
material_SIGN_DE_266_texture1_leftOffset = 52
material_SIGN_DE_266_texture1_relative_font_size = 20

and the .osm file entry:

<tag k='traffic_sign' v='DE:266-5' />

DE:266

material_SIGN_DE_279_transparency = BINARY
material_SIGN_DE_279_texture0_file = ./textures/signs-DE/templates/275.png
material_SIGN_DE_279_texture0_width = 0.84
material_SIGN_DE_279_texture0_height = 0.84
material_SIGN_DE_279_texture1_type = text
material_SIGN_DE_279_texture1_text = %{traffic_sign.subtype}
material_SIGN_DE_279_texture1_textColor = #FFFFFF
material_SIGN_DE_279_texture2_file = ./textures/signs-DE/templates/279_stripe.png
material_SIGN_DE_279_texture1_font = DIN 1451 Mittelschrift,PLAIN

and the .osm file entry:

<tag k='traffic_sign' v='DE:279-50' />

DE:279

Application document:

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

Coming up: Rendering destination signs

Intoduction

SVG texture support was an important part of for this Google Summer of Code project. Apart from the reasons mentioned in the application document, on why adding Scalable Vector Graphics support would be benefitial, its true importance lays on this fact: Most Wikimedia CC0 available images are SVG files. That would also be the reason that led in “swapping” priorities between the 3d and 4th task listed in the application; SVGs had to be supported if users were to make use of textures provided in traffic sign catalogues like this one.
By the end of it, this task ended up leaving some extra time in our hands, presenting a good opportunity to implement another useful functionality: Make external fonts configurable and able to be registered in the application. (Note: “external” refers to fonts not supported by default in the user’s OS). The need for a functionality like this (mostly) derived from the fact that texts on traffic signs use fonts not so widespread (e.g. Interstate) but it can also come in handy in many other cases as well.
The changes described bellow can be found under the July 12 2019 commits of this feature’s branch.
So, with that out of the way, let’s see how everything got blended into the project:

SVG textures support

The concept of implementing svg textures support was pretty straightforward: a really good support for png images already exists, that of course works with all target outputs of OSM2World; so converting svgs to pngs to make further use it would be the best course of action. As of the latest updates described in a previous diary entry, image layers in a texture are now of the ImageTextureData type. That of course makes ImageTextureData.java the appropriate class to implement such a mechanism.
A couple of changes took place in that class:

  1. A new private field private File convertedToPng was introduced to hold the file created after the conversion
  2. The private method private File SVG2PNG(File svg) was created to implement the actual conversion

The usual way of converting files from one type to another is through “Transcoding” methods; their name speaks for itself. For svgs such methods (and classes) come with svg libraries, like the one used in this case, Apache Batik. The Batik transcoders need a new File object to write the png to and those new files were deemed to also be temporary ones i.e. be deleted once the application terminates.
Apart from that, the getFile() method in ImageTextureData was extended to the state presented below and with that, pretty much everything worthy to be covered on svg to png conversion is included! Png exports with textures where svg images are being used can be found at the end of this entry.

public File getFile() {
	
	if(this.file.getName().endsWith(".svg") && this.convertedToPng == null) {
		convertedToPng = SVG2PNG(this.file);
	}
	
	if(this.file.getName().endsWith(".svg") && this.convertedToPng != null) {
		return convertedToPng;
	}
	
	return this.file;
	
}

Making external fonts configurable

Let me clear out what “configurable” stands for in this case: the user is now able to include in his configuration file a path to a folder containing font files, under the fontDirectory key. These fonts are then parsed and registered into the application, allowing them to be used in Font constructors, in-code, as well as in text layers definitions in a configuration file.
The method for that was defined in ConfigUtil.java that holds other configuration utilities as well.
public static void parseFonts(Configuration config) , as described before, takes a Configuration object (with the configuration file loaded) as a parameter, navigates to the folder path given under the fontDirectory key and loops through the files. Each file is then registered into the application using the “key” method of this mechanism, GraphicsEnvironment.registerFont().
Reading through the Apache Commons Configuration documentation, it was made clear that a PropertiesConfiguration object was always necessary if a configuration file was to be loaded. Following that, a call to parseFonts was made in the 2 classes that held such an object: OSM2World.java, which also includes the main class of the project and ReloadOSMAction.java which reloads a previously opened OSM file.
And with that said, making external fonts configurable mechanism is also wrapped-up!

PNG outputs of SVG textures used (stop sign and tennis net)

STOP sign tennis net

Application document:

https://github.com/JayGhb/GSoC-2019-Application/blob/master/application.pdf

Coming up: Traffic Sign catalogues

Introduction

This is the second post made regarding the Google Summer of Code 2019 progress. The first month is coming to an end and with it, the first 2 tasks as well. In this entry I will present what is new and what has changed, in regards to the first task as well as the work and decisions made on the second one. Exported images of demo renderings are also included at the bottom of this entry. You can see all the changes mentioned below in the pull request here
So, let’s begin:

Minor noteworthy changes on the 1st task

If you happened to follow my previous diary entry as well you may have noticed that it was mentioned that “Depending on their importance, I may include a brief of them in the next diary post”, referring to additional changes. Major ones are presented in the next paragraph below but I chose to also include the ones listed here; although they may not directly affect the flow/functionality of the program they still do play their role.
What is new:

  • Javadoc is created in important parts of the code such as the configureMaterial() method in TrafficSignModule and the File field in both TextTextureData (TTD) and ImageTextureData. The later Javadoc addition is to demonstrate the major differences these fields have despite their overall similarity.
  • Getter functions have been removed from TTD and its fields have been made public, following the concept of its parent superclass TextureData.
  • "osm2world" is now appended to every prefix of a temporary image created in TTD getFile() method as a way to help users understand where those new files in their systems came from
  • Last but not least, the hashCode() and equals() methods are now only defined in the TTD and ImageTextureData child classes instead of the TextureData parent one. Prior to that, an ImageTextureData object could be deemed equal to a TextureData one, as they used to bear the same fields, which should obviously not happen.

Major changes on the 1st task

  • TextTextureData now accepts all super-class fields as constructor parameters. That also inevitably meant that all those fields should be made configurable for the TTD objects via the configuration file. Thus, support for this is also implemented in Materials.java configureMaterials() method
  • Sticking to Materials.java configureMaterials(Config) method, this has also been restructured and had its flow altered, to improve readability and to avoid code duplication. That essential means 2 things

    1. The Wrap style parsing as well as the TexCoordFunction parsing are now methods as they are necessary for both types of texture layers.
    2. The “image” type is now used as the default type for a layer, by adding a
      String type = config.getString(typeKey, "image"); line

Based on that, the current flow is as presented below:

if ("text".equals(type)) {
        ...
        textureDataList.add(textTextureData);
} else if ("image".equals(type)) {
        ...
        textureDataList.add(imageTextureData);
} else {
        System.err.println("unknown type value: " + type);
}
  • Temporary created images are no longer stored in /textures folder due to the fact that, in the case of application-crashing, these files would “stick around” until manually deleted. By using createTempFile(String, String) without a directory parameter, the files are stored in the default temporary-file directory of the OS (/tmp for Ubuntu). Upon restart/shutdown the contents of this folder are deleted so problem solved!

  • POVRay target also ignores TTD layers. That is achieved by placing rather simple if layer instanceof TTD clauses in necessary parts of the code, being guided by the errors that occurred before that. As of now, for both obj and povray exports, if a TTD is present “above” and image layer, only the image layer will be rendered

Human-readable traffic sign values

For this task, the most important part is that of Add a configuration option of which country’s style of sign to assume, as same signs have different representations in different countries, as defined in the GSoC application document. The way that was going to be implemented was by defining configuration files for different countries (e.g. greece_config.properties) that would include entries that defined that style (and more). That was then going to be loaded together with the main configuration file without requiring any action by the user. So, to achieve that, classes that parse the configuration file needed to be altered. That was initiated with a change on OSM2World.java, which also holds the main class, by adding:

String locale = fileConfig.getString(localeKey);

if(locale != null) {
	String localeFileName = locale+"_config.properties";
	File localeProperties = new File(localeFileName);
	if(localeProperties.exists()) {
		fileConfig.append(new PropertiesConfiguration(localeFileName));
	}else {
		System.out.println(locale+"_config.properties file does not exist or it is not"
		+ "in the same directory as "+configFile.getName()+". Nothing happens");
	}
}

where localeKey stands for the name of the country defined in the main configuration file. But before going any further with altering other such classes (e.g. ReloadOSMAction.java), by digging further into the Java PropertiesConfiguration documentation it was found that this functionality is already implemented by default. What one has to do is add a line like include = pathToTheCountryConfigurationFile in the main .properties file and voila! Given that, it was then decided that no further action was necessary and a localization option as a command line argument is likely to be later implemented.

Png output of current results

The following renderings are created just by mapping the signs. An entry like <tag k='traffic_sign' v='DE:274-30' /> would create the sign in the first image and <tag k='traffic_sign' v='DE:274-50,1001-31[5]' /> would result to the sing in the second one. DE:274-30
DE:274-50,1001-31[5]

GSoC Application document

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

Coming up: SVG texture support

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

Today marks the official beginning of Google Summer of Code 2019! Given that, it might be a good time to introduce myself and let anyone interested know about my project for this summer. So let me begin with a few words about myself:

About me

My name is Iason Manoloudis and I am a Computer Science student in the Aristotle University of Thessaloniki, in Greece. I’ve been working on my application for OpenStreepMap as well as on the OSM2World project for some time now and after some back and forth with Tordanik, my application has been accepted! Working with an open source organization is a first for me and I really look forward to get more and more involved in the numerous aspects of OSM.

Regarding the project

Regarding this summer’s project, the main focus will be around implementing traffic sign rendering capabilities in OSM2World. This extends from “basic” speed limit signs to destination signs on highways with non-standard text, all the way to more generic implementations like svg texture support and more. The various tasks of it touch a (I could say) rather wide range of the existing codebase and for anyone interested, you are of course welcome to see more details on it in the application document. So far I have committed a small contribution as I get to learn my way around the project and, as it seems now, this exciting part of in-depth discovering a large project will never stop until the end of the summer.

I will make sure to post updates on the work here, in this diary, so stick around for weekly / bi-weekly entries as we go through this exciting period!