[OpenMap Users] Fw: A little change to DistanceMouseMode, and other problems

From: Piotr Kamiński <Piotr.Kaminski@ctm.gdynia.pl>
Date: Fri Jan 09 2004 - 02:34:55 EST

Hi,
I wrote about DistanceMouseMode modifications (see below). I can't find those changes in
current OpenMap sources. Don, could you add those changes? I've attached new DistanceMouseMode.java file.
Regards,
Piotr Kaminski

----- Original Message -----
From: pitek
To: openmap-users@bbn.com
Sent: Sunday, October 26, 2003 11:20 PM
Subject: A little change to DistanceMouseMode, and other problems

Hi all,
I've made a little change in DistanceMouseMode. I had a need to subclass
it and change the way it formats latitude, longitude, distance and azimuth.
In original class whole formating was done in mouseMoved() method.
I've changed it the way similar to CoordMouseMode.
Here is the code:

/**
     * Draw a rubberband line and circle as the mouse is moved.
     * Calculate distance and azimuth angle as the mouse moves.
     * Display distance and azimuth angle in on the infoDelegator.
     * @param e mouse event.
     */
    public void mouseMoved(MouseEvent e) {
 if (e.getSource() instanceof MapBean) {
     // only when the mouse has already been pressed
     if (mousePressed) {
  float lat1, lat2, long1, long2;
  // set the map bean
  theMap = (MapBean)(e.getSource());
  // erase the old line and circle first
  paintRubberband(rPoint1, rPoint2);
  // get the current mouse location in latlon
  rPoint2 = theMap.getProjection().inverse(e.getPoint());
  // paint the new line and circle up to the current mouse location
  paintRubberband(rPoint1, rPoint2);

  if (infoDelegator != null) {
      Debug.message("mousemodedetail",
      "DistanceMouseMode: firing mouse location");
      // lat, lon of anchor point
      lat1 = rPoint1.getLatitude();
      long1 = rPoint1.getLongitude();
      // lat, lon of current mouse position
      lat2 = rPoint2.getLatitude();
      long2 = rPoint2.getLongitude();
      // calculate great circle distance in nm
// distance = getGreatCircleDist(lat1, long1,
// lat2, long2, Length.NM);
      distance = (double)GreatCircle.spherical_distance(ProjMath.degToRad(lat1),
          ProjMath.degToRad(long1),
          ProjMath.degToRad(lat2),
          ProjMath.degToRad(long2));
      
      // calculate azimuth angle dec deg
      float azimuth = getSphericalAzimuth(lat1, long1, lat2, long2);
      // convert total distance into all distance units
// String distNM = df.format(totalDistance+distance);
      double tmpDistance = totalDistance+distance;
                    String infoLine;
                    infoLine = createDistanceInformationLine(rPoint2,tmpDistance,azimuth);
                    // setup the info event
                    InfoDisplayEvent info = new InfoDisplayEvent(this, infoLine);
                    // ask the infoDelegator to display the info
                    infoDelegator.requestInfoLine(info);
                }
     } else {
  fireMouseLocation(e);
     }
 }
    }
    

    protected String createDistanceInformationLine(LatLonPoint llp, double distance, double azimuth) {
        // setup the distance info to be displayed
        String unitInfo = null;
        // what unit is asked for
        if (unit == null) {
            unitInfo = df.format(Length.NM.fromRadians((float)distance)) +
            Length.NM.getAbbr() + ", " +
            df.format(Length.KM.fromRadians((float)distance)) +
            Length.KM.getAbbr() + ", " +
            df.format(Length.MILE.fromRadians((float)distance)) +
            Length.MILE.getAbbr() + " ";
        } else {
            unitInfo = unit.fromRadians((float)distance) + " " + unit.getAbbr();
        }
        // add the mouse lat, lon
        String infoLine = "Lat, Lon (" +
        df.format(llp.getLatitude()) +
        ", " + df.format(llp.getLongitude()) +
        "), distance (";
        // add the units
        infoLine = infoLine + unitInfo + ")";
        // add the azimuth angle if need be
        if (showAngle) infoLine = infoLine + ", angle (" +
        df.format(azimuth) + ")";
        return infoLine;
    }

