2017-05-29 38 views
0

我有以下markercollection.json文件,其中有几个地理对象在名为features的数组中。如何在异步访问外部JSON数据时将变异标记添加到地图

{ 
    "features": 
    [ 
     { 
      "name": "Point A", 
      "address": { 
       "street": "228 Park Ave S", 
       "zipcode": "10003", 
       "city": "New York" 
      }, 
      "description": "Sample description for point A", 
      "iconFile": "icon-marker-iconsample-a.png", 
      "filterPrimary": "hotel", 
      "year": "2014" 
     }, 
     { 
      "name": "Point B", 
      "address": { 
       "street": "542 W. 27th Street", 
       "zipcode": "10001", 
       "city": "New York" 
      }, 
      "description": "Sample description for point B", 
      "iconFile": "icon-marker-iconsample-b.png", 
      "filterPrimary": "pub", 
      "year": "2015" 
     } 
    ] 
} 

我正在使用传单JavaScript库在地图上放置相应的标记。由于我没有经度和纬度,我已将对象的address传递给地理编码服务。为此我正在使用mapbox,但我也尝试使用OSM nominatim。两者都按预期工作。

mapbox geocoding API需要传递一个回调函数来处理结果数据(即经度和纬度)。

到目前为止,我已经制定了如何将地理对象传递给地理编码器,并让我的addMarkers回调函数将相应的标记添加到我的地图。除此之外,我还希望我的标记具有不同的图标,具体取决于原始JSON文件中的iconFile值。

我一直无法弄清楚在哪里建立,然后添加我的自定义标记。我尝试为每个循环构建标记图标,但是为所有标记留下了相同的图标(请参阅我的屏幕截图)。

Result of console.log variable value when simply assigning the icon file string value within the loop and accessing it within the callback function

我想这是因为循环完成触发我addMarkers功能之前,这样的sIconFile值,最后循环迭代。

我是否需要链接另一个回调函数,如果是,那么执行此操作的最佳方法是什么?

 // Pass Mapbox access token and set initial map view 
     L.mapbox.accessToken = ACCESS_TOKEN; 
     var myMap = L.mapbox.map('map','mapbox.streets').setView([40.730610, -73.935242], 13); 

     // 
     var promise = $.getJSON('data/markercollection.json') 
      .then(function(data) { 

       /** 
       * Iterate through fetched data and do something... 
       */ 
       for (var i = 0; i < data.features.length; i++) { 

        // Build address string for passing to geocoder 
        var sAddress = data.features[i].address.street + ', ' + data.features[i].address.zipcode + ', ' + data.features[i].address.city; 

        // Icon file string variable 
        var sIconFile = data.features[i].iconFile; 

        /** 
        * Query Mapbox geocoder with address string 
        * and pass reply to addMakers function as per 
        * mapbox geocoder API 
        */ 
        L.mapbox.geocoder('mapbox.places').query(sAddress, addMarkers); 

        // Add markers to geocoded latitudes and longitudes to map 
        function addMarkers(err, geocoderCallbackData) { 
         console.log(sIconFile); // accessing the variable here does not work :(
         L.marker(geocoderCallbackData.latlng).addTo(myMap); 
        } 
       } 

      // Basic error-handling 
      }, function() { 
       console.log('An error has occured!'); 
     }); 

回答

3

通过通过data.featuresforEach(fn),而不是一个for(...)回路循环,你将受益于由fn提供的局部范围。

因此:

data.features.forEach(function(feature) { 
    var sAddress = feature.address.street + ', ' + feature.address.zipcode + ', ' + feature.address.city; 
    var sIconFile = feature.iconFile; 
    L.mapbox.geocoder('mapbox.places').query(sAddress, addMarkers); 
    function addMarkers(err, geocoderCallbackData) { 
     console.log(sIconFile); 
     L.marker(geocoderCallbackData.latlng).addTo(myMap); 
    } 
}); 
+1

的伟大工程。非常感谢你。 – wntrmt

相关问题