1

有一些 HTML5 的文件系统、文件访问功能的示例,用户可以添加文件而无需发送到服务器端。

我正在使用 OpenLayers 开发地图应用程序,我希望添加此功能,用户可以拖放 kml 文件或从对话框中选择 kml 文件,然后添加到本地地图。

OpenLayers 可以实现这种行为吗?如果是这样,怎么做?

4

1 回答 1

3

此演示的摘录:

http://jsfiddle.net/AbdiasSoftware/t42cu/

(小提琴更新了扩展名和文件大小检查)。

在 html 中定义一个放置区域:

<div id="fileDrop">Drop KML file here</div>

根据需要设置样式:

#fileDrop {
    padding:20px;
    text-align:center;
    border:3px dashed #777;
    border-radius:12px;
    opacity:0.5;
    color:#fff;
    }
#fileDrop:hover {
    background-color:rgba(255,255,255,0.7);
    }

要启用文件的拖放,您可以使用以下代码:

var fileDrop = document.getElementById('fileDrop');
fileDrop.addEventListener('dragover', fileDragOver, false);
fileDrop.addEventListener('drop', fileSelect, false);

// change style of the drop area when file is over
function fileDragOver(e) {
    e.stopPropagation();
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
}

//load file on drop
function fileSelect(e) {

    e.stopPropagation();
    e.preventDefault();

    var files = e.dataTransfer.files,
        f = files[0],
        reader,

        fname = f.name.toLowerCase(),
        fsize = f.size,

        maxSize = 1024 * 1024; // 1mb

    /// Check file extension and file size
    if (fname.length < 5 || fname.substring(fname.length - 4) !=='.kml') {
        alert('Need a .kml file!');
        return;
    }

    if (fsize > maxSize) {
        alert('File is too big!');
        return;
    }

    reader = new FileReader(),

    reader.onload = function(fe) {

        var kml = fe.target.result; // the file
        gotoOpenLayer(kml);

    }
    reader.readAsText(f);
}

gotoOpenLayer函数中,我们将文件转换为Blob,然后转换为objectURL

function gotoOpenLayer(kml) {

    var blob = new Blob([kml], {type: 'text/plain'});
    var lnk = window.URL.createObjectURL(blob);

    /// pass in lnk as url or kml as string to OpenLayers

    // ....
}

我找到了 url 加载和传递字符串的示例。

使用 Blob URL -

var map = new OpenLayers.Map({
    div: "map",
    layers: [
        new OpenLayers.Layer.WMS(
            "WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0",
            {layers: "basic"}
        ),
        new OpenLayers.Layer.Vector("KML", {
            strategies: [new OpenLayers.Strategy.Fixed()],
            protocol: new OpenLayers.Protocol.HTTP({

                url: lnk, /// url goes here

                format: new OpenLayers.Format.KML({
                    extractStyles: true, 
                    extractAttributes: true,
                    maxDepth: 2
                })
            })
        })
    ],
    center: new OpenLayers.LonLat(-112.169, 36.099),
    zoom: 11
});

或者通过将加载的文件作为字符串传递:

function getFeaturesFromKMLString (kml) {
    var format = new OpenLayers.Format.KML({
        'internalProjection': myMapObject.baseLayer.projection,
        'externalProjection': new OpenLayers.Projection("EPSG:4326")
    });
    return format.read(kml);
};

// ...
myVectorLayer.addFeatures(getFeaturesFromKMLString(kml));
于 2013-07-08T01:39:22.240 回答