【问题标题】:Rendering local files with HTML5 in OpenLayers在 OpenLayers 中使用 HTML5 渲染本地文件
【发布时间】:2013-05-23 09:20:42
【问题描述】:

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

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

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

【问题讨论】:

  • 我认为这是 Openlayers 中的协议问题,但链接中的示例没有足够的详细信息是否支持 HTML5。两年前已明确回答,因此限制 FileAccess 支持的浏览器那个时候。检查这个链接,看看我的意思html5demos.com/file-api

标签: html canvas svg openlayers


【解决方案1】:

此演示的摘录:

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

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

在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));

【讨论】:

  • 这个例子很好@Ken。我一直认为协议应该在本地工作,那样我们永远不会使用HTTP。我不知道window可以创建对象url..顺便说一句,是否可以限制文件大小并限制扩展名?
  • @Myra 当然是 :) 我更新了示例并用代码回答以检查扩展名和文件大小。
猜你喜欢
  • 2019-10-04
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 2019-08-09
  • 2019-05-18
  • 2022-10-21
  • 2012-02-19
相关资源
最近更新 更多