Level Map/Software Support
Although level maps are very compatible with level map unaware software, so that many programs (including all graphical 2D renderers) would not even benefit from a full support, other software (in particular routing software) should be level map aware if we decide to actually create and use level maps.
In order to make it easy for developers to add the functionality as needed, there should be a library (let's call it "liblevelmap") to support their tasks. The library must be as versatile as possible, to help as much as possible.
Along with the library, there should be some tools that can be used to add the functionality to unaware software indirectly if needed.
The purpose of this page is to discuss the requirements for software support, shaping the design of liblevelmap.
Requirement list for liblevelmap
|Expansion||Must be able to expand level maps into instances, pushing as much information from the level maps as possible to where it is needed. Vertical ways must be created as ways. All connections (junctions) must be provided. The output must be valid OSM data.||The main purpose||Essential|
|Expansion: Keeping Memberships||Level maps should be maintained in the expanded data. On top of their original members, the relations should also contain the instances they have produced (that are regular OSM objects now).||Ease of use, reversibility||High|
|Expansion: Reversibility||The expansion output should be reversible in a way that the source of all additional objects generated during the expansion can be clearly identified (from which "main" instance it is instantiated and which instance number).||Tools can run on persistent databases||High|
|Expansion: Minimum Change||
||Tools can run on persistent databases||High|
|Cleanup: Unused||The library should be able to remove instances from previous runs that are no longer used.||Tools can run on persistent databases||High|
|Cleanup: All||The library should be able to remove all instances from previous runs, reversing all expansion effects completely.||Tools can run on persistent databases||High|
|Streaming||Should work on-the-fly, being called from the input component of an OSM data consumer application||Call the hook and forget about it||High|
|Static Data||Should be able to work on OSM data stores somehow (databases, OSM files, PBF files, etc.)||Do an expansion/update before using the data||High|
|Expanded Data Format||A common data format for expanded level maps (common tags) should be used for expanded level map data||Different programs can share one expansion||Medium|
|Performance||The library must work as fast as possible while being as compatible as possible. If needed, different operation modes must be supported and chosen automatically. For example, if there is not enough memory, switch over to a two-pass mode.||Acceptance||Medium|
|Calculating Relative Heights||Calculate relative heights from the level map definitions, assuming a 4.5 m height per level by default. 4.5 m seems to be a good trade-off between the height of structures we are usually mapping (from at least 3.0 m for residential blocks, up to 6 m for bigger structures, including high road bridges).||Input for 3D rendering||Medium|
|Calculating Elevations||If original OSM elements have got ele=* and/or height=* tags, new ele=* tags should be calculated accordingly.||Completeness||Nice to have|
|Minimum Dependencies||The library should be based on as few requirements as possible||Flexibility||Essential|
|Java Support||Java must be supported at least as a binding for the library, because many consumers are written in that language||Usability||Essential|
|Standalone Tool Functionality||Implementing expansion and cleanup support at least on whole .osm, .osm.gz and .pbf files||Usability||Important|
|Standalone Tool on Java||The standalone tool should be a native binary for ...||One common implementation||Essential|
|Standalone Tool as a tarball||The standalone tool should be a available for user compiles and as required by GPL.||One common implementation||Essential|
|Standalone Tool on .NET / MONO||The standalone tool should be a native binary for ...||One common implementation||Alternative for others|
|Standalone Tool on win32 (compatible with basic Win98 through Win7, plus WINE)||The standalone tool should be a native binary for ...||Usability||Important|
|Standalone Tool on Linux i686||The standalone tool should be a native binary for ...||Usability||Important|
|Standalone Tool on win64||The standalone tool should be a native binary for ...||Usability||Nice to have|
|Standalone Tool on Linux x86_64||The standalone tool should be a native binary for ...||Usability||Nice to have|
|Standalone Tool on MacOS ???||The standalone tool should be a native binary for ...||Usability||???|
|Osmosis plugin||Implementing expansion and cleanup support as a plugin for osmosis||Flexibility||Important|
Which licence would be optimal for the library?
Which licence for the tool?
Nothing here yet.
Level Map Expanded Data Format
This is a list of tags that instantiated OSM objects should be given
|lm_expansion:is_generated=*||every object that is created by level map expansion||Identifies the objects as eligible for a level map cleanup|
|lm_expansion:is_generated=direct||... created due to a direct membership of the main instance in a level map||A membership is direct if the object is a level map member itself. It is indirect if it is part of a member (such as a node in a member way or a member of a member relation). Attributes from a direct membership always override attributes from an indirect membership, so this distinction may be needed by software working on databases.|
|lm_expansion:is_generated=indirect||... created due to an indirect membership of the main instance in a level map|
|lm_expansion:source_id=[type:]ID||every instance, including main instances||contains the ID of the object it was instantiated from. If the type differs, the ID must be prefixed with the original type. Usually the main instance's ID. vways are an exception, because they are ways, instantiated from a node. So vways have "node:vway_node_id" here.|
|lm_expansion:instance_no=instance_number||every instance, including main instances||contains a relative number of in the list of instances of this particular object. The main instance always is number 0. Instances below the main instance have negative numbers, instances above the main instance have positive numbers. Every set of instances has its own set of counters. There are no gaps.|
|lm_expansion:instance_min=instance_number||every instance, including main instances||contains the number of the lowest instance of this set. The number of existing instances is instance_max-instance_min+1.|
|lm_expansion:instance_max=instance_number||every instance, including main instances||contains the number of the highest instance of this set. The number of existing instances is instance_max-instance_min+1.|
|lm_expansion:level=level_name||every instance, including main instances||the short level name|
|lm_expansion:level_long=long_name||if defined for the level||the long level name|
|lm_expansion:level:language_code=foreign_level_name||if defined for the level||the short foreign language level name|
|lm_expansion:level_long:language_code=foreign_long_name||if defined for the level||the long foreign language level name|
|lm_expansion:above_ground=relative_elevation||every instance, including main instances||Relative elevation above the ground level assumed or defined in a level map.|
|lm_expansion:ele=absolute_elevation||if the original node had an elevation||Calculated during expansion.|