java 经纬度转成地址,地址转成经纬度

无障碍阅读方法

微信公众号关注:张家的小伙子
回复: 25749

文章说明

本文将说明,如何将经纬度转换为具体地址,或将地址转换为经纬度。
结合百度地图的API来进行使用。
本文直接上java代码,只要修改关键参数即可使用

前提

  1. 准备好个人的百度地图API key。可到百度地图开放平台中申请。此处省略申请流程。

转换工具类

通过一个具体的地址转成此地址对应的经纬度。

package com.zhangxiaoasan.util;

import com.alibaba.fastjson2.JSONObject;
import java.io.*;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* 说明: 此工具类主要用于处理地址转换经纬度,经纬度转换成地址使用。
* 修改一下关键部分内容即可使用
* @author 张小三
**/
public class  AddressCoordinateFormatUtil{
	// 修改。自己申请的百度地图 api key 
	private final static String mapApiKey="XXXXXXXXXXXXXXXXXXXXXX";
	
	// 地址转经纬度接口。百度地图Api接口地址url。?1 为占位符,在方法中会替换为真实的值。
	private static String addressToCoordinateApiUrl="http://api.map.baidu.com/geocoding/v3/?address=?1&output=json&ak=" + mapApiKey;
	
	// 经纬度转地址接口。百度地图Api接口地址url。?1 和 ?2 为占位符,在方法中会替换为真实的值。
	private static String coordinateToAddressApiUrl="http://api.map.baidu.com/reverse_geocoding/v3/?ak=" + mapApiKey + "&output=json&location=?1,?2";
	
	/**
	* 地址转经纬度:调用百度地图Api,传入地址名称,获取地址经纬度
	* @author 张小三
	* @param  address  地址名称
	* @return Map<String,BigDecimal> 返回 map。 map键说明:longitude 为经度。latitude为纬度。
	*/
	public static Map<String,BigDecimal> addressToCoordinate(String address){
		if (Objects.isNull(address) || address.trim().length() <= 0 ){
			 throw new RuntimeException("地址转经纬度失败,未输入地址!");
		}
		
		addressToCoordinateApiUrl = addressToCoordinateApiUrl.replaceAll("\\?1", address.trim()); // 替换占位符
		System.out.println("请求地址url:" + addressToCoordinateApiUrl);
		// 调用百度地图接口获取结果,
		// 返回结果类似于:
		// {"status":0,"result":{"location":{"lng":经度值,"lat":纬度值},"precise":0,"confidence":50,"comprehension":57,"level":"工业园区"}}
		// "status":0 成功状态
		String json = requestApi(addressToCoordinateApiUrl);	
		System.out.println("返回结果:" + json);
		if (Objects.isNull(json) || json.trim().length() <= 0 ){
			 throw new RuntimeException("地址转经纬度失败,接口无返回数据:"+json);
		}
		// 结果转换为json对象
		JSONObject obj = JSONObject.parseObject(json);
		if ("0".equals(obj.getString("status")) == false ) {
			throw new RuntimeException("地址转经纬度失败,接口返回状态值为失败:"+json);
		}
		BigDecimal lng = (BigDecimal)obj.getJSONObject("result").getJSONObject("location").get("lng"); // 经度
        BigDecimal lat = (BigDecimal)obj.getJSONObject("result").getJSONObject("location").get("lat"); // 纬度
        
		return new HashMap<String, BigDecimal>(){{
			put("longitude",lng );
			put("latitude",lat );
		}};
	}
	
