Click or drag to resize

Custom Layers Concept

A map can contain one to many layers of several types at a time. This chapter describes the concepts behind the layering mechanism of PTV xServer .NET.

This page contains the following sections:

Basics

The layers of a map are handled by the Map class. A layer can be seen as the combination of three parts:

  • An optional data provisioning part which is called the 'data source'

  • A rendering part which is called the 'canvas'

  • A 'layer' which is managed by the map regarding opacity, priority and so on

In general two kinds of layer exists:

  • Layers for tiled data

  • Layers for untiled data

The two kinds differ essentially in how they retrieve and display data e.g. when the map zooms or pans. The following sections provide a deeper insight on the topics which are roughly summed up for now.

Layer management

The LayerCollection class is responsible for managing the layers. So to get a layer on the map at all, an instance of it has to be added to the LayerCollection of a Map. The same applies for layer removal. Please ensure that all layers will be removed which are not needed any more. Violating this rule will cause memory leaks.

Example for adding a layer.

C#
ContentLayer = new ShapeLayer("Addresses") { SpatialReferenceId = "PTV_MERCATOR" };
map.Layers.Add(ContentLayer);

Example for removing a layer.

C#
wpfMap?.Layers.Remove(ContentLayer);

ContentLayer = null;
Layer structure

As mentioned before, a layer can be seen as a data provisioning part (the 'data source'), a rendering part (the 'canvas') and the combining part (the 'layer'). In this section a deeper look at these parts is taken.

Data provisioning part (the 'data source')

The data provisioning part - also called the 'data source' - is responsible for acquiring the data which should be displayed on the map. Two kinds of it are available:

  • Data sources providing tiled data. These providers are expected to implement the ITiledProvider interface.

  • Data sources providing untiled data. These providers are expected to implement the IUntiledProvider interface.

At a first glance there is not much difference between the interfaces ITiledProvider and IUntiledProvider. Both have a 'GetImageStream(...)' API. The difference is in the transfer parameters.

The ITiledProvider .GetImageStream(Int32, Int32, Int32) accepts 'x' and 'y' as PTV tile coordinates and 'zoom' as the desired zoom factor. So it is assumed that the data is also accessed on a tiled basis. Of course, it could be necessary to transform the PTV tile coordinates into the reference system of the data. As a result, the implementing class is called separately for all tile coordinates which are currently in the view of the map.

An untiled layer which is implemented by the IUntiledProvider interface accepts the map bounding rectangle as PTV-internal Mercator coordinates through the GetImageStream(Double, Double, Double, Double, Int32, Int32) API. That means the implementing class is called only once for a specific map view and it has to collect the corresponding data by evaluating the bounding rectangle. Of course, it could be necessary to transform the bounding rectangle into the reference system of the data here, too.

Rendering part (the 'canvas')

The rendering part (the 'canvas') is responsible for doing the actual drawing of the layer content. PTV xServer .NET contains predefined classes for the tiled and untiled use case:

As the names already indicate, the TiledCanvas is used if tiled data should be rendered and the UntiledCanvas is needed for rendering untiled data.

Feel free to implement an own canvas. Therefore, please consider the following information:

  • Inherit from WorldCanvas to render data on a geographical basis. Benefits arise from an automatic repositioning, if the map viewport changes. But it is necessary to convert the coordinates of the data into Mercator, because the class WorldCanvas implies this.

  • Inherit from ScreenCanvas to render data with screen coordinates. Elements of the canvas have an absolute dimension (= size in pixels) but have to be repositioned whenever the viewport changes.

  • Implement the Update(UpdateMode) API with your own business logic.

To dig even deeper, a canvas can also be implemented from scratch by inheriting from MapCanvas. This would be the case, if neither the ScreenCanvas nor the WorldCanvas fits the requirements. Then the abstract APIs CanvasToPtvMercator(Point) and PtvMercatorToCanvas(Point), have to be implemented too. These APIs handle the transformation from the PTV-internal Mercator reference system to the custom reference system of the canvas and vice versa.

The layer

The layer is the object which connects the data provisioning part (the 'data source') with the rendering part (the 'canvas') so that it can be added to a LayerCollection of a Map instance. Furthermore, layers have common functionality which is defined by the ILayer interface. That interface defines methods and properties for:

  • Name -> Unique name to identify the layer within the list of layers of the LayerCollection.

  • Caption -> The caption of the layer which is displayed in the LayersGadget gadget.

  • Copyright -> If existent, it returns the copyright text of the layer.

  • HasSettingsDialog -> Flag indicating whether there is a settings dialog which can be displayed to modify the layer settings using the GUI.

  • Opacity -> Defines if the layer is translucent or opaque.

  • Priority -> The priority of the layer, which has an effect on where the layer is painted between other layers.

  • AddToMapView(MapView) -> Adds the layer to the map.

  • RemoveFromMapView(MapView) -> Removes the layer from the map.

So every layer is expected to implement the ILayer interface. The BaseLayer is the reference implementation of the ILayer interface.

If tended to inherit from BaseLayer for implementing an own layer, it has to be guaranteed that none of the following classes fits the needs or at least may act as the base class of the customized layer:

  • UntiledLayer -> A layer which renders images on an untiled basis.

  • ShapeLayer -> A layer for displaying shapes on a tiled or untiled basis.

  • TiledLayer -> A layer which renders images using tiled bitmaps.

If that is truly not the case, it should be sufficient to inherit from BaseLayer. It is also possible to directly implement the ILayer interface, but because this is not the recommended way to go, this documentation does not go any deeper on that.

Instantiating a layer

The instantiation of a layer involves the following:

The canvases are created on the fly by calling the BaseLayerCanvasFactoryDelegates when the layer is added to a map.

Rendering

This chapter shows which APIs are called during the map rendering.

See Also