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

org.nervousync.utils.LocationUtils Maven / Gradle / Ivy

There is a newer version: 1.2.1
Show newest version
/*
 * Licensed to the Nervousync Studio (NSYC) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.nervousync.utils;

import org.nervousync.beans.location.GeoPoint;
import org.nervousync.exceptions.location.LocationConvertException;

/**
 * 

Geography Utilities

* * Current utilities implements features: *
    Convert GeoPoint at WGS84(GPS)/GCJ02/BD09
*
    Calculate distance of two given geography point. (Unit: Kilometers)
*
*

地理位置信息工具集

* * 此工具集实现以下功能: *
    在不同坐标系间转换数据,支持的坐标系:WGS84(GPS)/GCJ02/BD09
*
    计算两个物理坐标之间的距离,单位:公里
*
* * @author Steven Wee [email protected] * @version $Revision: 1.2.0 $ $Date: Dec 19, 2017 13:01:14 $ */ public final class LocationUtils { /** * Earth radius * 地球半径 */ private static final double EARTH_R = 6378245.0; /** * Square value of earth eccentricity * 地球偏心率平方值 */ private static final double EARTH_EE = 0.00669342162296594323; /** *

Private constructor for LocationUtils

*

地理位置信息工具集的私有构造方法

*/ private LocationUtils() { } /** *

Calculate distance of two given geography location. (Unit: Kilometers)

*

计算两个物理坐标之间的距离,单位:公里

* * @param beginPoint GroPoint instance of beginning geography location * 起始位置坐标的GroPoint实例 * @param endPoint GroPoint instance of end geography location * 终止位置坐标的GroPoint实例 * * @return Calculated distance value * 计算完成的距离值 * * @throws LocationConvertException * If convert GeoPoint instance to GPS location has error * 当转换GeoPoint为GPS坐标时出现错误 */ public static double calcDistance(final GeoPoint beginPoint, final GeoPoint endPoint) throws LocationConvertException { GeoPoint beginGPSPoint = anyToGPS(beginPoint); GeoPoint endGPSPoint = anyToGPS(endPoint); double tmpX = (endGPSPoint.getLongitude() - beginGPSPoint.getLongitude()) * Math.PI * EARTH_R * Math.cos(((beginGPSPoint.getLatitude() + endGPSPoint.getLatitude()) / 2) * Math.PI / 180) / 180; double tmpY = (endGPSPoint.getLatitude() - beginGPSPoint.getLatitude()) * Math.PI * EARTH_R / 180; return Math.hypot(tmpX, tmpY); } /** *

Convert given GeoPoint instance to GPS GeoPoint instance

*

转换给定的GeoPoint实例为GPS坐标GeoPoint实例

* * @param currentPoint Given GroPoint instance * 给定的坐标的GroPoint实例 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 * * @throws LocationConvertException * If convert GeoPoint instance to GPS location has error * 当转换GeoPoint为GPS坐标时出现错误 */ public static GeoPoint anyToGPS(final GeoPoint currentPoint) throws LocationConvertException { if (currentPoint == null) { throw new LocationConvertException(0x0000000C0001L, "Null_Point_Location_Error"); } switch (currentPoint.getLocationType()) { case GPS: return currentPoint; case GCJ_02: return GCJ02ToGPS(currentPoint.getLongitude(), currentPoint.getLatitude()); case BD_09: GeoPoint gcjPoint = BD09ToGCJ02(currentPoint.getLongitude(), currentPoint.getLatitude()); return GCJ02ToGPS(gcjPoint.getLongitude(), gcjPoint.getLatitude()); default: throw new LocationConvertException(0x0000000C0002L, "Not_Support_Type_Location_Error"); } } /** *

Convert given GeoPoint instance to GCJ02 GeoPoint instance

*

转换给定的GeoPoint实例为GCJ02坐标GeoPoint实例

* * @param currentPoint Given GroPoint instance * 给定的坐标的GroPoint实例 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 * * @throws LocationConvertException * If convert GeoPoint instance to GPS location has error * 当转换GeoPoint为GPS坐标时出现错误 */ public static GeoPoint anyToGCJ02(final GeoPoint currentPoint) throws LocationConvertException { if (currentPoint == null) { throw new LocationConvertException(0x0000000C0001L, "Null_Point_Location_Error"); } switch (currentPoint.getLocationType()) { case GPS: return GPSToGCJ02(currentPoint.getLongitude(), currentPoint.getLatitude()); case GCJ_02: return currentPoint; case BD_09: return BD09ToGCJ02(currentPoint.getLongitude(), currentPoint.getLatitude()); default: throw new LocationConvertException(0x0000000C0002L, "Not_Support_Type_Location_Error"); } } /** *

Convert given GeoPoint instance to BD09 GeoPoint instance

*

转换给定的GeoPoint实例为BD09坐标GeoPoint实例

* * @param currentPoint Given GroPoint instance * 给定的坐标的GroPoint实例 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 * * @throws LocationConvertException * If convert GeoPoint instance to GPS location has error * 当转换GeoPoint为GPS坐标时出现错误 */ public static GeoPoint anyToBD09(final GeoPoint currentPoint) throws LocationConvertException { if (currentPoint == null) { throw new LocationConvertException(0x0000000C0001L, "Null_Point_Location_Error"); } switch (currentPoint.getLocationType()) { case GPS: GeoPoint gcjPoint = GPSToGCJ02(currentPoint.getLongitude(), currentPoint.getLatitude()); return GCJ02ToBD09(gcjPoint.getLongitude(), gcjPoint.getLatitude()); case GCJ_02: return GCJ02ToBD09(currentPoint.getLongitude(), currentPoint.getLatitude()); case BD_09: return currentPoint; default: throw new LocationConvertException(0x0000000C0002L, "Not_Support_Type_Location_Error"); } } /** *

Convert GCJ02 GeoPoint instance to BD09 GeoPoint instance

*

转换GCJ02坐标的GeoPoint实例为BD09坐标GeoPoint实例

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 */ private static GeoPoint GCJ02ToBD09(final double longitude, final double latitude) { double fixValue = Math.sqrt(Math.pow(longitude, 2) + Math.pow(latitude, 2)) + 0.00002 * Math.sin(latitude * Math.PI); double delta = Math.atan2(latitude, longitude) + 0.000003 * Math.cos(longitude * Math.PI); double bdLat = fixValue * Math.sin(delta) + 0.006; double bdLon = fixValue * Math.cos(delta) + 0.0065; return GeoPoint.bd09Point(bdLon, bdLat); } /** *

Convert BD09 GeoPoint instance to GCJ02 GeoPoint instance

*

转换BD09坐标的GeoPoint实例为GCJ02坐标GeoPoint实例

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 */ private static GeoPoint BD09ToGCJ02(final double longitude, final double latitude) { double fixValue = Math.sqrt(Math.pow(longitude - 0.0065, 2) + Math.pow(latitude - 0.006, 2)) - 0.00002 * Math.sin((latitude - 0.006) * Math.PI); double fixTemp = Math.atan2(latitude - 0.006, longitude - 0.0065) - 0.000003 * Math.cos((longitude - 0.0065) * Math.PI); double gcjLat = fixValue * Math.sin(fixTemp); double gcjLon = fixValue * Math.cos(fixTemp); return GeoPoint.gcj02Point(gcjLon, gcjLat); } /** *

Convert GCJ02 GeoPoint instance to GPS GeoPoint instance

*

转换GCJ02坐标的GeoPoint实例为GPS坐标GeoPoint实例

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 */ private static GeoPoint GCJ02ToGPS(final double longitude, final double latitude) { if ((longitude < 72.004 || longitude > 137.8347) || (latitude < 0.8293 || latitude > 55.8271)) { return GeoPoint.gpsPoint(longitude, latitude); } else { GeoPoint deltaPoint = deltaPoint(longitude, latitude); return GeoPoint.gpsPoint(longitude - deltaPoint.getLongitude(), latitude - deltaPoint.getLatitude()); } } /** *

Convert GPS GeoPoint instance to GCJ02 GeoPoint instance

*

转换GPS坐标的GeoPoint实例为GCJ02坐标GeoPoint实例

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 */ private static GeoPoint GPSToGCJ02(final double longitude, final double latitude) { if ((longitude < 72.004 || longitude > 137.8347) && (latitude < 0.8293 || latitude > 55.8271)) { return GeoPoint.gcj02Point(longitude, latitude); } GeoPoint deltaPoint = deltaPoint(longitude, latitude); return GeoPoint.gcj02Point(longitude + deltaPoint.getLongitude(), latitude + deltaPoint.getLatitude()); } /** *

Calculate delta value of GeoPoint convert

*

计算地理坐标的偏移量

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return Converted GeoPoint instance * 转换后的GeoPoint实例 */ private static GeoPoint deltaPoint(final double longitude, final double latitude) { double transformLatitude = latitude / 180.0 * Math.PI; double magic = 1 - EARTH_EE * Math.pow(Math.sin(transformLatitude), 2); double magicSqrt = Math.sqrt(magic); double fixedLatitude = ((transformLatitude(longitude - 105.0, latitude - 35.0) * 180.0) / ((EARTH_R * (1 - EARTH_EE)) / (magic * magicSqrt) * Math.PI)); double fixedLongitude = ((transformLongitude(longitude - 105.0, latitude - 35.0) * 180.0) / (EARTH_R / magicSqrt * Math.cos(transformLatitude) * Math.PI)); return GeoPoint.deltaPoint(fixedLongitude, fixedLatitude); } /** *

Calculate value of transformed latitude

*

计算转换后的纬度值

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return transformed latitude value * 转换后的纬度值 */ private static double transformLatitude(final double longitude, final double latitude) { double result = -100.0 + 2.0 * longitude + 3.0 * latitude + 0.2 * Math.pow(latitude, 2); result += 0.1 * longitude * latitude + 0.2 * Math.sqrt(Math.abs(longitude)); result += calculate(longitude, latitude); result += (160.0 * Math.sin(latitude / 12.0 * Math.PI) + 320.0 * Math.sin(latitude * Math.PI / 30.0)) * 2.0 / 3.0; return result; } /** *

Calculate value of transformed longitude

*

计算转换后的经度值

* * @param longitude Longitude value of GeoPoint * 地理坐标经度值 * @param latitude Latitude value of GeoPoint * 地理坐标纬度值 * * @return transformed longitude value * 转换后的经度值 */ private static double transformLongitude(final double longitude, final double latitude) { double result = 300.0 + longitude + 2.0 * latitude + 0.1 * Math.pow(longitude, 2); result += 0.1 * longitude * latitude + 0.1 * Math.sqrt(Math.abs(longitude)); result += calculate(longitude, longitude); result += (150.0 * Math.sin(longitude / 12.0 * Math.PI) + 300.0 * Math.sin(longitude * Math.PI / 30.0)) * 2.0 / 3.0; return result; } private static double calculate(final double value1, final double value2) { return ((20.0 * Math.sin(6.0 * value1 * Math.PI) + 20.0 * Math.sin(2.0 * value1 * Math.PI)) * 2.0 / 3.0) + ((20.0 * Math.sin(value2 * Math.PI) + 40.0 * Math.sin(value2 / 3.0 * Math.PI)) * 2.0 / 3.0); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy