Author: tchemit Date: 2012-12-20 16:02:18 +0100 (Thu, 20 Dec 2012) New Revision: 96 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/96 Log: refs #1899: Cr?\195?\169er un ?\195?\169diteur de position spatiale (help to convert from sexagecimal to decimal) Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/GeoPositionHelper.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/GeoPositionHelper.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/GeoPositionHelper.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/GeoPositionHelper.java 2012-12-20 15:02:18 UTC (rev 96) @@ -0,0 +1,121 @@ +package fr.ifremer.tutti.persistence.spatial; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 Ifremer + * %% + * 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, either version 3 of the + * License, or (at your option) any later version. + * + * 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, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +/** + * Helper about geo position computation. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class GeoPositionHelper { + + /** + * Calcule le quadrant à partir d'une {@code longitude} et {@code latitude}. + * + * @param longitude la longitude décimale + * @param latitude la latitude décimale + * @return la valeur du quadrant ou {@code null} si l'une des deux + * coordonnées est {@code null}. + * @since 0.3 + */ + public static Integer getQuadrant(Float longitude, Float latitude) { + if (longitude == null || latitude == null) { + return null; + } + int result; + + if (latitude > 0) { + result = longitude > 0 ? 1 : 4; + } else { + result = longitude > 0 ? 2 : 3; + } + return result; + } + + /** + * Calcule la valeur signée de la longitude à partir du {@code quadrant} et + * de la valeur absolue de la {@code longitude}. + * + * @param quadrant la valeur du quandrant (peut être null) + * @param longitude la longitude décimale (peut être null) + * @return la valeur signée de la longitude ou {@code null} si l'une des + * deux données d'entrée est {@code null}. + * @since 0.3 + */ + public static Float getSignedLongitude(Integer quadrant, Float longitude) { + if (longitude == null) { + return null; + } + if (quadrant == null) { + + // cas special ou pas encore de quadrant positionne, on conserve + // juste la valeur de la longitude sans rien faire d'autre + return longitude; + } + int result; + switch (quadrant) { + case 1: + case 2: + result = 1; + break; + default: + result = -1; + } + return result * longitude; + } + + /** + * Calcule la valeur signée de la latitude à partir du {@code quadrant} et + * de la valeur absolue de la {@code latitude}. + * + * @param quadrant la valeur du quandrant (peut être null) + * @param latitude la longitude décimale (peut être null) + * @return la valeur signée de la latitude ou {@code null} si l'une des + * deux données d'entrée est {@code null}. + * @since 0.3 + */ + public static Float getSignedLatitude(Integer quadrant, Float latitude) { + if (latitude == null) { + return null; + } + if (quadrant == null) { + + // cas special ou pas encore de quadrant positionne, on conserve + // juste la valeur de la latitude sans rien faire d'autre + return latitude; + } + int result; + switch (quadrant) { + case 1: + case 4: + result = 1; + break; + default: + result = -1; + } + return result * latitude; + } +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/GeoPositionHelper.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java 2012-12-20 15:02:18 UTC (rev 96) @@ -0,0 +1,235 @@ +package fr.ifremer.tutti.persistence.spatial; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 Ifremer + * %% + * 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, either version 3 of the + * License, or (at your option) any later version. + * + * 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, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.apache.commons.lang3.ObjectUtils; + +import java.io.Serializable; + +/** + * Define a geo spatial position coordinate in degre, minute, second. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class SexagecimalPosition implements Serializable { + + private static final long serialVersionUID = 1L; + + protected boolean sign; + + protected Integer degre; + + protected Integer minute; + + protected Integer seconde; + + /** + * Methode statique de fabrique de position a partir d'une valeur du format + * decimal. + * <p/> + * Note : Si la valeur (au format decimal) vaut <code>null</code>, alors on + * reinitialise les composants de la position a <code>null</code> et la + * methode {@link #isNull()} vaudra alors {@code true}. + * + * @param decimal la valeur au format decimal + * @return une nouvelle instance de position convertie + */ + public static SexagecimalPosition valueOf(Float decimal) { + SexagecimalPosition r = new SexagecimalPosition(); + r.update(decimal); + return r; + } + + /** + * Methode statique de fabrique de position a partir d'une valeur du format + * degre-minute-seconde. + * + * @param d la valeur des degres + * @param m la valeur des minutes + * @param s la valeur des secondes + * @return une nouvelle instance de position convertie + */ + public static SexagecimalPosition valueOf(boolean sign, int d, int m, int s) { + SexagecimalPosition r = new SexagecimalPosition(); + r.setSign(sign); + r.setDegre(d); + r.setMinute(m); + r.setSeconde(s); + return r; + } + + /** + * @return {@code true} si aucune composante n'est renseigné, + * {@code false} autrement. + */ + public boolean isNull() { + return degre == null && minute == null && seconde == null; + } + + /** + * Mets a jour les composants de la position a partir d'une valeur decimal. + * <p/> + * Note : Si la valeur (au format decimal) vaut <code>null</code>, alors on + * reinitialise les composants de la position a <code>null</code> et la + * methode {@link #isNull()} vaudra alors {@code true}. + * + * @param decimal la valeur decimale a convertir (qui peut etre nulle). + */ + public void update(Float decimal) { + Integer d = null; + Integer m = null; + Integer s = null; + boolean si = false; + if (decimal != null) { + si = decimal < 0; + + decimal = Math.abs(decimal); + int remain = 0; + + d = (int) (Math.round(decimal + 0.5) - 1); + m = 0; + s = 0; + decimal = 60 * (decimal - d); + if (decimal > 0) { + m = (int) (Math.round(decimal + 0.5) - 1); + decimal = 60 * (decimal - m); + if (decimal > 0) { + s = (int) (Math.round(decimal + 0.5) - 1); + remain = (int) (10 * (decimal - s)); + } + } + if (remain > 9) { + s++; + } + if (s == 60) { + m++; + s = 0; + } + if (m == 60) { + d++; + m = 0; + } + } + degre = d; + minute = m; + seconde = s; + sign = si; + } + + public Float toDecimal() { + if (isNull()) { + return null; + } + Integer d = degre == null ? 0 : degre; + Integer m = minute == null ? 0 : minute; + Integer s = seconde == null ? 0 : seconde; + Float result = Float.valueOf(d); + if (m > 0) { + result += (float) m / 60; + if (s == 0) { + result += 0.5f / 3600; + } + } + if (s > 0) { + result += ((float) s + 0.5f) / 3600; + } + if (sign) { + result *= -1; + } + return result; + } + + public Integer getDegre() { + return degre; + } + + public Integer getMinute() { + return minute; + } + + public Integer getSeconde() { + return seconde; + } + + public boolean isSign() { + return sign; + } + + public void setDegre(Integer degre) { + this.degre = degre; + } + + public void setMinute(Integer minute) { + this.minute = minute; + } + + public void setSeconde(Integer seconde) { + this.seconde = seconde; + } + + public void setSign(boolean sign) { + this.sign = sign; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SexagecimalPosition other = (SexagecimalPosition) obj; + return sign == other.sign && + ObjectUtils.equals(degre, other) && + ObjectUtils.equals(minute, other.minute) && + ObjectUtils.equals(seconde, other.seconde); + + } + + @Override + public String toString() { + return super.toString() + "<" + (sign ? "-" : "") + degre + "° " + minute + "' " + seconde + "''>"; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 5 * (sign ? 1 : 0); + hash = 7 * hash + (degre != null ? degre.hashCode() : 0); + hash = 11 * hash + (minute != null ? minute.hashCode() : 0); + hash = 13 * hash + (seconde != null ? seconde.hashCode() : 0); + return hash; + } + + protected SexagecimalPosition() { + // contructeur non publique, on prefere l'utilisation de la methode + // #valueOf() + } +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native