导出单张地图以GeoJSON层以角5为png

问题描述 投票:1回答:4

我有一个单张地图用大量GeoJSON的的。我希望能够在地图图像导出为PNG。我已经尝试了小叶图像插件,其中出口基本地图,并且我也曾尝试(独立地)的html2canvas库输出地图div的内容到一个PNG文件。

不幸的是,使用单张图像输出仅显示背景层(映射),而不是任何以GeoJSON区域,而使用输出html2canvas结果示出所述层而不是背景图。

我不认为单张图像插件将是可行的,因为它有太多的限制。它要求所有图层被渲染到画布上,但这样做,性能跳水 - 这似乎并不能够处理这么多的地理区域。我也没有对服务器的太多的控制,并且是的NodeJS没有安装在那里。

html2canvas是更为看好。使用和文件保护程序,我能输出完整的图像和地区,具体如下:

html2canvas(myMap, {
            allowTaint:false,
            useCORS: true,
            width: 650,
            height: 500,

        }).then(canvas => {
            canvas.toBlob((blob) => {
                saveAs(blob, "my-map.png");
            });
        });

这工作出色,除了一个问题 - 该区域被渲染在错误的位置擦到画布上。也就是说,该区域的偏移是错误的。下面是一个例子。在地图的底部和右侧应覆盖到彩色等值线区域的边缘:leaflet image with regions, clipped

如何获得这些区域正确地呈现在地图上,并在错误的地方不被裁剪?

编辑:我看了一下在html2canvas网站here这看起来前途无量的问题。雷似乎并不有一个转换的问题,因为这样的,但有一个人是经历了什么,我认为是一个层偏移的问题。我在这里实现他们的解决方案:

function redraw() {
    var lat_tmp = map.getCenter().lat;
    var lng_tmp = map.getCenter().lng;
    map.setView([-66.22149259832975, -1.142578125]);
    setTimeout(function () {
        waitForTilesToLoad()
    }, 50000);
    map.setView([lat_tmp, lng_tmp]);
}

但它也没有工作,所以我仍然在试图解决这个问题。这不是一个真正的层偏移问题,我遇到的,但图层剪贴问题。

javascript angular leaflet html2canvas
4个回答
1
投票

有同样的问题最近也去了同样的报价话题,同时试图管理html2canvas。

在我的情况下(也许你也一样),地图是动态的,承载了太多的砖和亲切的元素(markeclusters,扇形图等)。它搞砸使用CraigVA给出的伎俩。

最后,我尝试了其他几个插件,并发现这是非常令人满意的:

Leaflet Easy Print

无毛刺,清洁PNG出口。


0
投票

我已经做的工作​​的公平位上移的GeoJSON的嫁给了背景砖视口,从上面的html2canvas链接。我没有得到它正确映射,如果我四处移动地图,而不是当我将其放大。这是非常棘手的,这是我不想做的,如果我能避免它。这可能是做这更糟糕的方式,仿佛传单的变化,该解决方案将打破。

DOM到影像给我,我需要相对于从DOM生成图像的一切。传单轻松打印给我什么额外的在什么DOM到图像的给我。有与DOM到影像控制台的错误,并使用单张打印容易出现时同样的错误。我也想控制图像导出自己。不利的一面,以DOM到影像的是,它只能在Chrome和Firefox。没有IE,无棱,无Safari浏览器。所以,我已经发布以此为不需要担心这些约束上,而希望能想出更好的解决方案后,人们可能的解决方案。

DOM到图像是一个很好的发现,因为我还可以与其他物体为好,如图表中使用它。荣誉对波将金的帮助送我走上这条路。

下面是使用domtoimage和文件保护的解决方案:

import { saveAs } from "file-saver";
import domtoimage from "dom-to-image";

domtoimage.toPng(myMapDomObject).then((myImage: string) => {
            const commaPos = myImage.indexOf(",");
            if (commaPos > 0) myImage = myImage.substring(commaPos + 1);
            const byteArray = Util.encodeByteArray(myImage);
            const blob = new Blob([byteArray], { type: "image/png" });
            saveAs(blob, "mymap.png");
        });

该Util.encodeByteArray方法是我自己的方法将图像字符串转换为字节数组用于创建可用于出口的斑点。它有问题,如果图像获得巨额显然,虽然这是从来没有发生在我身上。有可能是一个更好的方式来做到这一点,我目前不知道的。

export class Util {
    static encodeByteArray(bytes: string) {
        const byteCharacters = atob(bytes);
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        return byteArray;
    }
}

顺便说一句,我研究如何leaflet.browser.print作品。这似乎是能够产生相同的结果,并且是跨浏览器,但仅提供打印。其在GitHub代码的调查可能会提供一个更跨浏览器的解决方案,如果我可以计算出如何将内部图像输出。


0
投票

语气说:

在地图的底部和右侧应覆盖到彩色等值线区域的边缘:

我发现了一个简单的解决这个问题!

  1. 设置渲染器填充值(https://leafletjs.com/reference-1.4.0.html#renderer-padding)= 0
  2. 设置 “WINDOWWIDTH” 值(http://html2canvas.hertzen.com/configuration)= document.documentElement.clientWidth。

我希望这可以帮助你!祝好运。


0
投票

尝试从您的地图,然后出口去除去渲染填充。它为我工作。

在你的情况,类似的东西

myMap.getRenderer(myMap).options.padding = 0;
html2canvas(...

0
投票

由于写这个问题,时间公平位已经过去了。最终为我工作的解决方案是购买Telerik报告和实施任何映射解决方案,我需要在那里。这是一个非常好的选择,而且一直为我工作,所以如果你有这样做的机会,我会极力推荐它。您还可以得到一些不同的文件格式,开箱即用,以及解决方案看起来显著更专业。只是一个值得考虑的选择。

© www.soinside.com 2019 - 2024. All rights reserved.