/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma; import java.io.Serializable; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import static java.lang.Double.isNaN; public class Coordinate implements Comparable<Coordinate>, Serializable { private static final long serialVersionUID = 8139103526460838188L; private static final String[] LATITUDES_KEYS = new String[] { "lat", "latitude", "lt" }; private static final String[] LONGITUDES_KEYS = new String[] { "lon", "lng", "longitude", "lg" }; private final double longitude; private final double latitude; public Coordinate(double longitude, double latitude) { this.longitude = longitude; this.latitude = latitude; } public double getLongitude() { return longitude; } public double getLatitude() { return latitude; } public double[] toArray() { return new double[] { longitude, latitude }; } @Override public int compareTo(Coordinate o) { if(longitude < o.getLongitude()) return -1; if(longitude > o.getLongitude()) return 1; if(latitude < o.getLatitude()) return -1; if(latitude > o.getLatitude()) return 1; return 0; } @Override public boolean equals(Object obj) { if(this == obj) return true; if(obj == null) return false; if(obj instanceof Coordinate) { Coordinate o = (Coordinate) obj; return getLatitude() == o.getLatitude() && getLongitude() == o.getLongitude(); } return false; } @Override public int hashCode() { int result = 17; result = 37 * result + Double.valueOf(longitude).hashCode(); result = 37 * result + Double.valueOf(latitude).hashCode(); return result; } @Override public String toString() { return "[" + longitude + "," + latitude + "]"; } public static Coordinate getCoordinateFrom(String string) { // GeoJSON coordinate if(string.trim().startsWith("[")) { try { return getCoordinateFrom(new JSONArray(string)); } catch(JSONException e) { throw new MagmaRuntimeException("Not a valid GeoJSON coordinate", e); } } // JSON coordinate if(string.trim().startsWith("{")) { try { return getCoordinateFrom(new JSONObject(string)); } catch(JSONException e) { throw new MagmaRuntimeException("Not a valid JSON coordinate", e); } } // Google coordinate lat,long try { JSONArray array = new JSONArray("[" + string.trim() + "]"); return new Coordinate(array.getDouble(1), array.getDouble(0)); } catch(JSONException e) { throw new MagmaRuntimeException("Not a valid coordinate", e); } } public static Coordinate getCoordinateFrom(Object o) { if(o.getClass().equals(Coordinate.class)) { return (Coordinate) o; } if(o.getClass().equals(String.class)) { return getCoordinateFrom((String) o); } if(o.getClass().equals(JSONArray.class)) { return getCoordinateFrom((JSONArray) o); } if(o.getClass().equals(JSONObject.class)) { return getCoordinateFrom((JSONObject) o); } return getCoordinateFrom(o.toString()); } public static Coordinate getCoordinateFrom(JSONObject object) { double lat = getKeyValue(LATITUDES_KEYS, object); double lng = getKeyValue(LONGITUDES_KEYS, object); return new Coordinate(lng, lat); } public static Coordinate getCoordinateFrom(JSONArray array) { try { return new Coordinate(array.getDouble(0), array.getDouble(1)); } catch(JSONException e) { throw new MagmaRuntimeException("Not a valid GeoJSON coordinate", e); } } private static double getKeyValue(String[] keyList, JSONObject object) { double value = 0; for(String key : keyList) { value = object.optDouble(key); if(!isNaN(value)) { break; } } if(isNaN(value)) { throw new MagmaRuntimeException("The latitude or the longitude is not defined"); } return value; } }