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

org.nuiton.jaxx.widgets.gis.DmsCoordinate Maven / Gradle / Ivy

package org.nuiton.jaxx.widgets.gis;

/*
 * #%L
 * JAXX :: Widgets
 * %%
 * Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import io.ultreia.java4all.i18n.I18n;
import org.jdesktop.beans.AbstractSerializableBean;

import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Pattern;

/**
 * Geo coordinate in degree, minute, second format.
 * 

* Created on 10/23/13. * * @author Tony Chemit - [email protected] * @since 2.12 */ public class DmsCoordinate extends AbstractSerializableBean implements Coordinate { public static final String COORDINATE_STRING_PATTERN = "%s%s°%s'%s''"; public static final Pattern COORDINATE_PATTERN = Pattern.compile("(.*)°(.*)'(.*)''"); public static final String PROPERTY_SIGN = "sign"; public static final String PROPERTY_DEGREE = "degree"; public static final String PROPERTY_MINUTE = "minute"; public static final String PROPERTY_SECOND = "second"; private static final long serialVersionUID = 1L; protected boolean sign; protected Integer degree; protected Integer minute; protected Integer second; public static DmsCoordinate empty() { return new DmsCoordinate(); } /** * Methode statique de fabrique de position a partir d'un autre {@link DmsCoordinate}. *

* Note : Si la valeur vaut null, alors on * reinitialise les composants de la position a null 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 DmsCoordinate valueOf(DmsCoordinate decimal) { DmsCoordinate r = new DmsCoordinate(); if (decimal != null) { r.setSign(decimal.isSign()); r.setDegree(decimal.getDegree()); r.setMinute(decimal.getMinute()); r.setSecond(decimal.getSecond()); } return r; } /** * Methode statique de fabrique de position a partir d'une valeur du format * decimal. *

* Note : Si la valeur (au format decimal) vaut null, alors on * reinitialise les composants de la position a null 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 DmsCoordinate valueOf(Float decimal) { DmsCoordinate r = new DmsCoordinate(); r.fromDecimal(decimal); return r; } /** * Methode statique de fabrique de position a partir d'une valeur du format * degre-minute-seconde. * * @param sign le signe * @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 DmsCoordinate valueOf(boolean sign, Integer d, Integer m, Integer s) { DmsCoordinate r = new DmsCoordinate(); r.setSign(sign); r.setDegree(d); r.setMinute(m); r.setSecond(s); return r; } @Override public CoordinateFormat format() { return CoordinateFormat.dms; } public boolean isSign() { return sign; } public void setSign(boolean sign) { Object oldValue = isSign(); this.sign = sign; firePropertyChange(PROPERTY_SIGN, oldValue, sign); } public Integer getDegree() { return degree; } public void setDegree(Integer degree) { Object oldValue = getDegree(); this.degree = degree; firePropertyChange(PROPERTY_DEGREE, oldValue, degree); } public Integer getMinute() { return minute; } public void setMinute(Integer minute) { Object oldValue = getMinute(); this.minute = minute; firePropertyChange(PROPERTY_MINUTE, oldValue, minute); } public Integer getSecond() { return second; } public void setSecond(Integer second) { Object oldValue = getSecond(); this.second = second; firePropertyChange(PROPERTY_SECOND, oldValue, second); } public boolean isDegreeNull() { return degree == null || degree == 0; } public boolean isMinuteNull() { return minute == null || minute == 0; } public boolean isSecondNull() { return second == null || second == 0; } /** * @return {@code true} si aucune composante n'est renseignée, * {@code false} autrement. */ @Override public boolean isNull() { return degree == null && minute == null && second == null; } /** * Mets a jour les composants de la position a partir d'une valeur decimal. *

* Note : Si la valeur (au format decimal) vaut null, alors on * reinitialise les composants de la position a null et la * methode {@link #isNull()} vaudra alors {@code true}. * * @param decimal la valeur decimale a convertir (qui peut etre nulle). */ @Override public void fromDecimal(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.0f * (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; } } degree = d; minute = m; second = s; sign = si; if (decimal != null) { removeTrailingZero(); } } @Override public Float toDecimal() { if (isNull()) { return null; } int d = getNotNullDegree(); int m = getNotNullMinute(); int s = getNotNullSecond(); Float result = (float) 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; } result = CoordinateHelper.roundToFourDecimals(result); return result; } @Override public void addTrailingZero() { if (degree == null) { degree = 0; } if (minute == null) { minute = 0; } if (second == null) { second = 0; } } @Override public void removeTrailingZero() { if (degree != null && degree == 0) { degree = null; } if (minute != null && minute == 0) { minute = null; } if (second != null && second == 0) { second = null; } } @Override public void validateLatitude(BiConsumer messageConsumer) { Integer degree = getDegree(); if (degree != null) { if (degree > 90) { messageConsumer.accept(I18n.n("jaxx.validation.coordinate.degree.latitude.outOfBound"), degree); } } Integer minute = getMinute(); if (minute != null) { if (minute > 59) { messageConsumer.accept(I18n.n("jaxx.validation.coordinate.minute.latitude.outOfBound"), minute); } } Integer second = getSecond(); if (second != null) { if (second > 59) { messageConsumer.accept(I18n.n("jaxx.validation.coordinate.second.latitude.outOfBound"), second); } } } @Override public void validateLongitude(BiConsumer messageConsumer) { Integer degree = getDegree(); if (degree != null) { if (degree > 180) { messageConsumer.accept(I18n.n("jaxx.validation.coordinate.degree.longitude.outOfBound"), degree); } } Integer minute = getMinute(); if (minute != null) { if (minute > 59) { messageConsumer.accept(I18n.n("jaxx.validation.coordinate.minute.longitude.outOfBound"), minute); } Integer second = getSecond(); if (second != null) { if (second > 59) { messageConsumer.accept(I18n.n("jaxx.validation.coordinate.second.longitude.outOfBound"), second); } } } } public Integer getSignedDegree() { Integer result = null; if (!isDegreeNull()) { result = degree; if (isSign()) { result *= -1; } } return result; } public int getNotNullDegree() { return isDegreeNull() ? 0 : degree; } public int getNotNullMinute() { return isMinuteNull() ? 0 : minute; } public int getNotNullSecond() { return isSecondNull() ? 0 : second; } public boolean isLatitudeDegreeValid() { return isDegreeValid(false); } public boolean isLongitudeDegreeValid() { return isDegreeValid(true); } public boolean isMinuteValid() { boolean result = true; if (!isMinuteNull()) { if (60 == minute) { // check minute and second are null result = isSecondNull(); } else { result = 0 <= minute && minute < 60; } } return result; } public boolean isSecondValid() { return isSecondNull() || (0 <= second && second < 60); } @Override public String toString() { return "DmsCoordinateComponent{" + "sign=" + sign + ", degree=" + degree + ", minute=" + minute + ", second=" + second + '}'; } protected boolean isDegreeValid(boolean longitude) { boolean result = true; if (!isDegreeNull()) { int bound = longitude ? 180 : 90; if (bound == degree) { // check minute and second are null result = isMinuteNull() && isSecondNull(); } else { result = degree < bound; } } return result; } public void reset() { degree = null; minute = null; second = null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy