Commits

Henning Schröder committed a56e320

map widget added

  • Participants
  • Parent commits 31ae22c

Comments (0)

Files changed (81)

File qtwidgets/dockwidget.py

         self.pinButton.setChecked(True)
         self.connect(self.pinButton, SIGNAL("clicked(bool)"), self.togglePinned)
         self.pinButton.setVisible(True)
-        self.connect(dockWidget, SIGNAL("featuresChanged(QDockWidget.DockWidgetFeatures)"), self.featuresChanged)
+        #self.connect(dockWidget, SIGNAL("featuresChanged(QDockWidget.DockWidgetFeatures)"), self.featuresChanged)
+        dockWidget.featuresChanged.connect(self.featuresChanged)
         self.featuresChanged(0)
 
 

File qtwidgets/olmapwidget/__init__.py

+# -*- coding: utf-8 -*-
+import sys
+import os
+
+#sys.path.remove("/usr/lib/python2.7/site-packages")
+#import faulthandler
+#faulthandler.enable()
+#from fakehttpd import install_fake_httpd
+
+from PyQt4.QtCore import QByteArray, QObject, pyqtSlot, pyqtSignal, QTimer, SIGNAL, QVariant, QUrl, Qt
+from PyQt4.QtGui import QApplication, QWidget, QVBoxLayout
+from PyQt4.QtWebKit import QWebView, QWebSettings
+
+
+DEBUG = True
+
+
+class PythonWebKitBridge(QObject):
+
+    instance = None
+
+
+    def __init__(self, webview):
+        QObject.__init__(self, webview)
+        self.webview = webview
+        self.setObjectName("python")
+        self.is_ready = False
+        self.queue = []        
+        self.webview.page().mainFrame().javaScriptWindowObjectCleared.connect(self.attach)
+        self.attach()
+        self.__class__.instance = self
+
+
+    def execute(self, code, wait_ready=True):
+        if not self.is_ready and wait_ready:
+            self.queue.append(code)
+        else:
+            return self._execute(code)
+
+        
+    def _execute(self, code):
+        def pydict(qd):
+            d = {}
+            for k, v in qd.items():
+                d[unicode(k)] = v # convert from QString
+            return d
+
+        try_code = """try { %s
+        } catch(error) {
+          alert("execution failed: " + error);
+          result = {pyjs_exception: error}
+          result
+        }
+        """ % code
+        if DEBUG:
+            print "executing:\n", code
+        variant = self.webview.page().mainFrame().evaluateJavaScript(try_code)
+        result = variant.toPyObject()
+        if isinstance(result, dict):
+            result = pydict(result)
+            error = result.get("pyjs_exception")
+            if error:
+                error = pydict(error)
+                for row_number, line in enumerate(code.splitlines()):
+                    print "%3i: %s" % (row_number, line)
+                for k, v in error.items():
+                    print "%s: %s" % (k, v)
+                raise RuntimeError(error)
+        return result
+
+
+    
+    def attach(self):
+        self.webview.page().mainFrame().addToJavaScriptWindowObject(self.objectName(), self)
+        self._execute("""
+           var new_log = function() {
+                 var l = [];
+                 for(var i=0; i<arguments.length; i++)
+                   l.push(""+arguments[i]);
+                 python.log(l);
+                 try {
+                   console.old_log.apply(console, arguments);
+                 } catch(e) {}
+           };
+           if(console.old_log == undefined) {
+              console.old_log = console.log;
+              console.log = new_log;
+           }
+      
+        """)
+
+
+    @pyqtSlot("QStringList")
+    def log(self, msglist):
+        try:
+            print "[LOG] ", unicode(msglist[0]).encode("utf-8") % [unicode(msg).encode("utf-8") for msg in msglist[1:]]
+        except Exception:
+            print "[LOG] ", " ".join(unicode(msg).encode("utf-8") for msg in msglist)
+
+
+    ready = pyqtSignal()
+
+    @pyqtSlot()
+    def on_ready(self):
+        self.is_ready = True
+        self.ready.emit()
+        if self.queue:
+            for code in self.queue:
+                self._execute(code)
+            del self.queue[:]
+    
+
+
+        
+class OpenLayersBridge(PythonWebKitBridge):
+
+    click = pyqtSignal("int", "int", "float", "float")
+        
+    @pyqtSlot("int", "int", "float", "float")
+    def on_mouse_clicked(self, x, y, lat, lon):
+        self.click.emit(x, y, lat, lon)
+
+
+
+    def pixels2coord(self, x, y):
+        result = self.execute("""
+          var lonlat = map.getLonLatFromViewPortPx({x:%s, y:%s});
+          var pos = lonlat.clone();
+          var newpos = pos.transform(                              
+               map.getProjectionObject(),
+               new OpenLayers.Projection("EPSG:4326")
+                //new OpenLayers.Projection("EPSG:90913")
+             );
+
+          var result = {lat: newpos.lat, lon:newpos.lon};
+          result;
+        """ % (x, y))
+        return result["lat"], result["lon"]
+
+
+    
+class LayerBase(object):
+    js = ""
+    defaults = {}
+    args = ()
+
+    def __init__(self, *args, **kwargs):
+        for key, value in self.defaults.items():
+            self.__dict__[key] = value
+        for key, value in zip(self.args, args):
+            self.__dict__[key] = value
+        self.__dict__.update(kwargs)
+        self.oid = str(id(self)).replace("-", "X")
+        
+    
+    def create_js(self):
+        js = self.js % self.__dict__
+        return '''
+        var layer_%(id)s = new %(js)s
+        window.map.addLayer(layer_%(id)s);''' % {"js":js, "id": self.oid}
+
+    __str__ = create_js
+
+    
+
+class GooglePhysicalLayer(LayerBase):
+    args = ("name,")
+    defaults = {"name": "Google Physical"}
+    js = 'OpenLayers.Layer.Google("%(name)s", {type: google.maps.MapTypeId.TERRAIN})'
+
+    
+class GoogleStreetsLayer(LayerBase):
+    args = ("name,")
+    defaults = {"name": "Google Streets"}
+    js = 'OpenLayers.Layer.Google("%(name)s", {numZoomLevels: 20})'
+
+    
+class GoogleHybridLayer(LayerBase):
+    args = ("name,")
+    defaults = {"name": "Google Hybrid"}
+    js = 'OpenLayers.Layer.Google("%(name)s", {type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20})'
+
+    
+class GoogleSatelliteLayer(LayerBase):
+    args = ("name,")
+    defaults = {"name": "Google Satellite"}
+    js = 'OpenLayers.Layer.Google("%(name)s", {type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22})'
+
+
+    
+class VectorLayerBase(LayerBase):
+    pass
+
+
+class KmlLayer(VectorLayerBase):
+    args = ("name", "url")
+    js = '''OpenLayers.Layer.Vector(%(name)r, {
+           projection: map.displayProjection,
+           visibility: false,
+           strategies: [new OpenLayers.Strategy.Fixed()],
+                protocol: new OpenLayers.Protocol.HTTP({
+                url: %(url)r, 
+                format: new OpenLayers.Format.KML({extractStyles: true, extractAttributes: true})
+           })
+        })
+    '''
+
+
+
+class WmsLayer(LayerBase):
+    args = ("name", "url", "layers")
+    js = '''OpenLayers.Layer.WMS(%(name)r, %(url)r, {
+             layers: %(layers)r, version: '1.3.0', transparent: true, srs: "EPSG:90913"},
+                           { visibility: false, singleTile:
+                           true,transitionEffect: 'resize', sphericalMercator: true, 
+                           isBaseLayer: false, transparent: true,
+                           opacity: 0.8
+                           })
+    '''
+
+class BlueMarbleLayer(WmsLayer):
+    defaults = {"name": "Sattelite", "url": "http://localhost:7000/map/wms/", "layers": "sat"}
+
+    
+class BordersLayer(WmsLayer):
+    defaults = {"name": "Borders", "url": "http://localhost:7000/map/wms/", "layers": "topo"}
+
+
+class OsmLayer(LayerBase):
+    args = ("name", "url")
+    defaults = {"name": "OpenStreetMap", "url": "http://192.168.56.162/tiles/${z}/${x}/${y}.png"}
+    js = 'OpenLayers.Layer.OSM(%(name)r, %(url)r)'
+
+
+    
+class Marker(object):
+    
+    js = """
+      var point = new OpenLayers.LonLat(%(lon)s, %(lat)s);
+      var marker_%(oid)s = new OpenLayers.Marker(point);
+      marker_%(oid)s.map = window.map;
+      window.markers.addMarker(marker_%(oid)s);
+    """
+    
+    def __init__(self, lat, lon):
+        self.lat = lat
+        self.lon = lon
+        self.oid = str(id(self)).replace("-", "X")
+    
+
+    def create_js(self):
+        return self.js % self.__dict__
+
+
+class MapWidget(QWidget):
+    
+    def __init__(self, parent=None, lat=None, lon=None, zoom=None):
+        super(MapWidget, self).__init__(parent)
+        self._layout = QVBoxLayout(self)
+        self.layout().setContentsMargins(0, 0, 0, 0)
+        QWebSettings.globalSettings().setAttribute(QWebSettings.LocalContentCanAccessFileUrls, True)
+        QWebSettings.globalSettings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True)
+        QWebSettings.globalSettings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
+        self.webview = QWebView(self)
+        self.bridge =  OpenLayersBridge(self.webview)
+        self.bridge.click.connect(self.click)
+        self.layout().addWidget(self.webview)
+        QTimer.singleShot(0, lambda:self.init(lat, lon,zoom))
+        self.click.connect(self.clicked)
+        
+        
+    def pixel2coord(self, x, y):
+        return self.bridge.pixels2coord(0, 0)
+
+        
+    def clicked(self, x, y, lat, lon):
+        marker = Marker(lat, lon)
+        self.add_marker(marker)
+        
+
+    click = pyqtSignal("int", "int", "float", "float")
+    
+        
+    def init(self, lat, lon, zoom):
+        #self.webview.load(QUrl("http://localhost.app/static/index.html"))
+        #install_fake_httpd(self.webview)
+        #self.webview.load(QUrl("http://localhost.app/static/index.html"))
+        path = os.path.dirname(os.path.abspath(__file__))
+        html = open(os.path.join(path, "static", "index.html")).read()
+        if lon is not None:
+            html = html.replace("var lon = 8.2;", "var lon = %s;" % lon)
+        if lat is not None:
+            html = html.replace("var lat = 53.166;", "var lat = %s;" % lat)
+        if zoom is not None:
+            html = html.replace("var zoom = 4;", "var zoom = %s;" % zoom)
+        html = html.replace("http://localhost.app", "file://%s" % path)
+        if DEBUG:
+            open("debug.html", "w").write(html)
+        
+        self.webview.setHtml(html)
+
+        
+    def move_marker(self, lat, lon):
+        pass
+
+    
+    def center(self):
+        pass
+
+    
+    def set_center(self, lat, lon):
+        pass
+    
+    
+    def zoom(self, factor):
+        pass
+
+
+    def add_layer(self, layer):
+        self.bridge.execute(layer.create_js())
+
+        
+    def add_marker(self, marker):
+        self.bridge.execute(marker.create_js())
+
+        
+
+def main():
+    app = QApplication(sys.argv)
+    win = MapWidget(None)
+    win.add_layer(GoogleStreetsLayer())
+    win.add_layer(BlueMarbleLayer())
+    win.show()
+    return app.exec_()
+
+
+
+if __name__ == "__main__":
+    sys.exit(main() or 0)

