1.熟悉、梳理、总结项目研发实战中的
Python
开发日常使用中的问题、知识点等,如获取任意多边形区域内的经纬度点并可视化,找了N篇文章没发现有效的解决方案。
2.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!
3.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!
4.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!
文章目录
- 1.获取任意多边形边界经纬度`json`数据
- 2.根据多边形区域生成区域内的坐标点数据`Python`代码
- 3.经纬度点集压缩`Python`代码
- 4.生成点位可视化`html`代码
- 5.多边形及区域内经纬度点集可视化效果
1.获取任意多边形边界经纬度json
数据
-
方法一
:http://www.guihuayun.com/maps/region_datav.php
-
方法二(高德平台)
:https://lbs.amap.com/demo/javascript-api-v2/example/district-search/draw-district-boundaries
-
json
数据坐标点位解析python
代码示例jsonp_480370_1717574386373_ = { "status": "1", "info": "OK", "infocode": "10000", "count": "1", "suggestion": { "keywords": [], "cities": [] }, "districts": [{ "citycode": "0571", "adcode": "330112", "name": "临安区", "polyline": "119.826803,30.134153;119.826136,30.133364;119.824951,30.133047;119.821774,30.132589;119.817282,30.131128;119.814503,30.130486;119.813499,30.129761;119.811872,30.126984;119.81059,30.125801;119.807812,30.124766;119.804677,30.122295;119.80324,30.12009;119.802538,30.117812;119.802746,30.114885;119.802495,30.112591;119.802087,30.111689;119.800962,30.111131;119.797126,30.11034;119.791012,30.107358;119.790137,30.106339;119.789781,30.105194;119.789997,30.099349;119.789391,30.098497", "center": "119.724457,30.234375", "level": "district", "districts": [] }] } import geohash import pandas as pd ll_result = [] lnglats = [] for ii in jsonp_480370_1717574386373_['districts'][0]['polyline'].split(';'): lng, lat = ii.split(',') lnglats.append( [float(lng), float(lat)] ) ll_result.append( [lng, lat, geohash.encode( float(lat), float(lng), 6 )] ) ll_result_df = pd.DataFrame( ll_result ) ll_result_df.columns = ['lng', 'lat', 'geohash6'] ll_result_df.head(3)
-
边界数据可视化效果
2.根据多边形区域生成区域内的坐标点数据Python
代码
polygon_coords = lnglats
# 导入必要的库 # pip install shapely import numpy as np from shapely.geometry import Point, Polygon # ================================================ # 经纬度坐标点 lnglats(list) 数组赋值 polygon_coords = lnglats # 定义多边形区域的顶点坐标 grid_interval = 0.005 # 定义格网的经纬度间隔 # 定义格网范围 min_lon = min(polygon_coords, key=lambda x: x[0])[0] max_lon = max(polygon_coords, key=lambda x: x[0])[0] min_lat = min(polygon_coords, key=lambda x: x[1])[1] max_lat = max(polygon_coords, key=lambda x: x[1])[1] # 划分格网 lon_range = np.arange(min_lon, max_lon, grid_interval) lat_range = np.arange(min_lat, max_lat, grid_interval) polygon = Polygon(polygon_coords) grid_points = [] for lon in lon_range: for lat in lat_range: # print( lon, lat ) point = Point(lon, lat) # print( polygon.contains(point) ) if polygon.contains(point): # 判断格网是否在多边形内 grid_points.append((lon, lat)) # 打印落入多边形内的经纬度坐标格网 for point in grid_points: print(point)
3.经纬度点集压缩Python
代码
-
提示: 如果经纬度点太多,可视化过程比较慢,可能导致浏览器崩溃。
import math EARTH_RADIUS = 6371000 # 地球平均半径,单位:米 def haversine(lat1, lon1, lat2, lon2): """计算两个经纬度点之间的距离(单位:米)""" lat1, lon1, lat2, lon2 = map(math.radians, [lat1, lon1, lat2, lon2]) # 将经纬度转换为弧度 dlon = lon2 - lon1 # Haversine公式 dlat = lat2 - lat1 a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2 c = 2 * math.asin(math.sqrt(a)) r = EARTH_RADIUS return c * r def merge_points(points, threshold=10): """合并距离在threshold(单位:米)以内的经纬度点""" merged_points = [] for point in points: merged = False for merged_point in merged_points: distance = haversine(point[0], point[1], merged_point[0], merged_point[1]) if distance <= threshold: merged = True # 更新已合并的点(这里简单地取第一个点的经纬度) break if not merged: merged_points.append(point) return merged_points points = lnglats merged_points = merge_points(points, threshold=500) print(len(merged_points), len(lnglats))
4.生成点位可视化html
代码
ak=tUUW8mROQP659ly3fqG7eOjRz2kku5xt
替换为自己的百度ak
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";} #l-map{height:100%;width:78%;float:left;border-right:2px solid #bcbcbc;} #r-result{height:100%;width:20%;float:left;} </style> <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=tUUW8mROQP659ly3fqG7eOjRz2kku5xt"></script> <title>任意多边形区域及内部经纬度点位可视化</title> </head> <body> <div id="allmap"></div> </body> </html> <script type="text/javascript"> // 经纬度数据对象 var pointDataBJ = [ ]; // 多边形区域边界经纬度点位集合 var pointData = [ ]; // 多边形内部经纬度点位集合 var pointD = new BMap.Point(119.79569599999995, 30.133075); // 经纬度对象 var map = new BMap.Map("allmap"); // 创建百度地图实例 map.enableScrollWheelZoom(); // 允许百度地图缩放 map.centerAndZoom(pointD, 1); // 初始化地图级别和中心店 function showPointBJ (pointArr) { var myIconBJ = new BMap.Icon("./map_normal_bj.svg", new BMap.Size(50,50)); pointArr.forEach(function(item, index){ var point = new BMap.Point(item.longitude, item.latitude); // 经纬度对象 var marker = new BMap.Marker(point, {icon: myIconBJ}); // 创建标注 marker.mapDataIndex = index; // 将数据对象的索引存到对象中 map.addOverlay(marker); // 将标注添加到地图中 marker.addEventListener("click",getAttr); }); } function showPoint (pointArr) { var myIcon = new BMap.Icon("./map_normal.svg", new BMap.Size(50,50)); pointArr.forEach(function(item, index){ var point = new BMap.Point(item.longitude, item.latitude); // 经纬度对象 var marker = new BMap.Marker(point, {icon: myIcon}); // 创建标注 marker.mapDataIndex = index; // 将数据对象的索引存到对象中 map.addOverlay(marker); // 将标注添加到地图中 marker.addEventListener("click",getAttr); }); } // 调用的点击事件 function getAttr(){ // maker对象调用this就会指向他 var obj = this.getPosition(); //获取marker的位置 alert("marker的位置是" + obj.lng + "," + obj.lat); alert("marker的索引是" + this.mapDataIndex); // window.location.href="http://www.baidu.com"; } showPointBJ(pointDataBJ); showPoint(pointData); </script>
5.多边形及区域内经纬度点集可视化效果
1000米间隔
2000米间隔