New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to vector tiles #3201

Open
kocio-pl opened this Issue Apr 27, 2018 · 37 comments

Comments

@kocio-pl
Collaborator

kocio-pl commented Apr 27, 2018

Follow up to #1975 (comment)

As discussed privately among team members, it's good to migrate osm-carto to be rendered with vector tiles. To allow as smooth and painless migration path as possible, it should be ready for server side raster tiles rendering. It should be non-disruptive change for clients while allowing to start developing client side rendering and testing vector tiles in general.

This is not a fresh and untested approach, @gravitystorm has been using it for his own styles for a few years already - you can watch his presentation about it from SotM EU 2014:

https://www.youtube.com/watch?v=NoLJHgqDCzc

There's also a vector fork of osm-carto by @rory (also his presentation from SotM 2016):

https://github.com/geofabrik/openstreetmap-carto-vector-tiles
https://2016.stateofthemap.org/2016/converting-a-regular-carto-project-to-vector-tiles-osmcarto-case-study/

However this fork is quite old and happened before our v4.x database migration. It's not clear now how useful it could be, other than being proof of concept.

This ticket is about coordination of the effort, more specific tickets might be needed for subtasks and technical background (like choosing the proper software stack) is yet to be discussed and tested.

@kocio-pl kocio-pl added this to the New features milestone Apr 27, 2018

@jbelien

This comment has been minimized.

Contributor

jbelien commented Apr 27, 2018

Would be really awesome to support Vector Tiles ! 🎉
But imho I do not think we should migrate ... We should add Vector Tiles support while still providing Raster Tiles :)

@StyXman

This comment has been minimized.

Contributor

StyXman commented Apr 27, 2018

I would agree, but maintaining two different styles is too complicated, specially because they don't seem to be compatible, or at least nobody has written a converter from one to the other. Think about all the contributions, having to be implemented twice...

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 27, 2018

This problem is much wider than style, it's also related to deployment strategy (especially on OSMF servers, but most probably also for the forks following us, like German or Belgian) and tools to be used.

@jbelien The whole point with server side raster tiles rendering is about planning deployment so that vector osm-carto tiles are then transformed into raster tiles. In other words instead of:

osm-carto -> raster tiles

it would be:

osm-carto -> vector tiles -> raster tiles

so the final output should be very similar.

Please note however that from the osm-carto perspective it's just a migration. Raster tiles rendering will be done with some other tools, so it's a deployment problem. Yet my intention is to plan the whole process with our partners (including you 😄), not just abrupt change of the styling output.

@StyXman Rory's vector fork is designed to be easily synchronized with standard version, but that might not be the proper solution. Andy suggested making a development branch form the current release (like v4.10.0-vector) and not try to synchronize them. After some time, when we will be ready to really deploy vector tiles on production, we should only update the vector fork to the current version of plain osm-carto (like v4.44.4) or just port it directly (into v4.44.4-vector), whatever will be easier. This would be the switch point. From now on the vector version (which will become v5.0.0 most probably - or we could rename the whole project) will take over and the raster version will become the legacy.

So we plan to make only some plain development fork just to learn things, but after that there will be no more two versions, the old one won't be supported probably. There's always possibility that somebody will like to support it, but given that the migration should not affect end users (and possibly be friendly for our forks) and there are only few people involved, I don't quite believe it would be the case.

@imagico

This comment has been minimized.

Collaborator

imagico commented Apr 27, 2018

I would like to emphasize that the ideas @kocio-pl is presenting here are not a consensus position of the maintainers of this style. We have briefly touched this topic in non-public discussion but as most can probably imagine the opinions were more differentiated and no common conclusions were drawn so far.

So if @kocio-pl speaks of a 'we' here take that with a grain of salt. If this project makes major changes in the toolchain it is based on this does not automatically mean deployments of this style (including the one on OSMF servers) or derivative styles follow suit. Should such a major change become concrete in the future - no matter if this happens within this project or separately (as it was done when making the change from Mapnik XML to CartoCSS) it will be up to each of the deployments and forks to decide if to follow this change or not.

