All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.tidalwave.geo.CoordinateFormat Maven / Gradle / Ivy

/***********************************************************************************************************************
 *
 * forceTen - open source geography
 * Copyright (C) 2007-2012 by Tidalwave s.a.s. (http://www.tidalwave.it)
 *
 ***********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 *
 ***********************************************************************************************************************
 *
 * WWW: http://forceten.tidalwave.it
 * SCM: https://bitbucket.org/tidalwave/forceten-src
 *
 **********************************************************************************************************************/
package it.tidalwave.geo;

// COPIED FROM windrose.dev.java.net

/*******************************************************************************
 *
 * This classes formats polar coordinates (latitude and longitude).
 *
 * @author  Fabrizio Giudici
 * @version $Id$
 *
 ******************************************************************************/
public class CoordinateFormat
  {
    static public class Splitter
      {
//        private double angle;
        private int degreesRounded;
        private double primes;
        private int primesRounded;
        private double seconds;
        private int secondsRounded;
        private int secondsMillis;
        
        public Splitter (double angle)
          {
//            this.angle = angle;
            angle = (double)Math.round(Math.abs(angle) * RESOLUTION) / RESOLUTION;
            degreesRounded = (int)angle;
            primes = (angle - degreesRounded) * 60;
            primesRounded = (int)primes;
            seconds = (primes - primesRounded) * 60;
            secondsRounded = (int)seconds;
            secondsMillis = (int)Math.round(1000.0 * (seconds - secondsRounded));
            //
            // Take into account rounding errors.
            // FIXME: could be probably avoided by first multiplying by scale and
            // then using / and %
            //
            if (secondsMillis == 1000)
              {
                secondsMillis = 0;
                secondsRounded++;
              }

            if (secondsRounded == 60)
              {
                secondsRounded = 0;
                primesRounded++;
              }
            
            if (primesRounded == 60)
              {
                primesRounded = 0;
                degreesRounded++;
              }
          }
        
        public int getDegreesRounded()
          {
            return degreesRounded;  
          }
        
        public double getPrimes()
          {
            return primes;  
          }
        
        public int getPrimesRounded()
          {
            return primesRounded;  
          }
        
        public double getSeconds()
          {
            return seconds;  
          }
        
        public int getSecondsRounded()
          {
            return secondsRounded;  
          }
        
        public int getSecondMillis()
          {
            return secondsMillis;  
          }
      }
    
    private static final int RESOLUTION = 60 * 60 * 1000;
    
    private static final char NORTH = 'N';
    private static final char SOUTH = 'S';
    private static final char WEST = 'W';
    private static final char EAST = 'E';
    
    /***************************************************************************
     *
     * Formats a latitude in standard way (e.g. N 45 34'23.394").
     *
     * @param  latitude  the latitude to format in degrees
     * @return           the formatted latitude
     *
     **************************************************************************/
    public static String formatLatitude (double latitude)
      {
        return format(latitude, NORTH, SOUTH);
      }
    
    /***************************************************************************
     *
     * Formats a longitude in standard way (e.g. E 7 21'53.892").
     *
     * @param  longitude  the longitude to format in degrees
     * @return            the formatted longitude
     *
     **************************************************************************/
    public static String formatLongitude (double longitude)
      {
        return format(longitude, EAST, WEST);
      }
    
    /***************************************************************************
     *
     * Formats a generic polar coordinate.
     *
     * @param  angle            the coordinate
     * @param  positivePrefix   the prefix for positive values
     * @param  negativePrefix   the prefix for negative values
     *
     **************************************************************************/
    private static String format (double angle, char positivePrefix, char negativePrefix)
      {
        Splitter splitter = new Splitter(angle);
        //
        // Could be more compact with a NumberFormat, but we want to keep 
        // compatibility with J2ME.
        //
        StringBuffer buffer = new StringBuffer();
        buffer.append((angle >= 0) ? positivePrefix : negativePrefix);
        buffer.append(" ");
        buffer.append(splitter.getDegreesRounded());
        buffer.append("\u00b0 ");
        buffer.append(pad2(splitter.getPrimesRounded()));
        buffer.append("\' ");
        buffer.append(pad2(splitter.getSecondsRounded()));
        buffer.append(".");
        buffer.append(pad3(splitter.getSecondMillis()));
        buffer.append("\"");

        return buffer.toString();
      }
    
    /***************************************************************************
     *
     *
     **************************************************************************/
    private static String pad2 (int value)
      {
        String prefix = (value >= 10) ? "" : "0";
        return prefix + Integer.toString(value);
      }
    
    /***************************************************************************
     *
     *
     **************************************************************************/
    private static String pad3 (int value)
      {
        String prefix = (value >= 100) ? "" : 
                        (value >= 10)  ? "0" : 
                                         "00";
        return prefix + Integer.toString(value);
      }
  }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy