/* GNU General Public License CacheWolf is a software for PocketPC, Win and Linux that enables paperless caching. It supports the sites geocaching.com and opencaching.de Copyright (C) 2006 CacheWolf development team See http://www.cachewolf.de/ for more information. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package CacheWolf.navi; import CacheWolf.database.CWPoint; import ewe.sys.Convert; public class UTMProjection extends Projection { Ellipsoid ellip; public UTMProjection(Ellipsoid ellip) { this.ellip = ellip; zoneSeperately = true; // set to something else than 0 causes ProjectedPoint not to set epsgCode. epsgCode = -1; } //Overrides: project(...) in Projection public ProjectedPoint project(CWPoint wgs84, ProjectedPoint pp) { // we start with stripe 0, but officially this is stripe 1 int stripe = (int) Math.floor((wgs84.lonDec - 180) / 6); if (stripe < 0) stripe += 60; GkProjection.project(wgs84, ellip, 6, (stripe >= 30 ? stripe - 30 : stripe + 30), 3, 0.9996, pp); pp.zone = stripe + (int) (Math.floor((wgs84.latDec) / 8) + 13) * 200; return pp; } //Overrides: project(...) in Projection public ProjectedPoint project(CWPoint ll, ProjectedPoint pp, int epsg) { if (epsg == TransformCoordinates.LOCALSYSTEM_UTM_WGS84) return project(ll, pp); throw new UnsupportedOperationException("UTMProjection: project by epsg-code not supported"); } //Overrides: unproject(...) in Projection public CWPoint unproject(ProjectedPoint pp) { int stripe = pp.zone - (int) Math.floor(pp.zone / 200) * 200; int stripelon = stripe * 6 - 177; return GkProjection.unproject(pp, stripelon, ellip, 0.9996); } //Overrides: getNorthing(...) in Projection public double getNorthing(ProjectedPoint pp) { return (pp.rawNorthing >= 0 ? pp.rawNorthing : pp.rawNorthing + 10000000); } //Overrides: getEasting(...) in Projection public double getEasting(ProjectedPoint pp) { return pp.rawEasting + 500000; } //Overrides: set(...) in Projection public ProjectedPoint set(double northing, double easting, String zone, ProjectedPoint pp) { if (zone.length() < 1) throw new IllegalArgumentException("UTMProjection.set: zone must be set"); if (zone.length() > 3) throw new IllegalArgumentException("UTMProjection.set: zone must not have more than 3 letters"); char lastletter = zone.charAt(zone.length() - 1); int zoneletter = -1; if ((lastletter > 'a') && (lastletter < 'z')) zoneletter = lastletter - 'a'; if ((lastletter > 'A') && (lastletter < 'Z')) zoneletter = lastletter - 'A'; if (zoneletter > 'i' - 'a') zoneletter--; if (zoneletter > 'o' - 'a') zoneletter--; int zonenumer = -1; if (zoneletter == -1) { zoneletter = 'n' - 'a'; // default to northern hemisphere zonenumer = Convert.parseInt(zone); } else { zonenumer = Convert.parseInt(zone.substring(0, zone.length() - 1)); } if (zonenumer == -1) throw new IllegalArgumentException("UTMProjection.set: could not parse zone number"); return set(northing, easting, zonenumer, zoneletter, pp); } //Overrides: getZone(...) in Projection public String getZone(ProjectedPoint pp) { int zoneletter = (int) Math.floor(pp.zone / 200); return Convert.formatInt(pp.zone - zoneletter * 200 + 1) + getZoneLetter(zoneletter); } private char getZoneLetter(int number) { if (((char) (number)) > 'i' - 'a') number++; // skip I if (((char) (number)) > 'o' - 'a') number++; // skip O char ret = (char) (number + (int) 'A' - 1); return ret; } /** * * @param northing * @param easting * @param zone * @param zoneletternumber * @param pp * @return */ public ProjectedPoint set(double northing, double easting, int zone, int zoneletternumber, ProjectedPoint pp) { pp.rawEasting = easting - 500000; if (zoneletternumber < 'n' - 'a' -1) // 'n' is the first band in northern hemisphere, -1: skip the letter i pp.rawNorthing = northing - 10000000; else pp.rawNorthing = northing; pp.zone = zone - 1 + zoneletternumber * 200; // internally zone number starts with 0 return pp; } }