简体   繁体   English

从osm Overpass API读取和分析JSON-获取折线

[英]read and analyze JSON from osm overpass API - get polylines

with Overpass API I get this (polyline) data from OSM as JSON file: 使用Overpass API,我从OSM获得此(折线)数据作为JSON文件:

{
  "version": 0.6,
  "generator": "Overpass API",
  "elements": [
{
  "type": "node",
  "id": 308240514,
  "lat": 52.7074546,
  "lon": 7.1369361
},
{
  "type": "node",
  "id": 308729130,
  "lat": 52.6934662,
  "lon": 7.1353250
},
......
.......
.......
{
  "type": "way",
  "id": 99421713,
  "nodes": [
    1149813380,
    2103522316,
    2103522207,
    2103522202,
    2103522201,
    .....
    ....
    ],
      "tags": {
    "admin_level": "2",
    ......
  }
},
{
  "type": "way",
  "id": 99421718,
  "nodes": [
    647317213,
    2103495916,
    2103495906,
    2103495902,
    2103495901,
    ....
    ....
    ....
    ]

For printing the polylines (ways) in a mapping application like Google Maps API I need to get the coordinates (lat,lon in JSON) assigned to the ways (type:way) by the numbers in the nodes array - these numbers are the id's of the coordinates. 为了在诸如Google Maps API之类的地图应用程序中打印折线(航路),我需要获取通过节点数组中的数字分配给航路(类型:航路)的坐标(JSON中的经纬度),这些数字是ID的坐标。 As result I need something like this: 结果,我需要这样的东西:

"coords":{
"way1" : [(37.772323, -122.214897), (21.291982, -157.821856),(-18.142599, 178.431),(-27.46758, 153.027892)],
"way2" : [(37.772323, -122.214897),...........] 

I used jquery to get the JSON file and then loop through the data, so I could get the coordinates, but not assigned to the ways and also not in the right order like the nodes array. 我使用jquery来获取JSON文件,然后遍历数据,因此我可以获取坐标,但未分配方式,也未按照正确的顺序(如节点数组)进行分配。

$.getJSON(url, function(data) {
   $.each(data.elements, function(i,data){
      var coords = (data.lat,data.lon);
      .........

Anyone has an idea how to solve my problem? 有人知道如何解决我的问题吗? Is jquery solutions for this or it is better to use native javascript? 是jquery解决方案还是最好使用本机javascript?

... 2 days later: ... 2天后:

After a few hours of testing and trying at least I found a solution for my problem. 经过几个小时的测试和尝试,我至少找到了解决问题的方法。 Here is the javascript-code: 这是javascript代码:

$.getJSON('test.js', function(data) {

var ways = [];
var way_nodes = [];
var inhalt = [];

for (var x in data.elements) {
    if (data.elements[x].type == "way") {
        var way_tmp = data.elements[x].nodes;
        ways.push(way_tmp);
    }
    if (data.elements[x].type == "node") {
        inhalt = data.elements;
    }
}

for (var h in ways) {
    var mypath = [];
    way_nodes = ways[h];
    for (var k in way_nodes) {
        for (var x in inhalt) {
            if (way_nodes[k] == inhalt[x].id) {
                var coords = new google.maps.LatLng(inhalt[x].lat,inhalt[x].lon);  
                mypath.push(coords);
            }
        }
    }

    var polyline = new google.maps.Polyline({
        path: mypath,
        strokeColor: "#FF0000",
        strokeOpacity: 0.6,
        strokeWeight: 5
    });

    var poly_points = polyline.getPath();
    for (var i = 0; i < poly_points.length; i++) {
        bounds.extend(poly_points.getAt(i));
    }   
    polyline.setMap(map);
}
    map.fitBounds(bounds);
});

And here is a link to a working example displaying with the Google Maps API: http://www.ralf-wessels.de/test/apiv3/json/04map_osm_viele_polylines_structured.html# I don't know if this is the smartest way to solve the problem, specially if I work with big data. 以下是指向使用Google Maps API显示的工作示例的链接: http : //www.ralf-wessels.de/test/apiv3/json/04map_osm_viele_polylines_structured.html#我不知道这是否是最聪明的方法解决问题,特别是当我处理大数据时。 If someone knows a better way, I'm interested in this. 如果有人知道更好的方法,我对此很感兴趣。

For your data manipulation needs, I'd suggest looking into functional libraries like Lodash . 为了满足您的数据处理需求,建议您使用Lodash之类的功能库。 Or better yet, Ramda . 还是更好, 拉姆达 Lodash is more popular, Ramda is more convenient with emphasis on currying and function composition. Lodash更为流行,Ramda更加方便,着重于curring和函数组成。 Both share the upside of breaking things down to small, easily manageable parts. 两者都有将事物分解为易于管理的小部分的优势。

There's a bit of a learning curve, but after learning such a tool, you'll find just how much of a pain data manipulation with for-loops was. 有一些学习曲线,但是在学习了这样的工具之后,您会发现使用for循环进行痛苦数据处理有多少。

For example with Ramda, the same functionality could be achieved like this: 例如,使用Ramda,可以实现以下相同功能:

var parseWaysFromResponse = (function () {
    // function [{id:1, key1:val1 ...}, {id:2, key2:val2}]
    //    -> {1:{key1:val1 ...}, 2:{key2:val2 ...}}
    var generateIdToNodeMap = R.compose(
        R.mapObj(R.head),
        R.groupBy(R.prop('id'))
    );

    // Filter array of objects based on key "type"
    var elementTypeIs = function(typeVal) {
      return R.propEq('type', typeVal);
    }

    // Create {id:{values}} from the apiResponse elements
    var getNodes = R.compose(
      generateIdToNodeMap,
      R.filter(elementTypeIs('node'))
    );

    // Api elements -> [[way1 node-id1, id2, ...], [way 2 node-id1, ...]]
    var getWayNodes = R.compose(
      R.pluck('nodes'),
      R.filter(elementTypeIs('way'))
    );

    // Map generated by getNodes, node id -> [lat, lon] of given node id
    var linkNodeIdToCoords = R.curry(function (nodes, id) {
        return R.props(['lat', 'lon'], nodes[id])
    });

    return function (apiResponse) {
        var nodes = getNodes(apiResponse.elements);
        var getAllWays = R.compose(
            R.map(R.map(linkNodeIdToCoords(nodes))),
            getWayNodes
        );
        return getAllWays(apiResponse.elements)
    }
})();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM