Prehistory

Some time ago, due to the availability of free time, I thought about using maps to solve some interesting and unusual problems. One of the ideas that interested me was the idea of using maps to render the world in the game engine with the possibility of interactive interaction: the destruction of McDonald's in the chosen city, the local apocalypse of the neighbors in the garden, and similar pleasant things, but only in the case of the virtual world, little things.
However, despite the primitiveness of the idea, no ready-made solutions were found under the conditions formulated by me:
- Open source
- Real time world rendering in the game engine
- Support for major platforms (mobile, web, desktop)
- Desirable C # as the main development language.
Of course, the idea of rendering maps in 3D is absolutely not new and there are ready-made solutions with both open source and proprietary (in no case do I pretend to the full list):
As a rule, such solutions use
OpenStreetMap data for rendering the world in 3D, because This feature is in the cards and is actively
developing . Also, a great advantage of OSM is the ability to download a full data dump of the entire planet or of a certain part / city (for example,
geofabrik or
metro-extracts ), and without any hard licensing restrictions.
ActionStreetMap
Thus, it was decided to start developing your project from scratch called ActionStreetMap, which, in theory, should remind you of the nature of the source data and the way they are used. Unity3d was chosen as the game engine, which is not surprising because of the latter condition (C # development language) and the developed community, since this is my first experience in the field of game development.

The project started over a year ago and is in an active development stage, even though I'm still the only developer. Below are the main features that are currently implemented:
- Flat shading style
- Rendering basic OSM objects (buildings, roads, fences, trees, rivers, parks, POIs ...)
- Using SRTM data to create a height map
- Autoloading maps from OSM and SRTM server data from NASA server
- Offline maps (import from major OSM data formats - pbf, xml, o5m)
- Support for primitive search for places in offline mode
- Support for modification of some objects (experimental feature)
- Asynchronous loading of all and all (using Reactive Extensions)
- Ability to customize
I would like to dwell on the first and last points in more detail, despite the fact that I do not set goals to describe the internal structure of the project in this article.
Flat shading
After experimenting with building textures and unity terrain, it was decided to abandon the attempt to render a "plausible" city. The reasons are trivial:
- The lack of real data on the facades of buildings and other objects (texture of the Khrushchev on the facade of the Reichstag looks funny at first, but over time begins to strain ..)
- Performance
As a result, the “triangles” approach was chosen, although the ability to render something of your own in a different style is still present.
')
Customization
When I got acquainted with OSM maps, I was interested in the idea of using
CSS of a similar language to describe which objects should be srenderiny and how. As a result, a similar approach with some features was used in ASM. For example, buildings are partially determined by the following rules:
area[building] { builder: building; height:12; min_height: 0; levels: 5; fill-color:gradient(#c0c0c0, #a9a9a9 50%, #808080); facade-builder:empty; material:Materials/Buildings/Building; } area[building:levels] { height: eval(num(tag('building:levels')) * num(3.2)); } area[min_height] { min_height: eval(num(tag('min_height'))); } area[building:height] { height: eval(num(tag('building:height'))); } area[building:height][roof:height] { height: eval(num(tag('building:height')) - num(tag('roof:height'))); } area[building:cladding=brick] { fill-color:gradient(#0fff96, #0cc775 50%, #066139); } area[roof:material=brick] { roof-color:gradient(#0fff96, #0cc775 50%, #066139); }
This approach removed the logic of parsing rules from C # classes, and in combination with
Composition Root and Dependency Injection patterns used in the project, greatly simplified the task of customizing the rendering of OSM objects and added the ability to create "themes" (for example, winter, summer theme, etc. .), which can be changed without recompiling the source code.
Sources
The source code of the
demo project in the Unity Editor, as well as
web build with a small part of the map of Moscow are currently available.
The framework itself is not yet on github, but if the unity of the community is interested in its development, it can be published.