在线地图获取城市路网数据
在线地图获取城市路网数据
近期科研项目中,需要获取城市路网数据,于是详细阅读各大在线地图api接口,总结出来这么一条可行的思路:
- 首先获取城市轮廓
- 根据城市轮廓把城市分割成若干个小块
- 在每个小块中根据在线地图的POI检索接口,检索小块中的道路,获取道路清单
- 根据道路清单去获取道路经纬度数据
用到以下技术栈:
- Python程序开发
- 百度、高德在线地图接口
- 百度提供的JavaScript API GL
一、技术问题
针对这个问题,截止到当前日期(2023-09-25),有下面这几个问题
-
获取城市轮廓需要用到地图的行政区划边界查询接口,目前百度在线地图不提供,高德在线地图提供接口,接口地址:
URL https://restapi.amap.com/v3/config/district?parameters 请求方式 GET -
百度在线地图的多边形区域检索为高级权限,需要提交工单申请,但十有八九是不提供免费服务,高德在线地图的搜索POI接口提供多边形搜索接口服务
-
百度在线地图的POI编码中不包含道路,高德有一项为道路
综上,高德完胜。但无奈项目中用的是百度地图,所以无形中多了一步坐标转换的过程,而且在线地图对个人开发者的免费额度越来越少,只能将就先用了
二、技术实现
1、城市行政区划边界查询
这一步其实我个人是用百度离线地图来实现的,但既然高德提供了免费的接口,我也试了一下
import requestsurl = 'https://restapi.amap.com/v3/config/district'
key = '自己去申请ak'params = {'key': key,'keywords': '无锡','output': 'JSON','extensions': 'all'
}
response = requests.get(url=url, params=params)
if response:res_json = response.json()boundary = res_json['districts'][0]['polyline']boundary_list = boundary.split(';')boundaries = []for bound in boundary_list:item = bound.split(',')boundaries.append([float(item[0]), float(item[1])])
Python+json的处理,注意一下代码中输出数据的格式
得到的boundaries如下:

2、根据行政区划边界,切分网格
思路是根据行政区划边界的最大值和最小值,设定一个步长,根据步长来划分网格,下面是Python实现代码
def divide_region_by_step(coordinates, step):# 获取最小和最大经纬度min_lon = min(coord[0] for coord in coordinates)max_lon = max(coord[0] for coord in coordinates)min_lat = min(coord[1] for coord in coordinates)max_lat = max(coord[1] for coord in coordinates)# 计算经纬度方向上的步长# lon_step = step / 111.0 # 经度每度大概111公里# lat_step = step / 111.0 # 纬度每度大概111公里lon_step = steplat_step = step# 划分小区域regions = []current_lat = min_latwhile current_lat < max_lat:current_lon = min_lonwhile current_lon < max_lon:region = {'min_lon': current_lon,'max_lon': current_lon + lon_step,'min_lat': current_lat,'max_lat': current_lat + lat_step}regions.append(region)current_lon += lon_stepcurrent_lat += lat_stepreturn regions
这样切分不太精细,可以看一下切分的效果:

黑色的是无锡市的行政区划图,蓝色的是我画的网格,可以看到,左上角和右下角有大部分湖州的地方和苏州的地方也画了网格,我觉得边界以外的应该去掉,应该有解决办法,不过不想弄了
3、获取网格内的道路清单
我使用的是高德的搜索POI中的多边形搜索,请求地址为:
| URL | https://restapi.amap.com/v3/place/polygon?parameters |
|---|---|
| 请求方式 | GET |
| 必要参数 | key,types |
接口地址中的polygon其实就是2中矩形的对角的两个点
需要的参数是接口文档中给的一个查询POI类型,我高德提供的POI分类编码表下下来,发现代码190301表示道路名,所以就直接用这个参数了

