001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.util;
029
030import org.opencms.json.JSONException;
031import org.opencms.json.JSONObject;
032
033/**
034 * Utility methods for processing geo coordinates.
035 */
036public final class CmsGeoUtil {
037
038    /**
039     * Parses coordinates, either from a lat,lon pair or from the JSON generated by the location picker.
040     * @param coordinates the coordinates string
041     * @return the parsed coordinates
042     */
043    public static String parseCoordinates(String coordinates) {
044
045        if (coordinates == null) {
046            return null;
047        }
048        String locationPickerCoordinates = CmsGeoUtil.parseLocationPickerCoordinates(coordinates);
049        if (locationPickerCoordinates != null) {
050            return locationPickerCoordinates;
051        } else if (CmsGeoUtil.validateCoordinates(coordinates)) {
052            return coordinates;
053        }
054        return null;
055    }
056
057    /**
058     * Parses a location picker JSON value and returns the coordinates contained therein.
059     * @param jsonValue the JSON value as string
060     * @return the coordinates string or null if there are no valid location picker coordinates
061     */
062    public static String parseLocationPickerCoordinates(String jsonValue) {
063
064        try {
065            JSONObject json = new JSONObject(jsonValue);
066            if (!CmsGeoUtil.validateLocationPickerCoordinates(json)) {
067                return null;
068            }
069            return json.getString("lat") + "," + json.getString("lng");
070        } catch (JSONException e) {
071            return null;
072        }
073    }
074
075    /**
076     * Validates a coordinates string and returns the validation result.
077     * @param coordinates the coordinates string to validate
078     * @return whether the coordinates are valid (true) or invalid (false)
079     */
080    public static boolean validateCoordinates(String coordinates) {
081
082        if (CmsStringUtil.isEmptyOrWhitespaceOnly(coordinates)) {
083            return false;
084        }
085        if (!coordinates.contains(",")) {
086            return false;
087        }
088        String[] tokens = coordinates.split(",");
089        String latitude = tokens[0];
090        String longitude = tokens[1];
091        if (CmsGeoUtil.validateLatitude(latitude) && CmsGeoUtil.validateLongitude(longitude)) {
092            return true;
093        }
094        return false;
095    }
096
097    /**
098     * Validates a latitude string.
099     * @param latitude the latitude string to validate
100     * @return whether the string is a valid latitude value (true) or not (false)
101     */
102    public static boolean validateLatitude(String latitude) {
103
104        try {
105            double value = Double.parseDouble(latitude);
106            return (value <= 90) && (value >= -90);
107        } catch (NumberFormatException e) {
108            return false;
109        }
110    }
111
112    /**
113     * Validates the coordinates contained in a given location picker JSON value.
114     * @param jsonObject the JSON value
115     * @return whether JSON contains valid coordinates (true) or not (false)
116     */
117    public static boolean validateLocationPickerCoordinates(JSONObject jsonObject) {
118
119        try {
120            String latitude = jsonObject.getString("lat");
121            String longitude = jsonObject.getString("lng");
122            if (CmsStringUtil.isEmptyOrWhitespaceOnly(latitude) || CmsStringUtil.isEmptyOrWhitespaceOnly(longitude)) {
123                return false;
124            }
125            return validateLatitude(latitude) && CmsGeoUtil.validateLongitude(longitude);
126        } catch (JSONException e) {
127            return false;
128        }
129    }
130
131    /**
132     * Validates a longitude string.
133     * @param longitude the longitude string to validate
134     * @return whether the string is a valid longitude value (true) or not (false)
135     */
136    public static boolean validateLongitude(String longitude) {
137
138        try {
139            double value = Double.parseDouble(longitude);
140            return (value <= 180) && (value >= -180);
141        } catch (NumberFormatException e) {
142            return false;
143        }
144    }
145
146    /**
147     * Validates a radius string.
148     * @param radius the radius
149     * @return whether a valid radius string or not
150     */
151    public static boolean validateRadius(String radius) {
152
153        try {
154            double value = Double.parseDouble(radius);
155            return value >= 0;
156        } catch (NumberFormatException e) {
157            return false;
158        }
159    }
160
161    /**
162     * Validates a units string.
163     * @param units the units string
164     * @return whether a valid units string or not
165     */
166    public static boolean validateUnits(String units) {
167
168        if (CmsStringUtil.isEmptyOrWhitespaceOnly(units)) {
169            return false;
170        }
171        return units.equals("km") || units.equals("mi");
172    }
173}