Motivation:

MapLayer is doing too much

Contact:

full name

Tracker:

GEOT-3136 GEOT-3150 GEOT-3565

Tagline:

the map is back

This page represents the current plan; for discussion please check the tracker link above.

Children:

Summary

MapContext and MapLayer have really grown over time - and in some cases have diverged from their actual use.

The focus is on cleaning up MapLayer:

Over the course of the proposal MapContext and DefaultMapContext were also re-factored:

This proposal does not break any existing API; it provides a safe migration path forward (and like the Query proposal) makes use of classes directly for a simplified experience.

Status

This proposal is ready for voting; initial commit targeted for Sunday June 12th.

Voting has not started yet:

Tasks

 

no progress

(tick)

done

(error)

impeded

(warning)

lack mandate/funds/time

(question)

volunteer needed

Initial refactoring:

  1. (tick) Layer abstract class
  2. (tick) Split apart DefaultMapLayer into specific implementations
  3. (tick) Introduce DirectLayer subclass
  4. (tick) Refractor DefaultMapLayer to use a delegate Layer
  5. (tick) Refractor DefaultMapContext

Related activities:

Documentation Changes

History and Motivation

The MapContext (and MapLayer) classes are the last on Jody Garnett's top-to-bottom QA run for GeoTools 3.0. I am not quite sure of the history and motivation behind these classes; I suspect they were created by James in his early work on the SLD specification, or perhaps Martin in his working a "Lite" Java renderer. Oh wait it says Cameron Shorter (gasp!)

Here is where we are at today:

public interface MapLayer {
  getFeatureSource()
  getSource()
  getStyle()
  setStyle(Style)
  getTitle()
  setTitle(String)
  isVisible()
  setVisible(boolean)
  isSelected()
  setSelected(boolean)
  getQuery()
  setQuery(Query)
  getBounds()
  addMapLayerListener(MapLayerListener)
  removeMapLayerListener(MapLayerListener)
}

There is one implementation with an impressive array of constructors:

public class DefaultMapLayer implements MapLayer {
   DefaultMapLayer(FeatureSource, Style, String)
   DefaultMapLayer(CollectionSource, Style, String)
   DefaultMapLayer(FeatureSource, Style)
   DefaultMapLayer(FeatureCollection, Style, String)
   DefaultMapLayer(Collection, Style, String)
   DefaultMapLayer(FeatureCollection, Style)
   DefaultMapLayer(Collection, Style)
   DefaultMapLayer(GridCoverage, Style)
   DefaultMapLayer(AbstractGridCoverage2DReader, Style, String, GeneralParameterValue[])
   DefaultMapLayer(AbstractGridCoverage2DReader, Style, String)
   DefaultMapLayer(AbstractGridCoverage2DReader, Style)
   DefaultMapLayer(GridCoverage, Style, String)
   ...
}

Over time they have been hooked up to more and different kinds of data with some truly amazing twists and turns in order to:

Notes:

Proposal

So the proposal is pretty straight forward; a one two punch.

MapLayer to Layer

Here is a plan to tame map layer; while not breaking any existing client code:

  1. Introduce "Layer" as an abstract super class
  2. Create subclasses for each kind of content: GridCoverageLayer, FeatureSourceLayer, WMSLayer, etc... and Unit test the heck out of them
  3. Set up DefaultMapLayer to have a delegate Layer; have each constructor create the appropriate Layer instance to act as the delegate

Note the class MapLayer gained the following method:

@Deprecated
public interface MapLayer(){
  ..
  Layer toLayer();
}

Notes:

Planning for DirectLayer

  1. We can now introduce the concept of "DirectLayer" that is a layer that is responsible for its own paint method
  2. Other concrete Layers

DefaultMapContext to MapContent

Not a lot of thought needed on this one; the Interface/Class has grown over time and can be cut back:

I would like to move to an abstract class here; I can make DefaultMapContext extend it so that there is no code breakage.

Discussion and Ideas

Andrea had a number of ideas, but I could not keep track of them all:

Discussion of listeners:

Use of dispose()