The drawing add-on adds functionality to Lucy for drawing various shapes, such as points, polylines, polygons, buffers, and so on, on the map in multiple drawing layers.
Overview
The drawing add-on is the add-on that creates and registers the TLcyDrawingFormat
.
This format supports drawing models containing a variety of domain objects. The domain objects are typically drawn and manipulated
by the end user. The TLcyDrawingDataModelDescriptor
of the model contains the definition of the model properties. The TLcyDrawingFormat
encodes/decodes its model in/from an extension of the OGC Geography Markup Language (GML). The schema for this format can
be found as drawing.xsd
in the Lucy distribution.
The drawing add-on is designed in such a way that all logic relevant to a specific kind of domain object — for instance, a
circle, an ellipse, or a polyline — is grouped in an ALcyDomainObjectSupplier
. Most of the interaction with the domain objects therefore happens through this supplier. This design makes the format very
extensible. Supporting a new kind of shape, for instance MIL-STD 2525 symbols, is realized by adding a new ALcyDomainObjectSupplier
instance. See the next sections for more information.
The TLcyDrawingFormat
also adds an ALcyFormatBar
. See Format Bar documentation for more information about format bars. This format bar is typically available below the map component when a drawing layer
is selected. It displays a toolbar with many buttons to create and manipulate the various shape domain objects in the selected
drawing layer. Figure 1, “Overview of the TLcyDrawingAddOn.” shows the drawing add-on and its most important classes in a UML diagram.

The domain object supplier
The most important class in extending and customizing the drawing format is ALcyDomainObjectSupplier
. This class groups all functionality related to a specific type of domain object in a single class. Its functionality consists
of three major groups.
- Model
-
An
ALcyDomainObjectSupplier
instance is used as a factory to create new domain objects. It also provides functionality for object conversion (ALcyDomainObjectConverter
). The basic responsibility of a converter is to convert a domain object from one model to another. This is basically a clone operation with appropriate model transformations applied, for example, from a geodetic reference to a grid reference. The converter is also used for extruding domain object. It can also provide adapters to allow interaction with domain objects according to a given interface. This converter is used in many places in the drawing add-on. For instance, the drag-and-drop functionality uses the converter to copy and paste domain objects. Various actions in the toolbar also rely on the converter to interact with the domain objects. For instance, the create dome action uses the converter to adapt a domain object into anILcdCircle
from which it can easily create an appropriate dome. To allow editing of all properties of a domain object, theALcyDomainObjectSupplier
also provides anILcyCustomizerPanelFactory
. - Painting and editing
-
The supplier is a provider for painters and editors. As such, it has complete control over the handling of geometries and styling.
- File format
-
When a drawing model is saved in, or loaded from the drawing file format, an extension of GML, the domain object suppliers are used to (un)marshall the shapes they are responsible for. As such, each domain object can have a specialized XML representation that is appropriate to completely describe its state. The
ALcyDomainObjectSupplier
realizes this by providing appropriate XML marshallers and unmarshallers. See the LuciadLightspeed XML documentation for more information about the XML framework that is used for this.
The following figure shows this structure in a UML class diagram.

