Adding Graphic Objects on Top of an Imported Map

This section is based on an example that loads a map of the USA projected with a Lambert Azimuthal Equal Area projection into a manager, and adds cities on top of the map. The geographic coordinates indicated by the mouse pointer as well as the name of the cities pointed to are displayed in text fields at the bottom of the window. This section also gives information about the instantiating and the parameterization of a projected coordinate system, describes how to convert data from geographic coordinates to this projected coordinate system, and how to use a view interactor.
The complete source code for this example can be found in the following file:
Note
The purpose of this example is to give a tutorial on how to use coordinate transformations. It does not use JViews Maps beans such as IlvJMouseCoordinateViewer, to integrate with a data source or for map layer management.

Initializing coordinate systems

Since you need to convert from geographic coordinates to projected coordinates and vice versa, you need to keep an instance of these transformations. This is performed by means of the createTransformations() method.
First, initialize an instance of the projection used in the coordinate system of the imported map. In this example, the usa.ivl file is in Lambert Azimuthal Equal Area projection.
The projection parameters are:
Name of the Projection
Lambert Azimuthal Equal Area
Central Meridian
100DW
Central parallel
40DN
Measurement unit
Meters (the default value)
Offset
0 (the default value)
For more information on projection parameters see the section Projection parameters.
private void createTransformations()
{
  // Create the projection.
  IlvProjection projection = new IlvLambertAzimuthalEqualAreaProjection();
  projection.setEllipsoid(IlvEllipsoid.SPHERE);
  try {
      double centralMeridian = IlvAngularUnit.RADIAN.fromDMS("100DW");
      double centralParallel = IlvAngularUnit.RADIAN.fromDMS("40DN");
      projection.setCentralMeridian(centralMeridian);
      projection.setCentralParallel(centralParallel);
  } catch (IllegalArgumentException e) {
    System.out.println("wrong string passed to " 
                       + "IlvAngularUnit.RADIAN.fromDMS");
    System.out.println("unable to create the projection for the file"
                     + "usa.ivl");
    System.exit(0);
  }
Note that projection parameters are always specified using kernel units. In this case, the central meridian and parallel have to be specified in radians. Use the method IlvAngularUnit.RADIAN.fromDMS() to achieve this goal.
Once the Lambert Azimuthal projection has been initialized, you only have to create the corresponding projected coordinate system:
// Create the projected coordinate system.
IlvProjectedCoordinateSystem projectedCS = 
  new IlvProjectedCoordinateSystem("Lambert Azimutal Equal Area",
                                 projection);
You also create a geographic coordinate system whose ellipsoid is a simple sphere:
// Create the geographic coordinate system.
IlvGeographicCoordinateSystem geoCS =
   new IlvGeographicCoordinateSystem(IlvHorizontalShiftDatum.SPHERE_WGS84,
                             IlvMeridian.GREENWICH);
Finally, create the coordinate transformation and store also the inverse transformation for future quick reference:
// A coordinate transform.
geo2projCT = 
 IlvCoordinateTransformation.CreateTransformation(geoCS,projectedCS);
// The inverse transform.
proj2geoCT = geo2projCT.getInverse();

Adding cities

The addCitites() method adds a number of cities on top of the imported map of the United States:
private void addCities()
{
  addCity("Washington", "39D11'N", "76D51W");
  addCity("New York", "40D59'N", "73D39'W");
  addCity("Miami", "25D58'N", "80D02'W");
  addCity("San Francisco", "37D44'N", "122D20'W");
  addCity("Seattle", "47D51'N", "122D01'W");
  addCity("Denvers", "39D50'N", "104D53'W");
}
The coordinate conversion is performed in the addCity() method.
First, this method converts the DMS coordinates specified as string to degrees, in order to have the longitude and latitude coordinates of each point:
private void addCity(String cityName, String lat, String lon)
{
  try {
    double latitude = IlvAngularUnit.DEGREE.fromDMS(lat);
    double longitude = IlvAngularUnit.DEGREE.fromDMS(lon);
    IlvCoordinate coordinate = new IlvCoordinate(longitude,
                                                 latitude);
Then, it computes the projected coordinates by applying the forward coordinate transformation. If the coordinates cannot be transformed (for example, because the tolerance conditions have been exceeded), the transformation may throw an exception. This is why the code is contained inside a try/catch block.
The IlvProjectionUtil.invertY() method is then called to invert the y-coordinate: in the JViews Maps manager coordinate system, the y-axis is oriented downwards, whereas, in the projection coordinate system, it is oriented upwards.
    geo2projCT.transform(coordinate,coordinate);
    IlvPoint p = new IlvPoint((float)coordinate.x,
                                (float)coordinate.y);
    IlvProjectionUtil.invertY(p);
Note also that a new IlvPoint is allocated here. It will be used to create graphic objects (an IlvMarker) to represent the city. This graphic object is added to Layer #1 of the manager (Layer #0 contains the boundaries of the USA).
  IlvMarker marker = new IlvMarker(p, IlvMarker.IlvMarkerFilledDiamond);
      marker.setSize(4);
      marker.setForeground(Color.red);
      manager.addObject(marker, 1, false);
      marker.setName(cityName);
  } catch (IlvCoordinateTransformationException e) {
      e.printStackTrace();
  }

Setting the view interactor

In order to track mouse position, a view interactor is used. This is performed by means of the setViewInteractor() method.
First, create a selection interactor that will be used to select cities on the map. This interactor is configured so that multiple selections are not allowed, and the map cannot be modified, which means that the user will not be able to move cities around the map. The interactor is associated with the view. Note also that the elements making up Layer #0 (that is, borders) cannot be selected either.
private void setViewInteractor()
{
  IlvSelectInteractor interactor = new IlvSelectInteractor();
  interactor.setDragAllowed(false);
  interactor.setEditionAllowed(false);
  interactor.setMoveAllowed(false);
  interactor.setMultipleSelectionMode(false);
  manager.setSelectable(0, false);
  mgrview.pushInteractor(interactor);
Then, add a listener to the interactor that will display the longitude and the latitude indicated by the mouse in the appropriate text field. To compute the latitude and the longitude, apply the inverse transformation computed previously. The result returned by this method is formatted with the IlvAngularUnit.DEGREE.toDMS() method.
  // Display the position of the mouse.
  interactor.addMouseMotionListener(new MouseMotionAdapter() {
    public void mouseMoved(MouseEvent e) {
      // Get the point in manager coordinates.
      IlvTransformer t = mgrview.getTransformer();
      IlvPoint p = new IlvPoint(e.getX(), e.getY());
      t.inverse(p);
      IlvProjectionUtil.invertY(p);
      // Display the mouse position.
      try {
        IlvCoordinate c = new IlvCoordinate(p.x,p.y);
        proj2geoCT.transform(c,c);
        llField.setText(IlvAngularUnit.DEGREE.toDMS(c.x,false)
                        + " " +
                       IlvAngularUnit.DEGREE.toDMS(c.x,true));
      } catch (IlvCoordinateTransformationException ex) {
         System.out.println("Unable to inverse this point " + 
                            ex.getMessage());
       }
    }
  });
Finally, add a listener to the manager. This listener will display the name of the selected city in the appropriate text field.
manager.addManagerSelectionListener(new ManagerSelectionListener(){
  public void selectionChanged(ManagerSelectionChangedEvent e) {
    IlvGraphic g = e.getGraphic();
    if (g == null)
      return;
    String name = g.getName();
    if (name != null) 
       cityField.setText(name);
    }
  });
After you have compiled your sample, the map shown in Setting a view interactor should appear on the screen:
userman2.gif
Setting a view interactor