如何在异步访问外部 JSON 数据时向地图添加可变标记
How to add variying markers to a map when accessing external JSON data asynchronously
我有以下 markercollection.json 文件,在一个名为 features
的数组中包含多个地理对象。
{
"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
值。
我一直无法弄清楚在哪里构建并随后添加我的自定义标记。我尝试为每个循环构建标记图标,但所有标记都使用相同的图标(请参阅我的屏幕截图)。
我假设这是因为在我的 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!');
});
通过使用 forEach(fn)
而不是 for(...)
循环遍历 data.features
,您将受益于 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);
}
});
我有以下 markercollection.json 文件,在一个名为 features
的数组中包含多个地理对象。
{
"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
值。
我一直无法弄清楚在哪里构建并随后添加我的自定义标记。我尝试为每个循环构建标记图标,但所有标记都使用相同的图标(请参阅我的屏幕截图)。
我假设这是因为在我的 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!');
});
通过使用 forEach(fn)
而不是 for(...)
循环遍历 data.features
,您将受益于 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);
}
});