This design allows for a very heterogeneous drawing model. The only constraint on a domain object is that there must be an
ALcyDomainObjectSupplier
in the TLcyDrawingFormat
that can handle it.
Adding a new domain object instance to a drawing model is typically done as follows. First, an appropriate domain object supplier
is selected. There are various methods on TLcyDrawingFormat
to access the existing domain object suppliers. To make finding a specific domain object supplier easier, each supplier is
given a unique ID. The ID’s of the default suppliers can be found
as constants on TLcyDrawingFormat
. Note that the instance of TLcyDrawingFormat
can easily be retrieved from the drawing add-on instance. Once the domain object supplier is found, it is asked to create
a new domain object. This object can then be added to the drawing model.
Adding custom domain object types
An important feature of this design is the ability to add support for new kinds of shapes. This includes adding a button to the toolbar that adds the shape to the drawing layer and providing painters, editors and appropriate customizers for properties of these new shapes. The file format can be extended such that new shapes can also be read from and written into this format.
As an ALcyDomainObjectSupplier
instance represents the complete functionality for a certain domain object, adding (or removing) support for a domain object
is therefore equivalent to adding or removing an instance of this class. The TLcyDrawingFormat
comes into play here. It serves as manager of all domain object suppliers. It provides methods to add (addDomainObjectSupplier(ALcyDomainObjectSupplier)
) and remove instances (removeDomainObjectSupplier(ALcyDomainObjectSupplier)
). Note that adding and/or removing domain object suppliers is only supported during the add-on initialization phase, when
no drawing layers exist.
All suppliers typically have an active settable in the drawing toolbar to start creating a new domain object by clicking on the map. This settable is automatically created. The only thing that needs to be done to make the active settable appear is to configure it properly in the drawing add-on configuration file (see Layout of the drawing toolbar).
The lucy.drawing.customdomainobject sample shows how to add a custom domain object. It implements a custom ALcyDomainObjectSupplier
extension and registers a new instance to the drawing format.
Look at this example to learn more details about how to create your own ALcyDomainObjectSupplier
.
SLD
In many cases, the functionality of an ALcyDomainObjectSupplier
can be split in two distinct parts. On the one hand there is functionality that is specific to the geometry of the shape.
For instance, drawing a circle is different from drawing a polygon. On the other hand there is functionality that does not
depend on geometry. An example here is for instance supporting metadata (properties) or style information.
To support this common case, the drawing add-on provides TLcySLDDomainObjectSupplier
as an extension of ALcyDomainObjectSupplier
that implements this pattern. This class uses a separate ALcyShapeSupplier
class for all geometry-specific functionality. All default domain object suppliers of the drawing add-on use this extension.
SLD domain objects
In this extension, domain objects are TLcySLDDomainObject
instances. This class implements ILcdShapeList
, but instances will always contain exactly one ILcdShape
. This shape is typically a standard LuciadLightspeed shape such as for instance a TLcdXYCircle
or a TLcdLonLatHeightBuffer
. In case of grouping, the shape is an ILcdShapeList
containing the grouped domain objects. In case of extruded shapes, the shape is an ILcdExtrudedShape
.
TLcySLDDomainObject
keeps track of the properties of the shape and therefore implements ILcdDataObject
. Style information is also kept in the TLcySLDDomainObject
in a SLD style. This style is used during painting and contains the correct fill color, font information, icons, and so on.
Figure 3, “The model of the default drawing format.” shows this in a UML diagram.

Each drawing model has also one TLcyDrawingStyleRepository
that is accessible through the TLcyDrawingDataModelDescriptor
. This repository is used to store permanent styles that need to be stored and restored even if no domain object is currently
using them. These styles are encoded and decoded together with the rest of the model. The lucy.drawing.styles sample gives
an example of how this repository can be used.
SLD domain object supplier
TLcySLDDomainObjectSupplier
is the specialized ALcyDomainObjectSupplier
that handles the TLcySLDDomainObject
instances. This supplier has an associated ALcyShapeSupplier
that is responsible for shape-specific functionality. Functionality that is common is handled by the TLcySLDDomainObjectSupplier
itself. Figure 4, “Class diagram for TLcySLDDomainObjectSupplier and ALcyShapeSupplier.” shows this in a UML diagram.

TLcySLDDomainObjectSupplier
creates TLcySLDDomainObject
instances as model object. This happens as follows. First, the TLcySLDDomainObjectSupplier
asks its associated ALcyShapeSupplier
to create a new shape. The domain object supplier then selects an appropriate style for this shape. Then a new TLcySLDDomainObject
instance is created and returned. This object can then be added to the drawing model.
Figure 5, “Creating domain objects.” shows this in an interaction diagram.