来看代码:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:HP
# datetime:2023/9/22 14:18# encoding:utf-8
import pandas as pd
import requests# 读取行政区划边界文件
content = pd.read_excel('wuxi_positions_amap.xlsx', engine='openpyxl')
positions = content.values.tolist()def divide_region_by_step(coordinates, step):# 获取最小和最大经纬度min_lon = min(coord[0] for coord in coordinates)max_lon = max(coord[0] for coord in coordinates)min_lat = min(coord[1] for coord in coordinates)max_lat = max(coord[1] for coord in coordinates)# 计算经纬度方向上的步长# lon_step = step / 111.0 # 经度每度大概111公里# lat_step = step / 111.0 # 纬度每度大概111公里lon_step = steplat_step = step# 划分小区域regions = []current_lat = min_latwhile current_lat < max_lat:current_lon = min_lonwhile current_lon < max_lon:region = {'min_lon': current_lon,'max_lon': current_lon + lon_step,'min_lat': current_lat,'max_lat': current_lat + lat_step}regions.append(region)current_lon += lon_stepcurrent_lat += lat_stepreturn regionsstep = 0.1
results = divide_region_by_step(positions, step)url = 'https://restapi.amap.com/v3/place/polygon'
key = '自己去申请高德的key'
roads = []
for i in range(len(results)):print(str(i) + '-------------')polygon = str(results[i]['min_lon']) + ',' + str(results[i]['min_lat']) + '|' + str(results[i]['max_lon']) + ',' + str(results[i]['max_lat'])params = {"polygon": polygon,"types": '190301',"key": key,}response = requests.get(url=url, params=params)if response:response_json = response.json()for j in response_json['pois']:print(j['name'] + '-------------')district = j['adname']road = j['name']location = j['location']roads.append([district, road, location])
df_roads = pd.DataFrame(roads, columns=['行政区划', '路名', '经纬度'])
df_roads.to_excel('wuxi_roads.xlsx', index=False)
注意我读的文件就是第一步中获取的城市行政区划边界,看一下导出的数据:

