Remove MapView.py since it is deprecated in favor of Geoview
svn: r12612
This commit is contained in:
		@@ -1,4 +1,3 @@
 | 
			
		||||
src/DataViews/MapView.py
 | 
			
		||||
src/Filters/Rules/_HasGalleryBase.py
 | 
			
		||||
src/Filters/Rules/_HasLDSBase.py
 | 
			
		||||
src/Filters/Rules/_HasNoteBase.py
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,6 @@ pkgdata_PYTHON = \
 | 
			
		||||
	RepositoryView.py\
 | 
			
		||||
        SourceView.py
 | 
			
		||||
 | 
			
		||||
#	_MapView.py
 | 
			
		||||
 | 
			
		||||
pkgpyexecdir = @pkgpyexecdir@/DataViews
 | 
			
		||||
pkgpythondir = @pkgpythondir@/DataViews
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,844 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Gramps - a GTK+/GNOME based genealogy program
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2001-2006  Donald N. Allingham
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# $Id:MapView.py 9912 2008-01-22 09:17:46Z acraphae $
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Python modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
import gc
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
import math
 | 
			
		||||
import urllib
 | 
			
		||||
import urllib2
 | 
			
		||||
from xml.dom.minidom import parseString as xmlStringParser
 | 
			
		||||
 | 
			
		||||
log = logging.getLogger(".")
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# GTK/Gnome modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import gobject
 | 
			
		||||
import gtk
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Gramps Modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import PageView
 | 
			
		||||
import Config
 | 
			
		||||
import const
 | 
			
		||||
 | 
			
		||||
use_online_map = Config.get(Config.ONLINE_MAPS)
 | 
			
		||||
 | 
			
		||||
# Some initial places for debugging
 | 
			
		||||
glob_loc_data = [ # (Name, longitude, latitude)
 | 
			
		||||
        ("_Center", 0,0),
 | 
			
		||||
        ("_North",0,90),
 | 
			
		||||
        ("_South",0,-90),
 | 
			
		||||
        ("_West",-180,0),
 | 
			
		||||
        ("_East",180,0),
 | 
			
		||||
        ("Chicago",-87.75,41.83),
 | 
			
		||||
        ("Berlin",13.42,52.53),
 | 
			
		||||
        ("Honolulu",-157.83,21.32),
 | 
			
		||||
        ("Madrid",-3.72,40.42),
 | 
			
		||||
        ("Moscow",37.70,55.75),
 | 
			
		||||
        ("Vienna",16.37,48.22),
 | 
			
		||||
        ("Sydney",151.17,-33.92),
 | 
			
		||||
        ("Rio de Janeiro",-43.28,-22.88),
 | 
			
		||||
        ("Tokyo",139.75,35.67),
 | 
			
		||||
        ("Cape Town",18.47,-33.93),
 | 
			
		||||
        ("Anchorage",-150.00,61.17),
 | 
			
		||||
        ("Mannheim-Wallstadt",8.55,49.48),
 | 
			
		||||
        ("Mannheim-Neckarau",8.48,49.45),
 | 
			
		||||
        ("Gorxheimertal",8.73,49.53)]
 | 
			
		||||
 | 
			
		||||
enable_debug = False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Draws a map image and tries to allocate space in the correct aspect ratio
 | 
			
		||||
class GuideMap(gtk.DrawingArea):
 | 
			
		||||
    def __init__(self, map_pixbuf):
 | 
			
		||||
        gtk.DrawingArea.__init__(self)
 | 
			
		||||
        self.map_pixbuf = map_pixbuf
 | 
			
		||||
        self.connect("expose-event", self.expose_cb)
 | 
			
		||||
        self.connect("size-allocate", self.size_allocate_cb)
 | 
			
		||||
        self.gc = None
 | 
			
		||||
        self.current_area = None
 | 
			
		||||
        self.current_spot = None
 | 
			
		||||
        self.old_size = (-1,-1)
 | 
			
		||||
    
 | 
			
		||||
    # Set hightlight region
 | 
			
		||||
    def hightlight_area( self, area):
 | 
			
		||||
        self.current_area = area
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
 | 
			
		||||
    # Set hightlight region
 | 
			
		||||
    def hightlight_spot( self, spot):
 | 
			
		||||
        self.current_spot = spot
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
 | 
			
		||||
    # Redraw the image
 | 
			
		||||
    def expose_cb(self,widget,event):
 | 
			
		||||
        if not self.gc:
 | 
			
		||||
            self.gc = self.window.new_gc()
 | 
			
		||||
            self.gc.set_foreground( self.get_colormap().alloc_color("red"))
 | 
			
		||||
            self.gc.set_background( self.get_colormap().alloc_color("blue"))
 | 
			
		||||
        if self.backbuf and self.gc:
 | 
			
		||||
            self.window.draw_pixbuf( self.gc, self.backbuf, 0,0, 0,0, -1,-1)
 | 
			
		||||
            if self.current_area:
 | 
			
		||||
                r = self.map_to_screen(self.current_area[0],
 | 
			
		||||
                                       self.current_area[1],
 | 
			
		||||
                                       self.current_area[2],
 | 
			
		||||
                                       self.current_area[3])
 | 
			
		||||
                self.window.draw_rectangle( self.gc, False,
 | 
			
		||||
                                            r[0],r[1],r[2],r[3])
 | 
			
		||||
            if self.current_spot:
 | 
			
		||||
                r = self.map_to_screen(self.current_spot[0],
 | 
			
		||||
                                       self.current_spot[1])
 | 
			
		||||
                self.window.draw_line( self.gc,0,r[1],
 | 
			
		||||
                                       self.backbuf.get_width(),r[1])
 | 
			
		||||
                self.window.draw_line( self.gc,r[0],0,
 | 
			
		||||
                                       r[0],self.backbuf.get_height())
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
    # Scale backbuffer
 | 
			
		||||
    def size_allocate_cb(self,widget,allocation):
 | 
			
		||||
        # Always request a height, that is half of the width
 | 
			
		||||
        w = max( 128,allocation.width)
 | 
			
		||||
        self.set_size_request(-1,w/2)
 | 
			
		||||
        
 | 
			
		||||
        # only create new backbuffer if size is different
 | 
			
		||||
        new_size = (allocation.width,allocation.height)
 | 
			
		||||
        if new_size is not self.old_size:
 | 
			
		||||
            self.old_size = new_size
 | 
			
		||||
            self.backbuf = self.map_pixbuf.scale_simple(
 | 
			
		||||
                self.old_size[0],
 | 
			
		||||
                self.old_size[1],
 | 
			
		||||
                gtk.gdk.INTERP_BILINEAR)
 | 
			
		||||
            gc.collect()
 | 
			
		||||
 | 
			
		||||
    def map_to_screen( self, x,y,w=None, h=None):
 | 
			
		||||
        px = int((float(x) + 180.0) / 360.0 * self.backbuf.get_width())
 | 
			
		||||
        py = int((90-float(y)) / 180.0 * self.backbuf.get_height())
 | 
			
		||||
        if w and h:
 | 
			
		||||
            pw = int(float(w) / 360.0 * self.backbuf.get_width())
 | 
			
		||||
            ph = int(float(h) / 180.0 * self.backbuf.get_height())
 | 
			
		||||
            return (px,py,pw,ph)
 | 
			
		||||
        return (px,py)
 | 
			
		||||
 | 
			
		||||
