如何从JSON格式API的经纬度坐标生成QGIS可用的点几何要素
需求实现方案
可行性确认
你提到的从JSON接口提取属性、坐标生成QGIS点要素的需求完全可实现,QGIS自带原生JSON解析与矢量图层创建能力,也支持通过PyQGIS脚本实现批量接口调用与要素批量生成。
单次接口数据生成点要素(GUI无代码操作)
如果只需要拉取单次接口返回的数据,直接用QGIS自带的导入功能即可:
- 打开QGIS,依次点击菜单栏「图层」→「添加图层」→「添加矢量图层」
- 源类型选择「协议:HTTP(S)、云等」,格式选择「GeoJSON」,在URL输入框中填入你的API调用地址
- 点击「添加」后QGIS会自动识别返回JSON中的
geometry字段生成点要素,fields下的所有属性也会自动同步为要素属性表的对应字段 - 如果自动识别异常,可以使用「从表格创建点图层」工具,手动指定
latlon数组作为坐标来源,匹配对应属性字段即可。
批量循环拉取数据生成点要素(PyQGIS脚本实现)
如果需要分页批量拉取全量数据,推荐使用PyQGIS脚本实现,核心逻辑如下:
- 预先创建内存点图层,定义好需要存储的所有属性字段
- 按API分页规则编写循环逻辑,通过修改请求参数的
start偏移量拉取全量数据(你提供的API示例中nhits为总数据量,rows为单页返回条数,可作为循环终止条件) - 逐页解析返回的JSON,遍历
records数组,为每一条记录创建点几何、赋值属性后写入图层 - 全量数据拉取完成后,将图层加载到QGIS项目或导出为本地矢量文件
简化实现代码示例
import requests import time from qgis.core import * # 初始化内存点图层,坐标系默认WGS84 point_layer = QgsVectorLayer("Point?crs=epsg:4326", "公共活动点位", "memory") data_provider = point_layer.dataProvider() # 配置需要存储的属性字段,可根据实际需求扩展 data_provider.addAttributes([ QgsField("uid", QVariant.String), QgsField("活动标题", QVariant.String), QgsField("城市", QVariant.String), QgsField("开始日期", QVariant.String), QgsField("费用说明", QVariant.String), QgsField("活动描述", QVariant.String) ]) point_layer.updateFields() # API请求配置 base_api_url = "你的API调用基础地址" page_size = 100 # 单页返回条数,可根据接口限制调整 current_offset = 0 total_count = None # 循环拉取全量数据 while total_count is None or current_offset < total_count: # 拼接分页参数 req_url = f"{base_api_url}&start={current_offset}&rows={page_size}" resp = requests.get(req_url) resp.raise_for_status() json_data = resp.json() # 首次请求获取总数据量 if total_count is None: total_count = json_data["nhits"] # 遍历当前页所有记录 for record in json_data["records"]: # 创建点几何 lon, lat = record["geometry"]["coordinates"] point_geom = QgsPoint(lon, lat) feature = QgsFeature() feature.setGeometry(point_geom) # 赋值属性 fields = record["fields"] feature.setAttributes([ fields.get("uid"), fields.get("title"), fields.get("city"), fields.get("date_start"), fields.get("pricing_info"), fields.get("description") ]) data_provider.addFeature(feature) # 偏移量自增,添加延迟避免触发接口限流 current_offset += page_size time.sleep(1) # 将生成的图层添加到当前QGIS项目 QgsProject.instance().addMapLayer(point_layer)
注意事项
- 调用接口前请确认接口的请求频率限制,可调整代码中
time.sleep()的延迟值避免被接口封禁 - 如果接口有鉴权要求,可在
requests.get()中添加headers参数传入对应的token、cookie等鉴权信息 - 如果你的QGIS项目使用非WGS84坐标系,可在创建要素后添加坐标转换逻辑,统一转为项目坐标系
参考API返回JSON结构示例
{ "nhits": 49, "parameters": { "dataset": "evenements-publics-cibul", "timezone": "UTC", "rows": 1354, "start": 0, "format": "json", "facet": [ "tags", "placename", "department", "region", "city", "date_start", "date_end", "pricing_info", "updated_at", "city_district" ] }, "records": [ { "datasetid": "evenements-publics-cibul", "recordid": "41ca897b543df849ceb4a1c43fd4d11daeb251eb", "fields": { "uid": "99319396", "image": "http://cibul.s3.amazonaws.com/event_port-des-champs-elysees-tuileries_722620.jpg", "updated_at": "2016-06-19T18:53:27+00:00", "free_text": "## 18h30 : PARISANDES - Musique des Andes \n\n## 20h : LE PLOUM – Jazz \n\n## 21h30 : JOYLINER - Rock\n\n## 23h : ROUND WINDOW & 26$ IN MY HAND – Jazz & Rock \n\n## Association ADNI\n\n## Port des Champs Elysées - 75008 Paris\n\n## Péniche ARBOIS : rive droite - passerelle Solférino \n\n## Métro : Concorde ou Solférino", "latlon": [ 48.861288, 2.329838 ], "city": "Paris", "title": "Port Des Champs Elysées - Tuileries", "pricing_info": "Gratuit - Extérieur", "date_start": "2016-06-21", "department": "Paris", "image_thumb": "http://cibul.s3.amazonaws.com/evtbevent_port-des-champs-elysees-tuileries_722620.jpg", "date_end": "2016-06-21", "description": "Concerts Gratuits - Péniche ARBOIS - Jazz, Rock, Musique des Andes", "tags": "rock,jazz,gratuit,concert,andes,musique,péniche,quais,seine", "space_time_info": "Port des Champs Elysées - Quai des Tuileries, le mardi 21 juin à 18:30", "timetable": "2016-06-21T18:30:00 2016-06-21T00:00:00", "link": "http://openagenda.com/event/port-des-champs-elysees-tuileries", "address": "PORT DES TUILERIES", "lang": "fr", "placename": "Port des Champs Elysées - Quai des Tuileries", "region": "Île-de-France", "program_uid": "7633600 64984403 63658282 59310395 31778250" }, "geometry": { "type": "Point", "coordinates": [ 2.329838, 48.861288 ] }, "record_timestamp": "2017-03-29T15:13:50.163000+00:00" } ] }
内容的提问来源于stack exchange,提问作者Wendy Latizeau
相关产品推荐
相关产品推荐