其实效果不太好,有个坑需要注意下,接口中的参数:
params = {"polygon": polygon,"types": '190301',"key": key,}
只提供了秘钥、道路POI代码、网格坐标,其实还有一个offset我用的默认的,就是这个网格中返回的道路数据的条数,它默认是20,而且文档中标注强烈建议不超过25,若超过25可能造成访问报错,我看了一下我的运行结果,它最后生成的数据是1970条,而我的网格有99个,99*20=1980,也就是说,几乎每个网格中都返回了20条道路,我并没有一个个去考证网格中的数据是不是对的,但是就这个数据而言,也就是说,99个网格,总共只少了10条路,换句话说,几乎所有的网格中的数据应该是大于20条的,但因为限制,只返回了20条数据。所以返回的数据是不够的,因此,网格应该加密,加密的方法就是把划分网格的步长调小,但是由于高德限额的限制,我没有去尝试了。
至此已经获取到道路清单了
4、道路经纬度数据
按理说,这是最重要的,但是目前没有任何在线地图提供相关的接口
我最后使用离线地图获取的,给代码也没有意义了
三、JavaScript API GL的使用
技术实现的时候,我用了百度地图的JavaScript API,其实最后用到项目中也要使用JavaScript,不少小伙伴还只会Python,所以我提供一下我的html文件代码
<!DOCTYPE html>
<html>
<head><meta name="viewport" content="initial-scale=1.0, user-scalable=no"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>Baidu Map </title><style type="text/css">html {height: 100%}body {height: 100%;margin: 0px;padding: 0px}#container {height: 100%}</style><script type="text/javascript"src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=自己申请的百度地图AK"></script>
</head>
<body>
<div id="container"></div><script>const points = [[[119.527015, 31.11083], [119.627015, 31.21083]]] // 这里用自己的网格数据// console.log(points.length)const map = new BMapGL.Map("container"); // 创建地图实例const point = new BMapGL.Point(120.3119, 31.4912); // 创建点坐标map.centerAndZoom(point, 10); // 初始化地图,设置中心点坐标和地图级别map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放for (let i = 0; i < points.length; i++) {let pStart = new BMapGL.Point(points[i][0][0], points[i][0][1])let pEnd = new BMapGL.Point(points[i][1][0], points[i][1][1])let rectangle = new BMapGL.Polygon([new BMapGL.Point(pStart.lng, pStart.lat),new BMapGL.Point(pEnd.lng, pStart.lat),new BMapGL.Point(pEnd.lng, pEnd.lat),new BMapGL.Point(pStart.lng, pEnd.lat)], {strokeColor: "blue", strokeWeight: 2, strokeOpacity: 0.5}); //创建矩形map.addOverlay(rectangle)}const boundary = [[120.141768, 31.301344], [120.107967, 31.281801]] // 这里用自己的行政区划边界数据const boundary_points = []for(let i = 0; i < boundary.length; i++){boundary_points.push(new BMapGL.Point(boundary[i][0], boundary[i][1]))}const polygon = new BMapGL.Polygon(boundary_points, {strokeColor:"black", strokeWeight:5, strokeOpacity:0.5})map.addOverlay(polygon)
</script>
</body>
</html>
代码不解释了,主要是数据要换成自己的
相关文章:
在线地图获取城市路网数据
在线地图获取城市路网数据 近期科研项目中,需要获取城市路网数据,于是详细阅读各大在线地图api接口,总结出来这么一条可行的思路: 首先获取城市轮廓根据城市轮廓把城市分割成若干个小块在每个小块中根据在线地图的POI检索接口&a…...
8.2 Jmeter if控制器使用
前提:jmeter脚本需要用到if控制器,if判断如果查询不到,则去新增。 1、添加if控制器 线程组-->逻辑控制器-->如果(if)控制器 1)、Expression (must evaluate to true or false) :表达式(值必须是tru…...
科技云报道:青云科技打出“AI算力牌”,抢跑“云+AI”新增市场
科技云报道原创。 近三年,中国云计算市场在多个维度同时发生着剧烈变化——疫情极大加速了全社会对于数字化的认知和接受程度;一系列云原生技术依托着开源和蓬勃的市场而迅速发展演变,更多产品和技术名词同时涌向市场;国际关系复…...
学习路之PHP--lumen安装配置
一、下载lumen源码 composer create-project --prefer-dist laravel/lumen blog 安装lumen-generator composer require flipbox/lumen-generator 二、配置 bootstrap\app.php 97行 $app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class);三、生成…...
【C++】构造函数和析构函数第一部分(构造函数和析构函数的作用)--- 2023.9.25
目录 前言初始化和清理的概念构造函数和析构函数的作用构造函数的作用析构函数的作用 使用构造函数和析构函数的注意事项默认的构造函数和析构函数结束语 前言 在使用c语言开发的项目场景中,我们往往会遇到申请空间的需求,同时也肯定遇到过程序运行一段…...
CocosCreator3.8研究笔记(二十一)CocosCreator Tween系统理解
在 Cocos Creator 3.x 版本中, Tween系统代替了原来的Action系统。很多朋友不明白Tween到底是什么,Tween原理是什么?怎么使用Tween? 今天就来详细了解一下,希望能帮助到大家加深对Tween的了解,并快速掌握Tw…...
大数据学习-目录
学习内容持续更新ing 1.大数据学习1.0-Centos8虚拟机安装 大数据学习1.0-Centos8虚拟机安装_汉卿HanQ的博客-CSDN博客 2.大数据学习1.1-Centos8网络配置 大数据学习1.1-Centos8网络配置_汉卿HanQ的博客-CSDN博客 3.大数据学习1.2-yum配置 大数据学习1.2-yum配置_汉卿HanQ的…...
《动手学深度学习 Pytorch版》 7.5 批量规范化
7.5.1 训练深层网络 训练神经网络的实际问题: 数据预处理的方式会对最终结果产生巨大影响。 训练时,多层感知机的中间层变量可能具有更广的变化范围。 更深层的网络很复杂容易过拟合。 批量规范化对小批量的大小有要求,只有批量大小足够…...
Toaster - Android 吐司框架,专治 Toast 各种疑难杂症
官网 https://github.com/getActivity/Toaster 这可能是性能优、使用简单,支持自定义,不需要通知栏权限的吐司 想了解实现原理的可以点击此链接查看:Toaster 源码 集成步骤 如果你的项目 Gradle 配置是在 7.0 以下,需要在 bui…...
2023年9月26日,历史上的今天大事件早读
1620年9月26日大明皇帝朱常洛驾崩 1815年9月26日俄、普、奥三国在巴黎发表缔结“神圣同盟” 1841年9月26日清代思想家、诗人龚自珍逝世 1849年9月26日“生理学之父”巴甫洛夫诞生 1909年9月26日云南陆军讲武堂创办 1953年9月26日画家徐悲鸿逝世 1980年9月26日国际宇航联合…...
CListCtrl控件为只显示一列,持滚动显示其他,不用SetScrollFlags
CListCtrl控件为只显示一列,持滚动显示其他,不用SetScrollFlags 2023/9/5 下午4:52:58 如果您不希望使用 SetScrollFlags 函数来设置滚动条样式,可以使用以下代码将 CListCtrl 控件设置为只显示一列,并支持滚动显示其他内容: cpp // 设置控件样式和属性 m_listCtrl.Se…...
spring博客实现分页查询
1、首先创建dto下的分页类PageBean package com.zzz.blog.dto;import java.util.List;public class PageBean {private Integer pageSize; //页面大小private Integer currentPage; //当前页private Integer totalCount; //总条数private Integer totalPage; //总页数private …...
代码阅读分析神器-Scitools Understand
这里写目录标题 前言概要功能介绍1.代码统计2.图形化分析3.代码检查 使用方法下载及使用 前言 作为一名程序员,阅读代码是一个必须要拥有的能力,但无奈很多代码逻辑嵌套非常多,看起来非常吃力,看了那段逻辑就忘记了刚才的逻辑&am…...
学霸吐血整理‼《2023 年 IC 验证岗面试真题解析》宝藏干货!
Q1.定宽数组、动态数组、关联数组、队列各自的特点和使用方式。 Q2.fork…join/fork…join_any/fork…join_none 之间的异同 Q3.mailbox、event、semaphore 之间的异同 Q4.(event_handle)和 wait(event_handle.triggered)区别 Q5.task 和 function 异同区别 Q6.使用 clocking b…...
稳定性、可靠性、可用性、灵活性、解耦性
稳定性 平衡的能力 Linux系统的OOM机制、tcp的拥塞控制 可靠性 确定的能力 tcp的ACK、HA机制、加密 可用性 复原的能力 负债均衡、tcp的重传、冗余机制、故障域 灵活性 界限的能力 用户态、restful api、IP地址掩码 解耦性 不依赖的能力 分布式、SDN、容器、操作…...
docker搭建Redis三主三从
docker搭建Redis三主三从 首先启动6个redis进入容器构建主从关系连接进入6381作为切入点,查看集群状态 首先启动6个redis [rootdocker redis-node-1]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 …...
亚马逊要求的UL报告的产品标准是什么?如何区分
亚马逊为什么要求电子产品有UL检测报告? 首先,美国是一个对安全要求非常严格的国家,美国本土的所有电子产品生产企业早在很多年前就要求有相关安规检测。 其次,随着亚马逊在全球商业的战略地位不断提高,境外的电子设…...
如何在linux定时备份opengauss数据库(linux核心至少在GLIBC_2.34及以上)
前提环境,linux的核心至少在GLIBC_2.34及以上才能使用。 查看linux的glibc版本的命令如下 strings /lib64/libc.so.6 | grep GLIBC 如下图 或者用ldd --version 如下图 在官网下载对应的依赖包, 只需要这个lib文件即可,将这个包放在lin…...
SkyWalking快速上手(七)——Skywalking UI 界面简介
文章目录 前言1. 仪表盘1.1 指标展示1.2 自定义仪表盘 2. 拓扑图2.1 节点展示2.2 连接展示 3. 追踪3.1 请求链路3.2 请求详情 4. 性能剖析4.1 方法级别性能分析4.2 代码级别性能分析 5. 告警5.1 告警规则设置5.2 告警通知 6. 日志记录6.1 日志展示6.2日志分析6.3代码示例 总结 …...
python+vue驾校驾驶理论考试模拟系统
管理员的主要功能有: 1.管理员输入账户登陆后台 2.个人中心:管理员修改密码和账户信息 3.用户管理:管理员可以对用户信息进行添加,修改,删除,查询 4.添加选择题:管理员可以添加选择题目…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
