今天给大家分享一个java实现的地图坐标系经纬度转换工具类
/** Copyright (c). All rights reserved.* Use is subject to license terms.*/
package com.sf.gis.boot.utils;import org.apache.commons.codec.binary.Base64;import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;/*** 坐标转换工具(移植)。** @author fanhuigang*/
public class CoordTransform2
{private final static DecimalFormat FORMAT = new DecimalFormat("0.00000000");private final static int SCALE = 8;private final static double AVG_X = 0.006401062;private final static double AVG_Y = 0.0060424805;private final static double EARTH_RADIUS = 6378137.0;private final static double MARS_R = 6378245.0;private final static double MARS_EE = 0.00669342162296594323;/*** 预定义转换模式。*/public static enum Schema{bdmc2g("bmc2g"), bdmc2gm("bmc2gm"), bdmc2bll("bmc2bll"), bll2bdmc("bll2bmc"), g2bdmc("g2bmc"), gm2bdmc("gm2bmc"), /*gps2g("gps2g"), g2gps("g2gps"), */gps2b("gps2b"), b2gps("b2gps"), b2g("b2g"), g2b("g2b"), d2m("d2m"), m2d("m2d"),gps2mars("gps2mars"), mars2gps("mars2gps"), ll2wmc("ll2wmc"), wmc2ll("wmc2ll");private final String value;Schema(String value){this.value = value;}public String getValue(){return value;}}/*** 变形后转变形前(高德坐标转GPS)** @param lng* @param lat* @return*//* public static Double[] convertGoogle2GPS(double lng, double lat){String url = String.format(SysConf.get().getString("transform.itf.url"),"Public2Secret", FORMAT.format(lng), FORMAT.format(lat), "3600");return getXYBy(url);}*//*** 变形前转变形后(GPS转高德)** @param lng* @param lat* @return*//* public static Double[] convertGPS2Google(double lng, double lat){String url = String.format(SysConf.get().getString("transform.itf.url"),"Secret2Public", FORMAT.format(lng), FORMAT.format(lat), "3600");return getXYBy(url);}
*//*** 百度转高德(内网工具)** @param lng* @param lat* @return*/public static Double[] convertBaidu2Google(double lng, double lat){String url = "http://10.2.10.51:81/cgi-bin/bd.fcgi/?opt=bd_decrypt&x=" + FORMAT.format(lng) + "&y=" + FORMAT.format(lat);return getXYBy(url);}/*** 高德转百度(内网工具)** @param lng* @param lat* @return*/public static Double[] convertGoogle2Baidu(double lng, double lat){String urlstr = "http://10.2.10.51:81/cgi-bin/bd.fcgi/?opt=bd_encrypt&x=" + FORMAT.format(lng) + "&y=" + FORMAT.format(lat);return getXYBy(urlstr);}private static Double[] getXYBy(String urlstr){Double[] xy = null;String result = readURLData(urlstr);if(result != null && result.length() > 5){xy = readJSONBy(result);}return xy;}/*** GPS坐标转换为百度坐标** @param lng* @param lat* @return*/public static Double[] convertGPS2Baidu(double lng, double lat){String url = "http://map.baidu.com/ag/coord/convert?from=0&to=4&x=" + FORMAT.format(lng) + "&y=" + FORMAT.format(lat);return getXY(url);}/*** 百度坐标转换为GPS坐标** @param lng* @param lat* @return*/public static Double[] convertBaidu2GPS(double lng, double lat){return convertBaidu2GPS(lng, lat, 3);}public static Double[] convertBaidu2GPS(double lng, double lat, int c){Double[] xy = new Double[2];if(c < 1){return xy;}double ax = AVG_X;double ay = AVG_Y;for(int i = 1; i <= c; i++){xy = convertBaidu2GPS(lng, lat, ax, ay);ax = lng - xy[0];ay = lat - xy[1];}return xy;}private static Double[] convertBaidu2GPS(double x, double y, double ax,double ay){Double[] xy = null;double x_b = x - ax;double y_b = y - ay;Double[] xy_b = convertGPS2Baidu(x_b, y_b);if(xy_b != null){xy = new Double[2];xy[0] = BigDecimal.valueOf(x + x_b - xy_b[0]).setScale(SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();xy[1] = BigDecimal.valueOf(y + y_b - xy_b[1]).setScale(SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();}return xy;}private static Double[] getXY(String urlstr){Double[] xy = null;String result = readURLData(urlstr);if(result != null && result.length() > 5){xy = readJSON(result);}return xy;}private static String readURLData(String urlstr){String result = null;InputStream in = null;BufferedReader reader = null;FileOutputStream out = null;try{URL url = new URL(urlstr);HttpURLConnection httpConn = null;HttpURLConnection.setFollowRedirects(false);httpConn = (HttpURLConnection) url.openConnection();httpConn.setRequestMethod("GET");httpConn.setRequestProperty("Host", url.getHost());httpConn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0");httpConn.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");httpConn.setRequestProperty("Accept-Language", "zh-cn");httpConn.setRequestProperty("Accept-Encoding", "deflate");httpConn.setRequestProperty("Connection", "keep-alive");httpConn.setConnectTimeout(20000);int responseCode = httpConn.getResponseCode();if(responseCode == 200){in = httpConn.getInputStream();reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));String line = null;StringBuffer sb = new StringBuffer();while((line = reader.readLine()) != null){sb.append(line);}result = sb.toString();}}catch(Exception e){e.printStackTrace();}finally{try{if(reader != null){reader.close();}}catch(IOException ex){}try{if(in != null){in.close();}}catch(IOException ex){}try{if(out != null){out.close();}}catch(IOException ex){ex.printStackTrace();}}return result;}private static Double[] readJSONBy(String str){Double[] xy = null;try{String value = str.substring(1, str.length() - 1);value = value.replace("\"", "");String[] results = value.split(",");if(results.length == 2){String mapX = results[0].split(":")[1];String mapY = results[1].split(":")[1];xy = new Double[2];xy[0] = Double.parseDouble(mapX);xy[1] = Double.parseDouble(mapY);}}catch(Exception e){e.printStackTrace();}return xy;}private static Double[] readJSON(String str){Double[] xy = null;try{String value = str.substring(1, str.length() - 1);String[] results = value.split("\\,");if(results.length == 3){if(results[0].split("\\:")[1].equals("0")){String mapX = results[1].split("\\:")[1];String mapY = results[2].split("\\:")[1];mapX = mapX.substring(1, mapX.length() - 1);mapY = mapY.substring(1, mapY.length() - 1);mapX = new String(Base64.decodeBase64(mapX));mapY = new String(Base64.decodeBase64(mapY));xy = new Double[2];xy[0] = new BigDecimal(mapX).setScale(SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();xy[1] = new BigDecimal(mapY).setScale(SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();}}}catch(Exception e){e.printStackTrace();}return xy;}/*** 转换GPS坐标到MARS坐标。* @param x x坐标4gps* @param y y坐标4gps* @return mars坐标xy*/public static Double[] convertGPS2MXY(double x, double y){Double[] mxy = new Double[2];if(outOfChina(x, y)){mxy[0] = x;mxy[1] = y;return mxy;}double dLat = convertGPS2MY(x - 105.0, y - 35.0);double dLon = convertGPS2MX(x - 105.0, y - 35.0);double radLat = y / 180.0 * Math.PI;double magic = Math.sin(radLat);magic = 1 - MARS_EE * magic * magic;double sqrtMagic = Math.sqrt(magic);dLat = (dLat * 180.0) / ((MARS_R * (1 - MARS_EE)) / (magic * sqrtMagic) * Math.PI);dLon = (dLon * 180.0) / (MARS_R / sqrtMagic * Math.cos(radLat) * Math.PI);mxy[0] = x + dLon;mxy[1] = y + dLat;return mxy;}/*** 转换MARS坐标到GPS坐标。* @param x x坐标4mxy* @param y y坐标4mxy* @return gps坐标xy*/public static Double[] convertMXY2GPS(double x, double y){Double[] mxy = new Double[2];if(outOfChina(x, y)){mxy[0] = x;mxy[1] = y;return mxy;}double dLat = convertGPS2MY(x - 105.0, y - 35.0);double dLon = convertGPS2MX(x - 105.0, y - 35.0);double radLat = y / 180.0 * Math.PI;double magic = Math.sin(radLat);magic = 1 - MARS_EE * magic * magic;double sqrtMagic = Math.sqrt(magic);dLat = (dLat * 180.0) / ((MARS_R * (1 - MARS_EE)) / (magic * sqrtMagic) * Math.PI);dLon = (dLon * 180.0) / (MARS_R / sqrtMagic * Math.cos(radLat) * Math.PI);mxy[0] = x * 2 - (x + dLon);mxy[1] = y * 2 - (y + dLat);return mxy;}/*** 检查china边界。* @param x x坐标4gps* @param y y坐标4gps* @return 检查结果*/private static boolean outOfChina(double x, double y){ if(x < 72.004 || x > 137.8347) return true; if(y < 0.8293 || y > 55.8271) return true; return false; }/*** 转换GPS坐标到MARS坐标4X。* @param x x坐标4gps* @param y y坐标4gps* @return x坐标4mars*/private static double convertGPS2MY(double x, double y){double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0;return ret;}/*** 转换GPS坐标到MARS坐标4Y。* @param x x坐标4gps* @param y y坐标4gps* @return y坐标4mars*/private static double convertGPS2MX(double x, double y){double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0;return ret;}/*** 获得半径偏移量** 以3000为周期的变化*0.00002** @param y 纬度* @return 半径偏移量*/private static double get_delta_r(double y){return Math.sin(y * 3000 * (Math.PI / 180)) * 0.00002;}/*** 获得角度偏移量 以3000为周期的变化*0.000003** @param x 经度* @return 角度偏移量*/private static double get_delta_t(double x){double d = Math.cos(x * 3000 * (Math.PI / 180)) * 0.000003;return d;}/*** 高德转百度(工具)** @param lng* @param lat* @return*/public static Double[] convertG2B(double lng, double lat){// 确保以度参与计算lng = (Math.abs(lng) > 180d) ? lng / 3600d : lng;lat = (Math.abs(lat) > 180d) ? lat / 3600d : lat;double x1 = Math.cos(get_delta_t(lng) + Math.atan2(lat, lng)) * (get_delta_r(lat) + Math.sqrt(lng * lng + lat * lat)) + 0.0065;double y1 = Math.sin(get_delta_t(lng) + Math.atan2(lat, lng)) * (get_delta_r(lat) + Math.sqrt(lng * lng + lat * lat)) + 0.006;Double[] xys = new Double[2];xys[0] = BigDecimal.valueOf(x1).setScale(SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();xys[1] = BigDecimal.valueOf(y1).setScale(SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();return xys;}/*** 百度转高德(工具)默认迭代2次** @param lng* @param lat* @return*/public static Double[] convertB2G(double lng, double lat){return convertB2G(lng, lat, 2);}/*** 百度转高德(工具)** @param lng* @param lat* @param c 迭代次数* @return*/public static Double[] convertB2G(double lng, double lat, int c){// 确保以度参与计算lng = (Math.abs(lng) > 180d) ? lng / 3600d : lng;lat = (Math.abs(lat) > 180d) ? lat / 3600d : lat;Double[] xy = new Double[2];if(c < 1){return xy;}double ax = AVG_X;double ay = AVG_Y;for(int i = 1; i <= c; i++){xy = convertB2G(lng, lat, ax, ay);ax = lng - xy[0];ay = lat - xy[1];}return xy;}private static Double[] convertB2G(double x, double y, double ax, double ay){// 确保以度参与计算x = (Math.abs(x) > 180d) ? x / 3600d : x;y = (Math.abs(y) > 180d) ? y / 3600d : y;Double[] xy = null;double x_b = x - ax;double y_b = y - ay;Double[] xy_b = convertG2B(x_b, y_b);if(xy_b != null){xy = new Double[2];xy[0] = BigDecimal.valueOf(x + x_b - xy_b[0]).setScale(SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();xy[1] = BigDecimal.valueOf(y + y_b - xy_b[1]).setScale(SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();}return xy;}/*** 平面坐标转经纬度** @param x 平面坐标X* @param y 平面坐标Y* @return*/public static Double[] convertMC2Lnglat(double x, double y){Double[] res = convertMC2LL(x, y);return new Double[]{new BigDecimal(res[0]).setScale(SCALE, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(res[1]).setScale(SCALE, BigDecimal.ROUND_HALF_UP).doubleValue()};}/*** 经纬度转平面坐标** @param lng 经度* @param lat 纬度* @return*/public static Double[] convertLnglat2MC(double lng, double lat){Double[] res = convertLL2MC(lng, lat);return new Double[]{Double.parseDouble(String.format("%.2f", res[0])), Double.parseDouble(String.format("%.2f", res[1]))};}/*** 转换bdmc坐标到g经纬度坐标。* @param x mcx* @param y mcy* @return 转换后的g经纬度坐标*/public static Double[] convertBMC2G(double x, double y){Double[] xy = convertMC2Lnglat(x, y);return convertB2G(xy[0], xy[1]);}/*** 转换g经纬度坐标到bmc坐标。* @param x mcx* @param y mcy* @return 转换后的bmc坐标*/public static Double[] convertG2BMC(double x, double y){Double[] xy = convertG2B(x, y);return convertLL2MC(xy[0], xy[1]);}private static Double[] convertLL2MC(double x, double y){// 确保以度参与计算x = (Math.abs(x) > 180d) ? x / 3600d : x;y = (Math.abs(y) > 180d) ? y / 3600d : y;double[] cD = null;double[] llband ={75, 60, 45, 30, 15, 0};double[][] ll2mc ={{-0.0015702102444, 111320.7020616939, 1704480524535203.0, -10338987376042340.0, 26112667856603880.0, -35149669176653700.0, 26595700718403920.0, -10725012454188240.0, 1800819912950474.0, 82.5},{0.0008277824516172526, 111320.7020463578, 647795574.6671607, -4082003173.641316, 10774905663.51142, -15171875531.51559, 12053065338.62167, -5124939663.577472, 913311935.9512032, 67.5},{0.00337398766765, 111320.7020202162, 4481351.045890365, -23393751.19931662, 79682215.47186455, -115964993.2797253, 97236711.15602145, -43661946.33752821, 8477230.501135234, 52.5},{0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013, -1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5},{-0.0003441963504368392, 111320.7020576856, 278.2353980772752, 2485758.690035394, 6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5},{-0.0003218135878613132, 111320.7020701615, 0.00369383431289, 823725.6402795718, 0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45}};x = getLoop(x, -180, 180);y = getRange(y, -74, 74);for(int cC = 0; cC < llband.length; cC++){if(y >= llband[cC]){cD = ll2mc[cC];break;}}if(cD != null && cD.length > 0){for(int cC = llband.length - 1; cC >= 0; cC--){if(y <= -llband[cC]){cD = ll2mc[cC];break;}}}return convertor(x, y, cD);}private static Double[] convertor(double x, double y, double[] cD){double t = cD[0] + cD[1] * Math.abs(x);double cB = Math.abs(y) / cD[9];double cE = cD[2] + cD[3] * cB + cD[4] * cB * cB + cD[5] * cB * cB * cB + cD[6] * cB * cB * cB * cB + cD[7] * cB * cB * cB * cB * cB + cD[8] * cB * cB * cB * cB * cB * cB;t *= (x < 0 ? -1 : 1);cE *= (y < 0 ? -1 : 1);return new Double[]{t, cE};}private static Double[] convertMC2LL(double x, double y){double[] mcband ={12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0};double[][] mc2ll ={{1.410526172116255e-8, 0.00000898305509648872, -1.9939833816331, 200.9824383106796, -187.2403703815547, 91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 17337981.2},{-7.435856389565537e-9, 0.000008983055097726239, -0.78625201886289, 96.32687599759846, -1.85204757529826, -59.36935905485877, 47.40033549296737, -16.50741931063887, 2.28786674699375, 10260144.86},{-3.030883460898826e-8, 0.00000898305509983578, 0.30071316287616, 59.74293618442277, 7.357984074871, -25.38371002664745, 13.45380521110908, -3.29883767235584, 0.32710905363475, 6856817.37},{-1.981981304930552e-8, 0.000008983055099779535, 0.03278182852591, 40.31678527705744, 0.65659298677277, -4.44255534477492, 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06},{3.09191371068437e-9, 0.000008983055096812155, 0.00006995724062, 23.10934304144901, -0.00023663490511, -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4},{2.890871144776878e-9, 0.000008983055095805407, -3.068298e-8, 7.47137025468032, -0.00000353937994, -0.02145144861037, -0.00001234426596, 0.00010322952773, -0.00000323890364, 826088.5}};double[] cE = new double[2];for(int i = 0; i < mcband.length; i++){if(Math.abs(y) >= mcband[i]){cE = mc2ll[i];break;}}return convertor(x, y, cE);}private static double getRange(double cC, double a, double b){cC = Math.max(cC, a);cC = Math.min(cC, b);return cC;}private static double getLoop(double cC, double a, double b){while(cC > b){cC -= b - a;}while(cC < a){cC += b - a;}return cC;}/*** 获取图片左下角右上角经纬度** @param x 图片x坐标* @param y 图片y坐标* @param level 级别* @return 116.361753,40.042802|116.362903,40.041918*/public static Double[] getLnglat(int x, int y, int level){Double[] xy1 = convertMC2Lnglat((2 << (25 - level)) * x,(2 << (25 - level)) * y);Double[] xy2 = convertMC2Lnglat((2 << (25 - level)) * (x + 1),(2 << (25 - level)) * (y + 1));return new Double[]{xy1[0], xy1[1], xy2[0], xy2[1]};}public static Integer[] getGridXYByXY(int minX, int maxX, int minY, int maxY,int levelSmall, int levelBig){int c = 1 << (levelBig - levelSmall);return new Integer[]{minX * c, ((maxX + 1) * c - 1), minY * c, ((maxY + 1) * c - 1)};}public static Integer[] getGridXYByXY(int x, int y, int levelSmall,int levelBig){return getGridXYByXY(x, x, y, y, levelSmall, levelBig);}/*** 通过经纬度获取图片左下角右上角经纬度范围** @param lng_min 左下角经度* @param lat_min 左下角纬度* @param lng_max 右上角经度* @param lat_max 右上角纬度* @param level 级别* @return*/public static Integer[] getGridXYByLnglat(double lng_min, double lat_min,double lng_max, double lat_max, int level){Double[] pXY0 = convertLnglat2MC(Math.min(lng_min, lng_max),Math.min(lat_min, lat_max));Double[] pXY1 = convertLnglat2MC(Math.max(lng_min, lng_max),Math.max(lat_min, lat_max));int x0 = (int) Math.floor(pXY0[0] / (2 << (25 - level)));int y0 = (int) Math.floor(pXY0[1] / (2 << (25 - level)));int x1 = (int) Math.floor(pXY1[0] / (2 << (25 - level)));int y1 = (int) Math.floor(pXY1[1] / (2 << (25 - level)));return new Integer[]{x0, x1, y0, y1};}/*** 通过经纬度获取图片左下角右上角经纬度范围** @param lng_min 左下角经度* @param lat_min 左下角纬度* @param lng_max 右上角经度* @param lat_max 右上角纬度* @param levelSmall 小级别(13)* @param levelBig 大级别(19)* @return*/public static Integer[] getGridXYByLnglat(double lng_min, double lat_min,double lng_max, double lat_max, int levelSmall, int levelBig){Integer[] g = getGridXYByLnglat(lng_min, lat_min, lng_max, lat_max,levelSmall);return getGridXYByXY(g[0], g[1], g[2], g[3], levelSmall, levelBig);}private static double getRad(double d){return d * Math.PI / 180.0;}/*** 算法1:求两点之间的距离,输入单位: 度;返回单位:米。* @param lng1* @param lat1* @param lng2* @param lat2* @return 两点之间的距离*/public static double getGreatCircleDistance(double lng1, double lat1,double lng2, double lat2){// 确保以度参与计算lng1 = (Math.abs(lng1) > 180d) ? lng1 / 3600d : lng1;lat1 = (Math.abs(lat1) > 180d) ? lat1 / 3600d : lat1;lng2 = (Math.abs(lng2) > 180d) ? lng2 / 3600d : lng2;lat2 = (Math.abs(lat2) > 180d) ? lat2 / 3600d : lat2;double radLat1 = getRad(lat1);double radLat2 = getRad(lat2);double dy = radLat1 - radLat2;//adouble dx = getRad(lng1) - getRad(lng2);//bdouble s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(dy / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(dx / 2), 2)));s = s * EARTH_RADIUS;s = Math.round(s * 10000) / 10000.0;return s;}/*** 3857-->经纬度.* @param x* @param y* @return 经纬度坐标*/public static Double[] inverseMercator(double x, double y){double lon = x / 20037508.34d * 180.0d;double lat = y / 20037508.34d * 180.0d;lat = 180d / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180d)) - Math.PI / 2);return new Double[] { lon, lat };}/*** 经纬度-->3857.* @param lon* @param lat* @return 3857坐标*/public static Double[] forwardMercator(double lon, double lat){double x = lon * 20037508.34d /180d;double y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); y = y * 20037508.34d / 180d;return new Double [] { x, y };}/*** 度转秒。* @param x 经度(度)* @param y 维度(度)* @return 经纬度(秒)*/private static Double[] convertD2M(double x, double y){Double[] xy = new Double[2];xy[0] = (Math.abs(x) <= 180d) ? x * 3600 : x;xy[1] = (Math.abs(y) <= 180d) ? y * 3600 : y;return xy;}/*** 秒转度。* @param x 经度(秒)* @param y 维度(秒)* @return 经纬度(度)*/private static Double[] convertM2D(double x, double y){Double[] xy = new Double[2];xy[0] = (Math.abs(x) > 180d) ? x / 3600d : x;xy[1] = (Math.abs(y) > 180d) ? y / 3600d : y;return xy;}/*** 批量转换mc为g经纬度。* @param xyArray 逗号分隔的mc坐标串* @return 转换后的坐标串*/public static String convertMC2GLnglat(String xyArray){String xys[] = xyArray.split(",");StringBuilder sbd = new StringBuilder();for(int i = 0; i < xys.length; i += 2){Double xy1[] = convertMC2Lnglat(Double.valueOf(xys[i]), Double.valueOf(xys[i + 1]));Double xy2[] = convertB2G(xy1[0].doubleValue(), xy1[1].doubleValue());sbd.append(String.format("%f,%f", xy2[0] * 3600D, xy2[1] * 3600D));if(i < xys.length - 2){sbd.append(",");}}return sbd.toString();}/*** 批量按照目标schema转换坐标。* @param s 目标schema* @param xyArray 逗号分隔的坐标串* @return 转换后的坐标串*/public static String convertSchema(Schema s, String xyArray){String xys[] = xyArray.split(",");StringBuilder sbd = new StringBuilder();for(int i = 0; i < xys.length; i += 2){Double[] xy = convertSchema(s, Double.valueOf(xys[i]), Double.valueOf(xys[i + 1]));sbd.append(String.format("%f,%f", xy[0], xy[1]));if(i < xys.length - 2){sbd.append(",");}}return sbd.toString();}/*** 按照目标schema转换坐标。* @param s 目标schema* @param x 原始x* @param y 原始y* @return 转换后坐标*/public static Double[] convertSchema(Schema s, double x, double y){switch(s){case bdmc2bll:return convertMC2Lnglat(x, y);case bll2bdmc:return convertLnglat2MC(x, y);case bdmc2g:return convertBMC2G(x, y);case bdmc2gm:Double[] xy = convertBMC2G(x, y);xy[0] *= (Math.abs(xy[0]) <= 180d) ? 3600 : 1;xy[1] *= (Math.abs(xy[1]) <= 180d) ? 3600 : 1;return xy;case g2bdmc:case gm2bdmc:return convertG2BMC(x, y);// case gps2g:// return convertGPS2Google(x, y);// case g2gps:// return convertGoogle2GPS(x, y);case gps2b:return convertGPS2Baidu(x, y);case b2gps:return convertBaidu2GPS(x, y);case b2g:return convertB2G(x, y);case g2b:return convertG2B(x, y);case d2m:return convertD2M(x, y);case m2d:return convertM2D(x, y);case gps2mars://wgs84坐标转gcj02 加密return convertGPS2MXY(x, y);case mars2gps://gcj02转wgs84 解密return convertMXY2GPS(x, y);case ll2wmc:return forwardMercator(x, y);case wmc2ll:return inverseMercator(x, y);}return null;}
}
例如我们查询到了一些地图上面的设备,需要把设备的wgs84经纬度转换成火星坐标,可以这样操作:
/*** 讲设备的坐标按照目标schema转换坐标。** @param detailVo* @return*/private DeviceDetailVo convertXYSchema(DeviceDetailVo detailVo) {Double[] xyArray = CoordTransform2.convertSchema(CoordTransform2.Schema.gps2mars, detailVo.getX().doubleValue(), detailVo.getY().doubleValue());detailVo.setX(xyArray[0].floatValue());detailVo.setY(xyArray[1].floatValue());return detailVo;}