搜尋此網誌

2015年10月14日 星期三

列印google map圖台

使用google map圖台很方便
但有列印圖台畫面需求時候,該怎麼辦呢?
這裡小弟提供兩種方法


方法一:
直接使用javascript把html碼印出來
var content = window.document.getElementById("map"); // get you map details
        var newWindow = window.open(); // open a new window
        newWindow.document.write(content.innerHTML); // write the map into the new window
        //newWindow.print(); // print the new window
但是缺點是不支援Geojson畫出來的Marker
或是自己套疊上去的圖層(ex.wms、wfs)

方法二:
使用html2canvas這個好用的套件
我是使用html2canvas4.0.js
首先把js引用後
<script type="text/javascript" src="./js/html2canvas4.0.js"></script>
直接呼叫PrintMap就可以使用了
function PrintMap() {
        html2canvas(document.getElementById("map"), {
            useCORS: true,
            onrendered: function (canvas) {
                window.open(canvas.toDataURL("image/png")); // write the map into the new window
            }
        });
    }
他的方法是用canvas直接在瀏覽器端畫出來
然後產出一個以base64構成的圖片字串
但缺點是會比較吃瀏覽器端的效能,會比較慢
另外就是使用後發現cluster markers會無法顯示
會一直出現cross site沒有權限的issue
因此將useCORS: true,拿掉
另外加上proxy的header處理讓http看得懂
function PrintMap() {
        html2canvas(document.getElementById("map"), {
            "proxy": "./Handler/html2canvasproxy.ashx",
            onrendered: function (canvas) {
                window.open(canvas.toDataURL("image/png")); // write the map into the new window
            }
        });
    }
如此一來就可以正常運作了
提供大家參考

附上 html2canvasproxy.ashx 內容
==========start==========
<%@ WebHandler Language="C#" Debug="true" Class="Html2CanvasProxy" %>
/*
 * html2canvas-csharp-proxy 0.0.6
 * Copyright (c) 2014 Guilherme Nascimento (brcontainer@yahoo.com.br)
 * 
 * Released under the MIT license
 */

using System;
using System.IO;
using System.Web;
using System.Net;
using System.Text;
using System.Security.Cryptography;
using System.Text.RegularExpressions;

public class Html2CanvasProxy : IHttpHandler {
    //Setup
    private string defaultCallback = "console.log";  //Set default callback
    private string PATH = "images";                  //Path relative
    private int CCACHE = 60 * 5 * 1000;              //Limit access-control and cache
    private bool CROSSDOMAIN = false;                //Enable cross-domain for use proxy with a sub-domain

    private static string JsonEncodeString (string s, bool onlyEncode) {
        string[] vetor = new string[127];
        vetor[0]  = "\\0";
        vetor[8]  = "\\b";
        vetor[9]  = "\\t";
        vetor[10] = "\\n";
        vetor[12] = "\\f";
        vetor[13] = "\\r";
        vetor[34] = "\\\"";
        vetor[47] = "\\/";
        vetor[92] = "\\";

        int i = 0;
        int c;
        string d;
        string[] e = new string[s.Length];

        foreach (string j in e) {
            e[i] = s.Substring(i, 1);
            c = (int) Convert.ToChar(e[i]);
            if (c > 126) {
                d = "000" + c.ToString("X");
                e[i] = "\\u" + d.Substring(d.Length - 4);
            } else {
                if (!String.IsNullOrEmpty(vetor[c])) {
                    e[i] = vetor[c];
                } else if (!(c > 31)) {
                    d = "000" + c.ToString("X");
                    e[i] = "\\u" + d.Substring(d.Length - 4);
                }
            }
            i++;
        }

        if (onlyEncode) {
            return String.Join("", e);
        } else {
            return "\"" + String.Join("", e) + "\"";
        }
    }

