| 335 | } |
| 336 | |
| 337 | function fetchTraceGeoData(calcData) { |
| 338 | var PlotlyGeoAssets = window.PlotlyGeoAssets || {}; |
| 339 | var promises = []; |
| 340 | |
| 341 | function fetch(url) { |
| 342 | return new Promise(function (resolve, reject) { |
| 343 | d3.json(url, function (err, d) { |
| 344 | if (err) { |
| 345 | delete PlotlyGeoAssets[url]; |
| 346 | var msg = |
| 347 | err.status === 404 |
| 348 | ? 'GeoJSON at URL "' + url + '" does not exist.' |
| 349 | : 'Unexpected error while fetching from ' + url; |
| 350 | return reject(new Error(msg)); |
| 351 | } |
| 352 | |
| 353 | PlotlyGeoAssets[url] = d; |
| 354 | return resolve(d); |
| 355 | }); |
| 356 | }); |
| 357 | } |
| 358 | |
| 359 | function wait(url) { |
| 360 | return new Promise(function (resolve, reject) { |
| 361 | var cnt = 0; |
| 362 | var interval = setInterval(function () { |
| 363 | if (PlotlyGeoAssets[url] && PlotlyGeoAssets[url] !== 'pending') { |
| 364 | clearInterval(interval); |
| 365 | return resolve(PlotlyGeoAssets[url]); |
| 366 | } |
| 367 | if (cnt > 100) { |
| 368 | clearInterval(interval); |
| 369 | return reject('Unexpected error while fetching from ' + url); |
| 370 | } |
| 371 | cnt++; |
| 372 | }, 50); |
| 373 | }); |
| 374 | } |
| 375 | |
| 376 | for (var i = 0; i < calcData.length; i++) { |
| 377 | var trace = calcData[i][0].trace; |
| 378 | var url = trace.geojson; |
| 379 | |
| 380 | if (typeof url === 'string') { |
| 381 | if (!PlotlyGeoAssets[url]) { |
| 382 | PlotlyGeoAssets[url] = 'pending'; |
| 383 | promises.push(fetch(url)); |
| 384 | } else if (PlotlyGeoAssets[url] === 'pending') { |
| 385 | promises.push(wait(url)); |
| 386 | } |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | return promises; |
| 391 | } |
| 392 | |
| 393 | // TODO `turf/bbox` gives wrong result when the input feature/geometry |
| 394 | // crosses the anti-meridian. We should try to implement our own bbox logic. |