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.
The drawing add-on is the add-on that creates and registers the
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.
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.
ALcyDomainObjectSupplierinstance 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 an
ILcdCirclefrom which it can easily create an appropriate dome. To allow editing of all properties of a domain object, the
ALcyDomainObjectSupplieralso provides an
- 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
ALcyDomainObjectSupplierrealizes 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.
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
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
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.
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
(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 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.
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.
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
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
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
It manages a collection of
ALcyLspDomainObjectSupplierinstances that are responsible for handling the drawing of domain objects in a Lightspeed view. Just like in the
TLcyDrawingFormat, each drawing domain object must have one
ALcyLspDomainObjectSupplier. In other words, there is a supplier for points, one for polygons, and so on. The
ALcyDomainObjectSupplierwith stylers, shape discretizers, and editors specific to Lightspeed views.
TLcySLDDomainObjectinstances, it provides a specific
TLcyLspSLDDomainObjectSupplier. Similar to
TLcySLDDomainObjectSupplier, this class delegates shape-specific details to an associated shape supplier,
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
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
This is shown in the