如何将JSON转换为GeoJSON

5
我非常新手地学习JavaScript,我的基础知识遇到了瓶颈。我设置了一个Leaflet地图,希望从JSON中的坐标绘制基于divIcon的标记。通过无数次尝试让它工作的研究,我发现为什么我的JSON文件不起作用,即使我在控制台中确认它已被读取。我了解到Leaflet更喜欢它以GeoJSON的形式呈现,因此我花了几个小时研究如何转换它。我找到的大多数资料都过时了,不再适用于我,或者与我无关。这是我通过严格的研究所尝试的:
首先,我设置了一个变量来定义我的测试JSON文件的路径,就像这样:
var jsonData = "./data/tracking.json";

在我尝试将JSON转换为GeoJSON时,我尝试了这个方法。

var outGeoJson = {}
outGeoJson['properties'] = jsonData
outGeoJson['type']= "Feature"
outGeoJson['geometry']= {"type": "Point", "coordinates":
    [jsonData['lat'], jsonData['lon']]}

console.log(outGeoJson)

检查控制台后发现JSON文件中的数组坐标未定义。

enter image description here

我尝试寻找为什么会出现这种情况的原因,但没有得到合适的解释。我的理论是可能是因为JSON文件中的键在数组前面,而且它是一个数组导致的。我继续寻找有效的解决方案,以便处理此问题。接下来,我尝试了这个解决方案。

var geojson = {
  type: "FeatureCollection",
  features: [],
};

for (i = 0; i < jsonData.positions.length; i++) {
  if (window.CP.shouldStopExecution(1)) {
    break;
  }
  geojson.features.push({
    "type": "Feature",
    "geometry": {
      "type": "Point",
      "coordinates": [jsonData.positions[i].longitude, jsonData.positions[i].latitude]
    },
    "properties": {
      "report_at": jsonData.positions[i].report_at,
      "lat": jsonData.positions[i].lat,
      "lon": jsonData.positions[i].lon,
      "dir": jsonData.positions[i].dir,
      "first": jsonData.positions[i].first,
      "last": jsonData.positions[i].last
    }
  });
}

window.CP.exitedLoop(1);

console.log(geojson)

这个解决方案在控制台中报错:Uncaught TypeError: Cannot read property 'length' of undefined.

enter image description here

我尝试排查这个问题几个小时,但都没有成功。以下是我正在使用的测试JSON文件示例。

{
  "positions": [
    {
      "report_at": "2015-01-21 21:00:08",
      "lat": "38.9080658",
      "lon": "-77.0030365",
      "elev": "0",
      "dir": "0",
      "gps": "0",
      "callsign": "WX2DX",
      "email": "",
      "phone": "",
      "ham": "WX2DX",
      "ham_show": "0",
      "freq": "",
      "note": "",
      "im": "",
      "twitter": null,
      "web": "",
      "unix": "1421874008",
      "first": "William",
      "last": "Smith",
      "marker": "36181"
    }
  ]
}

我真正需要的仅是report_at、lat、lon、dir、first和last。其余内容我可以不用。我尝试的上述示例是否是一种良好或适当的转换方式?如果不是,那么有没有比我一直尝试的更好的建议,因为我可能由于对这种语言非常陌生而忽略了一些东西。谢谢!

编辑:由于有人提醒我没有加载JSON文件,所以我已经采取以下措施来加载它,因为这些建议适用于Node.js而不是本机JavaScript的一部分。

    $.getJSON("./data/tracking.json", function(jsonData) {
  var outGeoJson = {}
  outGeoJson['properties'] = jsonData
  outGeoJson['type']= "Feature"
  outGeoJson['geometry']= {"type": "Point", "coordinates":
      [jsonData['lat'], jsonData['lon']]}

  console.log(outGeoJson)
});

这确实加载了文件,因为它已经在控制台中显示为转换为GeoJSON格式。除非有更好的解决方案,否则我将保留目前的状态。

1
请注意,您将jsonData变量设置为路径字符串。您从未显示任何代码实际加载数据(例如从该文件中)。仅将某些变量设置为某个路径并不能自动加载它。您可以看到,因为您将properties属性设置为您的jsonData变量,并在控制台日志中显示properties显示为该路径字符串...所以jsonData不保存您的数据,而只是一些字符串。确保您正在加载/分配数据到您的变量中。 - Patrick Evans
我发布了var jsonData作为参考,以便您知道该变量在两个代码示例中的加载情况。我明白你的意思,这确实有道理。根据我遇到的一些问题和教程,这就是他们加载数据文件的方式。我有点困惑,因为如果它没有加载数据,那么为什么会显示一个包含两个条目的数组,这正好是该JSON文件中的条目数? - DFW Storm Force
2个回答

3
如果您的项目中已经添加了jQuery,则您离成功不远了:
$.getJSON("./data/tracking.json", function(jsonData) {
    /* 
    Here the anonymous function is called when the file has been downloaded.
    Only then you can be sure that the JSON data is present and you can work with it's data.
    You have to keep in mind if you are getting the file synchronously or asynchronously (default).
   */
});

那个完美地运作了,正是我尝试的方向,因为之前的建议给了我一个方向,让我知道它没有加载。在看到解决方案之前,我刚刚在我的编辑中添加了这个,但它确实起作用。 - DFW Storm Force

1

var jsonData = "./data/tracking.json";

尝试将此行替换为以下行:

var jsonData = require("./data/tracking.json"); 或者

import jsonData from "./data/tracking.json"; #es6风格

正如@PatrickEvans所提到的,您必须实际加载数据而不是仅仅提供路径字符串。

1
使用 var jsonData = require("./data/tracking.json"); 方法会在控制台中返回错误信息 Uncaught ReferenceError: require is not defined。而第二种方法 import jsonData from "./data/tracking.json"; 会返回错误信息 Unexpected identifier,但是如果使用这种方法,jsonData 该如何定义呢? - DFW Storm Force
1
require 是一个在 node.js 下运行的模块,不是浏览器中可用的客户端 JavaScript。因此它将无法工作。 - DFW Storm Force

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接