Fifth part of the Course "Java Open Source GIS Development - From the building blocks to extending an existing GIS application." held at the University of Potsdam in August 2011
1. Java Open Source GIS
Development
From the building blocks to extending
an existing GIS application.
Geoinformation Research Group, Department of Geography
University of Potsdam
August 2011
Part 5: Integrating with uDig and OMS3
Tutor: Andrea Antonello
ydroloGIS nvironmental ngineering
HydroloGIS S.r.l. - Via Siemens, 19 - 39100 Bolzano www.hydrologis.com
2. Integrating with uDig and OMS3
We have learned to develop around raster and vector data, read and write
formats and deal with projections and geometries.
We also viewed the maps we produced in a simple and very limited viewer.
What possibilities do we have to integrate in a professional way our
knowledge up to this point into a real GIS environment?
The solution we will see is the Spatial ToolBox for uDig. The toolbox
generates, through proper description/annotation of the code, graphical user
interfaces for your module. Modules can be loaded at runtime.
3. Introduction to OMS3
The Object Modeling System (OMS3) is a pure Java, object-oriented
lightweight modeling framework.
OMS allows model construction and model application based on
components.
It is a collaborative project active among the U.S. Department of Agriculture
and partner agencies and organizations involved with agro-environmental
modeling.
The lightweight of the framework consists mainly in the use of annotations in
the code.
4. The 3 steps in modeling
Basically OMS3 supplies a set of annotations to put on the code to describe
it and to mark fields and methods through them.
As in most generic modeling frameworks, the three main steps are:
• setting model resources and parameters
• executing the model
• freeing model resources if necessary
In order to make the framework understand what has to be used as
parameters and what as methods, we just need to annotate them. The
upside is that we can structure our code as we like, using our own way of
naming of variables and names.
5. The few important things that need to be kept in mind are:
• input and output fields have to be set public and annotated with @In and
@Out
• the method that executes the model, has to have no return value, no
parameter and be annotated with @Execute
Annotation example of input and output fields:
@Description("The map of digital elevation model (DEM).")
@In
public GridCoverage2D inElev;
@Description("The vector on which to calculate the profile.")
@In
public SimpleFeatureCollection inVector;
@Description("The profile.")
@Out
public double[][] outProfile = null;
6. Example module execution method:
@Execute
public void process(){
// execute your module here
}
Example for the resources freeing method:
@Finalize
public void free(){
// free resources before shutting module downw
}
7. Introduction to the uDig's Spatial Toolbox
The Spatial Toolbox is a frontend for GIS users, a graphical user interface
that can load any OMS3 annotated module.
Mouse clicks, region settings, raster resolution and all (most) needed GIS
notions are supplied to the widgets automatically. Annotations give hints.
The gui labels and documentations are responsability of the module
developer/maintainer.
8. User Interface built through the OMS3 annotations
ClassName
The Class name is not an annotation, but anyways important, since it results
in the name of the module. Choose it carefully.
9. @Label
The Label is a class annotation that is interpreted as a category. It is useful
to group various module in categories and subcategories (separated by
slash: / ).
10. @In/@Out
In and Out are field annotations that are used to define whether a field
should be handled as input or output. In the gui this can result in separate
tabs:
11. @Description
The Description annotation can be used for both classes and fields. In the
case of fields it is used as the text for the fields in the gui. In the case of
classes, it is used in the documentation page.
12. @Units and @Range
The Units and Range annotations are field annotations that add descriptive
text to the gui.
14. @Status, @Name, @Author, @License, @Keywords
Additional annotations, if available, are used in the gui as additional
information for the documentation.
15. @UI, the annotation that makes the gui smarter
The UI annotation is a field/class annotation that aims to make the gui
smarter. Its content is not standardized, and can be interpreted by the gui
generators to make the widgets more interactive.
@UI("infile")
Identifies a field that will contain an input (has to exist) file. The textfield
should present a button to browse the filesystem in open mode.
16. @UI("outfile")
Identifies a field that will contain an output (parent folder has to exist) file.
The textfield should present a button to browse the filesystem in save mode.
@UI("infolder")
Identifies a field that will contain an input (has to exist) folder. The textfield
should present a button to browse the filesystem in open mode.
17. @UI("outfolder")
Identifies a field that will contain an output (parent folder has to exist) folder.
The textfield should present a button to browse the filesystem in save mode.
@UI("crs")
Identifies a fields that contains a CRS definition. The textfield should present
a button to browse available CRS definitions.
18. @UI("process_XXXXX")
A set of annotations that identify processing region fields. Gui applications
can make use of these to autocompile the properties of a processing region.
Available properties are: process_north, process_south, process_west,
process_east, process_xres, process_yres, process_rows, process_cols
20. @UI("northing") and @UI("easting")
Identifies a textfield that can autocompile an easting and northing position.
Gui applications might be using this to listen to mouse click positions on a
map.
@UI("hide")
Identifies a module that should not be presented in the gui. This might for
example be due to the fact that the module is more than experimental.
21. How to write an OMS3 GIS module?
Writing (or porting) an OMS3 module is quite easy. Every module has input
and output parameters and once those are set, it needs to be executed.
When writing any module, it is a good manner to keep the handling of
input and output out of the game. Think it as: another module will take
care of that and pass me the read data.
This means that we can assume when writing the module that in most cases
the GIS data will be read and passed over by the Spatial Toolbox and we just
need to implement the algorithm.
With that in mind, we will now create a very simple module, in order to
understand the basics: the reprojection of a vector dataset.
22. The Vector Data Reprojector
Writing the module
First thing we create a class named SimpleVectorReprojector.
Then we add some descriptive metadata to the class to document it. Mind
that if you don't do documentation while you code, you probably won't be
able to catch up with it.
@Description("Module for vector reprojection.")
@Author(name = "Andrea Antonello", contact = "http://www.hydrologis.com")
@Keywords("CRS, Reprojection, Vector")
@Label("Potsdam/Raster")
@Status(Status.EXPERIMENTAL)
@Name("vectorreproject")
@License("General Public License Version 3 (GPLv3)")
public class SimpleVectorReprojector {
23. Next we define the input and output variables. Our inputs will be the vector
data to reproject, which at that point we know to be a SimpleFeature-
Collection:
@Description("The vector that has to be reprojected.")
@In
public SimpleFeatureCollection inVector;
and a code that will define the projection to apply to the data. For the code,
which will be in the EPSG format, we can use a String:
@Description("The code defining the target crs (ex. EPSG:4328).")
@UI("crs")
@In
public String pCode;
Note the @UI("crs") annotation, that will tell the gui generator that we
need a widget to choose coordinate reference systems from.
24. The output will be the reprojected vector data, so again a Simple-
FeatureCollection, simply annotated with the @Out annotation:
@Description("The output reprojected vector.")
@Out
public SimpleFeatureCollection outVector = null;
Once inputs and output are defined, we now need a method that performs
the processing. In the case of the vector reprojection, the GeoTools library
makes things really easy: one line to create the CRS from the EPSG code
and one line to reproject and put the result in the output variable.
@Execute
public void process() throws Exception {
CoordinateReferenceSystem targetCrs = CRS.decode(pCode);
outVector = new ReprojectingFeatureCollection(inVector, targetCrs);
}
In this case we do not need to free any resources, so that's it.
25. Building the library for the spatial toolbox
This is the moment in which we are going to be very happy about the fact
that we use maven for the project.
Building a library that can be loaded into the Spatial Toolbox is as easy as
running from commandline (inside the project folder, were the pom.xml file
resides:
mvn install
Maven might download some updated jars and take a little while the first
time, but then it should state something like:
...
[INFO] [surefire:test]
[INFO] No tests to run.
[INFO] [jar:jar]
[INFO] Building jar: /home/moovida/.../jgt-dev-example/target/jgt-dev-example-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] [install:install]
...
26. The jgt-dev-example-1.0-SNAPSHOT.jar is the library that you
wanted to build. It is the library you will load into the spatial toolbox. You
might even want to rename it to something more in line with its content.
By tweaking the pom file, it is also possible to make maven take care of
changing name and version. This is left as an exercise.
27. uDig and the Spatial Toolbox
Installing uDig
Once the module library is packaged, the developer work is done and we can
enjoy the user part.
To proceed we have to make sure that uDig is installed on your computer.
If that is not the case, you just need to go to uDig's download area and get
the installer (or archive) for your operating system. Depending on what you
downloaded you can follow the installer's instruction or, in the case of the zip
archive, simply unzip it and run uDig.
28. Loading libraries in the Spatial Toolbox
The next step is to load the library in the uDig Spatial Toolbox.
To do so we fire up uDig:
29. To open the Spatial Toolbox go under Window -> Show View -> Other:
30. You will see all available views, from which you select the Spatial Toolbox:
32. Push the settings button (the last button on the right):
and open the settings dialog:
The dialog allows you to load libraries through the plus button.
33. We now can load the library containing the vector reprojector.
Mind that uDig will need you to supply all the needed dependencies.
Udig itself supplies all the GeoTools dependencies.
Since we used also some JGrasstools methods, we will need to load also
that library.
34. Once the Ok button is pushed, uDig will browse the loaded libraries for OMS
annotated modules. To be precise, it searches for modules that have the
@Execute annotation and exatracts from them the information needed for
the toolbox. This leads, depending on the loaded libraries, to:
35. If you did everything as explained before, you should have the category
entries, but the module should not show up. This is due to the fact that we
defined the module as experimental, so the checkbox to activate
experimental support has to be checked:
36. Conclusions
In this last part we have seen how small yet powerful modules can be easily
integrated into uDig with a nice graphical user interface without additional
effort.
To summarize the steps:
• write a module based on GeoTools, JTS, Jaitools, JGrasstools
• annotate the fields and class properly to help the gui generator
• bundle the final version of the module in a jar library
• load it into uDig's Spatial Toolbox
37. Exercises
The line of sight
Needed data
• DEM (raster map)
• points of interest (vector map)
• viewers (vector map)
Task
Create a module that, finds out how many points of interest every
viewer is able to see, if placed at the different heights from the
ground: 1 meter, 10 meters, 100 meters. Create MultiLines for every
viewer by bundling all the successful lines of sight to a point of
interest.
38. The evacuation plan
Needed data
• the road network (vector map)
• the addresse along the roads (vector map)
• an evacuation area (vector map)
Task
Create a module that, given an evacuation area, subdivides that area
in circles/annuluses centered in the area's centroid. It then has to
produce the list of addresses divided by distance section.
39. Simple zonalstats
Needed data
• DEM (raster map)
• basins (vector map)
Task
Create a module that extracts basics statistics (max, min, avg) from
the DEM for each basin of the vector map.
40. This work is released under Creative Commons Attribution Share
Alike (CC-BY-SA)
Much of the knowledge needed to create this training material has
been produced by the sparkling knights of the GeoTools, JTS and
uDig community. Another essential source has been the Wikipedia
community effort.
Particular thanks go to those friends that directly or indirectly helped
out in the creation and review of this developer's handbook: Jody
Garnett from the uDig/GeoTools community and the TANTO team.
This tutorial was written with the support of the Geoinformation
Research Group of the University of Potsdam and HydroloGIS.