如何从JSON格式的API的经纬度坐标中获取点的几何形状
How to get the geometry of a point from the latitude and longitude coordinates of an API in JSON format
我正在尝试在我的 QGIS 项目中使用 json 格式的 API 数据。为此,我以这种方式调用 link。
我想从 JSON 获取属性以及纬度和经度坐标,以在 QGIS 中创建几何图形。这对你来说可能吗?我如何在循环中包含查询以获取坐标并创建数据点?
这是当前 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\u00a0: \u00a0PARISANDES - Musique des Andes \u00a0\n\n## 20h\u00a0: LE PLOUM \u2013 Jazz \u00a0\n\n## 21h30\u00a0: JOYLINER - Rock\n\n## 23h\u00a0:\u00a0ROUND WINDOW & 26$ IN MY HAND \u2013 Jazz & Rock \u00a0\n\n## Association ADNI\n\n## Port des Champs Elys\u00e9es - 75008 Paris\n\n## P\u00e9niche ARBOIS : rive droite - passerelle Solf\u00e9rino\u00a0\n\n## M\u00e9tro : Concorde ou Solf\u00e9rino",
"latlon": [
48.861288,
2.329838
],
"city": "Paris",
"title": "Port Des Champs Elys\u00e9es - Tuileries",
"pricing_info": "Gratuit - Ext\u00e9rieur",
"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\u00e9niche ARBOIS - Jazz, Rock, Musique des Andes",
"tags": "rock,jazz,gratuit,concert,andes,musique,p\u00e9niche,quais,seine",
"space_time_info": "Port des Champs Elys\u00e9es - Quai des Tuileries, le mardi 21 juin \u00e0 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\u00e9es - Quai des Tuileries",
"region": "\u00cele-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"
},
谢谢,
温蒂
我写了这个脚本,它递归地读取 json 文件并输出一个包含所有属性和几何图形的矢量图层。您可以输出此处列出的所有支持的文件类型:Vector drivers
将此代码作为新脚本粘贴到 QGIS python 控制台中。记得设置输入JSON文件路径,输出向量层路径带文件扩展名和CRS码。
import json
'''put inside the quotes your json file path'''
json_file_path = ''
'''put inside the quotes where the vector layer will be saved,
if not specified vector layer will be saved as a temporal layer'''
vector_layer_path = ''
vector_crs = 'EPSG:4326' # set here your crs
def scanDict(d):
for d_key in d.keys():
if type(d[d_key]) == dict:
for entry in scanDict(d[d_key]):
yield entry
else:
yield [d_key, d[d_key]]
json_file = json.load(open(json_file_path, 'r'))
records = json_file['records']
project = QgsProject().instance()
fields = list(dict(scanDict(records[0])).keys())
vector_layer = QgsVectorLayer(f"Point?crs={vector_crs}", "Points", "memory")
vector_layer.startEditing()
for field_name in fields:
q_field = QgsField(field_name, QVariant.String)
vector_layer.addAttribute(q_field)
vector_layer.commitChanges(stopEditing=False)
for record in records:
record_values = dict(scanDict(record))
x = record_values['coordinates'][0]
y = record_values['coordinates'][1]
feature = QgsFeature()
feature.setGeometry(QgsGeometry().fromPointXY(QgsPointXY(x, y)))
feature.setAttributes([str(item) for item in list(record_values.values())])
vector_layer.addFeature(feature)
vector_layer.commitChanges()
save_options = QgsVectorFileWriter.SaveVectorOptions()
save_options.driverName = "ESRI Shapefile"
save_options.fileEncoding = "UTF-8"
transform_context = project.transformContext()
if len(vector_layer_path):
error = QgsVectorFileWriter.writeAsVectorFormatV2(vector_layer, vector_layer_path, transform_context, save_options)
if error[0] == QgsVectorFileWriter.NoError:
print("file saved succesfull")
else:
print(error)
project.addMapLayer(QgsVectorLayer(vector_layer_path, 'Points', 'ogr'))
else:
project.addMapLayer(vector_layer)
我正在尝试在我的 QGIS 项目中使用 json 格式的 API 数据。为此,我以这种方式调用 link。
我想从 JSON 获取属性以及纬度和经度坐标,以在 QGIS 中创建几何图形。这对你来说可能吗?我如何在循环中包含查询以获取坐标并创建数据点?
这是当前 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\u00a0: \u00a0PARISANDES - Musique des Andes \u00a0\n\n## 20h\u00a0: LE PLOUM \u2013 Jazz \u00a0\n\n## 21h30\u00a0: JOYLINER - Rock\n\n## 23h\u00a0:\u00a0ROUND WINDOW & 26$ IN MY HAND \u2013 Jazz & Rock \u00a0\n\n## Association ADNI\n\n## Port des Champs Elys\u00e9es - 75008 Paris\n\n## P\u00e9niche ARBOIS : rive droite - passerelle Solf\u00e9rino\u00a0\n\n## M\u00e9tro : Concorde ou Solf\u00e9rino",
"latlon": [
48.861288,
2.329838
],
"city": "Paris",
"title": "Port Des Champs Elys\u00e9es - Tuileries",
"pricing_info": "Gratuit - Ext\u00e9rieur",
"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\u00e9niche ARBOIS - Jazz, Rock, Musique des Andes",
"tags": "rock,jazz,gratuit,concert,andes,musique,p\u00e9niche,quais,seine",
"space_time_info": "Port des Champs Elys\u00e9es - Quai des Tuileries, le mardi 21 juin \u00e0 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\u00e9es - Quai des Tuileries",
"region": "\u00cele-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"
},
谢谢,
温蒂
我写了这个脚本,它递归地读取 json 文件并输出一个包含所有属性和几何图形的矢量图层。您可以输出此处列出的所有支持的文件类型:Vector drivers
将此代码作为新脚本粘贴到 QGIS python 控制台中。记得设置输入JSON文件路径,输出向量层路径带文件扩展名和CRS码。
import json
'''put inside the quotes your json file path'''
json_file_path = ''
'''put inside the quotes where the vector layer will be saved,
if not specified vector layer will be saved as a temporal layer'''
vector_layer_path = ''
vector_crs = 'EPSG:4326' # set here your crs
def scanDict(d):
for d_key in d.keys():
if type(d[d_key]) == dict:
for entry in scanDict(d[d_key]):
yield entry
else:
yield [d_key, d[d_key]]
json_file = json.load(open(json_file_path, 'r'))
records = json_file['records']
project = QgsProject().instance()
fields = list(dict(scanDict(records[0])).keys())
vector_layer = QgsVectorLayer(f"Point?crs={vector_crs}", "Points", "memory")
vector_layer.startEditing()
for field_name in fields:
q_field = QgsField(field_name, QVariant.String)
vector_layer.addAttribute(q_field)
vector_layer.commitChanges(stopEditing=False)
for record in records:
record_values = dict(scanDict(record))
x = record_values['coordinates'][0]
y = record_values['coordinates'][1]
feature = QgsFeature()
feature.setGeometry(QgsGeometry().fromPointXY(QgsPointXY(x, y)))
feature.setAttributes([str(item) for item in list(record_values.values())])
vector_layer.addFeature(feature)
vector_layer.commitChanges()
save_options = QgsVectorFileWriter.SaveVectorOptions()
save_options.driverName = "ESRI Shapefile"
save_options.fileEncoding = "UTF-8"
transform_context = project.transformContext()
if len(vector_layer_path):
error = QgsVectorFileWriter.writeAsVectorFormatV2(vector_layer, vector_layer_path, transform_context, save_options)
if error[0] == QgsVectorFileWriter.NoError:
print("file saved succesfull")
else:
print(error)
project.addMapLayer(QgsVectorLayer(vector_layer_path, 'Points', 'ogr'))
else:
project.addMapLayer(vector_layer)