File qtwidgets/olmapwidget/debug.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+  <head>
+    <title></title>
+    <link rel="stylesheet" href="file:///home/henning/src/glider/glider_dev/src/qtwidgets/qtwidgets/olmapwidget/static/openlayers/theme/default/style.css" type="text/css">
+    <script src="file:///home/henning/src/glider/glider_dev/src/qtwidgets/qtwidgets/olmapwidget/static/openlayers/OpenLayers.js"></script>
+    <script src="file:///home/henning/src/glider/glider_dev/src/qtwidgets/qtwidgets/olmapwidget/static/jquery.js"></script>
+    <!--    
+    -->
+    <script src="http://maps.google.com/maps/api/js?v=3.7&sensor=false"></script>
+    <!-- 
+    -->
+
+    
+    <style type="text/css">
+        html, body, div {
+         margin: 0;
+         padding: 0;
+        }
+        #map {
+          height: 480px;
+          width: 640px;
+        }
+    </style>
+    
+    <script>
+  
+// HotPath http://trac.osgeo.org/openlayers/wiki/Release/2.11/GoogleMaps37
+if(1) OpenLayers.Layer.Google.v3.repositionMapElements = function() {
+    // This is the first time any Google layer in this mapObject has been
+    // made visible.  The mapObject needs to know the container size.
+    google.maps.event.trigger(this.mapObject, "resize");
+    
+    var div = this.mapObject.getDiv().firstChild;
+    if (!div || div.childNodes.length < 3) {
+        this.repositionTimer = window.setTimeout(
+            OpenLayers.Function.bind(this.repositionMapElements, this),
+            250
+        );
+        return false;
+    }
+
+    var cache = OpenLayers.Layer.Google.cache[this.map.id];
+    var container = this.map.viewPortDiv;
+    
+    // move the ToS and branding stuff up to the container div
+    // depends on value of zIndex, which is not robust
+    for (var i=div.children.length-1; i>=0; --i) {
+        if (div.children[i].style.zIndex == 1000001) {
+            var termsOfUse = div.children[i];
+            container.appendChild(termsOfUse);
+            termsOfUse.style.zIndex = "1100";
+            termsOfUse.style.bottom = "";
+            termsOfUse.className = "olLayerGoogleCopyright olLayerGoogleV3";
+            termsOfUse.style.display = "";
+            cache.termsOfUse = termsOfUse;
+        }
+        if (div.children[i].style.zIndex == 1000000) {
+            var poweredBy = div.children[i];
+            container.appendChild(poweredBy);
+            poweredBy.style.zIndex = "1100";
+            poweredBy.style.bottom = "";
+            poweredBy.className = "olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint";
+            poweredBy.style.display = "";
+            cache.poweredBy = poweredBy;
+        }
+        if (div.children[i].style.zIndex == 10000002) {
+            container.appendChild(div.children[i]);
+        }
+    }
+
+    this.setGMapVisibility(this.visibility);
+};
+    
+     $(document).ready(function() {   
+     
+        var lon = 8.2;
+        var lat = 53.166;
+        var zoom = 4;
+        var map, layer, markers, switcher, controls, options;
+     
+        switcher = new OpenLayers.Control.LayerSwitcher({'ascending':false});
+        controls = [
+          new OpenLayers.Control.NavToolbar(),
+          new OpenLayers.Control.Navigation(),
+          //new OpenLayers.Control.PanZoomBar(),
+          new OpenLayers.Control.PanZoom(),
+          
+          switcher,
+          new OpenLayers.Control.MousePosition(),
+          //new OpenLayers.Control.OverviewMap(),
+          //new OpenLayers.Control.ScaleBar(),               
+          new OpenLayers.Control.KeyboardDefaults()
+          ];
+        
+        options = {
+          controls: controls,
+          displayProjection: new OpenLayers.Projection("EPSG:4326"),  
+          projection: new OpenLayers.Projection("EPSG:900913"),
+          units: "m",
+          maxResolution: 156543.0339,
+          maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
+        };
+        
+
+        map = new OpenLayers.Map('map', options);
+        window.map = map;
+        
+        map.addLayer(new OpenLayers.Layer.OSM());                                             
+
+        var point = new OpenLayers.LonLat(lon, lat);
+        var center = point.clone().transform(
+          new OpenLayers.Projection("EPSG:4326"),   
+          map.getProjectionObject()        
+        );
+        map.setCenter(center, zoom);
+
+        var markers = new OpenLayers.Layer.Markers( "Markers", {displayInLayerSwitcher: false} );
+        window.markers = markers;
+        //var marker = new OpenLayers.Marker(point) ;        
+        //markers.addMarker(marker);
+        map.addLayer(markers);
+
+
+        map.events.register("click", map , function(e){
+             //var opx = map.getLayerPxFromViewPortPx(e.xy) ;
+             //marker.map = map ;
+             //marker.moveTo(opx);   
+             var lonlat = map.getLonLatFromViewPortPx(e.xy);
+             var pos = lonlat.clone();
+             var newpos = pos.transform(                              
+               map.getProjectionObject(),
+               new OpenLayers.Projection("EPSG:4326")
+                //new OpenLayers.Projection("EPSG:90913")
+             );
+             window.python.on_mouse_clicked(e.x ,e.y, newpos.lat, newpos.lon);
+     
+        });
+ 
+
+        $(window).resize(function() {
+          $("#map").width($(window).innerWidth()-4);
+          $("#map").height($(window).innerHeight()-4);
+        });
+        
+        $(window).trigger("resize");
+        
+        window.python.on_ready();
+       
+     });
+    </script>
+  </head>
+
+  <body>
+    <div id="map"></div>
+  </body>
+</html>