# Map tile files used by the ZoomMap
 | 
			
		||||
class MapTile(object):
 | 
			
		||||
    def __init__( self, filename, x, y, w, h, pw, ph):
 | 
			
		||||
        self.filename = filename
 | 
			
		||||
        self.full_path = os.path.join(const.IMAGE_DIR,filename)
 | 
			
		||||
        self.map_x = float(x)
 | 
			
		||||
        self.map_y = float(y)
 | 
			
		||||
        self.map_width = float(w)
 | 
			
		||||
        self.map_height = float(h)
 | 
			
		||||
        self.map_pixel_width = float(pw)
 | 
			
		||||
        self.map_pixel_height = float(ph)
 | 
			
		||||
        self.source_pixbuf = None
 | 
			
		||||
        self.source_scale = self.map_pixel_width / self.map_width
 | 
			
		||||
        self.scale = None
 | 
			
		||||
        self.scaled_pixbuf = None
 | 
			
		||||
        self.scaled_map_x = None
 | 
			
		||||
        self.scaled_map_y = None
 | 
			
		||||
 | 
			
		||||
    def set_viewport( self, target_scale, x_in, y_in, w_in, h_in):
 | 
			
		||||
        # intersect viewport with map area
 | 
			
		||||
        x = max(self.map_x, max(-180.0,x_in))
 | 
			
		||||
        y = min(self.map_y, min(  90.0,y_in))
 | 
			
		||||
        xmax = min( min(180.0,x_in+w_in), self.map_x+self.map_width)
 | 
			
		||||
        ymin = max( max(-90.0,y_in-h_in), self.map_y-self.map_width)
 | 
			
		||||
        w = xmax-x
 | 
			
		||||
        h = y-ymin
 | 
			
		||||
        
 | 
			
		||||
        if w > 0.0 and h > 0.0:
 | 
			
		||||
            # crop source tile to not scale the whole IMAGE_DIR
 | 
			
		||||
            xoffset = max(0,math.floor((x - self.map_x) * self.source_scale))
 | 
			
		||||
            xmax = max(0,math.ceil((x+w - self.map_x) * self.source_scale))
 | 
			
		||||
            yoffset = min(self.map_pixel_width,math.floor(-(y - self.map_y) * self.source_scale))
 | 
			
		||||
            ymax = min(self.map_pixel_height,math.ceil(-(y-h - self.map_y) * self.source_scale))
 | 
			
		||||
 | 
			
		||||
            rescale = target_scale / self.source_scale
 | 
			
		||||
            if int((xmax-xoffset)*rescale) > 0 and int((ymax-yoffset)*rescale) > 0:
 | 
			
		||||
                self.scaled_map_x = self.map_x + xoffset / self.source_scale
 | 
			
		||||
                self.scaled_map_y = self.map_y - yoffset / self.source_scale
 | 
			
		||||
                self.scaled_map_pixel_w = int((xmax-xoffset)*rescale)
 | 
			
		||||
                self.scaled_map_pixel_h = int((ymax-yoffset)*rescale)
 | 
			
		||||
                
 | 
			
		||||
                if enable_debug:
 | 
			
		||||
                    print 
 | 
			
		||||
                    print "Source-Map origin: %f x %f, %f, %f" % (self.map_x,self.map_y,self.map_width,self.map_height)
 | 
			
		||||
                    print "Source-Map pixels: %f x %f" % (self.map_pixel_width,self.map_pixel_height)
 | 
			
		||||
                    print "Source-Map scale: %f" % self.source_scale
 | 
			
		||||
                    print "Target origin: %f x %f, %f, %f" % (x,y,w, h)
 | 
			
		||||
                    print "Target scale: %f" % target_scale
 | 
			
		||||
                    print "Target crop: %f x %f, %f x %f" % (xoffset,yoffset,xmax,ymax)
 | 
			
		||||
                    print "Origin of crop: %f x %f" % (self.scaled_map_x,self.scaled_map_y)
 | 
			
		||||
                    print "scaled tile size: %f x %f pix" % (self.scaled_map_pixel_w,self.scaled_map_pixel_h)
 | 
			
		||||
 | 
			
		||||
                try:
 | 
			
		||||
                    if not self.source_pixbuf:
 | 
			
		||||
                        self.source_pixbuf = gtk.gdk.pixbuf_new_from_file( self.full_path)
 | 
			
		||||
        
 | 
			
		||||
                    clip_pixbuf = self.source_pixbuf.subpixbuf(int(xoffset),int(yoffset),int(xmax-xoffset),int(ymax-yoffset))
 | 
			
		||||
                        
 | 
			
		||||
                    self.scale = target_scale
 | 
			
		||||
                    self.scaled_pixbuf = clip_pixbuf.scale_simple( int((xmax-xoffset)*rescale), int((ymax-yoffset)*rescale), gtk.gdk.INTERP_BILINEAR)
 | 
			
		||||
                    clip_pixbuf = None
 | 
			
		||||
                except:
 | 
			
		||||
                    pass
 | 
			
		||||
 | 
			
		||||
            else:
 | 
			
		||||
                self.scale = None
 | 
			
		||||
                self.scaled_pixbuf = None
 | 
			
		||||
        else:
 | 
			
		||||
            self.scale = None
 | 
			
		||||
            self.scaled_pixbuf = None
 | 
			
		||||
 | 
			
		||||
    def free(self):
 | 
			
		||||
        self.scale = None
 | 
			
		||||
        self.scaled_pixbuf = None
 | 
			
		||||
 | 
			
		||||
