【问题标题】:Google Map screen capture is not working for marker and marker cluster using html2canvas谷歌地图屏幕截图不适用于使用 html2canvas 的标记和标记集群
【发布时间】:2015-04-27 21:35:15
【问题描述】:

我正在使用烧瓶做 python 项目,我使用谷歌地图 api 在项目中显示地图。我实现了html2canvas 脚本以成功捕获地图。但是我在地图上也有标记,它没有捕获。所以我尝试使用html2canvasPythonProxy 这是我的模板 gpsDataMap 的 javascript 文件的 sn-p:

$(window).load(function(){
      $('#saveMap').click(function(){
          html2canvas(document.getElementById('map'), {
             "logging": true, //Enable log (use Web Console for get Errors and Warnings)
             "proxy":"/surveyApp/gpsDataMap/html2canvas-proxy",
             useCORS:true,
             "onrendered": function(canvas) {
              var img = new Image();
             img.onload = function() {
             img.onload = null;
             document.body.appendChild(img);
           };
            img.onerror = function() {
            img.onerror = null;
            if(window.console.log) {
               window.console.log("Not loaded image from canvas.toDataURL");
                  } else {
            alert("Not loaded image from canvas.toDataURL");
               }
              };
                img.src = canvas.toDataURL("image/png");
               }
            });

        });
    });

还有我的python代码sn-p:

import os
import datetime

from flask import Flask, request, render_template, redirect, url_for, flash, Response
from flask.json import dumps
from flask import json
from flask import g, Blueprint, session, abort
from flask_principal import Identity, identity_changed, identity_loaded, RoleNeed, AnonymousIdentity
from flask_login import LoginManager, login_user, login_required, logout_user
from app import app
from model.user_info import SurveyForms

from flask.ext.pymongo import PyMongo

from inspect import getmembers, isfunction
import formConfig
import formTree
import fieldChoices
from dashboard import dashboardData
from collections import namedtuple
from pymongo import MongoClient
from flask import request


from html2canvasproxy import * #include html2canvasproxy in your application
import urlparse
import re




surveyApp_module = Blueprint('surveyApp_module', __name__)


app.config['MONGO_HOST'] = 'localhost'
app.config['MONGO_PORT'] = 27017
app.config['MONGO_DBNAME'] = 'survey'
mongo = PyMongo(app)

h2c = None
real_path = os.getcwd() + '/static/images'
virtual_path = '/gpsDataMap/images/'

@surveyApp_module.route('/')
@login_required
def show_formList():
    forms = []
    forms = [form.form_name for form in SurveyForms.select().where(SurveyForms.organization_name==session['organization_id'])]
    # strip .xml from string to compare with returnData
    forms =  [form.replace('.xml','') for form in forms]
    returnData = mongo.db.collection_names()
    returnData.pop(returnData.index('system.indexes'))
    intersected_forms = list(set(forms).intersection(returnData))
    if len(intersected_forms):
        return render_template('index_pjj.html', surveyEntries=intersected_forms)
    return render_template('index_pjj.html', surveyEntries=['No Survey'])

@surveyApp_module.route('/dashboard', methods=['POST'])
def dashboard():
    formName = request.form['whichSurvey']
    session['formName'] = formName
    formtree = formTree.formParseDict(formName)
    returnData = dashboardData(formName, mongo.db)
    summaryData = totalSummary(formName, mongo.db)
    jsonData = json.dumps(returnData)
    return render_template('dashboard.html', formName=formName, formTree=formtree, returnData=returnData, summaryData=summaryData, jsonData=jsonData)


@surveyApp_module.route('/gpsDataView', methods=['POST'])
def gpsDataView():
    formName = request.form['whichSurvey']
    gpsFields = formConfig.survey[formName]['gpsField']
    (location, fieldName, fieldSelection, fieldChoicesList) = "", "", "", []
    location = request.form['location']
    fieldName = request.form['fieldName']
    try:
        fieldSelection = request.form['fieldChoices']
    except KeyError:
        pass
    fieldChoicesList = request.form.getlist('fieldChoicesList')
    fieldData = commonFunctions.vizFieldList(formName)
    totalFieldData = commonFunctions.vizFieldListFull(formName)
    locationIdentifiers = fieldChoices.locationFieldChoices(formName, mongo.db)
    returnData = gpsVariate.getDataforGPSMap(formName, mongo.db, gpsFields, location, fieldName, fieldSelection, fieldChoicesList)
    return render_template('gpsDataMap.html', returnData=returnData, formName=formName, fieldData=fieldData, totalFieldData=totalFieldData, locationIdentifiers=locationIdentifiers)



    #Copy html2canvas.js to static folder (If not use cdns)
@surveyApp_module.route('/gpsDataMap/html2canvas.js')
def html2canvas_js():
    return app.send_static_file('html2canvas.js')



