根据经纬度确定行政区域_获取中国指定行政区域内所有POIS(兴趣点)的方法

本文介绍了如何通过递归切割外切矩形,并结合shapely库判断点在多边形内,从而精确获取中国特定行政区域内的所有POIs(兴趣点)。这种方法解决了之前按固定精度切割导致的效率和准确性问题。
摘要由CSDN通过智能技术生成

本文首发于:获取中国指定行政区域内所有POIS(兴趣点)的方法​xugongli.github.ioGitHub项目源码​github.com

早在2017年5月,曾经在知乎上写过一篇文章获取一个城市全部道路名的方法总结,总结了下当时对如何获取一个城市全部道路名的探索。

当时提出了两个方法,其中之一为:从高德地图获取该城市的行政区域边界经纬度并转化为百度经纬度坐标

根据转换后的经纬度坐标找到经纬度中最大值点和最小值点,生成该多边形区域的外切矩形。

3. 把外切矩形分成若干个小矩形。注:目百度地图web api接口的限制,一次最多只能返回某一个矩形区域内的400条数据,所以要把外包矩形分成若干个小矩形

4. 利用百度地图Place Api接口,在该矩形区域以“道路”为关键字在每个矩形区域内搜索。并存储获取到的道路名和经纬度。

不过当时在使用这个方法的过程中遗留了下面三个问题:获取一个城市的经纬度边界后,只生成了该多边形的外包矩形,无法准确判断获取的点是否在这个多边形区域内,而且如果一个城市如果区域为狭长形,如上图示的内蒙古自治区,这个矩形内的大部分区域其实都是非目标区域,而且这样采集下来耗时会非常久

因为未能解决如何判断一个点是否在一个凹多边形内的问题,所以必须对采集到的所有兴趣点进行存储,而且无法根据经纬度判定其是否在指定的行政区域内

切割矩形时无法预测切割后的小矩形区域内的兴趣点数量是否小于400,精度设置需要经过多次采集后根据采集结果来评估,比较耗时<

要根据经纬度获取所在区域,需要使用地图API或地理位置服务。以下是使用百度地图API和高德地图API的示例代码: 使用百度地图API: ```java import com.baidu.mapapi.model.LatLng; import com.baidu.mapapi.utils.CoordinateConverter; import com.baidu.mapapi.utils.CoordinateConverter.CoordType; import com.baidu.mapapi.utils.HttpUtil; import com.baidu.mapapi.utils.JsonParser; import java.util.HashMap; import java.util.Map; public class LocationUtils { private static final String BAIDU_MAP_API_KEY = "your-api-key"; /** * 根据经纬度获取所在区域 * @param latitude 纬度 * @param longitude 经度 * @return 区域名称 */ public static String getLocationByLatLng(double latitude, double longitude) { // 将经纬度转换为百度坐标系 LatLng latLng = new LatLng(latitude, longitude); CoordinateConverter converter = new CoordinateConverter(); converter.from(CoordType.GPS); converter.coord(latLng); LatLng baiduLatLng = converter.convert(); // 构造API请求参数 Map<String, String> params = new HashMap<>(); params.put("location", baiduLatLng.latitude + "," + baiduLatLng.longitude); params.put("output", "json"); params.put("pois", "0"); params.put("ak", BAIDU_MAP_API_KEY); // 发送API请求并解析结果 String result = HttpUtil.get("http://api.map.baidu.com/geocoder/v2/", params); String location = JsonParser.getLocation(result); return location; } } ``` 使用高德地图API: ```java import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.amap.api.maps2d.CoordinateConverter; import com.amap.api.maps2d.model.LatLng; import com.amap.api.maps2d.model.LatLngBounds; import com.amap.api.maps2d.model.LatLngBoundsCreator; import com.amap.api.maps2d.model.Poi; import com.amap.api.services.core.AMapException; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.geocoder.GeocodeSearch; import com.amap.api.services.geocoder.RegeocodeAddress; import com.amap.api.services.geocoder.RegeocodeResult; public class LocationUtils { private static final String AMAP_API_KEY = "your-api-key"; /** * 根据经纬度获取所在区域 * @param latitude 纬度 * @param longitude 经度 * @return 区域名称 */ public static String getLocationByLatLng(double latitude, double longitude) { // 将经纬度转换为高德坐标系 LatLng latLng = new LatLng(latitude, longitude); CoordinateConverter converter = new CoordinateConverter(); converter.from(CoordinateConverter.CoordType.GPS); converter.coord(latLng); LatLonPoint amapLatLng = new LatLonPoint(converter.convert().latitude, converter.convert().longitude); // 构造API请求参数 GeocodeSearch geocodeSearch = new GeocodeSearch(context); geocodeSearch.setApiKey(AMAP_API_KEY); RegeocodeResult result; try { result = geocodeSearch.getFromLocation(amapLatLng, 200, GeocodeSearch.AMAP); } catch (AMapException e) { e.printStackTrace(); return null; } if (result == null) { return null; } RegeocodeAddress address = result.getRegeocodeAddress(); if (address == null) { return null; } // 解析结果获取区域名称 JSONObject jsonObject = JSON.parseObject(address.toString()); JSONObject addressComponent = jsonObject.getJSONObject("addressComponent"); String district = addressComponent.getString("district"); if (district == null || district.isEmpty()) { return null; } return district; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值