class WMSMapTile(object):
 | 
			
		||||
    def __init__(self,capabilities,change_cb=None):
 | 
			
		||||
        self.change_cb = change_cb
 | 
			
		||||
        self.scaled_pixbuf = None
 | 
			
		||||
        self.handler_running = False
 | 
			
		||||
        self.target_scale = 0.0
 | 
			
		||||
        self.scaled_map_x = 0.0
 | 
			
		||||
        self.scaled_map_y = 0.0
 | 
			
		||||
        self.scaled_map_pixel_w = 0.0
 | 
			
		||||
        self.scaled_map_pixel_h = 0.0
 | 
			
		||||
        self.capabilities_url = capabilities
 | 
			
		||||
        u_reader = urllib2.urlopen(self.capabilities_url)
 | 
			
		||||
        # TODO: Put into an idle handler or thread
 | 
			
		||||
        response_body = u_reader.read()
 | 
			
		||||
        u_reader.close()
 | 
			
		||||
        xml_doc = xmlStringParser( response_body)
 | 
			
		||||
        # validate name of root element
 | 
			
		||||
        e = xml_doc.documentElement
 | 
			
		||||
        if e.nodeName != "WMT_MS_Capabilities":
 | 
			
		||||
            print "unsupported Document type '%s'" % e.nodeName
 | 
			
		||||
            return None
 | 
			
		||||
        self.map_request_params = {}
 | 
			
		||||
        self.map_request_params["VERSION"] = e.getAttribute("version")
 | 
			
		||||
        self.map_request_params["REQUEST"] = "GetMap"
 | 
			
		||||
        self.map_request_params["SERVICE"] = "WMS"
 | 
			
		||||
        self.map_request_params["REQUEST"] = "GetMap"
 | 
			
		||||
        self.map_request_params["REQUEST"] = "GetMap"
 | 
			
		||||
        self.map_request_params["FORMAT"] = "image/png"
 | 
			
		||||
        self.map_request_params["SRS"] = "epsg:4326"
 | 
			
		||||
        self.map_request_params["LAYERS"] = ""
 | 
			
		||||
        # Child-nodes of root element
 | 
			
		||||
        for n in e.childNodes:
 | 
			
		||||
            if n.nodeName == "Service":
 | 
			
		||||
                # Parse Service header
 | 
			
		||||
                map_title = n.getElementsByTagName("Title")[0].firstChild.data
 | 
			
		||||
                print " MAP Title: %s" % map_title
 | 
			
		||||
                try:
 | 
			
		||||
                    map_fees = e.getElementsByTagName("Fees")[0].firstChild.data
 | 
			
		||||
                except IndexError:
 | 
			
		||||
                    map_fees = "-"
 | 
			
		||||
                print " MAP Fees: %s" % map_fees
 | 
			
		||||
                try:
 | 
			
		||||
                    map_access_constraints = e.getElementsByTagName("AccessConstraints")[0].firstChild.data
 | 
			
		||||
                except IndexError:
 | 
			
		||||
                    map_access_constraints = "-"
 | 
			
		||||
                print " MAP AccessConstraints: %s" % map_access_constraints
 | 
			
		||||
    
 | 
			
		||||
            elif n.nodeName == "Capability":
 | 
			
		||||
                # Parse Capabilities
 | 
			
		||||
                for n2 in n.childNodes:
 | 
			
		||||
                    if n2.nodeName == "Request":
 | 
			
		||||
                        t1 = n2.getElementsByTagName("GetMap")[0]
 | 
			
		||||
                        t2 = t1.getElementsByTagName("DCPType")[0]
 | 
			
		||||
                        t3 = t2.getElementsByTagName("HTTP")[0]
 | 
			
		||||
                        t4 = t3.getElementsByTagName("Get")[0]
 | 
			
		||||
                        t5 = t4.getElementsByTagName("OnlineResource")[0]
 | 
			
		||||
                        self.map_get_url = t5.getAttribute("xlink:href")
 | 
			
		||||
                        if enable_debug:
 | 
			
		||||
                            print(" Map Tile base url: %s" % self.map_get_url)
 | 
			
		||||
                    elif n2.nodeName == "Layer":
 | 
			
		||||
                        # parse Layers
 | 
			
		||||
                        if not self._srs_is_supported(n2.getElementsByTagName("SRS")[0].firstChild.data):
 | 
			
		||||
                            print "Layer coordinates not supported :-("
 | 
			
		||||
                            return None
 | 
			
		||||
                        layer_title = n2.getElementsByTagName("Title")[0].firstChild.data
 | 
			
		||||
                        if enable_debug:
 | 
			
		||||
                            print " Layer: %s" % layer_title
 | 
			
		||||
                        for n3 in n2.childNodes:
 | 
			
		||||
                            if n3.nodeName == "Layer":
 | 
			
		||||
                                # parse Layers
 | 
			
		||||
                                layer_title = n3.getElementsByTagName("Name")[0].firstChild.data
 | 
			
		||||
                                if enable_debug:
 | 
			
		||||
                                    print "   - Layer: %s" % layer_title
 | 
			
		||||
                                if self.map_request_params["LAYERS"]:
 | 
			
		||||
                                    self.map_request_params["LAYERS"] += ","
 | 
			
		||||
                                self.map_request_params["LAYERS"] += layer_title
 | 
			
		||||
    def _srs_is_supported( self, srs_string):
 | 
			
		||||
        list = srs_string.lower().split()
 | 
			
		||||
        if "epsg:4326" in list:
 | 
			
		||||
            return True
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def idle_handler( self):
 | 
			
		||||
        """ fetches parts of the download and feeds them into a PixbufLoader """
 | 
			
		||||
        if enable_debug:
 | 
			
		||||
            print "idle_handler"
 | 
			
		||||
        if not self.handler_running or not self.url_handler:
 | 
			
		||||
            return False
 | 
			
		||||
        buf = self.url_handler.read(5000)
 | 
			
		||||
        if enable_debug:
 | 
			
		||||
            print len(buf)
 | 
			
		||||
        if len(buf) > 0:
 | 
			
		||||
            self.pixbufloader.write(buf)
 | 
			
		||||
            self.scaled_pixbuf = self.pixbufloader.get_pixbuf()
 | 
			
		||||
        else:
 | 
			
		||||
            if enable_debug:
 | 
			
		||||
                print "no more content."
 | 
			
		||||
            self.handler_running = False
 | 
			
		||||
            self.url_handler.close()
 | 
			
		||||
            try:
 | 
			
		||||
                self.pixbufloader.close()
 | 
			
		||||
            except gobject.GError:
 | 
			
		||||
                pass    # dont crash if nothing or not an image has been downloaded
 | 
			
		||||
            return False
 | 
			
		||||
        self.change_cb()
 | 
			
		||||
        return True
 | 
			
		||||
        
 | 
			
		||||
    def set_viewport( self, target_scale, x_in, y_in, w_in, h_in):
 | 
			
		||||
        new_scaled_map_pixel_w = int(w_in*target_scale)
 | 
			
		||||
        new_scaled_map_pixel_h = int(h_in*target_scale)
 | 
			
		||||
        if self.target_scale != target_scale\
 | 
			
		||||
                or self.scaled_map_x > x_in\
 | 
			
		||||
                or self.scaled_map_y < y_in\
 | 
			
		||||
                or self.scaled_map_pixel_w < new_scaled_map_pixel_w\
 | 
			
		||||
                or self.scaled_map_pixel_h < new_scaled_map_pixel_h:
 | 
			
		||||
            # only download new map is new viewport is larger
 | 
			
		||||
            # TODO: Fix above to be correct and add a cache of already downloaded tiles
 | 
			
		||||
            self.target_scale = target_scale
 | 
			
		||||
            self.scaled_map_x = x_in
 | 
			
		||||
            self.scaled_map_y = y_in
 | 
			
		||||
            self.scaled_map_pixel_w = int(w_in*target_scale)
 | 
			
		||||
            self.scaled_map_pixel_h = int(h_in*target_scale)
 | 
			
		||||
            self.map_request_params["BBOX"] = "%f,%f,%f,%f" % (x_in,y_in-h_in,x_in+w_in,y_in) # Neds to be set for request
 | 
			
		||||
            self.map_request_params["WIDTH"] = int(w_in*target_scale)
 | 
			
		||||
            self.map_request_params["HEIGHT"] = int(h_in*target_scale)
 | 
			
		||||
            params = urllib.urlencode(self.map_request_params)
 | 
			
		||||
            if self.handler_running:
 | 
			
		||||
                if enable_debug:
 | 
			
		||||
                    print "stopping current download"
 | 
			
		||||
                self.url_handler.close()
 | 
			
		||||
                try:
 | 
			
		||||
                    self.pixbufloader.close()
 | 
			
		||||
                except gobject.GError:
 | 
			
		||||
                    pass    # dont crash if nothing or not an image has been downloaded
 | 
			
		||||
            self.scaled_pixbuf = None
 | 
			
		||||
            self.url_handler = urllib.urlopen(self.map_get_url+params)
 | 
			
		||||
            self.handler_running = gobject.idle_add(self.idle_handler)
 | 
			
		||||
            self.pixbufloader = gtk.gdk.PixbufLoader()
 | 
			
		||||
        else:
 | 
			
		||||
            if enable_debug:
 | 
			
		||||
                print "new viewport fits inside old one. No download required."
 | 
			
		||||
 | 
			
		||||
    def free(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
# Zoomable map image
 | 
			
		||||
class ZoomMap( gtk.DrawingArea):
 | 
			
		||||
    def __init__( self, place_marker_pixbuf, hightlight_marker_pixbuf):
 | 
			
		||||
        gtk.DrawingArea.__init__(self)
 | 
			
		||||
        self.place_marker_pixbuf = place_marker_pixbuf
 | 
			
		||||
        self.hightlight_marker_pixbuf = hightlight_marker_pixbuf
 | 
			
		||||
        self.add_events(gtk.gdk.POINTER_MOTION_MASK)  # position overlay
 | 
			
		||||
        self.connect("expose-event", self.expose_cb)
 | 
			
		||||
        self.connect("size-allocate", self.size_allocate_cb)
 | 
			
		||||
        if enable_debug:
 | 
			
		||||
            self.connect("motion-notify-event", self.motion_notify_event_cb)
 | 
			
		||||
        self.gc = None
 | 
			
		||||
        self.current_pixel_size = (-1,-1)
 | 
			
		||||
        self.zoom_pos = (0,0)
 | 
			
		||||
        self.magnifer = 0.0 # in pixel per degree
 | 
			
		||||
        self.guide = None
 | 
			
		||||
        self.textlayout = self.create_pango_layout("")
 | 
			
		||||
        self.map_sources = {}
 | 
			
		||||
        self.initial_exposed = False
 | 
			
		||||
        if use_online_map:
 | 
			
		||||
            self.map_sources[0.0] = []
 | 
			
		||||
            self.map_sources[0.0].append(WMSMapTile("http://www2.demis.nl/wms/wms.asp?wms=WorldMap&VERSION=1.1.1&REQUEST=GetCapabilities",self.queue_draw))
 | 
			
		||||
 | 
			
		||||
    def add_map_source( self,filename, x, y, w, h,pw,ph):
 | 
			
		||||
        tile = MapTile( filename, x, y, w, h, pw, ph)
 | 
			
		||||
        if not tile.source_scale in self.map_sources:
 | 
			
		||||
            self.map_sources[tile.source_scale] = []
 | 
			
		||||
        self.map_sources[tile.source_scale].append( tile)
 | 
			
		||||
        
 | 
			
		||||
    # Set the guide map that should follow the zoom area
 | 
			
		||||
    def set_guide( self, guide):
 | 
			
		||||
        self.guide = guide
 | 
			
		||||
 | 
			
		||||
    def set_location_model( self, model, idx_name, idx_long, idx_lat):
 | 
			
		||||
        self.location_model = model
 | 
			
		||||
        self.idx_name = idx_name
 | 
			
		||||
        self.idx_long = idx_long
 | 
			
		||||
        self.idx_lat = idx_lat
 | 
			
		||||
        
 | 
			
		||||
    def motion_notify_event_cb(self,widget,event):
 | 
			
		||||
        self.textlayout.set_text( "Position: %03.0f,%03.0f pixel" % (event.x,event.y))
 | 
			
		||||
        (w, h) = self.textlayout.get_pixel_size()
 | 
			
		||||
        self.gc.set_foreground( self.get_colormap().alloc_color("white"))
 | 
			
		||||
        self.window.draw_rectangle( self.gc, True, 10,50,w, h)
 | 
			
		||||
        self.gc.set_foreground( self.get_colormap().alloc_color("red"))
 | 
			
		||||
        self.window.draw_layout( self.gc, 10, 50, self.textlayout)
 | 
			
		||||
        (lon,lat) = self.screen_to_map(event.x,event.y)
 | 
			
		||||
        self.textlayout.set_text( "Position: %03.0f,%03.0f degree" % (lon,lat))
 | 
			
		||||
        (w, h) = self.textlayout.get_pixel_size()
 | 
			
		||||
        self.gc.set_foreground( self.get_colormap().alloc_color("white"))
 | 
			
		||||
        self.window.draw_rectangle( self.gc, True, 10,70,w, h)
 | 
			
		||||
        self.gc.set_foreground( self.get_colormap().alloc_color("red"))
 | 
			
		||||
        self.window.draw_layout( self.gc, 10, 70, self.textlayout)
 | 
			
		||||
        
 | 
			
		||||
    # Redraw the image
 | 
			
		||||
    def expose_cb(self,widget,event):
 | 
			
		||||
        if not self.gc:
 | 
			
		||||
            self.gc = self.window.new_gc()
 | 
			
		||||
            self.gc.set_foreground( self.get_colormap().alloc_color("red"))
 | 
			
		||||
            self.gc.set_background( self.get_colormap().alloc_color("blue"))
 | 
			
		||||
        if not self.backbuf:
 | 
			
		||||
            self.size_allocate_cb( self,self.get_allocation())
 | 
			
		||||
        if self.backbuf and self.gc:
 | 
			
		||||
            #draw all maps
 | 
			
		||||
            scales = self.map_sources.keys()
 | 
			
		||||
            scales.sort()
 | 
			
		||||
            for scale in scales:
 | 
			
		||||
                for map in self.map_sources[scale]:
 | 
			
		||||
                    if map.scaled_pixbuf:
 | 
			
		||||
                        (px,py) = self.map_to_screen( map.scaled_map_x, map.scaled_map_y)
 | 
			
		||||
                        self.window.draw_pixbuf( self.gc, map.scaled_pixbuf, 0,0, px,py)
 | 
			
		||||
                        if enable_debug:
 | 
			
		||||
                            self.window.draw_rectangle( self.gc, False, px,py,map.scaled_map_pixel_w,map.scaled_map_pixel_h)
 | 
			
		||||
                            self.window.draw_line( self.gc, px,py,px+map.scaled_map_pixel_w,py+map.scaled_map_pixel_h)
 | 
			
		||||
                            self.window.draw_line( self.gc, px,py+map.scaled_map_pixel_h,px+map.scaled_map_pixel_w,py)
 | 
			
		||||
            gc.collect()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            # draw all available locations
 | 
			
		||||
            if self.location_model:
 | 
			
		||||
                iter = self.location_model.get_iter_first()
 | 
			
		||||
                while iter:
 | 
			
		||||
                    (n,x,y) = self.location_model.get( iter, self.idx_name, self.idx_long, self.idx_lat)
 | 
			
		||||
                    (px,py) = self.map_to_screen( x, y)
 | 
			
		||||
                    #if px > 0 and py > 0 and px < self.backbuf.get_width() and py < self.backbuf.get_height():
 | 
			
		||||
                        # draw only visible markers
 | 
			
		||||
                        #self.window.draw_pixbuf(
 | 
			
		||||
                        #    self.gc,
 | 
			
		||||
                        #    self.place_marker_pixbuf,
 | 
			
		||||
                        #    0,0,
 | 
			
		||||
                        #    px-self.place_marker_pixbuf.get_width()/2,
 | 
			
		||||
                        #    py-self.place_marker_pixbuf.get_height()/2,
 | 
			
		||||
                        #   -1,-1)
 | 
			
		||||
                    self.textlayout.set_text(n)
 | 
			
		||||
                    self.window.draw_layout(
 | 
			
		||||
                           self.gc,
 | 
			
		||||
                           px,py,
 | 
			
		||||
                           self.textlayout)
 | 
			
		||||
                    iter = self.location_model.iter_next( iter)
 | 
			
		||||
            
 | 
			
		||||
            # hightlight current location
 | 
			
		||||
            (px,py) = self.map_to_screen( self.zoom_pos[0], self.zoom_pos[1])
 | 
			
		||||
            self.window.draw_pixbuf(
 | 
			
		||||
                self.gc,
 | 
			
		||||
                self.hightlight_marker_pixbuf,
 | 
			
		||||
                0,0,
 | 
			
		||||
                px-self.hightlight_marker_pixbuf.get_width()/2,
 | 
			
		||||
                py-self.hightlight_marker_pixbuf.get_height()/2,
 | 
			
		||||
                -1,-1)
 | 
			
		||||
            #self.window.draw_rectangle( self.gc, False, px-3,py-3, 6,6)
 | 
			
		||||
            
 | 
			
		||||
            #(px1,py1) = self.map_to_screen(-180, 90)
 | 
			
		||||
            #(px2,py2) = self.map_to_screen( 180,-90)
 | 
			
		||||
            #self.window.draw_rectangle( self.gc, False, px1,py1,px2-px1,py2-py1)
 | 
			
		||||
            #self.window.draw_line( self.gc, px1,py1,px2,py2)
 | 
			
		||||
            #self.window.draw_line( self.gc, px1,py2,px2,py1)
 | 
			
		||||
            if enable_debug:
 | 
			
		||||
                # Output debugging info
 | 
			
		||||
                self.textlayout.set_text( "Magnifer: %f pixel per degree" % self.magnifer)
 | 
			
		||||
                self.window.draw_layout( self.gc, 10, 10, self.textlayout)
 | 
			
		||||
                self.textlayout.set_text( "Current map: %f pixel per degree" % self.selected_map_scale)
 | 
			
		||||
                self.window.draw_layout( self.gc, 10, 30, self.textlayout)
 | 
			
		||||
 | 
			
		||||
    def map_to_screen( self, lon, lat):
 | 
			
		||||
        px = int(self.current_pixel_size[0] / 2.0 + (lon - self.zoom_pos[0]) * self.magnifer)
 | 
			
		||||
        py = int(self.current_pixel_size[1] / 2.0 - (lat - self.zoom_pos[1]) * self.magnifer)
 | 
			
		||||
        return( px, py)
 | 
			
		||||
 | 
			
		||||
    def screen_to_map( self, px, py):
 | 
			
		||||
        px = float(px)
 | 
			
		||||
        py = float(py)
 | 
			
		||||
        lon = (px - self.current_pixel_size[0]/2) / self.magnifer + self.zoom_pos[0];
 | 
			
		||||
        lat = -(py - self.current_pixel_size[1]/2) / self.magnifer + self.zoom_pos[1];
 | 
			
		||||
        return( lon, lat)
 | 
			
		||||
 | 
			
		||||
    # Scale backbuffer
 | 
			
		||||
    def size_allocate_cb(self,widget,allocation):
 | 
			
		||||
        # only create new backbuffer if size is different
 | 
			
		||||
        new_size = (allocation.width,allocation.height)
 | 
			
		||||
        if new_size is not self.current_pixel_size or not self.backbuf:
 | 
			
		||||
            self.backbuf = True
 | 
			
		||||
            self.current_pixel_size = new_size
 | 
			
		||||
            if self.magnifer == 0.0:
 | 
			
		||||
                # scale map to full width
 | 
			
		||||
                self.magnifer = self.current_pixel_size[0] / 360.0
 | 
			
		||||
            x0,y0 = self.screen_to_map( 0, 0)
 | 
			
		||||
            x1,y1 = self.screen_to_map( new_size[0], new_size[1])
 | 
			
		||||
            self.guide.hightlight_area( (x0,y0,x1-x0, y0-y1))
 | 
			
		||||
            
 | 
			
		||||
            def cmpfunc(s):
 | 
			
		||||
                return((self.magnifer-s)*(self.magnifer-s))
 | 
			
		||||
                
 | 
			
		||||
            # select best matching tile set
 | 
			
		||||
            self.selected_map_scale = None
 | 
			
		||||
            smallest_scale = None
 | 
			
		||||
            largest_scale = None
 | 
			
		||||
            for s in self.map_sources.keys():
 | 
			
		||||
                if not self.selected_map_scale or cmpfunc(s) < cmpfunc(self.selected_map_scale):
 | 
			
		||||
                    self.selected_map_scale = s
 | 
			
		||||
                if not smallest_scale or s < smallest_scale:
 | 
			
		||||
                    smallest_scale = s
 | 
			
		||||
                if not largest_scale or s > largest_scale:
 | 
			
		||||
                    largest_scale = s
 | 
			
		||||
            if enable_debug:
 | 
			
		||||
                print "scale of display: %f" % self.magnifer
 | 
			
		||||
                print "available map scales:"
 | 
			
		||||
                print self.map_sources.keys()
 | 
			
		||||
                print "largest scale: %f" % largest_scale
 | 
			
		||||
                print "smallest scale: %f" % smallest_scale
 | 
			
		||||
                print "selected scale: %f" % self.selected_map_scale
 | 
			
		||||
            
 | 
			
		||||
            for s in self.map_sources.keys():
 | 
			
		||||
                for map in self.map_sources[s]:
 | 
			
		||||
                    if s == self.selected_map_scale or s == smallest_scale:
 | 
			
		||||
                        map.set_viewport( self.magnifer, x0, y0, x1-x0, y0-y1)
 | 
			
		||||
                    else:
 | 
			
		||||
                        map.free()
 | 
			
		||||
 | 
			
		||||
    # Scroll to requested position
 | 
			
		||||
    def scroll_to( self, long, lat):
 | 
			
		||||
        self.zoom_pos = (float( min(180,(max(-180,long)))), float(min(90,(max(-90,lat)))))
 | 
			
		||||
        self.backbuf = None
 | 
			
		||||
        if self.guide:
 | 
			
		||||
            self.guide.hightlight_spot( self.zoom_pos)
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
 | 
			
		||||
    def zoom_out(self):
 | 
			
		||||
        self.magnifer = max( 1.0, self.magnifer * 2.0/3.0)
 | 
			
		||||
        self.backbuf = None
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
    
 | 
			
		||||
    def zoom_in(self):
 | 
			
		||||
        self.magnifer = min( 1000.0, self.magnifer * 1.5)
 | 
			
		||||
        self.backbuf = None
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
    
 | 
			
		||||
    def zoom_normal(self):
 | 
			
		||||
        self.magnifer = 1.0
 | 
			
		||||
        self.magnifer = self.selected_map_scale
 | 
			
		||||
        self.backbuf = None
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
 | 
			
		||||
    def zoom_fit(self):
 | 
			
		||||
        self.magnifer = self.current_pixel_size[0] / 360.0
 | 
			
		||||
        self.backbuf = None
 | 
			
		||||
        self.queue_draw()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Place list widget
 | 
			
		||||
class MapPlacesList(gtk.TreeView):
 | 
			
		||||
    def __init__(self, data):
 | 
			
		||||
        self.lstore = gtk.ListStore(
 | 
			
		||||
            gobject.TYPE_STRING,
 | 
			
		||||
            gobject.TYPE_FLOAT,
 | 
			
		||||
            gobject.TYPE_FLOAT)
 | 
			
		||||
        
 | 
			
		||||
        self.change_data( data)
 | 
			
		||||
 | 
			
		||||
        gtk.TreeView.__init__(self, self.lstore)
 | 
			
		||||
        self.set_rules_hint(True)
 | 
			
		||||
        self.set_search_column(0)
 | 
			
		||||
 | 
			
		||||
        column = gtk.TreeViewColumn('Place', gtk.CellRendererText(), text=0)
 | 
			
		||||
        column.set_sort_column_id(0)
 | 
			
		||||
        self.append_column(column)
 | 
			
		||||
 | 
			
		||||
        column = gtk.TreeViewColumn('Lat', gtk.CellRendererText(), text=1)
 | 
			
		||||
        column.set_sort_column_id(1)
 | 
			
		||||
        self.append_column(column)
 | 
			
		||||
 | 
			
		||||
        column = gtk.TreeViewColumn('Long', gtk.CellRendererText(),text=2)
 | 
			
		||||
        column.set_sort_column_id(2)
 | 
			
		||||
        self.append_column(column)
 | 
			
		||||
 | 
			
		||||
    def change_data( self, data):
 | 
			
		||||
        self.lstore.clear()
 | 
			
		||||
        for item in data:
 | 
			
		||||
            iter = self.lstore.append()
 | 
			
		||||
            self.lstore.set(iter,
 | 
			
		||||
                0, item[0],
 | 
			
		||||
                1, item[1],
 | 
			
		||||
                2, item[2])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Map View main class
 | 
			
		||||
class MapView(PageView.PageView):
 | 
			
		||||
    def __init__(self,dbstate,uistate):
 | 
			
		||||
        PageView.PageView.__init__(self, _('Maps'), dbstate, uistate)
 | 
			
		||||
        dbstate.connect('database-changed',self.change_db)
 | 
			
		||||
        self.current_marker = None
 | 
			
		||||
 | 
			
		||||
    def navigation_type(self):
 | 
			
		||||
        return PageView.NAVIGATION_NONE
 | 
			
		||||
 | 
			
		||||
    def define_actions(self):
 | 
			
		||||
        self._add_action('ZoomIn',gtk.STOCK_ZOOM_IN,
 | 
			
		||||
                         _("Zoom _In"),tip=_("Zoom in by a factor of 2"),
 | 
			
		||||
                         callback=self.zoom_in_cb)
 | 
			
		||||
        self._add_action('ZoomOut',gtk.STOCK_ZOOM_OUT,
 | 
			
		||||
                         _("Zoom _Out"),tip=_("Zoom out by a factor of 2"),
 | 
			
		||||
                         callback=self.zoom_out_cb)
 | 
			
		||||
        self._add_action('ZoomNormal',gtk.STOCK_ZOOM_100,
 | 
			
		||||
                         _("_Normal Size"), tip=_("Return to normal size"),
 | 
			
		||||
                         callback=self.zoom_100_cb)
 | 
			
		||||
        self._add_action('ZoomFit',gtk.STOCK_ZOOM_FIT,
 | 
			
		||||
                         _("Best _Fit"),
 | 
			
		||||
                         tip=_("Produce the best fit of the map in the window"),
 | 
			
		||||
                        callback=self.zoom_fit_cb)
 | 
			
		||||
 | 
			
		||||
    def get_stock(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return the name of the stock icon to use for the display.
 | 
			
		||||
        This assumes that this icon has already been registered with
 | 
			
		||||
        GNOME as a stock icon.
 | 
			
		||||
        """
 | 
			
		||||
        return 'gramps-map'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # For debugging: Reads in location from xearth
 | 
			
		||||
    def get_xearth_markers(self):
 | 
			
		||||
        data = []
 | 
			
		||||
        try:
 | 
			
		||||
            f = open("/etc/xearth/xearth.markers")
 | 
			
		||||
            l = f.readline()
 | 
			
		||||
            #linere = re.compile('[^0-9.-]*(-?[0-9]+\.[0-9]+)[^0-9.-]*(-?[0-9]+\.[0-9]+).*"([^"])".*', "I")
 | 
			
		||||
            while l:
 | 
			
		||||
                if not l[0] == "#":
 | 
			
		||||
                    l = l.strip().replace('"',"").replace("    "," ").replace("   "," ").replace("  "," ").replace(" # ",", ")
 | 
			
		||||
                    m = l.split( None, 2)
 | 
			
		||||
                    if len(m) == 3:
 | 
			
		||||
                        data.append( (m[2],float(m[1]),float(m[0])))
 | 
			
		||||
                l = f.readline()
 | 
			
		||||
        except IOError:
 | 
			
		||||
            pass
 | 
			
		||||
        return data
 | 
			
		||||
 | 
			
		||||
    # Reads in locations from current GRAMPS database
 | 
			
		||||
    def get_markers_from_database(self, db):
 | 
			
		||||
        data = []
 | 
			
		||||
        for place_handle in db.get_place_handles():
 | 
			
		||||
            place = db.get_place_from_handle( place_handle)
 | 
			
		||||
            if place:
 | 
			
		||||
                try:
 | 
			
		||||
                    data.append( (place.get_title(),float(place.get_longitude()),float(place.get_latitude())))
 | 
			
		||||
                except (TypeError, ValueError):
 | 
			
		||||
                    # ignore places that dont have usable data
 | 
			
		||||
                    pass
 | 
			
		||||
        return data
 | 
			
		||||
 | 
			
		||||
    # Reads in textfiles from NIMA:
 | 
			
		||||
    # http://earth-info.nga.mil/gns/html/cntry_files.html
 | 
			
		||||
    def parse_nima_countryfile(self, filename):
 | 
			
		||||
        import csv
 | 
			
		||||
        data = []
 | 
			
		||||
        try:
 | 
			
		||||
            csvreader = csv.reader(open(filename), "excel-tab")
 | 
			
		||||
            l = csvreader.next()    # skip header
 | 
			
		||||
            l = csvreader.next()
 | 
			
		||||
            line = 1
 | 
			
		||||
            while l:
 | 
			
		||||
                if l[17] == "N" and l[9] == "P":
 | 
			
		||||
                    city = l[22]
 | 
			
		||||
                    lat = float( l[3])
 | 
			
		||||
                    lon = float( l[4])
 | 
			
		||||
                    
 | 
			
		||||
                    if line % 10 == 0:
 | 
			
		||||
                        data.append( (city, lon, lat))
 | 
			
		||||
                l = csvreader.next()
 | 
			
		||||
                line = line + 1
 | 
			
		||||
        except (IOError,StopIteration):
 | 
			
		||||
            pass
 | 
			
		||||
        return data
 | 
			
		||||
 | 
			
		||||
    def build_widget(self):
 | 
			
		||||
        hbox = gtk.HBox( False, 4)
 | 
			
		||||
        hbox.set_border_width( 4)
 | 
			
		||||
 | 
			
		||||
        no = gtk.Image()
 | 
			
		||||
        # The large zoomable map
 | 
			
		||||
        self.zoom_map = ZoomMap( 
 | 
			
		||||
            gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"bad.png")),
 | 
			
		||||
            gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"good.png")))
 | 
			
		||||
        if not use_online_map:
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_0.jpg', -180,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_1.jpg', -135,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_2.jpg', -90,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_3.jpg', -45,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_4.jpg', 0,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_5.jpg', 45,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_6.jpg', 90,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_7.jpg', 135,90, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_0.jpg', -180,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_1.jpg', -135,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_2.jpg', -90,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_3.jpg', -45,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_4.jpg', 0,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_5.jpg', 45,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_6.jpg', 90,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_7.jpg', 135,45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_0.jpg', -180,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_1.jpg', -135,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_2.jpg', -90,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_3.jpg', -45,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_4.jpg', 0,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_5.jpg', 45,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_6.jpg', 90,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_7.jpg', 135,0, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_0.jpg', -180,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_1.jpg', -135,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_2.jpg', -90,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_3.jpg', -45,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_4.jpg', 0,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_5.jpg', 45,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_6.jpg', 90,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_7.jpg', 135,-45, 45,45, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_0.jpg', -180,90, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_1.jpg', -90,90, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_2.jpg', 0,90, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_3.jpg', 90,90, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_0.jpg', -180,0, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_1.jpg', -90,0, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_2.jpg', 0,0, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_3.jpg', 90,0, 90,90, 400,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x800x400.jpg', -180,90, 360,180, 800,400)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x400x200.jpg', -180,90, 360,180, 400,200)
 | 
			
		||||
            self.zoom_map.add_map_source('world.topo.200407.3x128x60.jpg', -180,90, 360,180, 128,60)
 | 
			
		||||
 | 
			
		||||
        self.zoom_map.set_size_request(300,300)
 | 
			
		||||
        hbox.pack_start( self.zoom_map, True, True, 0)
 | 
			
		||||
        
 | 
			
		||||
        # On the right side
 | 
			
		||||
        vbox = gtk.VBox( False, 4)
 | 
			
		||||
        hbox.pack_start( vbox, False, False, 0)
 | 
			
		||||
        
 | 
			
		||||
        # The small guide map
 | 
			
		||||
        self.guide_map = GuideMap(
 | 
			
		||||
            gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"world.topo.200407.3x128x60.jpg")))
 | 
			
		||||
        self.guide_map.set_size_request(128,64)
 | 
			
		||||
        vbox.pack_start( self.guide_map, False, True, 0)
 | 
			
		||||
        
 | 
			
		||||
        self.zoom_map.set_guide(self.guide_map)
 | 
			
		||||
        
 | 
			
		||||
        # and the place list
 | 
			
		||||
        self.place_list_view = MapPlacesList( [])
 | 
			
		||||
        self.zoom_map.set_location_model(self.place_list_view.get_model(), 0,1,2)
 | 
			
		||||
        self.place_list_view.connect("cursor-changed", self.entry_select_cb)
 | 
			
		||||
        self.place_list_view.set_size_request(128,-1)
 | 
			
		||||
        vport = gtk.ScrolledWindow()
 | 
			
		||||
        vbox.pack_start(vport,True,True,0)
 | 
			
		||||
        vport.add( self.place_list_view)
 | 
			
		||||
 | 
			
		||||
        self.rebuild_places()
 | 
			
		||||
        
 | 
			
		||||
        return hbox
 | 
			
		||||
 | 
			
		||||
    def ui_definition(self):
 | 
			
		||||
        """
 | 
			
		||||
        Specifies the UIManager XML code that defines the menus and buttons
 | 
			
		||||
        associated with the interface.
 | 
			
		||||
        """
 | 
			
		||||
        return '''<ui>
 | 
			
		||||
          <toolbar name="ToolBar">
 | 
			
		||||
            <toolitem action="ZoomIn"/>  
 | 
			
		||||
            <toolitem action="ZoomOut"/>  
 | 
			
		||||
            <toolitem action="ZoomNormal"/>
 | 
			
		||||
            <toolitem action="ZoomFit"/>
 | 
			
		||||
          </toolbar>
 | 
			
		||||
        </ui>'''
 | 
			
		||||
 | 
			
		||||
    def change_db(self,db):
 | 
			
		||||
        """
 | 
			
		||||
        Callback associated with DbState. Whenenver the database
 | 
			
		||||
        changes, this task is called. In this case, we rebuild the
 | 
			
		||||
        columns, and connect signals to the connected database. Tere
 | 
			
		||||
        is no need to store the database, since we will get the value
 | 
			
		||||
        from self.state.db
 | 
			
		||||
        """
 | 
			
		||||
        db.connect('place-rebuild',self.rebuild_places)
 | 
			
		||||
        db.connect('place-update',self.rebuild_places)
 | 
			
		||||
    
 | 
			
		||||
    def rebuild_places(self, handle_list=None):
 | 
			
		||||
        d = glob_loc_data
 | 
			
		||||
        try:
 | 
			
		||||
            d = d + self.get_xearth_markers()
 | 
			
		||||
            #d = self.parse_nima_countryfile("/tmp/gm.txt")
 | 
			
		||||
            d = d + self.get_markers_from_database( self.dbstate.db)
 | 
			
		||||
        except:
 | 
			
		||||
            log.error("Failed to rebuild places.", exc_info=True)
 | 
			
		||||
        self.place_list_view.change_data( d)
 | 
			
		||||
 | 
			
		||||
    def entry_select_cb(self,treeview):
 | 
			
		||||
        s = treeview.get_selection()
 | 
			
		||||
        (model,sel) = s.get_selected_rows()
 | 
			
		||||
        for path in sel:
 | 
			
		||||
            iter = model.get_iter(path)
 | 
			
		||||
            self.zoom_map.scroll_to(model.get_value(iter,1),
 | 
			
		||||
                                    model.get_value(iter,2))
 | 
			
		||||
            break
 | 
			
		||||
 | 
			
		||||
    def zoom_in_cb(self, obj):
 | 
			
		||||
        self.zoom_map.zoom_in()
 | 
			
		||||
 | 
			
		||||
    def zoom_out_cb(self, obj):
 | 
			
		||||
        self.zoom_map.zoom_out()
 | 
			
		||||
 | 
			
		||||
    def zoom_100_cb(self, obj):
 | 
			
		||||
        self.zoom_map.zoom_normal()
 | 
			
		||||
 | 
			
		||||
    def zoom_fit_cb(self, obj):
 | 
			
		||||
        self.zoom_map.zoom_fit()
 | 
			
		||||
		Reference in New Issue
	
	Block a user