@surveyApp_module.route('/gpsDataMap/html2canvas-proxy')
def html2canvas_proxy():
    print ("is this proxy really calling ");
    h2c = html2canvasproxy(request.args.get('callback'), request.args.get('url'))
    h2c.userAgent(request.headers['user_agent'])
    # import pdb;pdb.set_trace()


    if request.referrer is not None:
        h2c.referer(request.referrer)

    h2c.route(real_path, virtual_path)

    r = h2c.result()
    # print r['mime']
    # print r['data']

    return Response(r['data'], mimetype=r['mime'])




 # Get images saved by html2canvasproxy
@surveyApp_module.route('/gpsDataMap/html2canvas/images/<image>')
def images(image):
    res = html2canvasproxy.resource(real_path, image)

    if res is None:
        return '', 404

    else:
        return res['data']

这是我的 main.py 脚本:

from app import app, db


from auth import *
from admin import admin
from model import *
from view import *
from filters.user_privilege import check_privilege
from filters.form_filter import filter_type

# custom filters
app.jinja_env.filters['check_privilege'] = check_privilege
app.jinja_env.filters['filter_type'] = filter_type


from surveyApp import surveyApp_module
app.register_blueprint(surveyApp_module, url_prefix='/surveyApp')

from view.accounts.login import login_module
app.register_blueprint(login_module)


if __name__ == '__main__':
    app.run(port=5555)

这样做时,我会在控制台中看到以下内容:

html2canvas: Preload starts: finding background-images html2canvas.js:21
html2canvas: Preload: Finding images html2canvas.js:21
html2canvas: Preload: Done. html2canvas.js:21
html2canvas: start: images: 1 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 2 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 3 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 4 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 5 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 6 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 7 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 8 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 9 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 10 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 11 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 12 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 13 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 14 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 15 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 16 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 17 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 18 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 19 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 20 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 21 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 22 / 23 (failed: 0) html2canvas.js:21
GET http://127.0.0.1:5555/home/bhim/app/surveyApp_bhim/images/a0af53c02bd2f2aed37f1d895edcf3485117c512.png 404 (NOT FOUND) html2canvas.js:2249
html2canvas: start: images: 23 / 23 (failed: 1) html2canvas.js:21
Finished loading images: # 23 (failed: 1) html2canvas.js:21
html2canvas: Error loading background: html2canvas.js:21
html2canvas: Renderer: Canvas renderer done - returning canvas obj 

更新: 调试器结果:

folder => images,
timeout => 30,
mimetype => application/javascript,
ua => Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0,
host => 127.0.0.1:5555,
scheme => http,
ref => ,
url => http://www.google.com,
callback => console.log,
default_callback => console.log,
status => 0,
routePath => /static/images/,
savePath => /home/bhim/app/surveyApp_bhim/static/images/,
prefix => htc_,
real_extension => ,
mimes => ['image/bmp', 'image/windows-bmp', 'image/ms-bmp', 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'text/html', 'application/xhtml', 'application/xhtml+xml']

更新谷歌地图图片截图

标记未被捕获。

【问题讨论】:

  • 你的“sn-p”不是一个整体?
  • @GuilhermeNascimento 我已经更新了 sn-p。
  • 我觉得我表达得不好,我想知道你是如何运行“应用程序”的,你创建了一个__init__.py和一个run.py?它的变量“app”从何而来?
  • 请发布您有问题的“文件夹结构/目标结构”(例如digitalocean.com/community/articles/… 中的示例)。
  • @GuilhermeNascimento 我从 main.py 文件运行应用程序。我已经更新了上面 main.py 文件的代码。

标签: javascript python google-maps html2canvas


【解决方案1】:

请先试试这个,它可能对你有用。

<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDY0kkJiTPVd2U7aTOAwhc9ySH6oHxOIYM&sensor=false">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script> 
<script type="text/javascript" src ="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="html2canvas.js?rev032"></script> 



<script type="text/javascript">

function initialize()
    {
    var mapProp = {
          center:new google.maps.LatLng(51.508742,-0.120850),
          zoom:5,
          mapTypeId:google.maps.MapTypeId.ROADMAP
      };
    var map=new google.maps.Map(document.getElementById("googleMap"), mapProp);
}

google.maps.event.addDomListener(window, 'load', initialize);

 $(window).load(function(){

    $('#load').click(function(){

            html2canvas($('#googleMap'), {
            useCORS: true,
                onrendered: function (canvas) {
                var dataUrl= canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");

                window.location.href = dataUrl;
                                    }
            });

    });
});
</script>
</head>

<body>
<div id="googleMap" style="width:500px;height:380px;"></div>
<input type="button" value="Save" id="load"/>
</body>

