使用 JSZip 为 Leaflet VectorGrid 提取多个 KML 文件

Using JSZip to extract multiple KML files for Leaflet VectorGrid

该地图使用 KML 文件生成单个 geoJSON 对象以传递给 VectorGrid 的切片器函数。为了提高性能,文件作为单个 KMZ 提供并使用 JSZip 库提取。然后我们遍历每个文件 (KML),解析它并转换为 geoJSON。这些特征连接到一个单独的数组,用于创建最终的 geoJSON 对象(一种廉价的合并方式)。

var vectorGrid;

JSZipUtils.getBinaryContent('/pathto/file.kmz', function (error, data) {
    JSZip.loadAsync(data).then(function (zip) {

        var featureArray = [];

        zip.forEach(function (path, file) {
            file.async('string').then(function (data) {
                // convert to geoJSON, concatenate features array
                featureArray = featureArray.concat(geoJSON.features);
            }
        }

        var consolidatedGeoJSON = {
            'type': 'FeatureCollection,
            'features': featureArray
        };

        vectorGrid = L.vectorGrid.slicer(consolidatedGeoJSON, options);

    }
}

我的想法是,一旦该操作完成,我就可以获取最终的 geoJSON 并将其简单地传递给切片器。然而,由于承诺的性质,它总是先构建切片器,然后再解析文件。

为了解决这个问题,我被迫将切片器函数放在 forEach 中,但放在 if 语句中检查当前文件是否是 zip 中的最后一个。这允许在地图上绘制矢量,但现在我无法在每个图层上单独启用悬停效果(每个 KML 包含一个特定的图层用作交互的区域轮廓)。

vectorGrid 滑块选项允许您指定 getFeatureId 函数,但我不明白如何将该 ID 传递给事件处理程序中的 setFeatureStyle 函数。

基本问题是您尝试在为 featureArray 赋值之前为 vactorGrid 赋值。我认为您需要使用 Promise.all(..)。类似的东西:

var zips=[];
zip.forEach(function(path,file) {
    zips.push(file.async('string');
});
Promise.all(zips).then(function(data){
 return data.map(function(value){
   return value.features;
 });
}).then(function(featureArray) {
  vectorGrid = L.vectorGrid.slicer(
    {type:'FeatureCollection',feature:featureArray}, options);
});