Personally and from a design perspective i think a fresh start as with the change from Mapnik XML to CartoCSS would - even if it maintains some level of design continuity - be a very healthy step.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 27, 2018

This ticket is exactly to make the discussion more open. You're right that this is not anything set in stone, it's just a draft made by Andy (based on his real life experience) and approved by me, so we could start with some clear vision. Thanks for a disclaimer.

So yes - take it with a big grain of salt... and join the discussion!

Personally and from a design perspective i think a fresh start as with the change from Mapnik XML to CartoCSS would - even if it maintains some level of design continuity - be a very healthy step.

It was hard enough in 2012 for one determined man to make it. Now it's much more complex, so I don't believe that somebody else will try to do that again.

But if you - or anybody else for that matter - really want to make such rewrite, it can be just as good solution. It might be even better in the long run, given your cartographic experience together with designing and coding skills. I just think it will take years to come with a first demo after the "simple" port will be ready, so I want to start with more limited approach, which I find to be more realistic.

I entirely share your position that any kind of competition could only make the state of OSM rendering more healthy.

@imagico

This comment has been minimized.

Collaborator

imagico commented Apr 27, 2018

For clarification - with:

Personally and from a design perspective i think a fresh start as with the change from Mapnik XML to CartoCSS would - even if it maintains some level of design continuity - be a very healthy step.

I meant creating a new project that does not try to imply being the mandatory/automatic successor of current osm-carto. I did not want to speculate how this project would start practically (in form of a new implementation from scratch or as a manual or automatic conversion of existing code) - that is a completely different question.

This would encourage everyone - both style developers and style users - to evaluate their choices and make a conscious decision about these choices and take responsibility for them - something that at the moment rarely happens which is rather problematic.

Project continuity can appear convenient but the truth is this project is not the same as it was five years ago in almost any aspect even as it is right now - i for example just illustrated in #1630 (comment) how much the development focus has shifted. If there is a major change in the underlying toolchain in addition to that this would be an excellent opportunity to give everyone a kick to make themselves aware of how much things have changed overall and to check if this still matches their individual goals as developers or style users.

@StyXman

This comment has been minimized.

Contributor

StyXman commented Apr 27, 2018

A consequence of doing vector tiles is, I think, the ability to turn on/off on the client the rendering certain features, typically POIs. This would probably help with things like rendering offices and, maybe, with PIOs that fall in multiple categories (for instance, here in .fr, some bakeries also sell take away food and coffee). Just an idea; I really don't know if this is possible.

@andrzej-r

This comment has been minimized.

Contributor

andrzej-r commented Apr 27, 2018

If the same stylesheet code can support both deployment targets then I think we could (and should) reuse/extend the current project. Otherwise, I'm with @imagico on that - it is better to fork the project under a new name, so that we don't force existing users to switch, and let people use and maintain the existing implementation if they wish so. Otherwise we end up with Gnome3 scenario where Gnome2 users have to fork and copy the existing implementation.

And, to make it clear, I am in favour of using vector tiles on the main osm map. Especially if, as planned, it can be rendered on the server side to avoid Web-GL. Many of the current usability issues (lack of language versions, lack of overlays for transport, POI categories etc) could be easily solved.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 28, 2018