【讨论】:

    【解决方案2】:

    1) 使用useCORS:trueproxy,切勿同时使用。

    2) 您的路线不同,请参阅:

    • virtual_path = '/gpsDataMap/images/'

    • @surveyApp_module.route('/gpsDataMap/html2canvas/images/&lt;image&gt;')

    3) 您的代理路由似乎是错误的(在您的 Javascript 中):

    • "proxy":"/surveyApp/gpsDataMap/html2canvas-proxy",

    • @surveyApp_module.route('/gpsDataMap/html2canvas-proxy')


    您没有意识到所有错误,为什么 userCORS 与“代理”会混淆。

    修复所有路由(路由是它们的虚拟路径)并修复你的javascript(不要使用userCORS:),请参阅:

    $(window).load(function(){
        $('#saveMap').click(function(){
            html2canvas(document.getElementById('map'), {
                    "logging": true, //Enable log (use Web Console for get Errors and Warnings)
                    //useCORS:true, "COMMENTED", remove useCORS
                    "proxy": YOUR_FIXED_ROUTE,
                    "onrendered": function(canvas) {
                        var img = new Image();
                        img.onload = function() {
                            img.onload = null;
                            document.body.appendChild(img);
                        };
    
                        img.onerror = function() {
                            img.onerror = null;
                            if(window.console.log) {
                                window.console.log("Not loaded image from canvas.toDataURL");
                            } else {
                                alert("Not loaded image from canvas.toDataURL");
                            }
                        };
                        img.src = canvas.toDataURL("image/png");
                    }
            });
        });
    });
    

    看,这是混合了“路由”的绝对路径:

    GET http://127.0.0.1:5555/home/bhim/app/surveyApp_bhim/images/a0af53c02bd2f2aed37f1d895edcf3485117c512.png 404 (NOT FOUND) html2canvas.js:2249

    代理响应的路由无论什么原因都是错误的,使用这个:

    1) 编辑您的代码,如下所示:

    @surveyApp_module.route('/gpsDataMap/html2canvas-proxy')
    def html2canvas_proxy():
        print ("is this proxy really calling ");
        h2c = html2canvasproxy(request.args.get('callback'), request.args.get('url'))
        h2c.userAgent(request.headers['user_agent'])
    
        if request.referrer is not None:
            h2c.referer(request.referrer)
    
        if request.args.get('debug_vars'): #Added
            return Response((',\n'.join(h2c.debug_vars())), mimetype='text/plain') #Added
    
        h2c.route(real_path, virtual_path)
    
        r = h2c.result()
        return Response(r['data'], mimetype=r['mime'])
    

    2) 在浏览器中运行:

    http://127.0.0.1:5000/gpsDataMap/html2canvas-proxy?callback=console.log&amp;url=http://www.google.com&amp;debug_vars=1

    3) 获取结果并在您的问题中发布。

    【讨论】:

    • 我已经更正了路线并更新了我的脚本,如上所述。我仍然没有得到标记。但是,它会捕获标记簇。
    • 嗨@BhimPrasadAle,请再次阅读我的回答,我需要你完成所有要求你的过程,尤其是变量的调试。
    • 你好@GuilhermeNascimento 我已经更新了上面的调试结果。
    • 最后一个问题:我没有捕捉到这些mts.googleapis.com/vt/icon/name=icons/spotlight/… 标记
    • 所有路线都在吗?你做了所有你花费的流程?如果是,那么可以为我提供该问题的在线示例吗?希望能帮到你。
    【解决方案3】:

    保存标记(html2canvas 的解决方法):

    (来源#1):http://humaan.com/custom-html-markers-google-maps/
    (来源#2):http://jsfiddle.net/BCr2B/99/

    实现您自己的标记非常快速且非常简单,从而规避了污染问题。

    function HTMLMarker(lat, lng, col) {
        this.lat = lat;
        this.lng = lng;
        this.col = col;
        this.pos = new google.maps.LatLng(lat, lng);
    }
    
    HTMLMarker.prototype = new google.maps.OverlayView();
    HTMLMarker.prototype.onRemove = function() {}
    HTMLMarker.prototype.onAdd = function() {}
    HTMLMarker.prototype.draw = function() {
        var self = this;
        var div = this.div;
    
        if(!div) {
            div = this.div = document.createElement('div');
            div.className = 'marker';
            div.style.position = 'absolute';
            div.style.width = '32px';
            div.style.height = '32px';
    
            switch(this.col) {
                case "green":
                    div.innerHTML = '<img src="/images/green-dot.png">';
                    break;
                case "yellow":
                    div.innerHTML = '<img src="/images/yellow-dot.png">';
                    break;
                case "red":
                    div.innerHTML = '<img src="/images/red-dot.png">';
                    break;
            }
    
            var panes = this.getPanes();
            panes.overlayImage.appendChild(div);
        }
    
    
        var position = this.getProjection().fromLatLngToDivPixel(this.pos);
        div.style.left = position.x - 16 + "px";
        div.style.top = position.y - 32 + "px";
    }
    

    然后添加:

    var htmlMarker = new HTMLMarker(data[gps].Latitude, data[gps].Longitude, "green");
    markersArray.push(htmlMarker.setMap(map));
    

    当您以这种方式导出时,地图标记会成功添加,因为它们来自本地来源。

    【讨论】:

    • 知道如何在 google.maps.Data() 中使用自定义标记实现 html2canvas?我的标记被剪掉了。
    猜你喜欢
    • 2013-03-24
    • 1970-01-01
    • 2023-03-20
    • 2016-04-03
    • 2013-01-13
    • 2013-12-13
    • 2012-06-11
    • 1970-01-01
    相关资源
    最近更新 更多