File qtwidgets/olmapwidget/fakehttpd.py

+# -*- coding: utf-8 -*-
+import mimetypes
+import os
+
+from PyQt4.QtCore import QByteArray, QTimer, SIGNAL, QVariant, QIODevice
+from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
+
+
+static_folder = os.path.join(
+    os.path.dirname(os.path.realpath(__file__)),
+    "static")
+
+	
+mimetypes.init()
+
+
+# From http://diotavelli.net/PyQtWiki/Using%20a%20Custom%20Protocol%20with%20QtWebKit
+# and http://doc.qt.nokia.com/qq/32/qq32-webkit-protocols.html
+class NetworkReply(QNetworkReply):
+    
+
+    def __init__(self, parent, request, operation, content, mime_type=None):
+        QNetworkReply.__init__(self, parent)
+        if isinstance(content, unicode):
+            content = content.encode("utf-8")
+        self.open(self.ReadOnly | self.Unbuffered)
+        self.data = QByteArray(content)
+        self.setRequest(request)
+        self.setOpenMode(QIODevice.ReadOnly)
+        self.setOperation(operation)
+        
+        if mime_type is None:
+            mime_type, encoding = mimetypes.guess_type(unicode(request.url().path()), strict=False)
+            mime_type = mime_type or "text/html"
+        content_type = "%s; charset=utf-8" % mime_type
+        self.setHeader(QNetworkRequest.ContentTypeHeader, QVariant(content_type))
+        self.setHeader(QNetworkRequest.ContentLengthHeader, QVariant(QByteArray.number(self.data.length())))
+        #if operation is QNetworkAccessManager.PostOperation:
+        #    self.setHeader("CC")
+        QTimer.singleShot(0, self, SIGNAL("metaDataChanged()"))
+        QTimer.singleShot(0, self, SIGNAL("readyRead()"))
+        print "new reply"
+        
+    
+    def abort(self):
+        pass
+        
+    
+    def bytesAvailable(self):
+        if self.data.length() == 0:
+            QTimer.singleShot(0, self, SIGNAL("finished()"))
+        count = self.data.length() + QNetworkReply.bytesAvailable(self)
+        return count
+                            
+    
+    def isSequential(self):
+        return True
+
+    
+    def readData(self, maxSize):
+        count = min(maxSize, self.data.length())
+        data = str(self.data[:count])
+        self.data.remove(0, count)
+        if self.data.length() == 0:
+            QTimer.singleShot(0, self, SIGNAL("finished()"))
+        return data
+
+        
+
+	
+class NetworkAccessManager(QNetworkAccessManager):
+    
+    
+    def __init__(self, old_manager):        
+        QNetworkAccessManager.__init__(self)
+        self.old_manager = old_manager
+        self.setCache(old_manager.cache())
+        self.setCookieJar(old_manager.cookieJar())
+        self.setProxy(old_manager.proxy())
+        self.setProxyFactory(old_manager.proxyFactory())
+        print "new manager"
+        
+        
+    def createRequest(self, operation, request, data):
+        url = request.url()
+        print "requesting", unicode(url)
+        if url.scheme() != "http" or (url.scheme() == "http" and url.host() != "localhost.app"):
+            return QNetworkAccessManager.createRequest(self, operation, request, data)
+        if operation == self.GetOperation:
+            #qs = unicode(url.encodedQuery())
+            path = unicode(url.path())
+            if path.startswith("/static"):
+                filename = os.path.join(static_folder, path[8:])
+                content = open(filename).read()
+            else:
+                raise RuntimeError("Unexpected request: %r" % path)
+            reply = NetworkReply(self, request, operation, content)
+            return reply
+        else:
+            print "Other request", operation, request, data
+            for entry in request.rawHeaderList():
+                print entry
+            raise RuntimeError("Unexpected request %r" % request.url())
+            #return QNetworkAccessManager.createRequest(self, operation, request, data)
+
+			
+			
+			
+def install_fake_httpd(webview):
+    #QWebSecurityOrigin.addLocalScheme("app")
+    #QWebSettings.globalSettings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
+	old_manager = webview.page().networkAccessManager()
+	new_manager = NetworkAccessManager(old_manager)
+	webview.page().setNetworkAccessManager(new_manager)

