Map-specific manager properties
Describes the classes available for managing various aspects of maps, such as altitude, display, data sources, layers, threads, and labeling.
Describes the altitude management classes and the use of this property.
Describes how to use the property and class provided for display preferences.
Describes the data source classes and use of this property.
Describes the class that provides the map layer tree model for style inheritance.
Describes the class that provides the thread facilities.
Describes the map labelling classes and the use of this property.
Briefly describes the areas of interest property class.
Briefly describes the coordinate system property class.
Describes the property used to make symbols persistent.
Altitude management
Describes the altitude management classes and the use of this property.
Provides general information and illustrates the classes for altitude management.
Explains how to use the property and class providing for accessing altitudes.
Explains how to develop code to read a new Digital Elevation Model (DEM) file format.
Altitude management classes
The class diagram for altitude management is shown in
Altitude Management UML Diagram.
Altitude Management UML Diagram
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at
<installdir> /jviews-maps/samples/mapbuilder/index.html.
Using the altitude provider property
Terrain analysis computations are based on the
IlvAltitudeProviderProperty of the manager and its underlying
IlvAltitudeProvider, which is responsible for providing altitudes for each point on a map.
The
IlvJMouseCoordinateViewer bean uses altitude property information to provide altitude information whenever the mouse is over an altitude providing map object. Many other features of
JViews Maps also use this information.
To access the altitude provider:
1. You can access the altitude provider by calling:
IlvAltitudeProvider provider =
IlvAltitudeProviderProperty.GetAltitudeProvider(manager);
2. To integrate another Digital Elevation Model, which provides the graphic objects with an
IlvAltitudeDataSource property, see
To retrieve the altitude attached to a graphic object below.
If you have read an image containing elevation data with an
IlvRasterAbstractReader, for an example, see
Writing a raster reader for DEM data; you can reuse its altitude information to provide altitude data by using an
IlvRasterAltitudeDataSource instance.
To attach an altitude data source to a graphic object:
1. You first need to decide on the structure of the attribute
property, for example, for a property containing only altitude data:
IlvAttributeInfoProperty info = new IlvAttributeInfoProperty(
new String[] { "myAltitudeDataSourcePropertyName" },
new Class[] { IlvRasterAltitudeDataSource.class },
new boolean[] { true });
2. You can then reuse this structural information with different altitude data sources, and set it as the graphic object property:
IlvFeatureAttribute value[] = { new
IlvRasterAltitudeDataSource(rasterImageReader, imageIndex) };
graphic.setNamedProperty(new IlvFeatureAttributeProperty(info, value);
If you use the default altitude management described in
Using the altitude provider property, you can also retrieve the altitude attached to an object as described.
To retrieve the altitude attached to a graphic object:
1. Get the attribute properties of the graphic object:
IlvAttributeProperty property = (IlvAttributeProperty)
graphic.getNamedProperty(IlvAttributeProperty.NAME);
2. You should find the altitude data source in that property:
IlvAltitudeDataSource ads =
(IlvAltitudeDataSource)property.getValue("myAltitudeDataSourcePropertyName")
;
3. As the data source object provides only altitude information for a specific latitude/longitude pair, you may need to transform the coordinates into latitude and longitude. Here is an example that converts a mouse location into such a pair:
// transform the mouse point into manager coordinates
IlvPoint pt=new IlvPoint(mouseLocation.x,mouseLocation.y);
view.getTransformer().inverse(pt);
IlvProjectionUtil.invertY(pt);
try {
// compute the coordinate transformation from manager coordinates to lat/
lon
IlvCoordinateSystem cs =
IlvCoordinateSystemProperty.GetCoordinateSystem(view.getManager());
IlvCoordinateTransformation ct =
IlvCoordinateTransformation.CreateTransformation(cs,
IlvGeographicCoordinateSystem.KERNEL);
// transform the point into lat/lon
IlvCoordinate c = new IlvCoordinate(pt.x, pt.y);
ct.transform(c, c);
// retrieve the altitude
} catch (IlvCoordinateTransformationException e) {
}
4. You can then obtain the altitude. You should check if its value is a valid double, because the default data source and default provider of the manager return a Double.NaN value when there is no altitude information available.
double alt = ads.getAltitude(c.x, c.y, 0);
if(!Double.isNaN(alt)){
return alt;
}
If the pixel values stored in the
IlvRasterMappedBuffer are altitudes, you can use the
IlvRasterAltitudeDataSource class directly as the altitude provider.
Use the
IlvRasterAltitudeDataSource class in the
IlvFeatureAttributeProperty of every image that the reader creates.
To set altitudes use:
public IlvFeatureAttributeProperty getProperties(int imageIndex)
{
IlvAttributeInfoProperty info = new IlvAttributeInfoProperty(
new String[] { " myAltitudeDataSourcePropertyName" },
new Class[] { IlvRasterAltitudeDataSource.class },
new boolean[] { true });
IlvFeatureAttribute values[] = new IlvFeatureAttribute[] {
new IlvRasterAltitudeDataSource(this,imageIndex)
};
return new IlvFeatureAttributeProperty(info, values);
}
See also To attach an altitude data source to a graphic object.
You need to provide
JViews Maps with a way of knowing where the resulting image is placed. This is done through two methods that return the transformation and
coordinate system used in the raster property boundaries.
To manage coordinates:
Provide two methods as shown in the following example, which assumes that the bounds are given in degrees.
private static IlvCoordinateTransformation INTERNAL =
IlvCoordinateTransformation.CreateTransformation
(IlvGeographicCoordinateSystem.KERNEL,
IlvGeographicCoordinateSystem.WGS84);
public IlvCoordinateSystem getCoordinateSystem() {
return INTERNAL.getTargetCS();
}
public IlvMathTransform getInternalTransformation(int imageIndex) {
return INTERNAL.getTransform();
}
Writing a raster reader for DEM data
To read a new Digital Elevation Model (
DEM format), you should write a subclass of
IlvRasterAbstractReader with an
addMap method. If you want to take advantage of map load and save features, you have to manage the serialization of the reader, that is, provide methods that perform the required functions.
To create the reader:
1. Load a list of raster DEM files as shown in the following example.
public class MyDEMReader extends IlvRasterAbstractReader {
// list of files to be read.
private ArrayList filenameList = new ArrayList();
/** default constructor */
public MyDEMReader() {
}
public void addMap(final String filename) throws IOException {
IlvRasterProperties loadingRaster = read/compute raster properties ...
IlvRasterMappedBuffer source= read/compute raster pixel values...
loadingRaster.setBaseName(filename);
// to retrieve the file name when serializing data.
addRaster(loadingRaster, source);
}
To use the map load and save features:
1. Serialize all the necessary information to rebuild the images - in this example, only the filenames.
public void write(IlvOutputStream stream) throws IOException {
super.write(stream);
int imageCount = getImageCount();
for (int i = 0; i < imageCount; i++) {
IlvRasterProperties props=getRasterProperties(i);
stream.write("filename"+i,props.getBaseName());
}
}
2. Rebuild the reader from serialized data. Because the image data may have been saved in an IMG file associated with the map, you should only read the filenames of the raster DEM not the files themselves:
public MyDEMReader(IlvInputStream stream) throws IlvReadFileException {
super(stream);
try {
for(int count=0;true;count++) {
String filename = stream.readString("filename"+count);
filenameList.add(filename);
}
} catch (IlvReadFileException e1) {
// No more filenames to read
}
}
3. If the complete map data is saved, the raw image data is reconnected by standard mechanisms. However, to reload files when the user has only saved the description of the map and not its data, write a reload method:
public void reload(IlvThreadMonitoringData monitorInfo) {
super.reload(monitorInfo);
// clear all images
dispose();
// save the known filenames in a temporary array – the addMap would
else add them again.
String[] filenames = (String[])filenameList.toArray(new String[0]);
// clear the file name list
filenameList.clear();
for (int i = 0; i < filenames.length; i++) {
try {
// load each file
addMap(filenames[i]);
if (monitorInfo != null) {
// update the thread monitoring information, if
necessary
int percent = Math.round(i/(float)filenames.length
* 100);
monitorInfo.updateProgress(percent);
}
} catch (IOException e) {
new IlvExceptionMessage(e,null);
}
}
}
The display preferences property
Map display preferences are accessible through the
IlvDisplayPreferencesProperty of the manager and its underlying
IlvDisplayPreferences, which is responsible for indicating user preferences when displaying the map.
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at
<installdir> /jviews-maps/samples/mapbuilder/index.html.
The display preferences are used to share:
The preferred unit and format to use for altitudes.
The preferred unit and format to use for distances.
The preferred coordinate formatter to use to show earth coordinates.
An indication of whether geodetic computation is activated or not.
Display preferences access
You can access the display preferences by calling:
IlvDisplayPreferences pref =
IlvDisplayPreferencesProperty.GetDisplayPreferences(manager);
This method creates or returns the last instance set of
IlvDisplayPreferences.
Display preferences uses
The
IlvJMouseCoordinateViewer bean uses preferences to format coordinates and altitude information whenever the mouse moves over the map.
The
IlvJAutomaticScaleBar also listens to this property in order to adapt the map distance unit to the preferences of the application.
When creating measurements (or an
IlvMapOrthodromyPath), a specific
IlvDistanceAttribute property is attached to contain the measurement length. This property displays itself taking into account the preferred distance unit found in the preferences.
The
IlvCoordinatePanelFactory needs to retrieve a coordinate formatter to know how to display the coordinates selected on the view, which can also edited by the user. You should usually do this by retrieving the coordinate formatter of the current preferences:
IlvDisplayPreferences prefs =
IlvDisplayPreferencesProperty.GetDisplayPreferences(manager);
IlvCoordinateFormatter formatter= prefs.getCoordinateFormatter();
JPanel coordPicker=new
IlvCoordinatePanelFactory.CoordPointInputPanel(view,formatter);
Adding a listener to changes in display preferences
You can listen to changes in this property (such as those triggered by the Display Preference Editor), by adding a named property listener on the manager:
manager.addNamedPropertyListener(new NamedPropertyListener() {
public void propertyChanged(NamedPropertyEvent event) {
if(event.getNewValue() instanceof IlvDisplayPreferencesProperty){
IlvDisplayPreferencesProperty
prop=(IlvDisplayPreferencesProperty)event.getNewValue();
IlvDisplayPreferences preferences=prop.getDisplayPreferences();
// manage the new preferences
...
}
}
});
Geodetic computation
All data sources should use the display preferences properties to adapt their rendering to the activation of geodetic computation, which is an important user choice.
When geodetic computation is activated, every polygon-like map feature is rendered, through the use of an
IlvGeodeticPathComputation, into a series of orthodromies (see
orthodromy measure). Whenever a segment of the polygon has two extremities on different sides of the screen, the polygon is cut into many areas, separated on the screen but representing the same map feature.
The data source property
Describes the data source classes and use of this property.
Describes the class that provides the data source property for a map.
Describes the two ways to reload your data sources.
Data source tree
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at
<installdir> /jviews-maps/samples/mapbuilder/index.htmlIlvMapDataSourceProperty
The
IlvMapDataSourceProperty class is a named property used to attach a
IlvMapDataSourceModel to an
IlvManager.
IlvManagerThis data source model controls all data sources that you import into the manager. It is also persistent data that is saved when you save the map.
Accessing the data source model
You can access the map data source model by calling:
IlvMapDataSourceModel dsm =
IlvMapDataSourceProperty.GetMapDataSourceModel(manager);
Adding a listener
As the IlvMapDataSourceProperty is a named property of the manager, you can add a listener that is called whenever the property as a whole is changed, for example:
manager.addNamedPropertyListener(new NamedPropertyListener() {
public void propertyChanged(NamedPropertyEvent event) {
if (event.getPropertyName().equals(IlvMapDataSourceProperty.NAME)) {
IlvMapDataSourceProperty p = (IlvMapDataSourceProperty)
event.getNewValue();
if (event.getType() == NamedPropertyEvent.PROPERTY_SET) {
...do something
}
}
}
});
Controlling data sources
You can allow users to edit and control individual data sources by adding an
IlvDataSourcePanel bean to your application. See
Using the GUI beans.
NOTE Although the Data Source Tree contains a Tree structure, JViews Maps uses only a single level tree, resulting in a simpler data source list. Future versions, or user applications, may use the full tree structure for advanced features.
Reloading all data sources
If you have created an instance of
IlvSDMEngine (even empty) in your manager.
To reload the data, you can simply write:
engine.loadData();
In case you do not want, or do not need, a symbol management utility, you can use the following code to reload your data:
To reload without using an IlvSDMEngine
1. Retrieve the data source model root :
DefaultMutableTreeNode root = (DefaultMutableTreeNode) dsm.getRoot();
2. Retrieve the map layers attached to each of the
data sources:
int count = root.getChildCount();
for (int i = 0; i < count; i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
IlvMapDataSource source = (IlvMapDataSource) node.getUserObject();
IlvMapLayer mlayer = source.getInsertionLayer();
3. Restart each data source ensuring that the tile manager updates the visible part of the view for data sources containing tiled layers:
source.reset();
source.start();
IlvManagerLayer layer = mlayer.getManagerLayer();
if (layer instanceof IlvTiledLayer) {
((IlvTiledLayer) layer).getTileController().updateView(getView());
}
Map layer tree
This layer tree model controls the order and style inheritance of
IlvMapLayer you add into your manager. This model is also persistent data that is saved when you save the map.
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at
<installdir> /jviews-maps/samples/mapbuilder/index.html.
Accessing the map layer tree model
You can access the layer tree model by calling:
IlvMapLayerTreeModel ltm =
IlvMapLayerTreeProperty.GetMapLayerTreeModel(manager);
Controlling the map layer tree
You can allow users to edit and control individual layer styles by adding an
IlvLayerTree bean in your application, see
Using the GUI beans.
Usually, applications only need to add layers with the
addChild method, or remove them with the
removeChild method of the layer model.
Adding a listener for layer organization changes
The map tree model is a subclass of DefaultTreeModel, so you can add a TreeModelListener to your application to trap any change in the layer organization.
Adding a listener for tree structure changes
As the
IlvMapLayerTreeProperty is also a named property of the manager, you can add a listener that is called whenever the entire tree structure is changed, for example:
manager.addNamedPropertyListener(new NamedPropertyListener() {
public void propertyChanged(NamedPropertyEvent event) {
if (event.getPropertyName().equals(IlvMapLayerTreeProperty.NAME)) {
IlvMapLayerTreeProperty p = (IlvMapLayerTreeProperty)
event.getNewValue();
if (event.getType() == NamedPropertyEvent.PROPERTY_SET) {
...do something
}
}
}
});
Adding code to all layers
If your application needs to apply a piece of code to all layers, whatever their depth in the tree, you should call the
getEnumeration method of the tree model, such as:
Enumeration e = ltm.getEnumeration();
while(e.hasMoreElements()) {
Object o = e.nextElement();
if(o instanceof IlvMapLayerTreeNode) {
IlvMapLayer layer =
(IlvMapLayer)((IlvMapLayerTreeNode)o).getUserObject();
... act on the layer
}
}
For example, the method
clearAllObjects in
IlvMapLayerTreeModel calls the
removeAllObjects for each layer found.
Thread monitoring
This threaded monitor is a centralized object with which threads should register their activities. The activities, that is, tasks, must also notify this controller of their progress.
All activity listeners registered with this controller are notified in turn of any activity progress. The
IlvThreadedActivityMonitorPanel is one such important listener. This bean provides the user with feedback on activities that are currently running, see
Using the GUI beans.
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at
<installdir> /jviews-maps/samples/mapbuilder/index.html.
Accessing the threaded activity monitor
You can access the threaded activity monitor by calling:
IlvThreadedActivityMonitor mon =
IlvThreadedActivityMonitorProperty.GetThreadedActivityMonitor(manager);
Providing threaded activity information
It is the responsibility of each thread to register, update and unregister their activities to provide the user with correct information on the background tasks that are running:
mon.updateActivityProgress(activityID,10,"doing something long");
... do something long that takes 10% of total time...
mon.updateActivityProgress(activityID,20,"doing another thing");
...
Setting the activity progress to 100% or unregistering the activity removes it from the list currently managed by the monitor.
Registering objects as listeners
You can also register your own objects as listeners to changes in the activity monitor with lines of code such as:
mon.addActivityListener(new IlvThreadedActivityMonitor.ActivityListener() {
public void activityChanged(ActivityEvent e) {
if(e.getEventType() ==
IlvThreadedActivityMonitor.ActivityEvent.ACTIVITY_REMOVED) {
... an activity just ended, do something.
}
});
Map labeling
Describes the map labelling classes and the use of this property.
Provides general information and illustrates the map labeling classes.
Explains how to use the interface for labeling in maps.
Describes the class for managing layers that are labeled and layers containing the labels.
Describes the factory for creating labels.
Map labeling classes
The class diagram for map labeling is shown in
Map Labeling UML Diagram.
Map Labeling UML Diagram
JViews Maps has a dynamic map labeling mechanism. When activated for a specified map layer, all graphic objects of this layer are labeled in a separate thread. This ensures maximum responsiveness of the GUI while performing the background layout. The labeling process is done every time the user changes the view by zooming, scrolling, and so on.
Using the IlvMapLabeler interface
The entry point for the dynamic map labeling mechanism is the
IlvMapLabeler interface. A class implementing this interface is responsible for managing labels for a given
IlvManager. The
IlvMapLabelerProperty class is a named property used to attach an
IlvMapLabeler to an
IlvManager. This map labeler handles all the data sources imported into the manager. The model data is made persistent and saved when you save the map.
You can access the map labeler by calling:
IlvMapLabeler labeler = IlvMapLabelerProperty.GetMapLabeler(manager);
If a specific labeler is not set for the property, this method creates or returns an instance of
IlvMapDefaultLabeler. This default labeler class automatically creates and configures a map layer for labels and listens for changes to the layer structure attached to the view. This allows the labeling to be updated when layer order changes. It also contains an internal
IlvMapLabelFactory to create the appropriate labels for graphic objects, according to the LABEL_ATTRIBUTE field of the
IlvMapLayer. For more information about
IlvMapLabelFactory, see
The IlvMapLabelFactory Interface.
To add labels to a given map layer on your map:
1. Define the layer to be labeled:
IlvMapLayer layerToLabel;
2. Create a default IlvMapDefaultLabeler and set it on the manager:
IlvMapLabeler labeler =
IlvMapLabelerProperty.GetMapLabeler(manager);
3. Since this labeler has to interact with the view, you must indicate in which view it is to display the labels:
4. Set the label attribute for the map layer to specify which attribute of the graphic objects should be displayed as a label (check the available attributes in the file format you read in):
5. Register the map layer to label with the labeler:
6. Finally, notify the labeling thread to compute labels for all the labeled layers:
The IlvMapLabelManager class
The
IlvMapDefaultLabeler class holds references to labeled layers (the layers to be labeled) and label layers (the layers that display the labels). This class also holds a reference to an
IlvMapLabelManager that acts as a controller for label rendering operations. The
IlvMapLabelManager class monitors changes in the view (scrolling, zooming...), creates labels for all the visible graphic objects in the view that require labeling, and lays them out and draws them. This is all done in a separate thread so that user interaction is not blocked. Basically, this class contains the
JViews Maps rendering engine.
The IlvMapLabelFactory Interface
To create labels for graphic objects, the
IlvMapLabelManager class relies on a label factory implementing the
IlvMapLabelFactory interface. Any object implementing this interface is responsible for returning the appropriate
IlvMapLabelingLabel instances for specified
IlvGraphic objects. This is done by implementing the method:
labeler.setView(view);
layerToLabel.getStyle().setLabelAttribute("NAME");
labeler.addLayer(layerToLabel);
labeler.performLabeling();
public IlvMapLabelingLabel[] getGisLabel(IlvGraphic comp);
The default label factory performs the following tasks:
It extracts an attribute from the specified
IlvGraphic object (according to the label attribute in the
IlvMapStyle of the
IlvMapLayer being labeled), and takes its
String representation as the text of the label.
Then it creates the appropriate instance of the
IlvMapLabelingLabel class, according to the kind of graphic object being labeled:
IlvMapAreaLabel for closed areas with a label placed within visible parts of the area.
The
IlvMapLabelManager uses this default implementation of the factory, but you can provide your own implementation if you want to have fine control over what is labeled, and how. To replace the default label factory with your own label factory:
IlvMapLabelFactory myLabelFactory = new myLabelFactory(); //Your own
implementation.
//Get the map labeler.
IlvMapLabeler labeler =
IlvMapLabelerProperty.GetMapLabeler(manager);
//Set the factory, if the labeler is an IlvMapDefaultLabeler instance.
if(labeler instanceof IlvMapDefaultLabeler) {
IlvMapDefaultLabeler dflt = (IlvMapDefaultLabeler)labeler;
dflt.setLabelFactory(myLabelFactory);
}
Controlling renderer parameters
When you implement your own
IlvMapLabelFactory, you can specify a set of layout and rendering parameters for each instance of
IlvMapLabelingLabel that you create in the constructor.
For more information about these parameters, see the
IlvMapPointLabel,
IlvMapLineLabel, and
IlvMapAreaLabel classes.
Areas of interest
The
IlvAreasOfInterestProperty class is a named property used to store areas of interest in an
IlvManager.
For more information on this property see
Area of Interest panel.
Coordinate system
The
IlvCoordinateSystemProperty class is a named property used to store the geographic or coordinate system in which the map should be displayed. It can be different from the individual data source coordinate system in which case
JViews Maps will automatically perform a reprojection of the data.
See the relevant data source documentation in the Readers and Writers section, for more information.
See
Coordinate System Editor for examples of use.
Persistent symbol model
The
IlvPersistentSDMModelProperty class is a named property used to make the symbols added through the
IlvSymbologyTreeView API persistent. It is not compatible with the
JViews Diagrammer designer way of symbol persistence through an xml description in a separate file.
Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.