    private static string Ascii2Inline (string str) {
        string[] x = {
            "\n",
            "\r",
            " ",
            "\"",
            "#",
            "&",
            "/",
            "\\",
            ":",
            "?",
            "\0",
            "\b",
            "\t"
        };

        string[] y = {
            "%0A",
            "%0D",
            "%20",
            "%22",
            "%23",
            "%26",
            "%2F",
            "%5C",
            "%3A",
            "%3F",
            "",
            "",
            "%09"
        };

        int i = 0;

        foreach (string j in x) {
            str = str.Replace(j, y[i]);
            i++;
        }
        return str;
    }

    private static string ReadFileEnconding (string file, bool base64) {
        FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);

        byte[] filebytes = new byte[fs.Length];

        fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
        fs.Close();

        if (base64) {
            return Convert.ToBase64String(filebytes);
        }
        return Html2CanvasProxy.Ascii2Inline(System.Text.Encoding.Default.GetString(filebytes));
    }

    public void ProcessRequest (HttpContext context) {
        string GMDATECACHE = DateTime.UtcNow.ToString();
        string ERR = "";
        string MIME = "";
        string CHARSET = "";
        string[] tmp;
        string[] makeAdress;
        string username = "";
        string password = "";
        string httpType = "http";
        string basicAuth = "";

        HttpResponse HS = context.Response;

        //set access-control
        HS.AddHeader("Access-Control-Max-Age", CCACHE.ToString());
        HS.AddHeader("Access-Control-Allow-Origin", "*");
        HS.AddHeader("Access-Control-Request-Method", "*");
        HS.AddHeader("Access-Control-Allow-Methods", "OPTIONS, GET");
        HS.AddHeader("Access-Control-Allow-Headers", "*");

        //mime
        HS.ContentType = "application/javascript";

        //GET
        string geturl = context.Request.QueryString["url"];
        string getcallback = context.Request.QueryString["callback"];

        if (getcallback == "" || getcallback == null) {
            ERR = "get param callback is undefined";
            getcallback = defaultCallback;
        } else if (geturl == "" || geturl == null) {
            ERR = "get param url is undefined";
        } else {
            string realpath = HttpContext.Current.Server.MapPath("./" + PATH);
            bool isExists = System.IO.Directory.Exists(realpath);
            if (!isExists) {
                System.IO.Directory.CreateDirectory(realpath);
                isExists = System.IO.Directory.Exists(realpath);

                if (!isExists) {
                    ERR = "\"" + realpath + "\" folder can not be created.";
                }
            }

            if (geturl.IndexOf("https") == 0) {
                httpType = "https";
            }

            geturl = Regex.Replace(geturl, "^(https|http)[:]//", "");

            if (ERR == "") {
                tmp = geturl.Split('/');

                if (tmp[0].IndexOf("@") != -1) {
                    makeAdress = tmp[0].Split('@');
                    makeAdress = makeAdress[0].Split(':');

                    if (makeAdress.Length > 1) {
                        username = makeAdress[0];
                        password = makeAdress[1];
                    } else {
                        username = makeAdress[0];
                    }

                    //Basic authentication
                    basicAuth = Convert.ToBase64String(
                        System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password)
                    );
                }

                WebRequest request = WebRequest.Create(httpType + "://" + geturl);

                // If required by the server, set the credentials.
                request.Credentials = CredentialCache.DefaultCredentials;

                //Set same user agent
                ((HttpWebRequest) request).UserAgent = context.Request.UserAgent;

                //Auth basic
                request.Headers["Authorization"] = "Basic " + basicAuth;

                try {
                    HttpWebResponse response = (HttpWebResponse) request.GetResponse();

                    if (response.StatusCode != HttpStatusCode.OK) {
                        ERR = response.StatusCode.ToString();
                    } else if (response.Headers["Content-Length"] == "0") {
                        ERR = "source is blank (Content-length: 0)";
                    } else {
                        MIME = response.ContentType.ToLower().Trim();

                        if (MIME.IndexOf(";") != -1) {
                            tmp = MIME.Split(';');
                            MIME = tmp[0].Trim();

                            tmp[0] = "";
                            CHARSET = string.Join(" ", tmp).Remove(0, 1).Trim();
                        }

                        //Some servers use image/svg-xml (minus signal) instead of image/svg+xml (plus signal)
                        if ("|image/jpeg|image/jpg|image/png|image/gif|image/svg+xml|image/svg-xml|text/html|application/xhtml|application/xhtml+xml|".IndexOf("|" + MIME + "|")== - 1) {
                            ERR = MIME + " mime is invalid";
                        } else {
                            HashAlgorithm sha = SHA1.Create();
                            byte[] shafilebyte = sha.ComputeHash(Encoding.UTF8.GetBytes(geturl));
                            string shafile = BitConverter.ToString(shafilebyte).Replace("-", "").ToLowerInvariant();

                            string extesionFile = MIME.Replace("image/", "")
                                                        .Replace("text/", "")
                                                        .Replace("application/", "")
                                                        .Replace("x-", "")
                                                        .Replace("jpeg", "jpg")
                                                        .Replace("xhtml+xml", "xhtml")
                                                        .Replace("svg+xml", "svg").Replace("svg-xml", "svg");

                            shafile = shafile + "." + extesionFile;

                            Stream receiveStream = response.GetResponseStream();

                            using (System.IO.FileStream fs = System.IO.File.Create(realpath + "\\" + shafile)) {
                                int bytesRead;
                                long sizeBytes = response.ContentLength;

                                if (!(sizeBytes > 1)) {
                                    sizeBytes = Int32.MaxValue / 2;
                                }

                                byte[] buffer = new byte[sizeBytes];

                                while((bytesRead = receiveStream.Read(buffer, 0, buffer.Length)) != 0) {
                                    fs.Write(buffer, 0, bytesRead);
                                }
                            }

                            if (System.IO.File.Exists(realpath + "\\" + shafile)) {
                                HS.AddHeader("Last-Modified", DateTime.UtcNow.ToString("R"));
                                HS.AddHeader("Cache-Control", "max-age=" + (CCACHE - 1));
                                HS.AddHeader("Pragma", "max-age=" + (CCACHE - 1));
                                HS.AddHeader("Expires", new DateTime(DateTime.UtcNow.Ticks).AddSeconds(CCACHE - 1).ToString("R"));

                                if (CROSSDOMAIN) {
                                    bool isBase64 = MIME.IndexOf("image/svg") == -1 && MIME.IndexOf("text/") == -1;
                                    string dataURI = "data:" + Html2CanvasProxy.JsonEncodeString(MIME, true);

                                    if (CHARSET != "" && CHARSET != null) {
                                        dataURI += ";" + Html2CanvasProxy.JsonEncodeString(CHARSET, true);
                                    }

                                    if (isBase64) {
                                        dataURI += ";base64";
                                    }

                                    HS.Write(
                                        getcallback + "(\"" +
                                            dataURI + "," +
                                            Html2CanvasProxy.ReadFileEnconding(realpath + "\\" + shafile, isBase64) +
                                        "\")"
                                    );
                                } else {
                                    string fullurl = "http://";
                                    if (context.Request.Url.Port == 443) {
                                        fullurl = "https://";
                                    }

                                    fullurl += context.Request.Url.Host;
                                    if (context.Request.Url.Port != 80 && context.Request.Url.Port != 443) {
                                        fullurl += ":" + context.Request.Url.Port.ToString();
                                    }

                                    string[] uri = context.Request.Url.Segments;
                                    uri[uri.Length - 1]="";

                                    fullurl += String.Join("/", uri).Replace("//","/");
                                    fullurl += PATH + "/" + shafile;

                                    HS.Write(getcallback + "(" + Html2CanvasProxy.JsonEncodeString(fullurl, false) + ")");
                                }
                                return;
                            } else {
                                ERR = "no such file";
                            }
                        }
                    }
                } catch (WebException e) {
                    ERR = e.ToString();
                }
            }
        }

        HS.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        HS.Cache.SetValidUntilExpires(false);
        HS.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        HS.Cache.SetCacheability(HttpCacheability.NoCache);
        HS.Cache.SetNoStore();

        HS.Write(getcallback + "(" + Html2CanvasProxy.JsonEncodeString("error:" + ERR, false) + ")");
    }

    public bool IsReusable {
        get {
            return false;
        }
    }
}
==========end==========

沒有留言:

張貼留言