You typically use the LuciadRIA Map
or WebGLMap
components to visualize and edit data with a geospatial reference in the browser.
You can also visualize data without a geospatial reference, though.
You visualize non-georeferenced data by setting a Cartesian reference on the map, and positioning the data along axes.
Use cases for non-geospatial views in 2D and 3D
Possible two-dimensional use cases include the creation of scatter plots or the creation of vertical views, which represent distance and height on their axes. See the LuciadRIA vertical view sample for an example of an implementation.
A possible three-dimensional use case is an asset viewer. In an asset viewer, users can visualize a single asset without a globe, in its own local coordinate system. See the LuciadRIA 3D icons sample for an example of an implementation.
A 3D Cartesian Map
is especially beneficial for data that has no geolocation, for example a LIDAR scan or a CAD model of a building that hasn’t
been georeferenced yet. Figure 3, “Point cloud Cartesian” shows you a non-georeferenced point cloud visualized in its local, Cartesian 3D reference.
A 3D Cartesian Map
also supports the use of a 3D orthographic camera, as opposed to the perspective camera that LuciadRIA normally works with.
This type of camera is commonly used in CAD applications.
It shows your assets in an isometric view, which allows you to compare the relative size and angle of objects, regardless
of their distance to the camera.
Figure 4, “3D Cartesian perspective” shows you a 3D Cartesian view with a perspective camera. Notice how the tower in the background appears much smaller than the one in the foreground.
Figure 5, “3D Cartesian orthographic” shows you the same scene as Figure 4, “3D Cartesian perspective”, but with an orthographic camera. Notice how both towers are the same size, regardless of their distance from the camera. This makes it easier to compare relative sizes and angles
Using a non-geospatial view
You can use a non-georeferenced map in LuciadRIA in the same way as a georeferenced Map
or WebGLMap
: a non-georeferenced map just has a Cartesian reference instead of a georeference.
Because only the reference is different, the API to visualize data on a non-georeferenced view is the same.
Re-using the LuciadRIA map instead of introducing a third-party library has its benefits. It means that you can use all existing
LuciadRIA map features: you can add more than one layer, select and edit elements, add labels, and declutter labels. You can
also re-use the existing controllers, painters, and label painters, and even the models. See the vertical view sample for
an illustration. It adds regular FeatureLayer
instances configured with a FeaturePainter
to the vertical view.
To visualize data in a non-georeferenced view, you need to:
-
Create a Cartesian reference for your view
-
Add your data to the Cartesian view
Creating a Cartesian reference
A Cartesian reference is a CoordinateReference
that uses a Cartesian coordinate system: a tuple of numerical coordinates specifies each point uniquely in a coordinate system.
These are the signed distances from the point to three fixed perpendicular axes X, Y and Z.
In LuciadRIA, all axes of a Cartesian reference are associated with a quantity, such as a length or a weight. They’re expressed
in a unit of measure, such as meters or kilograms.
LuciadRIA has two built-in 2D Cartesian references. You can use them as a model reference and/or a map reference.
You can also use the built-in 3D Cartesian reference |
You can create a Cartesian reference with the ReferenceProvider.createCartesianReference
method.
You must specify the unit and quantity for each of the axes by passing a UnitOfMeasure
instance for each axis.
See
Program: Creation of a Cartesian reference.
samples/verticalview/VerticalView.ts
)
const X_AXIS_UOM = getUnitOfMeasure("NauticalMile");
const Y_AXIS_UOM = getUnitOfMeasure("FlightLevel");
const VERTICAL_VIEW_REFERENCE = createCartesianReference({
xUnitOfMeasure: X_AXIS_UOM,
yUnitOfMeasure: Y_AXIS_UOM
});
A UnitOfMeasure
is associated with a certain type of quantity, and indicates in which unit this quantity is expressed.
You can’t create instances of this class directly.
You must retrieve them from the UnitOfMeasureRegistry
class.
For more information, see the reference documentation of those classes.
Adding data to a Cartesian view
A LuciadRIA map is capable of visualizing the data of models with different references. Those model references may be different from the reference of the map itself. The map takes care of the conversion of the model reference to the map reference if both references are compatible. This automatic conversion applies to both georeferences and Cartesian references.
When are references compatible?
Two Cartesian references are compatible when:
-
The X-axes of both references represent the same type of quantity
-
The Y-axes of both references represent the same type of quantity.
-
If there are any, the Z-axes of both references represent the same type of quantity.
Examples of quantity types are physical quantities like distance, weight, or time. Each axis may represent a different type of quantity. Although the quantity type for each axis must be the same in both references, you can express them in distinct units of measure.
Consider two compatible references A and B. In both, the X-axes represent distance and the Y-axes represent time. Reference A expresses distance in meters, while B expresses it in feet. Even though the units of measure differ, A and B are still compatible. This means that you can add a model with reference A to a Map with reference B.
All georeferences that LuciadRIA supports, are compatible. That means that you can add any model with a georeference to a georeferenced map, with a correct data visualization as a result.
Dealing with reference incompatibility
LuciadRIA maps also support scenarios in which the model reference is incompatible with the map reference.
The main goal is to share a model between maps with distinct references, for example between a georeferenced map and a vertical view. Sharing a model between maps has the benefit that you can visualize updates to the model on both maps. The consequence is a model reference that’s incompatible with the reference of the map, though.
To support such a scenario, you must configure the FeatureLayer
with a ShapeProvider
.
The ShapeProvider
provides shapes in a reference that’s compatible with the map reference.
The shape provider must create a new shape for each of the Feature
instances in the model.
It must define the new shape in a reference that’s compatible with the map reference, and that matches the reference of the
ShapeProvider
.
The map displays the shapes returned by the ShapeProvider
.
The FeaturePainter
receives the original Feature
contained in the model and the shape returned by the ShapeProvider
in its paintBody
method.
You can still access the original shape through the Feature
.
You don’t need to make the reference of the |
The vertical view sample shows you two example ShapeProvider
implementations: the AirspaceShapeProvider
and AirTrackShapeProvider
classes.
You only need a |
Limitations and conventions for 3D Cartesian references
When your map has a 3D Cartesian reference, you can visualize various (potentially 2D) shapes on the map. Because it’s a 3D non-geospatial map, certain concepts that are applicable to geocentric maps may not have the same meaning on 3D Cartesian maps. Therefore, you must consider certain limitations and conventions with those maps.
-
These are limitations and conventions related to references:
-
The reference of the model data and the map must be equal or compatible. Geospatial references are never compatible with Cartesian references.
-
Automatic conversions between Cartesian references and geospatial references are not supported.
-
The X-axis of the map’s coordinate system serves as the east direction, the Y-axis as the north direction and the Z-axis as the up direction where applicable. This is the case for
LookAt
andIconStyle.heading
, for example.
-
-
Some limitations and conventions apply because there is no Earth — so no terrain, no ellipsoid, nor an atmosphere — on the map in a Cartesian reference:
-
Raster layers are not supported.
-
Draping has meaning on geocentric maps but doesn’t mean anything on 3D Cartesian maps. Any drape styling is ignored, the data is always styled with
DrapeTarget.NON_DRAPED
. -
When you’re using
Map.getViewToMapTransformation
, the Z = 0 plane takes on the role of terrain and ellipsoid. So, for the corresponding location modes, the transformation yields a world point position on the Z = 0 plane. -
The above-terrain navigation constraint is not supported.
-
Above-terrain icons are not supported.
-
The starfield graphical effect is disabled by default. You can still enable it if you want to.
-
The
atmosphere
graphics effect is not supported.
-
-
These are limitations and conventions related to cameras:
-
LookAt
andLookFrom
use the axes directions to define yaw and pitch. -
The depth range is not automatically adjusted, because the default
WebGLMap.adjustDepthRange
setting is false on 3D maps with a Cartesian reference. You can still enable depth range adjusting if you want to. It then uses z-values as "terrain" height. -
The lack of automatic depth range adjusting also means that the camera may need near and far values that are tailored to the application specifically. If the data uses very large coordinates for example, the far value must increase to ensure all objects are properly in view. The near value may have to increase too.
-
3D orthographic cameras are supported.
-
Visualizing and decorating the axes
When your map has a Cartesian reference, you may want to show the X-axis and Y-axis. You may also want to style those axes with ruler-like tick marks, and add labels to those axes.
This section explains how to visualize axes, and decorate those axes by adding measurement units in the form of tick marks, tick labels, feature icons, and feature labels.
Creating room for axis decorations
To visualize an axis and decorate it, first configure the map with a border. The purpose of the border is to create space at the left or bottom of the map. You express the space in pixels. This way, you reserve a blank area that you can use to style either the axes themselves, or to draw features.
Displaying axis tick marks and tick mark labels
To show tick marks for the measurement units on the X and Y axes, use a AxisConfiguration
object.
Use the map axes
property to configure the axes with such an AxisConfiguration
for both the X-axis and the Y-axis.
In that configuration object, you can set the length of the measuring ticks on the axis, the style of the ticks, and their
labels. For more detail about those properties, see the API documentation.
const map = new WebGLMap("map", {
border: {
left: 16,
bottom: 32
},
axes: {
xAxis: {
labelRotation: 0,
spacing: {
minimumTickSpacing: 200,
mapSpacing: [1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000]
},
labelStyle: {
fill: 'rgb(0,0,0)',
strokeWidth: 1,
font: '10px sans-serif',
offsetX: -10,
offsetY: 0,
textAnchor: 'end',
alignmentBaseline: 'middle'
},
gridLine: true,
subTicks: 9
},
yAxis: {}
}
});
Decorating the bottom border and the left border with features and feature labels
You can use the bottom border and the left border of the map to draw a feature with the optional paintBorderBody
and
paintBorderLabel
methods of FeaturePainter
.
To draw border features, enable the PaintRepresentation.BOTTOM_BORDER_BODY
or PaintRepresentation.LEFT_BORDER_BODY
representation, and call the paintBorderBody
method.
To draw feature labels, enable the PaintRepresentation.BOTTOM_BORDER_LABEL
or PaintRepresentation.LEFT_BORDER_LABEL
representation, and call the paintBorderLabel
method.
LuciadRIA executes those methods for each border. Inspect paintstate.border
to find out
for what border LuciadRIA requests the painting and styling information.
If you implemented those methods, and a feature falls within the X-range of the map, the feature ends up on the bottom border.
Similarly, if a feature falls within the Y-range of the map, the feature also ends up on the left border.
LuciadRIA centers bottom border labels by default. It also right-aligns left border labels to the Y-axis by default.
You can change the label position by setting the PointLabelStyle.positions
property.
You can only draw icon features and simple point labels in the border. You can’t draw shapes, nor can you draw in-path or on-path labels. |
The vertical view map doesn’t display the left border decorations by default. You must enable the left border paint representations explicitly for layers used in the vertical view map. |
const painter = new FeaturePainter();
painter.paintBorderBody = function(borderGeoCanvas, feature, shape, layer, map, state) {
if (state.border === Map.Border.BOTTOM) {
borderGeoCanvas.drawIcon(shape, {
image: image,
offsetY: 16
});
}
};
painter.paintBorderLabel = function(borderLabelCanvas, feature, shape, layer, map, state) {
const borderStyle = state.border === Map.Border.LEFT ? leftBorderLabelStyle : bottomBorderLabelStyle;
const text = state.border === Map.Border.LEFT ? (feature.properties as any).level
: (feature.properties as any).name;
borderLabelCanvas.drawLabel((feature.properties as any).name, shape, borderStyle);
};
Fitting tightly around the data in a Cartesian view
After a map fit, you may end up with excess space on a LuciadRIA map with a non-geographic reference. The default LuciadRIA map fit leaves some padding around the axes in a Cartesian view. It also preserves the scale ratio between the X and Y axes before and after the fit. To remove any excess space, see How to fit on bounds so there is a tight fit around the data.