ol3

under the hood

http://ol3js.org/

Objectives

  • Explain design decisions
  • Understand ol3 architecture
  • Fast-start ol3 development

ol3 Requirements

  • All of OpenLayers 2's functionality
  • All map projections
  • All widely-used browsers
  • Huge range of raster and vector data sources
  • 2D, tilted 2D, 3D and globe views
  • Mobile, tablet, desktop and server
  • Components usable by other projects
  • Future unknown functionality
  • Small library size
  • "Simple" API

OpenLayers 3 must be everything to everybody

Nobody individual will use more
than 15% of ol3's functionality

...except every individual
uses a different 15%

Tackling complexity

  • Small, de-coupled, components
  • Well-defined responsibilities
  • Unidirectional dependencies
  • Generic internal representations
  • Best available JavaScript tooling

Tooling

  • Closure Compiler in advanced mode
  • Closure Linter
  • PhantomJS
  • Mocha + expect.js
  • Travis CI
  • ...all turned up to 11!

Closure Compiler and Closure Library

You don't have to use it in your application!

Closure Compiler

  • Minification twice as good as UglifyJS (size)
  • 25% speed boost (speed)
  • Produces "perfect" custom builds
  • Steep (but worthwhile) learning curve
  • JS for engineers vs. JS for computers

ol3 full build sizes

Raw JavaScript ~1Mb + Closure library
Whitespace only, gzip'd ~290Kb
Simple optimizations, gzip'd ~180Kb
Advanced optimizations, gzip'd ~90Kb
Application + ol3, gzip'd ~32Kb

ol.Map

1 × ol.layer.LayerGroup
1 × ol.View
N × ol.control
N × ol.interaction
1 × ol.renderer

ol.renderer

  • DOM, Canvas and WebGL back-ends (example)
  • requestAnimationFrame
  • 60 fps performance = 16.67ms/frame
  • renderFrame / ol.FrameState
  • Before render functions to modify state
  • Post-render functions for low-priority/expensive operations
  • Efficiency considerations (view hints, animating state, GC)

ol.animation


function fly(map, frameState) {
  if (frameState.time < start) {
    // before animation starts
    // ...
    return true;
  } else if (frameState.time < start + duration) {
    // animation running
    var delta = easing((frameState.time - start) / duration);
    var deltaResolution = resolution - frameState.view2DState.resolution;
    frameState.animate = true;
    frameState.view2DState.resolution += delta * deltaResolution;
    frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
    return true;
  } else {
    // animation finished
    return false;
  }
};
          
Animation example · Composable example

Sources, layers, and renderers

Source Source class Layer Renderer
OSM, WMTS, XYZ, TileWMS ol.source.Tile ol.layer.Tile Canvas, WebGL, DOM
ImageWMS, ImageStatic ol.source.Image ol.layer.Image Canvas, WebGL, DOM
GeoJSON, GML, KML ol.source.Vector ol.layer.Vector Canvas, WebGL*, DOM

Sources vs. layers

  • Sources operate on data
  • Layers describe how a source is presented
  • Source params: URL, API key, WMS params, ...
  • Layer params: visible, opacity, ...
  • Sources can have multiple "users", or used in isolation
  • Sources provide a uniform interface

Tile sources

  • Metadata request
  • Tile arrangement
  • Tile sizes
  • Tile resolutions
  • Tile coordinate origin
  • Tile URL generation
  • Date line wrap
  • Extra parameters (e.g. WMTS dimensions)
  • Data extent
  • Attributions
  • Load balancing

ol.source.Tile

Tile grid How tiles are laid out
Tile URL function Converts tile coordinates to URLs
Tile load function For advanced use

ol.source.Tile


var options = ol.source.WMTS.optionsFromCapabilities(
    capabilities, 'fmzk');

var map = new ol.Map({
  layers: [
    new ol.layer.Tile({
      source: new ol.source.WMTS(options)
    }
  ]
  // ...
});
          
Example

ol.Object and ol.Collection

  • Events when properties change
  • Events when elements are added or removed
  • Property binding allows property values to be shared between objects

ol.Object


var map = new ol.Map({
  view: new ol.View2D({
    center: [0, 0],
    zoom: 2
  })
  // ...
});

var view = map.getView();

var rotationSlider = document.getElementById('rotation');
var rotation = new ol.dom.Input(rotationSlider);
rotation.bindTo('valueAsNumber', view, 'rotation');
          
Bind input example · Side-by-side example

ol.layer.LayerGroup

  • Layers are a tree rather than a flat list
  • Multiple layers can be treated as a single layer

Layer group example

Next steps

  • WebGL-compatible internal vector API
  • Performance improvements
  • Vector editing
  • Build system improvements

Long term

  • More flexible composition
  • Cesium / OpenWebGlobe integration
  • Flat Earth 3D

Play

ol3js.org

Get involved

github.com/openlayers/ol3

wiki/Developer-Guide