如何从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)