We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Gleo Feature Frenzy

00:00

Formal Metadata

Title
Gleo Feature Frenzy
Title of Series
Number of Parts
156
Author
Contributors
License
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Gleo is a nascent javascript WebGL mapping library. It aims to find a niche alongside Leaflet, OpenLayers, MapLibre and Deck.gl. This library was presented at FOSS4G 2022. This will be a presentation of the features developed during the last year, including live examples, clustering, colour spaces, and vector field handling.
Keywords
Standard deviationArchitectureComplex (psychology)VolumenvisualisierungAxonometric projectionBootingCircleRadiusSymbol tableEquals signTriangleLocal GroupMetreZoom lensPlug-in (computing)Sign (mathematics)Game controllerLaptopObject-oriented programmingLibrary (computing)Local ringGoogle MapsNeuroinformatikMappingTouchscreenLevel (video gaming)Social classGodTesselationDemo (music)Extension (kinesiology)Point (geometry)Order (biology)2 (number)Web 2.0Open setMultiplication signSlide ruleStructural loadCartesian coordinate systemState of matterINTEGRALSinc functionFreewareVolumenvisualisierungOpen sourceBitVideo gameComputer architectureWhiteboardLecture/ConferencePanel paintingComputer animation
DialectSymbol tableLogicBootingLocal GroupRadiusCircleInteractive televisionExecution unitPointer (computer programming)Computer iconInversion (music)CAN busScale (map)Random numberComputer fontInterior (topology)System callStructural loadPoint (geometry)CASE <Informatik>Multiplication signVector spaceSemiconductor memoryWeb crawlerMessage passingLine (geometry)Symbol tableFunctional (mathematics)KonturfindungObject-oriented programmingColor spaceString (computer science)Arrow of timeArtistic renderingCursor (computers)Right angleDifferent (Kate Ryan album)Category of beingMereologyPixelShader <Informatik>Disk read-and-write headRandom matrixClique-widthSingle-precision floating-point formatGraph coloringGroup actionVertex (graph theory)Extension (kinesiology)Thread (computing)Web 2.0InterpolationAlgorithmError messageVolumenvisualisierungSocial classOrder (biology)TriangleLogicGeometrySet (mathematics)Web browserTouchscreenData structureBoundary value problemSource codePointer (computer programming)Object (grammar)Instance (computer science)Level (video gaming)Direction (geometry)Position operatorType theoryComputer programmingPlug-in (computing)1 (number)Data compressionComputer animationLecture/Conference
Computer fontInversion (music)Conic sectionInteractive televisionSymbol tableCAN busMechatronicsMaizeRouter (computing)Axonometric projectionBound statePhysical systemConstructor (object-oriented programming)Graphical user interfaceStructural loadVideo projectorLine (geometry)ChainMach's principleGeometryBootingPixelExecution unitDivisorVortexLine (geometry)Projective planeGodSymbol tableTouchscreenChainCirclePrice indexVideo game1 (number)Arrow of timeMultiplication signDivisorStructural loadField (computer science)BitWeb 2.0Graph coloringPoint (geometry)GeometryVolumenvisualisierungMathematicsMereologyCartesian coordinate systemTrajectoryPolygon meshNumberLevel (video gaming)AngleBootingBoom (sailing)Right angleCodeContinuum hypothesisMappingArtistic renderingVisualization (computer graphics)String (computer science)Greatest elementSound effectSequenceShift operatorSquare numberComputer reservations systemRectangleParameter (computer programming)FrictionRepetitionConic sectionOrder (biology)Coordinate systemSheaf (mathematics)Scalar fieldPlanningControl flowPredictabilityRaster graphicsComputer animationLecture/Conference
Musical ensembleScale (map)PixelInversion (music)Disk read-and-write headSymbol tableMiniDiscInteractive televisionVector spaceBootingDemo (music)Bridging (networking)Point cloudClique-widthFunction (mathematics)Price indexLogarithmMaxima and minimaComa BerenicesExecution unitTwin primePolygonInfinite conjugacy class propertySimilarity (geometry)PlastikkarteDivisorAtomic nucleusThomas KuhnColor managementDot productPoint (geometry)GeometryBitMultiplication signSymbol tableVertex (graph theory)Set (mathematics)Demo (music)Line (geometry)Software developerStructural loadPolygonVolumenvisualisierungVector spaceSubject indexingComplex (psychology)TesselationComputer fileMereologyLevel (video gaming)Functional (mathematics)GeometryCASE <Informatik>Representation (politics)Core dumpMetropolitan area networkVideo game2 (number)Real numberMathematicsMessage passingMixed realityBootingRight angleBoom (sailing)InformationMappingCodeLangevin-GleichungRouter (computing)Computer animationLecture/Conference
GeometryComputer-assisted translationSicLecture/ConferenceComputer animation
Transcript: English(auto-generated)
Thank you, Delia. I'm happy because you kind of made my first slide already. So thank you for that. This is kind of the state of the art for JavaScript mapping libraries in the free open source world. We don't talk about Google Maps here. We don't talk about RGIS JavaScript here. And we don't talk about Mapbox GL here. But Map Library is kind of the golden child of the map
renders right now, because it's really fast performant on vector tiles. The problem is you cannot get away from Web Mercator. That's, for me, one big disadvantage from Map Library. There's also open layers. But the onboarding of open layers is kind of clunky a little bit. So I'm not really happy with it. I tried to do some deep integration with open layers
and kind of fail because the internal architecture, for me, I don't really get it. That's just me. And then everybody loves Leaflet. Everybody absolutely loves Leaflet because it's so easy to get in. But we have reached, in Leaflet, a performance ceiling long time ago because there's no WebGL support. And in order to show more than 1,000 points, you need WebGL.
That's it. So I have been doing GLIO for like four years now with the goals of being easy to get onboard. And really, the main point here is object-oriented programming extensibility. You have classes, and you have class extensions, and things that really, really look like Leaflet plugins. It's not going to be super optimized for vector tiles.
Text support is kind of not working right now. But this is kind of the summary. If you have not seen GLIO before, this is how it looks like on JavaScript. If you have ever used Leaflet, it's like, no, wait, let's leave that. No, that's GLIO. This is what GLIO looks like. It really feels like Leaflet.
And there has been a bunch of new features seen last year. And I'm going to explain all of this with a live demo that you can run on your phones and laptops as well. So I'm going to leave this slide for a couple of seconds so you can copy it. People were asking me, are you going to live demo something in your slides?
And I said, have you been asking? Come on. What could possibly go wrong with 20 minutes of live demos in a conference in a computer that's not yours? OK. So before I start with the GLIO demos, I'm going to go to the Leaflet GLIO demos.
Oh, I did point to local host? Oh, god damn it. It failed. Live, yes. So sorry. Then I'm going to leave this up on the screen a couple
more seconds. I'm so sorry, folks. I messed it up. Nice. OK, I hope everybody has copied that. OK, so this is the first thing I wanted to show. This is not full GLIO. This is Leaflet. If you look closely here at the bottom,
where's the plus sign on this thing here? Oh, this works on the other way. It's actually Leaflet. This is actually Leaflet with the Leaflet zoom controls. But everything that's moving on top, it's like 5,000 points, and that's WebGL GLIO.
So if you have a Leaflet application and you don't want to get rid of all your entire infrastructure for your Leaflet application, you can just load Leaflet GLIO as a Leaflet plugin and start putting stuff on top, which is nice. So the first thing I want to show in, oh, it's a bit too, yep, so you go to examples here.
The first thing I want to show is the symbol group. This is really not exciting. It's just a logical grouping of symbols. So you add symbols to a group, and then you add the group to the map, and then you remove the group from the map, and it works. Not exciting, but it needed to be done. So that's one of the new things. Then there's the pointer cursor.
It's also not exciting. So you have the normal pointer, the arrow thingy, and when you go on top of the thing, it turns into a hand, and then you take it out, and then it turns to an arrow. So not exciting, but it's kind of needed and not trivial to do in WebGL when you're rendering stuff. Especially when you need to make it work with Leaflet GLIO, so that's it.
Something that was made last year is the thing about, oh, I don't have it working here. I didn't push last night, so that does that. Next thing is the stroke road. This is one of the fancy ones, which is the line string symbols stroke road. Road rendering is hard, especially when you take into account the casing.
So the usual way to do it is you render the casing, which is a white line, and then you render the main line on top, and then takes two render passes. So this approach is using just one render pass for everything. So in one single symbol with the geometry, you got two different widths and two different colors,
so this is rendered all at once. Also, you notice that the crossing of the road looks properly. It looks proper. If you remove one of the symbols, you see the casing goes. Doing this in one single render pass is kind of interesting to see in the shaders.
Next is the heading triangle. So if you have features, we have a direction, there's a symbol for that. Not really complicated, but it works. And you can update the heading with JavaScript. It's just plain JavaScript to modify the heading. I can change properties from the symbols
and changing this property with the setter with this line here. This will go all the deep down, locate the part of the GPU memory where that value is being held and redo the whole thing, and it works reliably. Then I spent an awful, awful lot of time
on the freaking cluster. So if you have used least load, you know about leaf load marker cluster, this is pretty much the same thing, but for you. So it's the same thing. It renders, it has this, it has a function that you can define
to define how a cluster is going to show. It has this fancy animation which spawns the spider thingy when you have points, because the use case I'm dealing with, the points are not in the same, exact same geographical position, but are slightly apart from each other. So this kind of calls out
to each one of the points in the cluster, which is nice. This is taking a lot of time. You have these symbolizer functions for the cluster as well. You can customize the spider behavior, et cetera, et cetera, et cetera. Then we're going to the decorators, which is one of the nice things about Glio.
Glio is fully object-oriented. It does not use style sheets. That means I can, every symbol is a class, so I have symbol instances, and I can decorate the class to change the behavior of all symbols of that same kind. This here is one single dataset
with one single set of geometries and one single set of colors in here, in this line. And it's been drawn two times, one offset. And if you notice, one of them is using RGB interpolation. The one at the left is using RGB interpolation and is creating these kind of muted colors.
The one on the right is using HSL color space interpolation and in order to do that, what I do is just decorate the class. So when I do the new symbol, I use the decorated class. So this is object-oriented programming. I don't like style sheets
because they don't allow me the necessary flexibility that I want. With this, I can take, again, in the style of the plugins, I can take an existing symbol and add more functionality on top of it. In this case, this changes the functionality of how you do color interpolation between vertices or between pixels.
Next is the Edgify, which I'm going to show with this one. This is mostly a debug symbol. So you've seen already the one where I hover over the big marker here and it turns into a hand. So this actually shows you the boundary between the pixels that have the normal cursor
and the pixels that have the hand cursor. So with this, I can dig down into the internal structure. I can show the internal data for the symbol in a different way to make it obvious to me when I'm debugging. This is mostly a debug, but this shows the capability of doing something different with the internal data.
Also, this is also a basic edge detection algorithm. If the symbol on the pixel next to me is different, then I render black. That's the algorithm for this. But this has helped me locate some errors with the extent of sub-symbols when I'm doing weird extrusions of vertices.
Next is the text label. Where's the text label? So text labels in Glio were already there. The interesting thing now is that they are in a web worker. One of the problems with Glio is that everything runs in the main thread. So vector telecompression runs in the main thread,
which is a performance blocker. It's a bottleneck right now. One of the things I was able to easily put into a different web worker, into a different thread, is text rendering. Because text, depending on the browser's 2D rendering capabilities to render it, text is hard.
And if you are going to draw a thousand labels for text, it takes time. It would take a lot of time in the main thread if I would not be doing this. This is mostly internal if you go to sources and text worker. So this is the new functionality. This functionality that runs in this different worker instead of the main thread.
So internally, it speeds things up. I was also able to work in custom typefaces. Because this is rendered on the browsers 2D rendering engine for Canvas, you cannot load these typefaces with CSS. You have to specifically load this
with some Glio functionality here, which is asynchronous. And since it's asynchronous, you have to wait for it and do it. But it works, and it works quite reliably. So I'm happy about it. Next. Is. Screen Edgify. I like this one, because this is the one I start
showing how this plugin-like thing work. And you will say, hey, you are just doing a decorator. You're decorating the sprites, the little markers. And you're creating three of them, and there's nothing special about them, right? Well, you're wrong, because they stick to the edge.
The behavior is different. It's not a graphical change in behavior. It's a change on how the coordinates are rendered on the screen. If the coordinate goes out of the minus one, plus one edges of the WebGL rendering thing, I snap the thing, and you can see them all the time.
And you can apply this to pretty much any symbol you like, because this is a decorator. This is not a style sheet thing. In the same thing that I can do, I can do this with circles. Like, hey, we'll do this with circles. Or with text labels.
Text labels are going to be nicer. I have time for this, right?
It's the same, right? Oh my God, it sticks to the edge. So you can do this with any point symbol. It will stick to the edge of the screen when you scroll down.
Next is the off-screen indicator. So I am creating three circles and three off-screen indicators here. And they are paired in the coordinates. And what this does is when some of them go out of the screen, you have this fancy little arrow. And it will actually calculate the angle
to the point, to the geometry of the screen, et cetera, et cetera, et cetera. So this is an application of a previous, or the code for the previous one, plus some new fanciness to calculate the angles. This is something that I want to see on maps with a very small number of points on them. It's really useful when you're going to a venue and there's some point outside of town,
which is the freaking airport every time. I want a little arrow pointing to it. And when I go to the airport, I want four little arrows pointing to the main places in the main city. So I want to see this in use. Next is one of the boring ones that we all need at some point or another in life, which is a geotiff loader. I mean, it's a geotiff loader.
It loads geotiffs. That's it, if it works, which is not working. So, I'm so glad I had the plan B, which is this. It looks like this. You just send the URL to the geotiff and it loads the geotiff in black and white or whatever.
I need to work a little bit more on making it render to a scalar field and then making some colors on it, et cetera, et cetera. But it's nice to be able to do this in some non-webmercator projection. This handles non-webmercator. If you look closely at the edges of the geotiff,
you will see that they are not square. So there is a reproduction ongoing underneath here, which is why I'm going to talk next about, no, I was going to talk about equal earth, not this one, equal earth. So I can, when I define the map here, I can define it with, oh yes, I know this.
I know this back. Just refresh. So I go to equal earth. And when I define the map, I say, hey, the CRS of this map is going to be EPSG8857, which is equal earth. And that happens. And the rest of it is just a raster,
the blue marble rectangular raster. And I'm adding some geojson here. The geojson is in that long in 4326 and it's shown in equal earth and it just works transparently. And since I did that, I thought it was a good idea to do automatic projection detection. This is Conical Lambert for Europe.
And this has been guessed, the data, the parameters for this prediction are being guessed from the name of the CRS. This makes a request to CRSexplorer.project or that Javier can tell you about more later during the coffee breaks. And it works. I mean, fetches the projection data
and re-projects everything. Then, chains, chains. Lines are hard. If you've paid attention to the talk, to the previous talk, line rendering is hard. And because it's hard, I made the lazy way of rendering lines, which is I'm going to render separate segments.
And I don't care if it looks a bit weird on the joints. I don't have to think about the joints and how they extrude together and everything. I will make them slightly transparent on the ends in order to minimize the visual effect impact of this. But this is a lazy way of doing things. Why do I want to do the lazy way of doing things?
Because the normal way of doing things creates a lot of artifacts. This is a heat chain and a heat stroke on the top and a heat chain on the bottom. And this is, if you look at the code here, I'm just generating a sequence of points and I'm using the same points for both geometries
of both symbols up and down. The one on the top, which is the normal way of doing strokes, it creates this absolutely horrible, jaggy artifacts, which are really, really, really hard to get rid of when you're doing very close by points in a line string. If you look straight down to the same section of line,
this is the same section of line with heat strokes. It looks a tiny bit worse on some of the joints, but overall it gets rid of those artifacts. So that's why I want to do this lazy way of rendering things. Then hue shiftify. I am bad on time right now.
I'm really bad on time. It shifts the hue. It turns the thing to, does it load? Yes. You put a number here, which started, it's zero. So it looks like a normal topographical map. You put a different number and it shifts the hue in the HSL color ramp.
That's it. Not very useful, but it has to be done. It's one of the possibilities of this, and you can apply it, of course, to more different things. The same thing with the delune mesh. It's the same thing. I'm shifting the hue of the points that are part of the mesh. Factor scallify.
No, not trajectoryify, factor scallify. Where's factor scallify? Here. This is one of these that you need for actual cartography. Do you want the same symbol to be very small when you are zoomed out? And as you zoom in, it turns bigger and bigger and bigger and bigger. Of course, this is exaggerated, but this is something that cartographers want.
So it has to be done. Then circle gouge. Boring one. I'm out of time. I'm not going to say a lot about it. It's a percentage. You'd like to click it like SQL with a percentage. That's it. Protomaps loader.
Protomaps. Brandon is not here? Oh, yeah. So I'm not gonna talk about protomaps. If you want to know about protomaps, ask Brandon. He's the man about it. So you put a protomaps file on this, and you have a symbolizer function, and it symbolizes things.
Because I like protomaps a lot, and Brandon has been fighting with road in the highway exchanges. Come on. Are you loading? Tell me you're loading. Is this failing again? Don't fail on me again, please. I'm on a live demo.
Now it works. So this just renders coastlines and roads, and I'm using my road symbolizer, my road stroke symbol. And the highway interchanges, even though I have bumped it out quite a bit, they look kind of nice for a one-pass render
of complex interchanges, with the joins and whatnot. If you see this example, the symbolizer function is a bit more complicated, and it has this set index for all the segments of roads, so you can change it and play it at home, because I'm kind of out on time. Then the debug dump. One of my problems is knowing what the hell is going on under the hood here.
So I can click on one of this, because everything's interactive, right? And I can see the wireframe representation of this line for debugging purposes. And every time I do this in this particular code, I am getting some information, and I need to uncomment something here.
Here, I need to uncomment this. I can also dump all the vertex data for the WebGL data for that symbol, which is really nice when you're fighting some very weird cases that might appear somewhere in, where's Manhattan? Are you loading? Come on, load for me.
Load for me. Are you loading this one? That's bad, and it's your fault, Brandon. So I can click on it. I can click on it. I can click on this artifact, and I can see where the bad geometry comes from. And I can see all the internal,
this starts from 17. So I can see all the internal vertex data for that specific symbol, which for debugging purposes, it saves my life, and it saves hours of my sanity, and I love it. So last, I'm going to talk about Monte,
I know I'm out of time by one minute. Just bear with me for a second. Monte Carlo Phi. This is based on the Monte Carlo method. I just get one symbol, which is a sprite of a person, and I apply the Monte Carlo Phi decorator, and I turn this into a polygon symbolizer. So this is a polygon geometry,
and I'm doing 250 people, which is really nice. I did this on Monday on the hotel because I was annoyed by the official corporate map for the attendance countries, and this is the kind of, you know, spied driven development. I want to make it better than you,
so I made this on the hotel room two days ago. And then, if you follow social networking, and you follow Tony Scardi, he asked me, okay, but can't you make them dance? And I said, okay, hold my beer.
So I think that's all I have.
Thank you for listening to me. And thank you to all the people who came from all these countries and are dancing at the rhythm. Thank you, Juan.
We have time for questions. How many people are represented on this map? All of us. Yeah, one person to one person. This is a one person to one person ratio.
I don't know what's going on in the Netherlands. There's lots of people from the Netherlands for no reason. You mentioned that it's not really ready for vector tiles, why is that?
I am not aiming for vector tile performance. I am aiming for flexibility. That's the thing. I could, right now, I could take this symbol, go into some protobuf, some protomaps vector tiles, and apply this, hell, I'm gonna do it. I'm gonna do it. I'm gonna take this.
Let me copy paste the code real quick. I'm aiming for flexibility. That's my thing. I want flexible, fast development on the JavaScript side of things.
I don't want to go crazy with ultra optimizing the WebGL things and byte packing stuff. I want to be flexible. So I can go into the Monte Carlo file and get this thing.
This is the problem with live demos on the questions part of the talk. And then I want 50.
Now I have people all over the seas. Now I have people around with two minutes of development. I'm changing the symbolizer for the polygons of vertex tiles all over. And I'm applying a custom thing.
So this is what I am aiming for. I'm aiming for flexibility, not full on performance. That's my goal. Okay, I think that's all the time we have. Thank you, Juan. You're gonna find them everywhere. Thank you. Thank you. Thank you. Thank you.