	/**
	* 经纬度转地址:调用百度地图Api,传入经纬度,获取地址名称
	* @author 张小三
	* @param  longitude 经度 Double
	* @param  latitude  纬度 Double
	* @return String 返回经纬度对应的地址名称。
	*/
	public static String coordinateToAddress(Double longitude, Double latitude){
		if (Objects.isNull(longitude) || Objects.isNull(latitude)){
			throw new RuntimeException("经纬度转地址失败,输入的经纬度不正确");
		}
		coordinateToAddressApiUrl = coordinateToAddressApiUrl
									.replaceAll("\\?1", String.valueOf(latitude))
									.replaceAll("\\?2", String.valueOf(longitude)); // 替换占位符
		System.out.println("请求地址url:" + addressToCoordinateApiUrl);
		// 调用百度地图接口获取结果,
		// 返回结果类似于:
		// {"status":0,"result":{"location":{"lng":经度值,"lat":纬度值},"formatted_address":"具体地址名称","edz":{"name":""},"business":"科技园,大冲","addressComponent":{"country":"中国","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","province":"广东省","city":"深圳市","city_level":2,"district":"南山区","town":"粤海街道","town_code":"440305007","distance":"75","direction":"东北","adcode":"440305","street":"沙河西路","street_number":"2029-西门"},"pois":[],"roads":[],"poiRegions":[],"sematic_description":"","formatted_address_poi":"","cityCode":340}}
		// "status":0 成功状态
		String json = requestApi(coordinateToAddressApiUrl);	
		System.out.println("返回结果:" + json);
		if (Objects.isNull(json) || json.trim().length() <= 0 ){
			 throw new RuntimeException("经纬度转地址失败,接口无返回数据:"+json);
		}
		// 结果转换为json对象
		JSONObject obj = JSONObject.parseObject(json);
		if ("0".equals(obj.getString("status")) == false ) {
			throw new RuntimeException("经纬度转地址失败,接口返回状态值为失败:"+json);
		}
		JSONObject result= obj.getJSONObject("result");
		if (Objects.isNull(result) ){
			 throw new RuntimeException("经纬度转地址失败,接口返回数据不符合预期,无法获取到result节点:"+json);
		}
		return result.getString("formatted_address");
	}
	

	/**
	* 请求百度地图接口
	* @author 张小三
	* @param  url  接口具体地址
	* @return String 返回json格式的字符串
	*/
	private static String requestApi(String url) {
        StringBuilder json = new StringBuilder();
        try {
          	URLConnection urlConnection = new URL(url).openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection .getInputStream(), "UTF-8"));
            String inputLine = null;
            while ((inputLine = in.readLine()) != null) {
                json.append(inputLine);
            }
            in.close();
        } catch (MalformedURLException e) {} catch (IOException e) {}
        return json.toString();
    }
}

使用方法和结果

	public static void main(String[] args) {
		// 地址转经纬度
		Map<String,BigDecimal> map = addressToCoordinate("广东省深圳市南山区深南大道9037号");
		System.out.println("地址转经纬度结果:"+map.get("longitude")+","+map.get("latitude"));
		System.out.println();
		System.out.println();

		// 经纬度转地址
		String s = coordinateToAddress(113.97941, 22.54068);
		System.out.println("经纬度转地址结果:"+s);
	}

在这里插入图片描述

要将经纬度换为平面笛卡尔坐标,可以借助数学公式和Java编程实现。具体步骤如下: 第一步,计算地球上两个经度之间的距离。经度的范围是-180到180度,可以将其换为0到360度。假设待换的经纬度坐标为(latitude, longitude),其中latitude表示纬度,longitude表示经度。将longitude换为0到360度的范围后,可以使用以下公式来计算两个经度之间的距离: distance = longitude2 - longitude1 第二步,计算地球上两个纬度之间的距离。纬度的范围是-90到90度,可以将其换为0到180度。假设待换的经纬度坐标为(latitude, longitude),可以使用以下公式来计算两个纬度之间的距离: distance = latitude2 - latitude1 第三步,将两个距离值换为平面笛卡尔坐标。假设地球上的实际距离是distance,那么可以定义一个比率factor来将地球上的距离换为平面坐标系上的距离。根据实际情况来决定factor的取值,通常可以考虑使用地球的平均直径作为参考值。然后,可以使用以下公式将地球上的距离换为平面坐标系上的距离: cartesian_distance = distance * factor 最后,得到的平面笛卡尔坐标可以表示为(x, y)形式,其中x和y表示平面笛卡尔坐标系中的横坐标和纵坐标。 以上是将经纬度换为平面笛卡尔坐标的基本步骤和公式。在Java编程中,可以根据上述步骤和公式编写相应的代码来实现换功能。需要注意的是,实际应用中可能还需要考虑椭球体的几何形状和具体的参考坐标系,以得到更精确的换结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小张帅三代

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值