下面内容包括:
一定要点击运行,有个运行按钮
),在中间的地图组件中会呈现查询到的线路,并会弹出"保存文件”,在此修改文件名,文件为json格式import json
import geopandas as gpd
from shapely.geometry import LineString
import glob
import math
# 读取 JSON 文件
# 获取当前目录下所有的 JSON 文件
json_files = glob.glob('./data/*.json')
# 高德gcj-02 转4326
# 公交坐标数据转化
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626 # π
a = 6378245.0 # 长半轴
ee = 0.00669342162296594323 # 扁率
def gcj02towgs84(lng, lat):
"""
GCJ02(火星坐标系)转GPS84
:param lng:火星坐标系的经度
:param lat:火星坐标系纬度
:return:
"""
if out_of_china(lng, lat):
return lng, lat
dlat = transformlat(lng - 105.0, lat - 35.0)
dlng = transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic = math.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [lng * 2 - mglng, lat * 2 - mglat]
def transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(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
def transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(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
def out_of_china(lng, lat):
"""
判断是否在国内,不在国内不做偏移
:param lng:
:param lat:
:return:
"""
if lng < 72.004 or lng > 137.8347:
return True
if lat < 0.8293 or lat > 55.8271:
return True
return False
def coordinates(c):
lng,lat = c.split(',')
lng,lat = float(lng),float(lat)
wlng,wlat = gcj02towgs84(lng,lat)
return wlng,wlat
# 使用示例
gcj02_lng, gcj02_lat = 116.481499, 39.990475 # 示例GCJ-02坐标
wgs84_lng, wgs84_lat = gcj02towgs84(gcj02_lng, gcj02_lat)
print(f"WGS 84坐标:经度={wgs84_lng}, 纬度={wgs84_lat}")
# 数据处理
# 准备用于构建 GeoDataFrame 的数据
gdf_data = []
for file_path in json_files:
with open(file_path, 'r') as file:
# 解析 JSON 文件
json_list = json.load(file)
# 遍历列表中的每个字典元素
for json_data in json_list:
if 'path' in json_data: # 检查每个字典元素中是否有 'path' 键
line_coords = [gcj02towgs84(point['lng'], point['lat']) for point in json_data['path']]
# line_string = LineString(line_coords)
# line_coords = [(point['lng'], point['lat']) for point in json_data['path']]
line_string = LineString(line_coords)
gdf_data.append({
'id': json_data.get('id', ''),
'type': json_data.get('type', ''),
'name': json_data.get('name', ''),
'geometry': line_string
})
# 创建 GeoDataFrame
gdf = gpd.GeoDataFrame(gdf_data, crs='EPSG:4326')
# 显示 GeoDataFrame
gdf.plot()
gdf.to_file('./公交线路json/101-102-103_line.geojson',driver='GeoJSON',encoding='utf-8')
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>公交线路查询</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
<style type="text/css">
html,body,#container{
height:100%;
}
</style>
</head>
<body>
<div id="container"></div>
<div class="input-card" style='width:18rem;'>
<label style='color:grey'>公交线路查询</label>
<div class="input-item">
<div class="input-item-prepend"><span class="input-item-text" >线路名称</span></div>
<input id='BusLineName' type="text" value='101' >
</div>
<input id="search" type="button" class="btn" value="查询" />
</div>
<script type="text/javascript"
src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=AMap.LineSearch"></script>
<script language="javascript">
/*
* 该示例主要流程分为三个步骤
* 1. 首先调用公交路线查询服务(lineSearch)
* 2. 根据返回结果解析,输出解析结果(lineSearch_Callback)
* 3. 在地图上绘制公交线路()
*/
var map = new AMap.Map("container", {
resizeEnable: true,
center: [116.397428, 39.90923],//地图中心点
zoom: 13 //地图显示的缩放级别
});
var linesearch;
/*公交线路查询*/
function lineSearch() {
var busLineName = document.getElementById('BusLineName').value;
if(!busLineName) return;
//实例化公交线路查询类,只取回一条路线
linesearch = new AMap.LineSearch({
pageIndex: 1,
city: '宿迁',
pageSize: 2,
extensions: 'all'
});
//搜索“536”相关公交线路
linesearch.search(busLineName, function(status, result) {
map.clearMap()
if (status === 'complete' && result.info === 'OK') {
lineSearch_Callback(result);
} else {
alert(result);
}
});
}
/*公交路线查询服务返回数据解析概况*/
/*公交路线查询服务返回数据解析概况*/
function lineSearch_Callback(data) {
var lineArr = data.lineInfo;
var lineNum = data.lineInfo.length;
if (lineNum == 0) {
alert("未找到相关线路信息。");
} else {
for (var i = 0; i < lineNum; i++) {
var pathArr = lineArr[i].path;
var stops = lineArr[i].via_stops;
var startPot = stops[0].location;
var endPot = stops[stops.length - 1].location;
if (i == 0) { // 作为示例,只绘制一条线路
drawbusLine(startPot, endPot, pathArr);
}
}
// 下载查询到的公交线路数据
download(JSON.stringify(lineArr, null, 4), 'busLineData.json', 'application/json');
}
}
/*绘制路线*/
function drawbusLine(startPot, endPot, BusArr) {
//绘制起点,终点
new AMap.Marker({
map: map,
position: startPot, //基点位置
icon: "https://webapi.amap.com/theme/v1.3/markers/n/start.png",
zIndex: 10
});
new AMap.Marker({
map: map,
position: endPot, //基点位置
icon: "https://webapi.amap.com/theme/v1.3/markers/n/end.png",
zIndex: 10
});
//绘制乘车的路线
busPolyline = new AMap.Polyline({
map: map,
path: BusArr,
strokeColor: "#09f",//线颜色
strokeOpacity: 0.8,//线透明度
isOutline:true,
outlineColor:'white',
strokeWeight: 6//线宽
});
map.setFitView();
}
lineSearch();
document.getElementById('search').onclick = lineSearch;
function download(data, filename, type) {
var file = new Blob([data], {type: type});
if (window.navigator.msSaveOrOpenBlob) {
// IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
} else {
// Others
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
</script>
</body>
</html>