Skip to content
Torben Barsballe edited this page Mar 6, 2018 · 31 revisions

Description

Mapbox has recently defined an open standard for drawing vector tiles that has been picked up by not only their own software but by the OpenLayers team. Initial investigation into this standard shows that it is a "whole" map standard similar to "SLD" describing both the layers that make up the map, and the symbology used to represent them visually. All the example uses we can find online are limited to styling a single layer at a time.

Here are the features we are looking to develop (first as a community module) and then extension extension:

  • MBStyle - facade for easy access to extension functionality

  • MBStyleParser - parse provided JSON file into MBStyle object for internal use

  • MBStyle data structure - wrapping around parsed JSON file, providing utility methods for access as java objects and conversion to GeoTools data structures (literals, filters, expressions)

    • MBLayer - subclass for each type providing access to specific options
    • MBFunction - captures dynamic styling (attribute or zoom based)
    • MBFilters
  • MBStyleTransform - generate geotools style objects from the MB Style data structure

While some features (3d extrusions, camera and lighting angle) are not suitable for use by GeoTools the rest of it looks quite fun.

To faithfully reproduce these styles some additional plugins will be needed for the renderer:

  • SpriteIconFactory - icon factory configured with PNG sheet and json file documenting icon name / location / bound offsets in sprite sheet

Challenges:

  • "property and zoom function" is similar to interpolate with different ranges provided at each zoom level

    Example MapBox property and zoom function:

    {
      "circle-radius": {
        "property": "rating",
        "stops": [
    
          // zoom is 0 and "rating" is 0 -> circle radius will be 0px
          [{zoom: 0, value: 0}, 0],
    
          // zoom is 0 and "rating" is 5 -> circle radius will be 5px
          [{zoom: 0, value: 5}, 5],
    
          // zoom is 20 and "rating" is 0 -> circle radius will be 0px
          [{zoom: 20, value: 0}, 0],
    
          // zoom is 20 and "rating" is 5 -> circle radius will be 20px
          [{zoom: 20, value: 5}, 20]
    
        ]
      }
    }
    
  • best way to provide blur effect

  • rendering transformation for hue rotation

References:

JSON Library

GeoTools uses the following JSON libraries:

  • com.googlecode.json-simple:json-simple: geotools json, couchdb datastore, geojson datastore
  • com.google.code.gson:gson: mongodb datastore
  • org.restlet:org.restlet.ext.json: sfs datastore
  • org.json:json: sfs datastore
  • com.amazonaws:aws-java-sdk-core (includes its own json library): grib datastore
  • com.fasterxml.jackson.core:jackson-core: grib datastore, netcdf datastore

For context downstream GeoServer Jackson and Jettison (not recommended - project appears stuck).

Status

Choose one of:

  • Under Discussion
  • In Progress
  • Completed
  • Rejected,
  • Deferred

Voting:

  • Andrea Aime
  • Ben Caradoc-Davies
  • Christian Mueller
  • Ian Turton
  • Justin Deoliveira
  • Jody Garnett
  • Simone Giannecchini

Tasks

This section is used to make sure your proposal is complete (did you remember documentation?) and has enough paid or volunteer time lined up to be a success. Use initials to indicate volunteer, or ⚠️ where volunteer is neededs. Proposals that lack resources to be successful are unlikely to be approved.

Rough planning:

  • Focus on styling a single layer using a mapbox style

    • Requires a parser for mapbox style capable of producing the internal geotools style objects; package as a geotools community module.
    • Setup geoserver extension and integration for new style format
  • Whole map styling (optional)

    • LayerGroup defines both an order of layers, and the style associated with each layer - this information can be defined from a single mapbox style
    • (Optional) Consider offering SLD the same ability to define a LayerGroup

API Change

This is an extension and will be responsible for supporting the use of MapBox Style files.

Code example:

// similar to Ysld code example
StyledLayerDescriptor style = MapBoxStyle.parse( reader );

Internally the extension provides greater access to the parsed style:

MBStyle mbstyle = MapBoxStyleParser.parse( reader );

// pull back all layers for a provided source
List<MBLayer> layers = mbstyle.layers( "mapbox://mapbox.mapbox-streets-v6" );

// pull back selected layers for a provided source
List<MBLayer> layers = mbstyle.layers( "mapbox://mapbox.mapbox-streets-v6", "water" ); 

Which can be used to Generate Styler Layer Descriptor:

StyleLayerDescriptor sld = MBStyleTransformer.transform( layers );

Examples

Line Example

Discussion:

  • hsv definition of color using percentages
  • minzoom
  • simple format of filter definition covering both geometry type and attribute checks
  • "line-dasharray" stops - the last example appears to be zoom dependency

Example:

{
  "id": "bridge-construction",
  "type": "line",
  "metadata": {
    "mapbox:group": "1444855799204.86"
  },
  "source": "composite",
  "source-layer": "road",
  "minzoom": 14,
  "filter": [
    "all",
    ["==","$type","LineString"],
    ["all",
      ["==","class","construction"],
      ["==","structure","bridge"]
    ]
  ],
  "layout": {
    "line-join": "miter"
  },
  "paint": {
    "line-width": {
      "base": 1.5,
      "stops": [[12.5,0.5],[14,2],[18,18]]
    },
    "line-color": "hsl(230, 24%, 87%)",
    "line-opacity": {
      "base": 1,
      "stops": [[13.99,0],[14,1]]
    },
    "line-dasharray": {
      "base": 1,
      "stops": [
        [14,[0.4,0.8]],
        [15,[0.3,0.6]],
        [16,[0.2,0.3]],
        [17,[0.2,0.25]],
        [18,[0.15,0.15]]
      ]
    }
  },
  "interactive": true
}
Clone this wiki locally