File qtwidgets/olmapwidget/fakehttpd.pyc

Binary file added.

File qtwidgets/olmapwidget/static/gmaps.js

+
+
+window.google = window.google || {};
+google.maps = google.maps || {};
+(function() {
+  
+  function getScript(src) {
+    document.write('<' + 'script src="' + src + '"' +
+                   ' type="text/javascript"><' + '/script>');
+  }
+  
+  var modules = google.maps.modules = {};
+  google.maps.__gjsload__ = function(name, text) {
+    modules[name] = text;
+  };
+  
+  google.maps.Load = function(apiLoad) {
+    delete google.maps.Load;
+    apiLoad([null,[[["http://mt0.googleapis.com/vt?lyrs=m@179000000\u0026src=api\u0026hl=en-US\u0026","http://mt1.googleapis.com/vt?lyrs=m@179000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"m@179000000"],[["http://khm0.googleapis.com/kh?v=113\u0026hl=en-US\u0026","http://khm1.googleapis.com/kh?v=113\u0026hl=en-US\u0026"],null,null,null,1,"113"],[["http://mt0.googleapis.com/vt?lyrs=h@179000000\u0026src=api\u0026hl=en-US\u0026","http://mt1.googleapis.com/vt?lyrs=h@179000000\u0026src=api\u0026hl=en-US\u0026"],null,null,"imgtp=png32\u0026",null,"h@179000000"],[["http://mt0.googleapis.com/vt?lyrs=t@128,r@179000000\u0026src=api\u0026hl=en-US\u0026","http://mt1.googleapis.com/vt?lyrs=t@128,r@179000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"t@128,r@179000000"],null,[[null,0,7,7,[[[330000000,1246050000],[386200000,1293600000]],[[366500000,1297000000],[386200000,1320034790]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026"]],[null,0,8,8,[[[330000000,1246050000],[386200000,1279600000]],[[345000000,1279600000],[386200000,1286700000]],[[354690000,1286700000],[386200000,1320035000]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026"]],[null,0,9,9,[[[330000000,1246050000],[386200000,1279600000]],[[340000000,1279600000],[386200000,1286700000]],[[348900000,1286700000],[386200000,1302000000]],[[368300000,1302000000],[386200000,1320035000]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026"]],[null,0,10,19,[[[329890840,1246055600],[386930130,1284960940]],[[344646740,1284960940],[386930130,1288476560]],[[350277470,1288476560],[386930130,1310531620]],[[370277730,1310531620],[386930130,1320034790]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1.16\u0026hl=en-US\u0026"]],[null,3,7,7,[[[330000000,1246050000],[386200000,1293600000]],[[366500000,1297000000],[386200000,1320034790]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026"]],[null,3,8,8,[[[330000000,1246050000],[386200000,1279600000]],[[345000000,1279600000],[386200000,1286700000]],[[354690000,1286700000],[386200000,1320035000]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026"]],[null,3,9,9,[[[330000000,1246050000],[386200000,1279600000]],[[340000000,1279600000],[386200000,1286700000]],[[348900000,1286700000],[386200000,1302000000]],[[368300000,1302000000],[386200000,1320035000]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026"]],[null,3,10,null,[[[329890840,1246055600],[386930130,1284960940]],[[344646740,1284960940],[386930130,1288476560]],[[350277470,1288476560],[386930130,1310531620]],[[370277730,1310531620],[386930130,1320034790]]],["http://mt0.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026","http://mt1.gmaptiles.co.kr/mt?v=kr1p.16\u0026hl=en-US\u0026"]]],[["http://cbk0.googleapis.com/cbk?","http://cbk1.googleapis.com/cbk?"]],[["http://khm0.googleapis.com/kh?v=59\u0026hl=en-US\u0026","http://khm1.googleapis.com/kh?v=59\u0026hl=en-US\u0026"],null,null,null,null,"59"],[["http://mt0.googleapis.com/mapslt?hl=en-US\u0026","http://mt1.googleapis.com/mapslt?hl=en-US\u0026"]],[["http://mt0.googleapis.com/mapslt/ft?hl=en-US\u0026","http://mt1.googleapis.com/mapslt/ft?hl=en-US\u0026"]],[["http://mt0.googleapis.com/vt?hl=en-US\u0026","http://mt1.googleapis.com/vt?hl=en-US\u0026"]]],["en-US","US",null,0,null,null,"http://maps.gstatic.com/mapfiles/","http://csi.gstatic.com","https://maps.googleapis.com","http://maps.googleapis.com"],["http://maps.gstatic.com/intl/en_us/mapfiles/api-3/7/17","3.7.17"],[3136971342],1.0,null,null,null,null,0,"",null,null,0,"http://khm.googleapis.com/mz?v=113\u0026",null,"https://earthbuilder.google.com","https://earthbuilder.googleapis.com"], loadScriptTime);
+  };
+  var loadScriptTime = (new Date).getTime();
+  getScript("http://maps.gstatic.com/intl/en_us/mapfiles/api-3/7/17/main.js");
+})();

File qtwidgets/olmapwidget/static/index.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+  <head>
+    <title></title>
+    <link rel="stylesheet" href="http://localhost.app/static/openlayers/theme/default/style.css" type="text/css">
+    <script src="http://localhost.app/static/openlayers/OpenLayers.js"></script>
+    <script src="http://localhost.app/static/jquery.js"></script>
+    <!--    
+    -->
+    <script src="http://maps.google.com/maps/api/js?v=3.7&sensor=false"></script>
+    <!-- 
+    -->
+
+    
+    <style type="text/css">
+        html, body, div {
+         margin: 0;
+         padding: 0;
+        }
+        #map {
+          height: 480px;
+          width: 640px;
+        }
+    </style>
+    
+    <script>
+  
+// HotPath http://trac.osgeo.org/openlayers/wiki/Release/2.11/GoogleMaps37
+if(1) OpenLayers.Layer.Google.v3.repositionMapElements = function() {
+    // This is the first time any Google layer in this mapObject has been
+    // made visible.  The mapObject needs to know the container size.
+    google.maps.event.trigger(this.mapObject, "resize");
+    
+    var div = this.mapObject.getDiv().firstChild;
+    if (!div || div.childNodes.length < 3) {
+        this.repositionTimer = window.setTimeout(
+            OpenLayers.Function.bind(this.repositionMapElements, this),
+            250
+        );
+        return false;
+    }
+
+    var cache = OpenLayers.Layer.Google.cache[this.map.id];
+    var container = this.map.viewPortDiv;
+    
+    // move the ToS and branding stuff up to the container div
+    // depends on value of zIndex, which is not robust
+    for (var i=div.children.length-1; i>=0; --i) {
+        if (div.children[i].style.zIndex == 1000001) {
+            var termsOfUse = div.children[i];
+            container.appendChild(termsOfUse);
+            termsOfUse.style.zIndex = "1100";
+            termsOfUse.style.bottom = "";
+            termsOfUse.className = "olLayerGoogleCopyright olLayerGoogleV3";
+            termsOfUse.style.display = "";
+            cache.termsOfUse = termsOfUse;
+        }
+        if (div.children[i].style.zIndex == 1000000) {
+            var poweredBy = div.children[i];
+            container.appendChild(poweredBy);
+            poweredBy.style.zIndex = "1100";
+            poweredBy.style.bottom = "";
+            poweredBy.className = "olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint";
+            poweredBy.style.display = "";
+            cache.poweredBy = poweredBy;
+        }
+        if (div.children[i].style.zIndex == 10000002) {
+            container.appendChild(div.children[i]);
+        }
+    }
+
+    this.setGMapVisibility(this.visibility);
+};
+    
+     $(document).ready(function() {   
+     
+        var lon = 8.2;
+        var lat = 53.166;
+        var zoom = 4;
+        var map, layer, markers, switcher, controls, options;
+     
+        switcher = new OpenLayers.Control.LayerSwitcher({'ascending':false});
+        controls = [
+          new OpenLayers.Control.NavToolbar(),
+          new OpenLayers.Control.Navigation(),
+          //new OpenLayers.Control.PanZoomBar(),
+          new OpenLayers.Control.PanZoom(),
+          
+          switcher,
+          new OpenLayers.Control.MousePosition(),
+          //new OpenLayers.Control.OverviewMap(),
+          //new OpenLayers.Control.ScaleBar(),               
+          new OpenLayers.Control.KeyboardDefaults()
+          ];
+        
+        options = {
+          controls: controls,
+          displayProjection: new OpenLayers.Projection("EPSG:4326"),  
+          projection: new OpenLayers.Projection("EPSG:900913"),
+          units: "m",
+          maxResolution: 156543.0339,
+          maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
+        };
+        
+
+        map = new OpenLayers.Map('map', options);
+        window.map = map;
+        
+        map.addLayer(new OpenLayers.Layer.OSM());                                             
+
+        var point = new OpenLayers.LonLat(lon, lat);
+        var center = point.clone().transform(
+          new OpenLayers.Projection("EPSG:4326"),   
+          map.getProjectionObject()        
+        );
+        map.setCenter(center, zoom);
+
+        var markers = new OpenLayers.Layer.Markers( "Markers", {displayInLayerSwitcher: false} );
+        window.markers = markers;
+        //var marker = new OpenLayers.Marker(point) ;        
+        //markers.addMarker(marker);
+        map.addLayer(markers);
+
+
+        map.events.register("click", map , function(e){
+             //var opx = map.getLayerPxFromViewPortPx(e.xy) ;
+             //marker.map = map ;
+             //marker.moveTo(opx);   
+             var lonlat = map.getLonLatFromViewPortPx(e.xy);
+             var pos = lonlat.clone();
+             var newpos = pos.transform(                              
+               map.getProjectionObject(),
+               new OpenLayers.Projection("EPSG:4326")
+                //new OpenLayers.Projection("EPSG:90913")
+             );
+             window.python.on_mouse_clicked(e.x ,e.y, newpos.lat, newpos.lon);
+     
+        });
+ 
+
+        $(window).resize(function() {
+          $("#map").width($(window).innerWidth()-4);
+          $("#map").height($(window).innerHeight()-4);
+        });
+        
+        $(window).trigger("resize");
+        
+        window.python.on_ready();
+       
+     });
+    </script>
+  </head>
+
+  <body>
+    <div id="map"></div>
+  </body>
+</html>