3

上周,我构建了一个允许用户绘制形状、添加标签和计算区域的客户端 html 页面。最终,系统需要能够将这项工作变成可以自动添加到 Word 文档中的平面图像。

我已经研究了各种方法来做到这一点,并不断陷入陷阱。一种方法是发送页面服务器端的 html,然后使用 Windows 窗体中的 Browser 对象对其进行渲染和截屏。另一个(我还没有尝试过)将涉及做类似的事情,但使用 PhantomJS 服务器端。

但是,我意识到我从页面获取的 HTML 并没有呈现我所期望的内容,所以我向前迈出了一步,后退了两步。

作为一个快速测试,我将此按钮单击事件添加到我的页面,它捕获页面的 HTML:

var html = document.documentElement.outerHTML;
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("C:\\Test.html", true);
s.Write(html);
s.Close();

这是页面包含的内容类型的示例(我在屏幕截图中需要):

预期的屏幕截图内容。

但是,如果我在 Internet Explorer 中查看 Test.html,我会得到:

谷歌在 IE 中映射 HTML 示例。

..如果我在 Chrome 中打开它,我会得到:

谷歌在 chrome 中映射 HTML 示例。

我想这与谷歌地图的工作方式有关(它动态加载和删除 javascript 数据文件以帮助渲染形状)。如果我可以完整地捕获 HTML 并正常工作,那么我希望我能够在服务器端对其进行截图,但看起来并不乐观。

任何可靠地将页面转换为平面图像的想法?

PS我也在研究谷歌的静态地图API,但它不支持圆圈或自定义叠加层(据我所知)!

编辑:我已经意识到形状被绘制到动态画布对象中,并在地图上平铺,并且这些画布元素不会随页面 HTML 一起出现(即使它们这样做了,它们似乎也不包含形状DOM 中的数据)。

4

1 回答 1

3

过去我不得不做一些非常相似的事情。

我所做的是,我绘制了各种颜色的多边形,添加了地标、形状等,然后使用 Json 将所有内容保存到一个字符串中。

我使用 javascript 来保存所有数据,如下所示:

 var feature = MapToolbar.features[type+'Tab'][id];
 var vertices = MapToolbar.getLatLngVertices(feature.getPath());
 allData[id] = { color: feature.fillColor, data: vertices}; });
 var allDataJson = JSON.stringify(allData);
 var hfPolyPath = $("div.hiddenVars input").get(0);

getLatLngVertices:

  getLatLngVertices: function(path) {
     var pathArray = path.getArray();
     var vertices = [];
     for( var i = 0, n = pathArray.length;  i < n;  i++ ) {
        var latLng = pathArray[i];
        vertices.push({ lat: latLng.lat(), lng: latLng.lng() });
     }
     return vertices;
    },

我将代码包装到一个名为“SaveBounds()”的函数中,它会为我生成 Json 字符串并将其保存在隐藏字段中。

然后我使用 google api 生成了一个静态图像。

这可以在服务器端完成,也可以使用 jQuery。在我的情况下,我需要将图像作为电子邮件的附件发送,所以我必须在服务器端进行,但使用 jQuery 应该更容易。

您需要做的是使用http://maps.googleapis.com/maps/api/staticmap 您可以将所有查询字符串参数添加到其中,以生成与动态地图看起来相同的图像。

我在 C# 中的代码是:

            sb.Append("http://maps.googleapis.com/maps/api/staticmap?");
            sb.Append("center=" + centerMap.Value.Substring(1, centerMap.Value.Length - 1));
            sb.Append("&zoom" + zoom.Value);
            sb.Append("&size=450x450");
            sb.Append("&mapType=" + mapType.Value);

            var decodedMapData = Server.UrlDecode(polyPath.Value);

            var dataObject = JsonConvert.DeserializeObject<dynamic>(decodedMapData);

            string staticImgSrc = sb.ToString();

            foreach (var key in dataObject)
            {
                var color = key.Value["color"];
                var array = key.Value["data"];
                var fillcolor = "0x" + color.ToString().Substring(1) + "80";
                staticImgSrc += "&path=color:0x00000080|weight:2|fillcolor:" + fillcolor;
                var count = 0;
                var lat = string.Empty;
                var lng = string.Empty;
                foreach (var arrayItem in array)
                {
                    staticImgSrc += "|" + arrayItem.lat.ToString() + "," + arrayItem.lng.ToString();
                    if (count == 0)
                    {
                        lat = arrayItem.lat.ToString();
                        lng = arrayItem.lng.ToString();
                    }
                    count++;
                }
                staticImgSrc += "|" + lat + "," + lng;
            }

            staticImgSrc += "&sensor=false";

您可以使用最终图像 url 来保存图像、通过电子邮件发送或任何您喜欢的方式。您可以根据需要添加任意数量的形状和地标,并且可以将它们填充为您想要的任何颜色。您可以控制地图类型、定位、缩放等,因此最终结果是与您开始使用的动态地图完全相同的图像。

于 2013-07-26T15:14:15.713 回答