In sublass I have two methods, which only formats infoLine string:

  protected String createDistanceInformationLine(LatLonPoint llp, double distance, double azimuth) {
        String infoLine = "Lat: " + GeoFormatter.formatLatitude(llp.getLatitude())
        + " Lon: " + GeoFormatter.formatLongitude(llp.getLongitude())
        + " Distance: " + df.format(Length.NM.fromRadians((float)distance)) + Length.NM.getAbbr()
        + " = " + df.format(Length.KM.fromRadians((float)distance)) + Length.KM.getAbbr()
        + " Azimuth: " + GeoFormatter.formatAzimuth(azimuth,3);
        return infoLine;
    }
 
       protected String createCoordinateInformationLine(int x, int y, LatLonPoint llp) {
        if (llp != null) {
            return "Lat: " + GeoFormatter.formatLatitude(llp.getLatitude())
            + " Lon: " + GeoFormatter.formatLongitude(llp.getLongitude());
        } else {
            return "x, y (" + x + "," + y + ")";
        }
    }

Additionaly I used GeoFormatter class:

package com.obrctm.geo;

import java.text.NumberFormat;

public class GeoFormatter {
    
    /**
     * Tworzy nowy obiekt klasy Formatter.
     */
    private GeoFormatter() {
    }
        
    public static String formatLatitude(float latitude) {
       return formatDegreesMinutes(latitude, 2, latitude <0 ? "S" : "N");
    }
    
    public static String formatLongitude(float longitude) {
       return formatDegreesMinutes(longitude, 3, longitude <0 ? "W" : "E");
    }
    
    public static String formatDegreesMinutes(double value, int integerDigits, String semisphere) {
        double valueAbs = Math.abs(value);
        int degrees = (int)valueAbs;
        double minutes = (valueAbs - degrees)*60.0;
        
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMinimumIntegerDigits(integerDigits);
        nf.setMaximumIntegerDigits(integerDigits);
        String strDegrees = nf.format(degrees);
        nf.setMinimumIntegerDigits(2);
        nf.setMaximumIntegerDigits(2);
        nf.setMinimumFractionDigits(3);
        nf.setMaximumFractionDigits(3);
        String strMinutes = nf.format(minutes);
        return strDegrees+"\u00b0"+strMinutes+"'"+semisphere;
    }
    
    public static String formatAzimuth(double value, int fractionDigits) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMinimumIntegerDigits(3);
        nf.setMaximumIntegerDigits(3);
        nf.setMinimumFractionDigits(fractionDigits);
        nf.setMaximumFractionDigits(fractionDigits);
        return nf.format(value)+"\u00b0";
    }
}

Don, what do you think about this little change in DistanceMouseMode?
The GeoFormatter class could be, or could not be added to OpenMap if you like.
But I think that separation of string formatting and distance calculation is
important I'd like to see it in OpenMap's main source tree. This little change
helps me a lot in changing DistanceMouseMode presentation with simple
overriding of two methods.

We could make this even better using strategy pattern. User could specify
its own class for distance or coordinates presentation. For example instead of
using InformationDelegator he/she could use its own GUI window.
Instead of simple string/label presentation, complex JavaBeans GUI could be used.
Such class could be specifed in properties file or dynamicaly change at run-time.
    
Some time ago I wrote about changing ProjectionFactory class. Don, are you going
to implement some kind of pluggable projections, as you wrote?

I'm facing again with localization problem. Did you rethink how to make OpenMap
localization? The last e-mail thread finished without clear conclusion. I'd like
to know how to make localization if I start doing it. Someone wrote about
French localization. Is there any progress in this domain?

Please let me know what do you think about those problems.

Best regards,
Piotr Kaminski

--
[To unsubscribe to this list send an email to "majdart@bbn.com"
with the following text in the BODY of the message "unsubscribe openmap-users"]
Received on Fri Jan 9 02:36:06 2004

This archive was generated by hypermail 2.1.8 : Thu May 12 2005 - 07:18:37 EDT