To allow editing the properties of a drawing shape, the TLcySLDDomainObjectSupplier
provides an ILcyCustomizerPanelFactory
(see Customizer Panels documentation for more details about customizers in Lucy). This factory creates a ILcyCompositeCustomizerPanel
containing customizers for (1) editing the properties and (2) extrusion properties and (3) one or more customizers for the
geometry properties of the shape. The latter customizers are created using the factories supplied by ALcyShapeSupplier.createShapeCustomizerPanelFactories
.
An ALcyShapeSupplier
should also provide an ALcyShapeCodec
. This codec is needed, among other things, to implement undo in the customizers, to clone shapes and to implement shape conversion.
For painting, TLcySLDDomainObjectSupplier
separates styling from geometry. Styling is implemented based on the SLD implementation provided by LuciadLightspeed (consult
for more info on this the LuciadLightspeed Developer’s Guide). The basic idea here is that the painters provided by ALcyShapeSupplier
are only concerned with the geometry. So no fill or line style, colors, and so on, are taken into account. From the point
of view of the ALcyShapeSupplier
, this means that it doesn’t have to provide a normal ILcdGXYPainter
, but instead a set of painters (one for strokes, one for fills, and so on). The TLcyShapePainterProviderContainer
class facilitates this. The styling characteristics are retrieved from the TLcdSLDFeatureTypeStyle
instance associated with the domain object.
For (un)marshalling drawing shapes to the drawing file format, TLcySLDDomainObjectSupplier
takes care of styling and metadata properties. The ALcyShapeSupplier
only needs to provide support for its specific shape.
Custom shapes
The introduction of ALcyShapeSupplier
makes adding custom shapes even more simple. In cases where this separation of style and geometry is applicable, new types
of domain objects can be supported by registering new TLcySLDDomainObjectSupplier
instances with an appropriate ALcyShapeSupplier
. This is usually much more simple then creating a new ALcyDomainObjectSupplier
from scratch because a lot of the functionality is already handled by TLcySLDDomainObjectSupplier
.
The sample lucy.drawing.hippodrome shows how to add a hippodrome shape. It is based on the existing LuciadLightspeed hippodrome
sample and defines a HippodromeShapeSupplier
. Look at this example to learn more details about how to create your own ALcyShapeSupplier
.
Configuration
The TLcyDrawingAddOn.cfg
properties file allows many properties of the drawing add-on to be configured. The following paragraph provide some more
details on some important parts. The file itself is also documented with many comments explaining the different properties.
Similar to the toolbar of a map component or Lucy’s menu bar, the toolbar of the drawing add-on can be fully customized. It can be customized in the configuration file of the drawing add-on in the same fashion the other menu bars and toolbars can be customized. Please refer to Action Bars documentation to learn how to do this customization. The name of the drawing toolbar is drawingToolBar.
Apart from the menu- and toolbar items, there is one more important part of the Drawing add-on that can be customized: predefined layers. With predefined layers, one can provide the default properties a Drawing layer should have and its default model reference. Program: The properties in config/lucy/drawing/TLcyDrawingAddOn.cfg that determine the predefined layers. shows the relevant section of the configuration file that configures the predefined layers. The result of this sample configuration is shown in Figure 6, “The resulting dialog that is shown when creating a Drawing layer.”.
TLcyDrawingAddOn.defaultFeatures.names=NAME, Population, Capital
TLcyDrawingAddOn.defaultFeatures.classes=String, Integer, Boolean
TLcyDrawingAddOn.defaultReference=lucy/drawing/defaultReference.ref
TLcyDrawingAddOn.allowCustomLayers=true

Drawing in Lightspeed views
To visualize drawing layers in a Lightspeed view, the TLcyLspDrawingFormat
is introduced.
This format is designed in a similar way to the TLcyDrawingFormat
:
-
It manages a collection of
ALcyLspDomainObjectSupplier
instances that are responsible for handling the drawing of domain objects in a Lightspeed view. Just like in theTLcyDrawingFormat
, each drawing domain object must have oneALcyLspDomainObjectSupplier
. In other words, there is a supplier for points, one for polygons, and so on. TheALcyLspDomainObjectSupplier
complements aALcyDomainObjectSupplier
with stylers, shape discretizers, and editors specific to Lightspeed views. -
For
TLcySLDDomainObject
instances, it provides a specificALcyLspDomainObjectSupplier
extension calledTLcyLspSLDDomainObjectSupplier
. Similar toTLcySLDDomainObjectSupplier
, this class delegates shape-specific details to an associated shape supplier,ALcyLspShapeSupplier
. -
It offers a format bar factory that is specific to Lightspeed views, and contains UI to create new domain objects, change the style or perform calculations on the domain objects.
To support a custom domain object with custom styling in Lightspeed, you’ll need to create both an
ALcyDomainObjectSupplier
and a ALcyLspDomainObjectSupplier
extension.
The lucy.drawing.customdomainobject
sample shows how to do this.
Similarly, if you want to support a custom shape that uses the default SLD styling, you only need
to create a ALcyShapeSupplier
and ALcyLspShapeSupplier
.
This is shown in the lucy.drawing.hippodrome
sample.