OpenLayers 3: Under The Hood
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 95 | |
Author | ||
License | CC Attribution - ShareAlike 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 and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/15569 (DOI) | |
Publisher | ||
Release Date | ||
Language | ||
Production Place | Nottingham |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
FOSS4G Nottingham 201369 / 95
17
25
29
31
32
34
48
50
56
58
68
69
70
82
89
91
00:00
Decision theoryArchitectureFunction (mathematics)Level (video gaming)Axonometric projectionWeb browserRange (statistics)Vector spaceRaster graphicsView (database)Graphics tabletMobile WebServer (computing)UsabilityConnectivity (graph theory)Library (computing)Graph (mathematics)EmulationKolmogorov complexityAlgebraic closureAsynchronous Transfer ModeCompilerPerfect graphMetropolitan area networkCurveComputerLocal GroupControl flowMenu (computing)Wide area networkSummierbarkeitConditional-access moduleSpecial unitary groupUniform resource nameAsynchronous Transfer ModeSoftware developerAlgebraic closureFraction (mathematics)Representation (politics)Graph (mathematics)CompilerQuicksortParsingCodeSoftware frameworkLibrary (computing)BitCartesian coordinate systemSound effectWeb browserVector spaceCore dumpConnectivity (graph theory)BuildingObject (grammar)Perfect graphCurveData structureSoftware testingFunctional (mathematics)Complex (psychology)VolumenvisualisierungElement (mathematics)Expected valueFunction (mathematics)Front and back endsMaxima and minimaProduct (business)View (database)Projective planeDecision theoryDifferent (Kate Ryan album)Variable (mathematics)Level (video gaming)Entire functionType theoryRaw image formatMultiplication signContinuous integrationGaussian eliminationComputabilityBranch (computer science)Goodness of fitBand matrixMathematical optimizationOpen sourceINTEGRALMappingPoisson-KlammerReal numberOpen setSpacetimeCellular automatonClient (computing)Process (computing)Scripting languageVirtual machineFreewareCAN busCentralizer and normalizerAbsolute valueSet (mathematics)ForestIdentity managementMatching (graph theory)Video gameMoment (mathematics)Dependent and independent variablesMereologyInsertion lossAdaptive behaviorStaff (military)Web 2.0NumberRight angleCovering spaceArchaeological field surveySystem administratorComputer animation
08:35
First-person shooterFrame problemState of matterFunction (mathematics)View (database)Operations researchEmulationMetropolitan area networkWide area networkPhysical lawWechselseitige InformationExponential functionValue-added networkCAN busMenu (computing)ArmInfinityMUDUniform resource nameExecution unitMach's principleDirected graphVector spaceComputer-generated imageryFluid staticsSequenceKey (cryptography)Uniform resource locatorInterface (computing)Point (geometry)Multiplication signComplex (psychology)AreaVideo gameQuicksortMusical ensembleRotationGraph (mathematics)CodeProcess (computing)Frame problemState of matterInsertion lossMetropolitan area networkTesselationImage resolutionFlow separationMatching (graph theory)Level (video gaming)Lattice (order)Computer fileCASE <Informatik>Operator (mathematics)Cartesian coordinate systemFunction (mathematics)Degree (graph theory)Cycle (graph theory)Basis (linear algebra)WritingFront and back endsMobile WebDifferent (Kate Ryan album)Interrupt <Informatik>Presentation of a groupWeb 2.0Water vaporView (database)Structural loadPower (physics)Software frameworkComputer-generated imagerySource codeBit rateInteractive televisionPrime idealGame theoryWave packetType theorySocial classParameter (computer programming)SpeicherbereinigungCalculationZoom lensDemo (music)Drop (liquid)Keyboard shortcutWeb browserBefehlsprozessorWeb applicationAsynchronous Transfer ModeDirected graphHelmholtz decompositionBitLine (geometry)Vector spaceConfiguration spaceConnectivity (graph theory)Representation (politics)Electronic mailing listObject (grammar)Computer animation
14:49
Image resolutionCoordinate systemUniform resource locatorLine (geometry)Dimensional analysisParameter (computer programming)LastteilungFunction (mathematics)Structural loadDirected graphSummierbarkeitGamma functionValue-added networkMetropolitan area networkMaxima and minimaWide area networkEvent horizonElement (mathematics)Category of beingObject (grammar)outputView (database)Pointer (computer programming)Interior (topology)IcosahedronArmFunction (mathematics)Direction (geometry)Software testingSlide ruleTesselationImage resolutionLevel (video gaming)QuicksortElement (mathematics)Object (grammar)Matching (graph theory)Point (geometry)Interpreter (computing)Graph (mathematics)Structural loadView (database)MathematicsMereologyParameter (computer programming)outputPhysical systemPower (physics)Total S.A.Multiplication signCASE <Informatik>Phase transitionWeb browserEvent horizonPrisoner's dilemmaPhysical lawMassOpen setMultiplicationBounded variationFront and back endsPatch (Unix)Negative numberCartesian coordinate systemFile systemCodeWeb pageComplex (psychology)Roundness (object)Process (computing)MappingMetropolitan area networkPosition operatorComputer fileRotationCategory of beingElectronic mailing listWeb 2.0Client (computing)AbstractionServer (computing)Computer-generated imageryBitHookingType theoryKeyboard shortcutImplementationCoordinate systemUniform resource locatorDirected graphMetadataComputer architectureDemo (music)Different (Kate Ryan album)Greatest elementZoom lensDebuggerComputer animation
21:03
Special unitary groupMetropolitan area networkSummierbarkeitValue-added networkGame theorySynchronizationCodeDifferent (Kate Ryan album)MappingView (database)Level (video gaming)Open setCartesian coordinate systemLine (geometry)Element (mathematics)Presentation of a groupMetropolitan area networkMatching (graph theory)ResultantComputer animation
21:56
Electronic mailing listNetwork topologyLocal GroupRule of inferenceMoving averageSimulationMagnetic stripe cardVector spaceBuildingPhysical systemEmulationDisintegrationCurvatureTerm (mathematics)3 (number)Electronic program guideSoftware developerWikiCartesian coordinate systemPhysical systemRaster graphicsSoftware developerVector spaceMultiplicationTesselationDemo (music)NumberKeyboard shortcutElectric generatorPoint (geometry)Power (physics)SurfaceLink (knot theory)Functional (mathematics)Source codeGroup actionLebesgue integrationLevel (video gaming)Connectivity (graph theory)Right angleDemosceneElectronic mailing listGeometryDifferent (Kate Ryan album)Open sourceNetwork topologyComputer-generated imageryElectronic program guideGraph coloringBoundary value problemType theoryFlow separationHeat transferPixelOpen setTerm (mathematics)Spectrum (functional analysis)Set (mathematics)Video gameInsertion lossStaff (military)Computer configurationMatching (graph theory)Mixed realityQuicksortGraph (mathematics)INTEGRALShooting methodWeb 2.0Student's t-testComputer animation
Transcript: English(auto-generated)
00:00
Thank you very much to Tim there. Fantastic demonstration of what OpenLayers 3 is capable of right now. The goal of this talk is to actually, now that Eric's provided the justification and the framework for OpenLayers 3, Tim's showing what it can do. This is going to look at a bit more detail of what's going on actually in the library itself and how we achieve some of these effects. And this is mainly targeted at people who were
00:23
interested in writing fairly advanced applications of OpenLayers 3. So yeah, we'll peek inside. So we'll talk about some of the, justify some of the design decisions we've made, give you a little view of some of the OpenLayers 3 architecture. There's quite a lot there.
00:41
We only have 20 minutes, so there's only a couple of things we're going to look at. And finally, trying to motivate you to have a sort of fast start to give you that initial step to dive into the OpenLayers 3 code, either to use new applications or to start contributing to the project, or both. Requirements for OpenLayers 3, it's a very ambitious project, as Eric described. There's a huge amount of stuff that people want.
01:06
We want to build on all the success and functionality of OpenLayers 2, but we also want to bring in new technologies, WebGL, Canvas. We want to support 3D in there. We want to integrate with other geospatial applications like Cesium and OpenWebGlobe. We want our
01:23
stuff to be reusable. We want our parsers to be reusable. It's just a huge amount there. I mean, it's basically OpenLayers 3 just has to be everything to everybody. That said, it makes for a big, very big library if you do this. And it was one of the criticisms of OpenLayers 2 is you end up with a lot of code. And indeed, no one,
01:43
any individual is going to use anything more than a small fraction of what OpenLayers 3 is capable of. Well, the problem, of course, comes that everybody uses a different fraction. So how do we cope? We have these very complex requirements, but still we need to deliver very specific builds for people for their individual applications.
02:04
So what are we doing to tackle this complexity of the problem? We're trying to decompose the elements of the geospatial library into core components that can be well-separated and can be composed together to build the applications that you need. And we'll look at concrete examples of this, like the difference between sources and layers. All
02:25
of these have well-defined responsibilities, so you can mix and match them and put them together in interesting ways. And we'll see a couple of nice examples of that. Unidirectional dependencies. This means we try to make a layered approach so that each layer is built on the layer before. There are no dependencies between layers.
02:46
Generic internal representations. That's what allows us to provide all this functionality across so many different backends. And then on the actual, that's our design approach. And then behind this, we're using the best available JavaScript tooling that we can
03:00
get our hands on. The tooling that is the closure compiler. It's a product from open source project from Google. I'm sure many of you know about it. It does explain why we use that in a sec. We have a linter. We're running in absolute strict mode. We have automatic tests running in Phantom JS. We do full integration testing. We have
03:25
behavior-driven development with expect.js, and we have continuous integration. Every pull request has to pass all these integration tests before it can be merged, and this runs automatically. So we've put in all the tools that we can to help us build a really
03:43
high quality library. We use them absolutely to the maximum. The closure compiler and closure library. This is contentious because when you write code for the closure compiler, it's not quite like normal JavaScript. And I want
04:01
to make it very clear that even though we use it, you don't have to use it in your application. So you will just the same way as you get a build of OpenLayers 2 or a build of Leaflet, which is the one we minified, you can also just get a build of OpenLayers 3 that is minified and specific to your needs. You don't need to, you
04:20
didn't, if you don't want to use the closure compiler, you don't have to. That said, there are some good reasons why you might use it. Why do we use it? It has fantastic code minification. Probably the second best minifier is uglify.js, and it's about, produces code just half the size of that. That directly
04:40
translates into faster loading, lower bandwidth costs for you. The code produced by the compiler is faster than the normal JavaScript that you write. There's a couple of reasons for this. One is the compiler can do lots of optimisations on your code and eliminate branches which are not taken, functions which are not called. But also
05:03
the way that you write code for the closure compiler means that you have to be very strict with your, the types of your objects or your types of your variables. And this sort of code then runs very, very well on the JavaScript engines, V8, Spider Monkey and so on that we have. So this directly translates into a real
05:25
speed advantage. And it produces also perfect custom builds. You can build something in OpenLayers 3 with just the code you need. It is a steep learning curve with it. You only need to really worry about that if you're going to be contributing to OL3.
05:41
I'll just make a brief comment on this and move on with this stuff. But what makes the sits in a very strange place. We need to write it for humans. We want nice APIs. We want code that's easy to read. Lots of big comments, small structure and so on. On the other side, we want code when we deliver it to the browser. We want code which the computer likes, which is small, compact, no extra stuff.
06:06
The closure compiler allows us to separate these two designs. So we write good JavaScript for people in our application and the closure compiler generates good JavaScript, high-performance JavaScript to run your application in your user's browser. This is the current size of the library.
06:24
In raw JavaScript, I've just checked, it's gone over a megabyte and that's excluding the closure library. By the time you strip out the white spaces and comments, you're down to 300K unzipped, this is. And you can see the full library currently fully zipped at about 90 kilobytes. And that's everything in there.
06:41
All the functionality, all the different formats, parsers, backends and so on. With the closure compiler, this is the reason why you might want to do it if you're in, you really care about speed and size. If you build your application level three, you can get your entire application and open layers three together down to about 32K. So it gets really, really small, despite
07:03
having this huge amount of functionality. So now we're a bit more into the architecture. Eric's already covered this, so Tim's covered this as well. So I'm going to look at stuff that they haven't talked about in their talk and give you a couple of examples. So the rendering, we want to have three different
07:24
backends for it. We want a DOM renderer for all the browsers, we want Canvas, which is very widely supported at the moment, has very good performance. And for future, we want WebGL, which has a lot of interesting ideas, the possibilities when it comes to handling large amounts of vector data, and it also is, of course, the only way in
07:42
which we'll be able to do 3D. At the moment, we have these three renders implemented. They produce almost pixel perfect duplications. These three, they obviously look the same, that's the way it should be, but these three maps here, they've got three different backends, and you
08:01
see that the only one I click on is actually gets the animated zoom, but they're producing the same thing. What this means is that you, as an application developer user of OpenLayers 3, you don't have to care about what backend you're using, and you will just get the OpenLayers 3 will pick this for you. At the
08:22
moment, I'll just put a little bracket there. There are some things that only work in some of the renderers, but we're working on that, and the goal is compatibility across the three backends as far as possible, so you don't have to care about it. The way that you do animations and rendering is very
08:44
different between these backends. What this means is that the way that OpenLayers 3 works is actually closer to a game engine running at 60 frames a second than it is to
09:01
a classic DOM based JavaScript web app. So if you look under the hood, you'll see quite a lot of things that look a little bit strange there. I'll give you, while I'm going to the point, I'll give you a quick example of the before render functions, which is how we do our animation. I will say as well, as now as we're trying to run at 60 frames a second to get that smooth animation, that means we
09:23
have to care a lot about efficiency. This means that we have a few shortcuts in there. We call them view hints that allow us, for example, when we're animating to do a zoom, that we don't keep redrawing for every single frame, that we reuse an existing image and stretch it as we zoom in. Animating state is very important for mobile browsers
09:44
that we don't just keep turning at 60 frames a second because that will sit there and use your battery up. So we have this low power mode that once the view is settled, then it doesn't consume any more CPU. If you want smooth animation, you have to care about garbage
10:01
collection in JavaScript. JavaScript's got to stop the world garbage collector. So if you generate too much garbage, you'll get these garbage collection interruptions and you'll get frame drops and it'll look as, come across as juddery animation. So all of these things are going in on under the hood.
10:23
Animation, this is we're doing our animations, we redraw each frame. This is an example of a so-called pre-render function, which allows us to actually modify what's going to be drawn. So what this function here is called before we actually draw, it receives the
10:43
map and a frame state, which is an object which contains a full list of layers, views, everything that we're going to actually draw in this frame. And we get the opportunity to modify it. So while the animation is running, we've got, we'll have an end time, but we can actually modify, particularly with this line
11:04
here, for example, we can actually modify the resolution at which the map will be drawn immediately before the frame is done. And we can calculate that on the exact time, here we're doing exact calculation of when we're drawing the frame
11:21
compared to where we are in animation. So we end up with smooth animation, even if we drop, we end up dropping frames or whatever, even if the time is not regular. To show what this looks like, you've seen the demos from Tim and Eric, that these, all of
11:43
these sort of animations are done with this sort of thing. What's kind of interesting is that when you have these multiple animations is you can compose them. So if I do a spin to roam here, this is both a pan animation, changing from Istanbul to Rome, and
12:03
the rotation. If you do a fly to burn, we're doing both a pan and a zoom out and a zoom in, and you combine them all together, and you get a pan, a zoom out, and a rotation. And they're all independent, they all independently modify the frame state. The way that actually looks, this is the actual code
12:22
from the example. Sorry, it's quite small there, and I can't pan down anymore. But basically, we create three different animations, pan, bounce, that fly out and rotate, and then, sorry, it's really small, but this file function, this poor for render says on our map, do these things for me. What this means for you is if you want to start providing
12:40
really interesting, interactive ways of interacting with the map, you want to do cool fly-throughs or follow tours or tell stories by moving the view around, then that framework is there for you to do this. This is an example now of a decomposition of
13:01
what's going on, sources, layers, and renderers. Tim already talked about difference between sources and layers. I'm going to give you a couple of examples here and justify it in the case, give a concrete example in the case of tiles. So sources, the example, we have many different data sources we have to read. However, we've grouped them into three main classes,
13:21
tiles, our obvious image, which is a single image rather than individual tiles, and vectors, which is, of course, vector data. Separation on top of that is the layer, and we'll look at the details, difference between sources and layers in a sec. And then behind that, we have the different renderers, the different rendering backends, and there's a specialism for each type of this sort of class of layer. What this
13:44
means is that as we add more and more data sources here, they add more formats, more different tile providers, and so on, we actually get, as long as they fit within these existing classes and these existing layers, so we don't have to do any more work on the renderers.
14:01
So we can increase the amount of data sources we support without increasing the complexity of the rest of the program. Equally, if we want, we could even imagine adding a new renderer, maybe targeting SVG, we can do that at that end, and then we don't have to modify our sources or layers to do that. An example
14:20
now, so here's differences between sources and layers. So sources basically operate on data where the layers describe how it's presented. Your parameters are source or configure that source, there might be an API key, various parameters and so on, whereas the layer parameters are more to do with presentation. Sources are, as I said, one of the goals is that OpenLayers 3 should be
14:42
usable, the components should be reusable in other projects, and sources are that low-level representation of tiles stored on a server somewhere that you can reuse elsewhere. This, if you're writing, if you just have a single map in your page, then there's probably not so much interest
15:01
for you, but when we start integrating with other applications, Cesium, Open Web Globe, the ability to expose our tiles only to them without encumbering them with all our rendering architecture is a very powerful abstraction.
15:21
For example, with tile sources, these things just vary massively. There's a huge amount, I mean, there's a long list there you can read, some tile JSON or Bing, you need to make some metadata requests first, or you might want to pass some WMTS capabilities, how the tiles are arranged, where the coordinate system is, what direction the tile
15:42
coordinates increase, how you cope with dateline wraps, all this sort of stuff, just massive amount of variation. What we do in a, our OpenLayers 3 tile source just has three properties. It takes all that complexity and it abstracts it
16:01
behind three properties. We have a tile grid, which tells us how the tiles are laid out. This is interesting properties here. This is one of the examples. The black tiles here are actually canvas tiles generated in the browser on demand, so they're not loaded
16:20
from a server. What's kind of interesting here is that, I'll zoom out a bit, you'll notice that many of those tile coordinates actually have negative values in them. And the reason is, in OpenLayers 3, one of the simplifications we've made is that the origin of tile coordinates is always in the bottom
16:40
left-hand corner. And when we have something like OpenStreetMap or Google, which starts in the top left corner, we actually use negative numbers. So we can just treat that as a simple, everything starts in the bottom left corner. And that massively simplifies the implementation of the rest of the code. I'll zoom out a little bit further. Actually, you can see it here on this one. We have
17:01
multiple worlds here. We're doing Dateline Wrap. And you'll see that the tile coordinate of this part of the U.S. here is different from the tile coordinate. So it has the same image tile behind it, but has a different tile coordinate. And this simplification of saying the tile grid is infinite starting from the bottom left makes things a lot
17:21
easier. The tile URL function, it takes these coordinates and converts them into URLs. That's a way to hook in all your WMTS parameters, that sort of stuff. To observe here that these two U.S. tiles, this one and this one, they have different coordinates but the same image URL
17:41
behind them. So here we're doing Dateline Wrap by being clever with our tile URL function. The final one, a tile load function. This is an extra hook you can put in to sort of fiddle with the tile or modify the tile loading process. There's an application if you want
18:01
to store your tiles in PouchDB, for example, or you want to use the file system API, if you want to use open layers as a front end to an application that uses Cordova or Node WebKit where you have a slight different non-URL access to tiles. That tile load function allows you to hook that
18:20
in. Fred Juno, a very nice demo, where he uses this tile load function to actually modify the tiles here. These are open street map tiles. The images are downloaded and then they are transformed using a bit of Canvas magic on the client.
18:41
And so this abstraction here, these three elements, give us all this power and all this flexibility. Of course, for application errors, you don't have to worry about it. We provide a whole load of pre-configured sources. You want to WMTS, you
19:00
can just provide the URL to your capabilities and off it goes. I'm running out of time, so I'm going to be very quick now. Total change of subjects, URL object and URL dot collection. This is a sort of active object type implementation. It is extremely heavily inspired by MVC
19:21
object in Google Maps, if you use that. And I'll show you, this view makes many tricky things very easy to implement. What they provide, they provide a consistent interface for events. You'll know what the event is, you'll get when a property changes. Collections support events when things are added or removed. And what's
19:41
particularly interesting, I'll show you a demo of now, is property binding, which allows two different objects to share the same value. So here's an example of using an object, or create a map, the first part, we'll get that map's view. And then in our document, this is the demonstration that Tim showed earlier, that little slider
20:00
that moved and stopped as he rotated the map. So we'll get that document, we'll wrap it in this little bit of URL dot DOM input magic to get our slider. And now, this bind to magic here, says the value of this slider should be the view's rotation. And I'll show you the full demo that you
20:21
can play with here. But this is, here's our map, here's our rotation slider, and as I move the slider, the map rotates, and equally, as I move, as I rotate the map, the slider moves. A lot of things in OpenLayers 3 are these magic
20:41
whole object properties. All your layers are, so we can change the opacity of the layer here. On WebGL, we can change colors, toggle visibility, and so on. Resolution here is bound to a view parameter, the view, resolution of view. So as I zoom in, that changes and
21:00
zoom out. And in fact, you can take this to fairly extreme examples. In the way that we do this three side-by-side example I showed at the start of the presentation, is the actual views of these three maps are bound together. So as I move one, the other two move with it because they're showing the same view, the approach.
21:20
This gets really easy, this makes it very easy to make rich applications that compose many different elements together. For example, you've just seen an opacity slider done very easily. Here we have multiple views. If you want side-by-side views of different data, you can keep them perfectly in sync by binding the views. If you want a 3D view in cesium or
21:42
open WebGLOBE next to a 2D map in OpenLayers 3, by binding the views, you get that behavior immediately and with very few lines of code. The final demo I'm going to talk about is a work done by
22:00
a guy called Bruno Binet at Camp2Camp. Classically, layers, we have a list of layers and they're drawn. In OpenLayers 3, we actually have a tree of layers. This has a number of interesting components. Particularly, it allows you to group data from multiple sources and combine them and treat them as a single layer. If you
22:21
want an application where you have used tiles when you're very zoomed out, but then generate WMS images as you zoom in, these layer groups allow you to do that and allow you to treat that as a single actual layer. So Bruno put together this nice demo here. Sorry it's
22:41
so small. This map has, in fact, three layers and I'll open it all up so you can see. So we have three actual layers of which two are grouped together and I can operate on those two together. So here, the colors and the individual
23:00
layers first. We've got country boundaries and we have a nice little raster layer. These things here, we group them together and we can toggle their visibility together. We can toggle their opacity together. I think Hue should work as well. Yes, and so
23:20
on. So this means that what you can do now is you can compose data from multiple different sources. You can have a raster layer which has a WFS type vector layer on top of it and you can treat them as the same thing and put them all together.
23:42
So you can see this is all demonstrations of how we've separated things into small components and then by having these as separate components, there's then lots of rich ways in which you can bind them together to make really rich, interesting, and powerful applications. The next steps, what we're working on right now is we
24:02
want to get vector that's working with WebGL. That's our, CounterCamp's our immediate priority. We've got some performance improvements to do in the way that we, sometimes we're composing few to many transparent pixels, but that's going to be behind the scenes to anyone. This is not going to
24:20
affect the API at all. Boundless Geo are doing some great work on vector editing that Tim showed off earlier. And behind the scenes, I mean this is a big, we have a lot of tools in there to show we used all the tools turned up to 11. The build system is pretty complicated. We need to simplify it to make it more accessible. In the very long term, we want to more flexible
24:41
composition. This is, I'll go into the details, but we want to make it easier to mix different data, different renderers behind together. For example, you might have a canvas raster layer with a WebGL vector layer for a number of points and then a canvas based vector layer on top of that. Or you might put an SVG on.
25:01
Integration with existing open source globes and flatter 3D is 3D but not on the surface of the globe and that's the year and a half or so out. But we're trying to put all the foundations in place so that this functionality can be built on top. That's
25:20
it for me. These are the links. Please do go to o3js.org and play around. All the examples that I've shown are just standard OpenLayers 3 examples. So you can look at the source code to get involved from GitHub and the developer guide on the wiki shows you how to get started. Thank you.