Sure, we could make a fork(s) under some other name. Instead of long and muddy "OSM Carto Classic/Legacy" I would rather go with something like "Vektor Flagship" and call the other styles/deployments from the same family like "Vektor Drakkar" or some other fancy vessel type that makes sense ("Vektor Flagship One" comes to mind for OSMF deployment). Right name can be quite important to avoid confusion (see #2927) and with many possible styles basing on the same vector engine such a double part name could help identify them (hence "Vektor" instead of "Vector" - not too common name on the net).

It's an interesting idea that new style could be based on automatic conversion of existing code, but I don't believe it. It would mean writing code parser and this is not trivial programming task, as seen lately on a very simple example (see #3151).

That means that we have not too much options left. One is kind of Rory's fork, which tries to add some vector-related things on top of existing CartoCSS+SQL syntax and I believe it's the way to go. Another is to write something from scratch and this would be quite another fork, which basically would be very light at the beginning. It might be nice competitor, but it would not allow smooth upgrade. That's why I want to keep the Andy's path. It's easier to make a lighter skin for such full-featured fork than make a different fork and try to recreate osm-carto features.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

@gravitystorm Could you tell what software stack are you using for Thunderforest styles?

@gravitystorm

This comment has been minimized.

Owner

gravitystorm commented Apr 30, 2018

@kocio-pl Custom software, based on the tilelive modules.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

Rory told me that he was trying tilelive-copy (so probably https://github.com/mapbox/tilelive), but it was slow. His new tool is much faster, but not production ready due to bugs: https://github.com/rory/tileigi. Would somebody like to test them a bit?

@pnorman

This comment has been minimized.

Collaborator

pnorman commented Apr 30, 2018

tileigi is not suitable for the osm.org because it only does pre-generation of vector tiles, which won't work with regular updates. It's also not really stable enough that I'd trust it in production yet.

@pnorman

This comment has been minimized.

Collaborator

pnorman commented Apr 30, 2018

I've been talking with @rory today. More on that later.

If we want to have a port which is a Mapnik style based on server-side vector tiles, I recommend starting by eliminating all layers which label polygons. Instead, use ST_PointOnSurface, and when applicable, combine them with the point version of the layer. This will eliminate one major difference between the port and what we currently have, without breaking what we currently have.

@matthijsmelissen

This comment has been minimized.

Collaborator

matthijsmelissen commented Apr 30, 2018

@pnorman I'm not sure if I follow you entirely. Why would polygon labels cause a difference between the current style and the vector port?

When we use ST_PointOnSurface, we have no guarantee about the location that is chosen (except that is lies in the polygon), right?

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

Very good news! 👍

I wait for the summary of your talk with Rory. In case you wonder how it looks like, the new style is named Bolder and you can find it here: https://github.com/pnorman/bolder

@pnorman

This comment has been minimized.

Collaborator

pnorman commented Apr 30, 2018

@pnorman I'm not sure if I follow you entirely. Why would polygon labels cause a difference between the current style and the vector port?

You can't label polygons with vector tiles because they're cut at tile boundaries. You have to turn the polygons to a point that is labeled. https://youtu.be/wQc492mtK-c?t=9m30s has an overview of the causes.

When we use ST_PointOnSurface, we have no guarantee about the location that is chosen (except that is lies in the polygon), right?

The only guarantee the function specification gives is that it lies on the surface. In practice, the algorithm does the centroid if possible. #349 (comment) has some examples of how Mapnik and ST_PointOnSurface work. Neither is uniformly better. There are methods believed to generate better results than ST_PointOnSurface like PIA, but those wouldn't be what we'd use initially.

In general, moving to vector tiles makes labels harder, and even if you do your best, you end up with worse labels.

@pnorman

This comment has been minimized.

Collaborator

pnorman commented Apr 30, 2018

From the conversation with @rory, we discussed a few things

Geofabrik's interest is multiple languages with reasonable performance, retina tiles, and slightly changed styles for clients (colour changes, dropped features, etc). Vector tiles are good at this.

Rory found tilelive had bad performance, so he started tileigi, which can be 100x at generating tiles. Tileigi currently only pregenerates tiles, it doesn't serve them live. Most of the performance gains he got are from using vector metatiles: the practice of requesting the area of 8x8 tiles, and slicing the result up into 64 individual tiles, and storing individual tiles on disk.

osm-carto is a very complex style, and it can take hundreds of milliseconds to go from vector to raster for a single tile. This is exceptionally slow, and I'd consider times under 10ms more "normal". We discussed a number of ways to improve performance to make up for the osm-carto complexity and number of layers. The most likely route is to carry the metatiling farther. Instead of querying the area of 8x8 z14 tiles and slicing them before putting them on disk, put the unsliced tile (a z11 tile with a high resolution) on disk. Then, when a request for a z14 raster tile comes in, fetch the combined tile, generate a raster for the 8x8 area, and store the sliced tiles in memory. The in-memory tiles can be used for the subsequent requests for nearby tiles. This is technically overzoom for the vectors, and metatiles for the rasters.

What you can see from the above is that there is no software serving stack for Mapnik vector tiles that is 100% there for our needs.


Some more changes that would help maintaining a vector fork are

  • Drop use of classes for layers. You can't do classes with vector tiles
  • way_pixels is an issue for where overzoom is used. See rory's presentation for details, but we couldn't think of a solution for this.
  • We could set buffers per-layer. Neither of us were sure what would happen to raster if buffers were set per-layer.
  • #2524 is an issue with retina, which matters more when we have easy support for retina.
@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

From my point of view:

  • rendering based on the size is essential, for example I was not able to find anything better for natural reserves to avoid mess; but since the area size data are in the database and the software is somehow aware what is the current zoom, so it should be possible to calculate current size of the area, or am i missing something?
  • retina is just the nice addition
  • I have no idea about what could be done with classes and buffers

But also:

  • What about vector patterns (#2045)? Maybe just replacing the raster images with vector ones in the new implementation would be enough.
  • What about software support? Mapnik is supported and developed, so is Kosmtik and Carto CSS is on a way to become legacy, but still supported. What about new stack?
  • Is there a chance to deploy this style in parallel on OSM.org? Pro: it can use the same database, contra: vector tiles can have many output formats (server side raster tiles, vector tiles with different looks) and I'm not sure how to serve them
  • Is there a way to port the osm-carto features more easily than just rewriting them all from scratch by hand?
@dieterdreist

This comment has been minimized.

dieterdreist commented Apr 30, 2018

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

This is how Bolder looks like when rendered with repo instructions and Liechtenstein data:

screenshot-2018-4-30 tegola mvt tile server

I was wondering about possible geometry distortion, which is a big issue for @imagico. Here it is on z19 compared to osm-carto on z19 - I don't understand why the size is different with the same zoom level, but at least geometry seems to be unchanged (even without "Turning Off Simplification of Geometries" option):

screenshot-2018-4-30 tegola mvt tile server 2
screenshot-2018-4-30 openstreetmap

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

Bolder client-side style with Mazovian voivodship/Warsaw data:

screenshot-2018-4-30 bolder - tangram js
screenshot-2018-4-30 bolder - tangram js 1
screenshot-2018-4-30 bolder - tangram js 2

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

Client side rendering is quite fast only on highest zoom levels, but we have just 7 layers here instead of 82. It's very CPU intensive process.

@pnorman

This comment has been minimized.

Collaborator

pnorman commented Apr 30, 2018

Client-side rendering is incompatible with the approach that Andy has suggested of incremental work, using small steps.

software is somehow aware what is the current zoom,

afaik, Mapnik doesn't let you use the zoom in calculations. If it did, we could stop converting area to pixels, and do the math in the MSS. But without that ability, we need to use different thresholds for different levels of overzoom.

retina is just the nice addition

It's one of the big reasons to use vector tiles. I don't know osm.org's usage numbers, but in general >50% of users can be expected to have a device with a high DPI screen.

What about vector patterns (#2045)? Maybe just replacing the raster images with vector ones in the new implementation would be enough.

There's no direct relation with vector patterns. It's already an issue. It might become more common to do retina tiles with vector tiles, so more people might hit the blurry issue.

What about software support? Mapnik is supported and developed, so is Kosmtik and Carto CSS is on a way to become legacy, but still supported. What about new stack?

We'd still be using Mapnik, Kosmtik, and CartoCSS. We'd need some Mapnik-based vector tile server for production, probably something based on tilelive. There are no clear candidates here. Tessera, Kartotherian, and others all would sort of work, but I'm not convinced that vector tiles have the performance without tricks like mentioned above, and no one has coded a stack with those kinds of tricks yet.

Is there a way to port the osm-carto features more easily than just rewriting them all from scratch by hand?

There's no rewriting involved. See @rory's talk for what's needed to port the style.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented Apr 30, 2018

afaik, Mapnik doesn't let you use the zoom in calculations. If it did, we could stop converting area to pixels, and do the math in the MSS. But without that ability, we need to use different thresholds for different levels of overzoom.

I see. @talaj Could you comment on this? Is this something doable in a near future or maybe something that could be ported from your fork, for example?

@talaj

This comment has been minimized.

talaj commented May 1, 2018

@kocio-pl This is possible already by render-time variables . @zoom variable is implemented in tilelive-mapnik.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented May 1, 2018

Sounds good, thanks!

There's no rewriting involved. See @rory's talk for what's needed to port the style.

I will watch it once again, but I'm not sure what your project has to do with his effort. I can understand that vector tile production and serving might be done with different tools, but I don't understand how the CartoCSS rules can be used in Bolder?

@systemed

This comment has been minimized.

Contributor

systemed commented May 2, 2018

Moving to vector tiles gives an opportunity to decouple cartography and schema, which I believe is essential.

Porting osm-carto to vector tiles as a single project would achieve some nice-to-haves (clickable POIs, better multilingual support, sharper display on retina imagery, better zooming) but nothing transformational.

Providing a style-agnostic vector tile base, however, enables multiple styles to be hosted on osm.org and even for users to load their own local styles. This would demonstrate the USP of OSM as compared to Google Maps; provide an opportunity to resolve the perennial tension between osm-carto as a mapper feedback style and new users' desire for something that "just looks nice"; and encourage a healthy ecosystem around vector tile cartography rather than one dominated by a particular company and its authoring tool.

Obviously osm-carto as one (and almost certainly the principal) consumer of these vector tiles would have significant input into the schema. But the schema should be agnostic rather than being designed for the needs of one particular map style.

I'd suggest that a good place to start would be a new experimental project for this vector tiles schema. I'm sure people like @pnorman and @rory would have a lot they could bring to that.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented May 2, 2018

Any ideas how such schema should look like to be style-agnostic? I mean how should it be different from just the osm-carto vector tiles?

@imagico

This comment has been minimized.

Collaborator

imagico commented May 2, 2018

@systemed - in principle i am with you here, back in 2015 i called this establishing a middle layer between mapping and rendering.

But there is a very strong risk of underestimating the difficulty of actually making this truly style-agnostic, in particular since you - for generating vector tiles - will obviously want to have all the expensive processing steps already in the vector tiles and these expensive parts also tend to be full of subjective design decisions which makes them inherently non-generic and not style-agnostic.

Within the cartographic scope of this style, in particular with the mapper feedback function and the fairly direct and non-complex relationship between original data and rendering result this requires, designing fairly generic vector tiles would be significantly easier - if you accept a significant data volume overhead in the form of the vector tiles containing - for every style they are used for - a significant amount of data that is ultimately not actually used in rendering.

But even then - if you take for example some of the closest variants of this style out there - the German and French style, https://github.com/SomeoneElseOSM/openstreetmap-carto-AJT and maybe also some of the things i implemented in https://github.com/imagico/openstreetmap-carto/tree/alternative-colors - it would already be really difficult to design a vector tile schema that would allow reproducing all of these variants. In return, if a vector tile schema does not allow for this bandwidth of map design this would severely limit the options you would later have in actual map styling.

But yes, decoupling development of cartographic data processing - you could also call it designing a data schema to be used in rendering - from the actual rendering is something that is highly desirable and quite underdeveloped in the OSM ecosystem so far.

@andrzej-r

This comment has been minimized.

Contributor

andrzej-r commented May 2, 2018

I think tiles, whether vector or raster are not a place for generalisation. They are already strongly coupled to projection and zoom levels. If we want them to perform efficiently they should store minimum amount of data required for rendering. If other styles end up needing the same data - great, but we shouldn't dump half of the database into tiles for the sake of flexibility. We would just end up with a less efficient implementation of the database.

Now, there is nothing stopping us from generating multiple sets of vector tiles, just like we are doing it now with raster ones. The difference is, we could then combine several such tiles during rendering. For example, we could move all labels to separate tiles, one for each language version, or transport routes, or pois.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented May 2, 2018

The key problem with serving generic/agnostic vector tiles is hardware and performance.

It's good to have all the data available on-line, but we just have too many of them to do it. For example OSM Carto filters some data while importing into rendering database (see this part of lua file). Then there are some big SQL queries in project.mml, which are optimized to fetch only some data on some zoom levels. Sometimes it would be more readable to write them as Carto CSS rules in MSS files, but that would make everything more resource hungry. And even with all these constrains, tile requests on OSM.org are dropped from a rendering queue on a daily basis - some server resources are not fully used only in the night:

https://munin.openstreetmap.org/openstreetmap/render.openstreetmap/renderd_processed.html

Now, there is nothing stopping us from generating multiple sets of vector tiles, just like we are doing it now with raster ones.

I like this idea very much. This way or another we need some additional resources for producing vector tiles (it's still very important to find them), but this sounds like a good value for the money. I can imagine that many map styles will need roads, water, buildings, addresses, POIs, admin borders and at least some natural features, so they can have a priority.

@kocio-pl kocio-pl added this to General issues in Vector tiles migration May 7, 2018

@gravitystorm

This comment has been minimized.

Owner

gravitystorm commented May 8, 2018

Moving to vector tiles gives an opportunity to decouple cartography and schema, which I believe is essential.

I would suggest that this opportunity is deferred, and instead the simplest-possible move to vector tiles is done first. Any decoupling / generalisation / multiple style support should be considered separately as a follow-on project. If too many complex things are attempted simultaneously, then nothing gets completed.

I have experience in designing vector tilesets that are used by multiple styles, and it was hard enough when I had full control over the styles, and the opportunity to work on the system full time too!

I suggest that efforts are put on making the next steps - converting this style to use vector tiles, and deploying to the OSMF hardware - as small and as focussed as possible. Anything that is not strictly necessary can come later.

@pnorman

This comment has been minimized.

Collaborator

pnorman commented May 8, 2018

Moving to vector tiles gives an opportunity to decouple cartography and schema, which I believe is essential.

I'd like to see this happen. But I also think this is the worst style to do it with, because osm-carto's needs are the most complex. In each of the last 5 minor versions we've made changes which would increment the vector tile schema version. In only one of them was I able to see that it was clearly a simple compatible change.

Thinking about the problem more generally, I don't think it's possible to keep up a good development pace, have a schema used by other renderings that are not closely-tied, and represent the full scope of OSM data. Only two are possible at once.

Tilezen and OpenMapTiles drop some combination of the three, and I consider those the most likely routes for this to happen.


There's no rewriting involved. See @rory's talk for what's needed to port the style.

I will watch it once again, but I'm not sure what your project has to do with his effort. I can understand that vector tile production and serving might be done with different tools, but I don't understand how the CartoCSS rules can be used in Bolder?

Nothing. Rory's effort was about porting a CartoCSS Mapnik style to a CartoCSS tm2style + tm2source style for server-side vector tile rendering. Bolder is a new client-side rendered style, and doesn't use CartoCSS, tm2source, tilelive, node-mapnik, or Mapnik. I don't understand why Bolder keeps getting mentioned here. I'm not reproducing OpenStreetMap Carto technical or cartographically with it.

@kocio-pl

This comment has been minimized.

Collaborator

kocio-pl commented May 8, 2018

I don't understand why Bolder keeps getting mentioned here. I'm not reproducing OpenStreetMap Carto technical or cartographically with it.

Oh, now I see. I thought that it was somehow related to your talk with Rory, but it's just a different vector project using the same database schema.

So for now we don't have a software stack for migration and I'm not sure how should it look like. However we can make current style suitable for using vectors as mentioned in #3201 (comment). Unfortunately this is something which requires more coding skills to start with than I have, so I wait for example changes which I could follow.

@matthijsmelissen

This comment has been minimized.

Collaborator

matthijsmelissen commented Aug 13, 2018

ESRI has created a vector implementation of this style in ArcGIS:

http://esri.maps.arcgis.com/apps/View/index.html?appid=d6b18a2e774c4959ba855f6ac90952a2

Impressive work!

@kocio-pl

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment