Shape Layer Concept |
The ShapeLayer is a layer which is used to easily display business data on a map.
This page contains the following sections:
If data should be displayed in a geographical context, the usage of a ShapeLayer is reasonable. Its main purpose is to:
Display UI controls at a specific location on the map.
Provide automatic clipping of large controls.
Define how the UI controls should be scaled.
Handling data with a different projection than the WpfMap.
Provide standard UI controls for polylines and polygons.
The ShapeLayer accepts any kind of FrameworkElement as UI control to be displayed. To instruct the ShapeLayer where the control has to be displayed, the LocationProperty has to be added or the MapIcon class has to be used to encapsulate the FrameworkElement.
The following subsections describe the basics more detailed.
This section contains the following subsections:
Instantiating a ShapeLayer is pretty easy.
ShapeLayer aShapeLayer = new ShapeLayer("UniqueName");
By default, the ShapeLayer uses the SpatialReferenceId "EPSG:4023" which corresponds to the WGS84 coordinate system. A unique name has to be specified for the layer as this is the rule for creating other layers, too.
Now the ShapeLayer is ready for use. After creating a control, a location must be set.
// create a control FrameworkElement newContent = ...; // set the location of the new control by attaching a property newContent.SetValue(ShapeCanvas.LocationProperty, new Point(8.427, 49.013)); // or alternatively ShapeCanvas.SetLocation(newContent, new Point(8.427, 49.013));
If all is set up, the control can be added to the layer. The example also shows how to remove a control respectively and how to completely clear the list of controls of the layer.
// add the control to the layer aShapeLayer.Shapes.Add(newContent); aShapeLayer.Refresh(); ... // remove a control from the layer aShapeLayer.Shapes.Remove(newContent); aShapeLayer.Refresh(); ... // clear all controls aShapeLayer.Shapes.Clear(); aShapeLayer.Refresh();
For creating the ShapeLayer, the coordinates of the location have to be specified in the projection, which was initially used. Another thing to keep in mind is to 'refresh' the layer after content has been modified.
This example uses a certain SpatialReferenceId for constructing the ShapeLayer. If a SpatialReferenceId is specified, all controls that are added to the layer must contain coordinates of this reference.
ShapeLayer aShapeLayer = new ShapeLayer("UniqueName") { SpatialReferenceId = "EPSG:505456" };
Scaling a control means to specify if and how width and height of the control should change when the map scale changes (zooming). To do that, there is the ScaleFactorProperty. Its value of type double may range from 0.0 to 1.0. The two extremes are:
0.0, resulting in a constant object size. This means the original size was specified in device-independent units and the object is always the same size regardless of the currently set map scale. This parameter value is intended for objects containing only one spatial coordinate.
1.0, resulting in a so-called logical object size, with all sizes specified by coordinates according the spatial reference system. Now, the object size depends on the map scale. For an example, if Mercator is used as projection, a value of 1.0 specifies the object size in meters, since one logical unit in the Mercator projection corresponds to one meter. As a result, if the map scale changes, the object shrinks or grows accordingly. This parameter value addresses objects with a geometrical extension, which should also be integrated into the rendering presentation.
Values between 0.0 and 1.0 are valid and interpreted on a nonlinear basis.
// create a control FrameworkElement newContent = ...; // set the logical scale factor of the new control by attaching a property newContent.SetValue(ShapeCanvas.ScaleFactorProperty, 0.8); // or alternatively ShapeCanvas.SetScaleFactor(newContent, 0.8);
Sometimes it is desirable to draw a control not centered over a location, for example if a pin is used as the symbol representation. Then the pin should be drawn in such a way that the tip points directly to the location. For this use case, the MapIcon class can be used to wrap such controls. The MapIcon class provides an Anchor property which can be set to values of the LocationAnchor enumeration. An example how this can be used is shown below:
// create a control FrameworkElement newContent = ...; // wrap it with a MapIcon MapIcon icon = new MapIcon(newContent) { Anchor = MapIcon.LocationAnchor.RightBottom }; // set the location on the icon icon.Location = new System.Windows.Point { X = 8.427, Y = 49.013 }; // if desired set the logical scale factor icon.LogicalScaleFactor = 0.8;
The width and height properties are used from the wrapped control.
Generally, the ShapeLayer is capable of handling all inheritors of FrameworkElement. So the custom UI control has to inherit from that class.
Before adding the custom UI control to a ShapeLayer, a location property has to be attached. For a code example see here.
If the custom UI control should use a certain logical scale factor, this factor have to be set explicitly. For a code example see here.
The MapPolyline is an implementation for a polyline which can be rendered by the ShapeLayer. There are special requirements regarding clipping and reduction of a polyline to handle it with reasonable performance as a WPF element. The MapPolyline class respects these requirements.