diff --git a/utilcode/src/main/java/com/blankj/utilcode/utils/BitUtils.java b/utilcode/src/main/java/com/blankj/utilcode/utils/BitUtils.java new file mode 100644 index 0000000000..ba487be2cb --- /dev/null +++ b/utilcode/src/main/java/com/blankj/utilcode/utils/BitUtils.java @@ -0,0 +1,175 @@ +/* +******************* Copyright (c) ***********************\ +** +** (c) Copyright 2015, 蒋朋, china. sd +** All Rights Reserved +** +** +** +** +** _oo0oo_ +** o8888888o +** 88" . "88 +** (| -_- |) +** 0\ = /0 +** ___/`---'\___ +** .' \\| |// '. +** / \\||| : |||// \ +** / _||||| -:- |||||- \ +** | | \\\ - /// | | +** | \_| ''\---/'' |_/ | +** \ .-\__ '-' ___/-. / +** ___'. .' /--.--\ `. .'___ +** ."" '< `.___\_<|>_/___.' >' "". +** | | : `- \`.;`\ _ /`;.`/ - ` : | | +** \ \ `_. \_ __\ /__ _/ .-` / / +** =====`-.____`.___ \_____/___.-`___.-'===== +** `=---=' +** +** +** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +** +** 佛祖保佑 永无BUG +** +** +** 南无本师释迦牟尼佛 +** + +**----------------------版本信息------------------------ +** 版 本: V0.1 +** +******************* End of Head **********************\ +*/ + +package com.blankj.utilcode.utils; + + +import java.io.PrintStream; +import java.nio.ByteBuffer; + +/** + * 文 件 名: BitUtils + * 创 建 人: 蒋朋 + * 创建日期: 16-9-27 08:56 + * 邮 箱: jp19891017@gmail.com + * 博 客: https://jp1017.github.io/ + * 描 述:Java 位运算的常用方法封装 + * 修 改 人: + * 修改时间: + * 修改备注: + */ + +public class BitUtils { + public static final String TAG = "BITUTILSLOG"; + + private BitUtils() { + throw new UnsupportedOperationException("u can't fuck me..."); + } + + /** + * 获取运算数指定位置的值
+ * 例如: 0000 1011 获取其第 0 位的值为 1, 第 2 位 的值为 0
+ * + * @param source + * 需要运算的数 + * @param pos + * 指定位置 (0<=pos<=7) + * @return 指定位置的值(0 or 1) + */ + public static byte getBitValue(byte source, int pos) { + return (byte) ((source >> pos) & 1); + } + + + /** + * 将运算数指定位置的值置为指定值
+ * 例: 0000 1011 需要更新为 0000 1111, 即第 2 位的值需要置为 1
+ * + * @param source + * 需要运算的数 + * @param pos + * 指定位置 (0<=pos<=7) + * @param value + * 只能取值为 0, 或 1, 所有大于0的值作为1处理, 所有小于0的值作为0处理 + * + * @return 运算后的结果数 + */ + public static byte setBitValue(byte source, int pos, byte value) { + + byte mask = (byte) (1 << pos); + if (value > 0) { + source |= mask; + } else { + source &= (~mask); + } + + return source; + } + + + /** + * 将运算数指定位置取反值
+ * 例: 0000 1011 指定第 3 位取反, 结果为 0000 0011; 指定第2位取反, 结果为 0000 1111
+ * + * @param source + * + * @param pos + * 指定位置 (0<=pos<=7) + * + * @return 运算后的结果数 + */ + public static byte reverseBitValue(byte source, int pos) { + byte mask = (byte) (1 << pos); + return (byte) (source ^ mask); + } + + + /** + * 检查运算数的指定位置是否为1
+ * + * @param source + * 需要运算的数 + * @param pos + * 指定位置 (0<=pos<=7) + * @return true 表示指定位置值为1, false 表示指定位置值为 0 + */ + public static boolean checkBitValue(byte source, int pos) { + + source = (byte) (source >>> pos); + + return (source & 1) == 1; + } + + /** + * 入口函数做测试
+ * + * @param args + */ + public static void main(String[] args) { + + // 取十进制 11 (二级制 0000 1011) 为例子 + byte source = 11; + + // 取第2位值并输出, 结果应为 0000 1011 + for (byte i = 7; i >= 0; i--) { + Log.d(TAG, getBitValue(source, i) + ""); + } + + // 将第6位置为1并输出 , 结果为 75 (0100 1011) + Log.d(TAG, setBitValue(source, 6, (byte) 1) + ""); + + // 将第6位取反并输出, 结果应为75(0100 1011) + Log.d(TAG, reverseBitValue(source, 6) + ""); + + // 检查第6位是否为1,结果应为false + Log.d(TAG, checkBitValue(source, 6) + ""); + + // 输出为1的位, 结果应为 0 1 3 + for (byte i = 0; i < 8; i++) { + if (checkBitValue(source, i)) { + Log.d(TAG, i + ""); + } + } + + } +} diff --git a/utilcode/src/main/java/com/blankj/utilcode/utils/CoordinateTransformUtil.java b/utilcode/src/main/java/com/blankj/utilcode/utils/CoordinateTransformUtil.java new file mode 100644 index 0000000000..9d73b34694 --- /dev/null +++ b/utilcode/src/main/java/com/blankj/utilcode/utils/CoordinateTransformUtil.java @@ -0,0 +1,170 @@ +package com.blankj.utilcode.utils; + +/** + * 百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换的工具 + * 参考: 实现的Java版本 + * 博客: + */ +public class CoordinateTransformUtil { + private final static double X_PI = 3.14159265358979324 * 3000.0 / 180.0; + // π + private final static double PI = 3.1415926535897932384626; + // 长半轴 + private final static double A = 6378245.0; + // 扁率 + private final static double EE = 0.00669342162296594323; + + /** + * 百度坐标系(BD-09)转WGS坐标 + * + * @param lng 百度坐标纬度 + * @param lat 百度坐标经度 + * @return WGS84坐标数组 + */ + public static double[] bd09ToWGS84(double lng, double lat) { + double[] gcj = bd09Togcj02(lng, lat); + double[] wgs84 = gcj02ToWGS84(gcj[0], gcj[1]); + return wgs84; + } + + /** + * WGS坐标转百度坐标系(BD-09) + * + * @param lng WGS84坐标系的经度 + * @param lat WGS84坐标系的纬度 + * @return 百度坐标数组 + */ + public static double[] wgs84Tobd09(double lng, double lat) { + double[] gcj = wgs84Togcj02(lng, lat); + double[] bd09 = gcj02Tobd09(gcj[0], gcj[1]); + return bd09; + } + + /** + * 火星坐标系(GCJ-02)转百度坐标系(BD-09) + * + * 谷歌、高德——>百度 + * @param lng 火星坐标经度 + * @param lat 火星坐标纬度 + * @return 百度坐标数组 + */ + public static double[] gcj02Tobd09(double lng, double lat) { + double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * X_PI); + double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * X_PI); + double bd_lng = z * Math.cos(theta) + 0.0065; + double bd_lat = z * Math.sin(theta) + 0.006; + return new double[] { bd_lng, bd_lat }; + } + + /** + * 百度坐标系(BD-09)转火星坐标系(GCJ-02) + * + * 百度——>谷歌、高德 + * @param bd_lon 百度坐标纬度 + * @param bd_lat 百度坐标经度 + * @return 火星坐标数组 + */ + public static double[] bd09Togcj02(double bd_lon, double bd_lat) { + double x = bd_lon - 0.0065; + double y = bd_lat - 0.006; + double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI); + double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI); + double gg_lng = z * Math.cos(theta); + double gg_lat = z * Math.sin(theta); + return new double[] { gg_lng, gg_lat }; + } + + /** + * WGS84转GCJ02(火星坐标系) + * + * @param lng WGS84坐标系的经度 + * @param lat WGS84坐标系的纬度 + * @return 火星坐标数组 + */ + public static double[] wgs84Togcj02(double lng, double lat) { + if (outOfChina(lng, lat)) { + return new double[] { lng, lat }; + } + double dlat = transformLat(lng - 105.0, lat - 35.0); + double dlng = transformLng(lng - 105.0, lat - 35.0); + double radlat = lat / 180.0 * PI; + double magic = Math.sin(radlat); + magic = 1 - EE * magic * magic; + double sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (A / sqrtmagic * Math.cos(radlat) * PI); + double mglat = lat + dlat; + double mglng = lng + dlng; + return new double[] { mglng, mglat }; + } + + /** + * GCJ02(火星坐标系)转GPS84 + * + * @param lng 火星坐标系的经度 + * @param lat 火星坐标系纬度 + * @return WGS84坐标数组 + */ + public static double[] gcj02ToWGS84(double lng, double lat) { + if (outOfChina(lng, lat)) { + return new double[] { lng, lat }; + } + double dlat = transformLat(lng - 105.0, lat - 35.0); + double dlng = transformLng(lng - 105.0, lat - 35.0); + double radlat = lat / 180.0 * PI; + double magic = Math.sin(radlat); + magic = 1 - EE * magic * magic; + double sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (A / sqrtmagic * Math.cos(radlat) * PI); + double mglat = lat + dlat; + double mglng = lng + dlng; + return new double[] { lng * 2 - mglng, lat * 2 - mglat }; + } + + /** + * 纬度转换 + * + * @param lng + * @param lat + * @return + */ + public static double transformLat(double lng, double lat) { + double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; + return ret; + } + + /** + * 经度转换 + * + * @param lng + * @param lat + * @return + */ + public static double transformLng(double lng, double lat) { + double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; + return ret; + } + + /** + * 判断是否在国内,不在国内不做偏移 + * + * @param lng + * @param lat + * @return + */ + public static boolean outOfChina(double lng, double lat) { + if (lng < 72.004 || lng > 137.8347) { + return true; + } else if (lat < 0.8293 || lat > 55.8271) { + return true; + } + return false; + } +}