* src/DataViews/_MapView.py: Reworked to display multiple smaller tiled map images

* src/images/mk_blue_marble.py: Script to create the map tiles out of the nasa blue marble image
* src/images/Makefile.am: Add map tile images and bootstrap them using mk_blue_marble.py



svn: r6307
This commit is contained in:
Martin Hawlisch 2006-04-10 21:41:42 +00:00
parent a6ccb47a55
commit 83a6d06277
4 changed files with 428 additions and 73 deletions

View File

@ -1,3 +1,11 @@
2006-04-10 Martin Hawlisch <Martin.Hawlisch@gmx.de>
* src/DataViews/_MapView.py: Reworked to display multiple smaller
tiled map images
* src/images/mk_blue_marble.py: Script to create the map tiles out of
the nasa blue marble image
* src/images/Makefile.am: Add map tile images and bootstrap them using
mk_blue_marble.py
2006-04-10 Nathan Bullock <nathanbullock@gmail.com> 2006-04-10 Nathan Bullock <nathanbullock@gmail.com>
* src/GrampsDb/_ReadGedcom.py: LDS fixes. * src/GrampsDb/_ReadGedcom.py: LDS fixes.
* src/Editors/_EditLdsOrd.py: LDS fixes. * src/Editors/_EditLdsOrd.py: LDS fixes.

View File

@ -30,6 +30,7 @@ import gc
import re import re
import logging import logging
import os import os
import math
log = logging.getLogger(".") log = logging.getLogger(".")
@ -51,6 +52,7 @@ import RelLib
import PageView import PageView
import const import const
# Some initial places for debugging
glob_loc_data = [ # (Name, longitude, latitude) glob_loc_data = [ # (Name, longitude, latitude)
("_Center", 0,0), ("_Center", 0,0),
("_North",0,90), ("_North",0,90),
@ -67,7 +69,12 @@ glob_loc_data = [ # (Name, longitude, latitude)
("Rio de Janeiro",-43.28,-22.88), ("Rio de Janeiro",-43.28,-22.88),
("Tokyo",139.75,35.67), ("Tokyo",139.75,35.67),
("Cape Town",18.47,-33.93), ("Cape Town",18.47,-33.93),
("Anchorage",-150.00,61.17)] ("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 # Draws a map image and tries to allocate space in the correct aspect ratio
@ -79,13 +86,19 @@ class GuideMap(gtk.DrawingArea):
self.connect("size-allocate", self.size_allocate_cb) self.connect("size-allocate", self.size_allocate_cb)
self.gc = None self.gc = None
self.current_area = None self.current_area = None
self.current_spot = None
self.old_size = (-1,-1) self.old_size = (-1,-1)
# Set hightlight region # Set hightlight region
def hightlight_area( self, area): def hightlight_area( self, area):
self.current_area = area self.current_area = area
self.queue_draw() self.queue_draw()
# Set hightlight region
def hightlight_spot( self, spot):
self.current_spot = spot
self.queue_draw()
# Redraw the image # Redraw the image
def expose_cb(self,widget,event): def expose_cb(self,widget,event):
if not self.gc: if not self.gc:
@ -101,6 +114,14 @@ class GuideMap(gtk.DrawingArea):
self.current_area[3]) self.current_area[3])
self.window.draw_rectangle( self.gc, False, self.window.draw_rectangle( self.gc, False,
r[0],r[1],r[2],r[3]) 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 # Scale backbuffer
def size_allocate_cb(self,widget,allocation): def size_allocate_cb(self,widget,allocation):
@ -118,32 +139,117 @@ class GuideMap(gtk.DrawingArea):
gtk.gdk.INTERP_BILINEAR) gtk.gdk.INTERP_BILINEAR)
gc.collect() gc.collect()
def map_to_screen( self, x,y,w,h): def map_to_screen( self, x,y,w=None,h=None):
px = int((float(x) + 180.0) / 360.0 * self.backbuf.get_width()) px = int((float(x) + 180.0) / 360.0 * self.backbuf.get_width())
py = int((90-float(y)) / 180.0 * self.backbuf.get_height()) py = int((90-float(y)) / 180.0 * self.backbuf.get_height())
pw = int(float(w) / 360.0 * self.backbuf.get_width()) if w and h:
ph = int(float(h) / 180.0 * self.backbuf.get_height()) 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,pw,ph)
return (px,py)
# Map tile files used by the ZoomMap
class MapTile:
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
# Zoomable map image # Zoomable map image
class ZoomMap( gtk.DrawingArea): class ZoomMap( gtk.DrawingArea):
def __init__(self, map_pixbuf, place_marker_pixbuf, def __init__( self, place_marker_pixbuf, hightlight_marker_pixbuf):
hightlight_marker_pixbuf):
gtk.DrawingArea.__init__(self) gtk.DrawingArea.__init__(self)
self.map_pixbuf = map_pixbuf
self.place_marker_pixbuf = place_marker_pixbuf self.place_marker_pixbuf = place_marker_pixbuf
self.hightlight_marker_pixbuf = hightlight_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("expose-event", self.expose_cb)
self.connect("size-allocate", self.size_allocate_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.gc = None
self.old_size = (-1,-1) self.current_pixel_size = (-1,-1)
self.zoom_pos = (0,0) self.zoom_pos = (0,0)
self.current_area = (0,0,0,0) self.magnifer = 0.0 # in pixel per degree
self.magnifer = 0.5
self.guide = None self.guide = None
self.textlayout = self.create_pango_layout("") self.textlayout = self.create_pango_layout("")
self.map_sources = {}
self.initial_exposed = False
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 # Set the guide map that should follow the zoom area
def set_guide( self, guide): def set_guide( self, guide):
self.guide = guide self.guide = guide
@ -154,6 +260,21 @@ class ZoomMap( gtk.DrawingArea):
self.idx_long = idx_long self.idx_long = idx_long
self.idx_lat = idx_lat 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 # Redraw the image
def expose_cb(self,widget,event): def expose_cb(self,widget,event):
if not self.gc: if not self.gc:
@ -163,15 +284,28 @@ class ZoomMap( gtk.DrawingArea):
if not self.backbuf: if not self.backbuf:
self.size_allocate_cb( self,self.get_allocation()) self.size_allocate_cb( self,self.get_allocation())
if self.backbuf and self.gc: if self.backbuf and self.gc:
self.window.draw_pixbuf( self.gc, self.backbuf, 0,0, 0,0, -1,-1) #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 # draw all available locations
if self.location_model: if self.location_model:
iter = self.location_model.get_iter_first() iter = self.location_model.get_iter_first()
while iter: while iter:
(n,x,y) = self.location_model.get( iter, self.idx_name, self.idx_long, self.idx_lat) (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) (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(): #if px > 0 and py > 0 and px < self.backbuf.get_width() and py < self.backbuf.get_height():
# draw only visible markers # draw only visible markers
#self.window.draw_pixbuf( #self.window.draw_pixbuf(
# self.gc, # self.gc,
@ -180,11 +314,11 @@ class ZoomMap( gtk.DrawingArea):
# px-self.place_marker_pixbuf.get_width()/2, # px-self.place_marker_pixbuf.get_width()/2,
# py-self.place_marker_pixbuf.get_height()/2, # py-self.place_marker_pixbuf.get_height()/2,
# -1,-1) # -1,-1)
self.textlayout.set_text(n) self.textlayout.set_text(n)
self.window.draw_layout( self.window.draw_layout(
self.gc, self.gc,
px,py, px,py,
self.textlayout) self.textlayout)
iter = self.location_model.iter_next( iter) iter = self.location_model.iter_next( iter)
# hightlight current location # hightlight current location
@ -197,78 +331,100 @@ class ZoomMap( gtk.DrawingArea):
py-self.hightlight_marker_pixbuf.get_height()/2, py-self.hightlight_marker_pixbuf.get_height()/2,
-1,-1) -1,-1)
#self.window.draw_rectangle( self.gc, False, px-3,py-3, 6,6) #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, long, lat): def map_to_screen( self, lon, lat):
px = int(self.backbuf.get_width() / self.current_map_area[2] * px = int(self.current_pixel_size[0] / 2.0 + (lon - self.zoom_pos[0]) * self.magnifer)
(float(long) - self.current_map_area[0])) py = int(self.current_pixel_size[1] / 2.0 - (lat - self.zoom_pos[1]) * self.magnifer)
py = int(self.backbuf.get_height() / self.current_map_area[3] *
(-float(lat) + self.current_map_area[1]))
return( px, py) 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 # Scale backbuffer
def size_allocate_cb(self,widget,allocation): def size_allocate_cb(self,widget,allocation):
# only create new backbuffer if size is different # only create new backbuffer if size is different
new_size = (allocation.width,allocation.height) new_size = (allocation.width,allocation.height)
if new_size is not self.old_size or not self.backbuf: if new_size is not self.current_pixel_size or not self.backbuf:
self.old_size = new_size 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))
# Desired midpoint in map def cmpfunc(s):
pw = int(self.old_size[0]*self.magnifer) return((self.magnifer-s)*(self.magnifer-s))
ph = int(self.old_size[1]*self.magnifer)
# 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
px = int((float(self.zoom_pos[0]) + 180.0) / 360.0 for s in self.map_sources.keys():
* self.map_pixbuf.get_width()) for map in self.map_sources[s]:
py = int((90-float(self.zoom_pos[1])) / 180.0 if s == self.selected_map_scale or s == smallest_scale:
* self.map_pixbuf.get_height()) map.set_viewport( self.magnifer, x0, y0, x1-x0, y0-y1)
else:
px = max( pw/2, px) map.free()
py = max( ph/2, py)
px = min( px, self.map_pixbuf.get_width()-1-pw/2)
py = min( py, self.map_pixbuf.get_height()-1-ph/2)
try:
zoomebuf = self.map_pixbuf.subpixbuf( max(0,int(px-pw/2)),max(0,int(py-ph/2)),
min(self.map_pixbuf.get_width(),pw),
min(self.map_pixbuf.get_height(),ph))
self.backbuf = zoomebuf.scale_simple(self.old_size[0],
self.old_size[1],
gtk.gdk.INTERP_BILINEAR)
gc.collect()
mx = 360.0 / self.map_pixbuf.get_width() * (px-pw/2.0) - 180.0
my = 90.0 - 180.0 / self.map_pixbuf.get_height() * (py-ph/2.0)
mw = 360.0 / self.map_pixbuf.get_width() * pw
mh = 180.0 / self.map_pixbuf.get_height() * ph
self.current_area = (px-pw/2, py-ph/2, pw,ph)
self.current_map_area = (mx, my, mw, mh)
if self.guide:
self.guide.hightlight_area( (mx,my,mw,mh))
except:
pass
# Scroll to requested position # Scroll to requested position
def scroll_to( self, long, lat): def scroll_to( self, long, lat):
self.zoom_pos = ( min(180,(max(-180,long))), min(90,(max(-90,lat)))) self.zoom_pos = (float( min(180,(max(-180,long)))), float(min(90,(max(-90,lat)))))
self.backbuf = None self.backbuf = None
if self.guide:
self.guide.hightlight_spot( self.zoom_pos)
self.queue_draw() self.queue_draw()
def zoom_out(self): def zoom_out(self):
self.magnifer = min( 10, self.magnifer * 1.5) self.magnifer = max( 1.0, self.magnifer * 2.0/3.0)
self.backbuf = None self.backbuf = None
self.queue_draw() self.queue_draw()
def zoom_in(self): def zoom_in(self):
self.magnifer = max( 0.1, self.magnifer * 0.75) self.magnifer = min( 500.0, self.magnifer * 1.5)
self.backbuf = None self.backbuf = None
self.queue_draw() self.queue_draw()
def zoom_normal(self): def zoom_normal(self):
self.magnifer = 1 self.magnifer = 1.0
self.magnifer = self.selected_map_scale
self.backbuf = None self.backbuf = None
self.queue_draw() self.queue_draw()
def zoom_fit(self): def zoom_fit(self):
self.magnifer = 2 self.magnifer = self.current_pixel_size[0] / 360.0
self.backbuf = None self.backbuf = None
self.queue_draw() self.queue_draw()
@ -400,10 +556,54 @@ class MapView(PageView.PageView):
no = gtk.Image() no = gtk.Image()
# The large zoomable map # The large zoomable map
self.zoom_map = ZoomMap( self.zoom_map = ZoomMap(
gtk.gdk.pixbuf_new_from_file(os.path.join(const.image_dir,"land_shallow_topo_2048.jpg")),
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,"bad.png")),
gtk.gdk.pixbuf_new_from_file(os.path.join(const.image_dir,"good.png"))) gtk.gdk.pixbuf_new_from_file(os.path.join(const.image_dir,"good.png")))
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.add_map_source("europe_2_0.jpg",0,90,90,90,1024,1024)
self.zoom_map.set_size_request(300,300) self.zoom_map.set_size_request(300,300)
hbox.pack_start( self.zoom_map, True, True, 0) hbox.pack_start( self.zoom_map, True, True, 0)
@ -413,7 +613,7 @@ class MapView(PageView.PageView):
# The small guide map # The small guide map
self.guide_map = GuideMap( self.guide_map = GuideMap(
gtk.gdk.pixbuf_new_from_file(os.path.join(const.image_dir,"land_shallow_topo_350.jpg"))) 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) self.guide_map.set_size_request(128,64)
vbox.pack_start( self.guide_map, False, True, 0) vbox.pack_start( self.guide_map, False, True, 0)

View File

@ -12,8 +12,6 @@ dist_pkgdata_DATA = \
flist.svg\ flist.svg\
good.png\ good.png\
gramps.png\ gramps.png\
land_shallow_topo_2048.jpg\
land_shallow_topo_350.jpg\
locked.png\ locked.png\
logo.png\ logo.png\
media.svg\ media.svg\
@ -32,6 +30,55 @@ dist_pkgdata_DATA = \
stock_lock.png\ stock_lock.png\
tools.png\ tools.png\
somerights20.gif \ somerights20.gif \
document.png document.png\
world.topo.200407.3x128x60.jpg\
world.topo.200407.3x400x200.jpg\
world.topo.200407.3x800x400.jpg\
world.topo.200407.3x1600x800_tile_0_0.jpg\
world.topo.200407.3x1600x800_tile_0_1.jpg\
world.topo.200407.3x1600x800_tile_0_2.jpg\
world.topo.200407.3x1600x800_tile_0_3.jpg\
world.topo.200407.3x1600x800_tile_1_0.jpg\
world.topo.200407.3x1600x800_tile_1_1.jpg\
world.topo.200407.3x1600x800_tile_1_2.jpg\
world.topo.200407.3x1600x800_tile_1_3.jpg\
world.topo.200407.3x3200x1600_tile_0_0.jpg\
world.topo.200407.3x3200x1600_tile_0_1.jpg\
world.topo.200407.3x3200x1600_tile_0_2.jpg\
world.topo.200407.3x3200x1600_tile_0_3.jpg\
world.topo.200407.3x3200x1600_tile_0_4.jpg\
world.topo.200407.3x3200x1600_tile_0_5.jpg\
world.topo.200407.3x3200x1600_tile_0_6.jpg\
world.topo.200407.3x3200x1600_tile_0_7.jpg\
world.topo.200407.3x3200x1600_tile_1_0.jpg\
world.topo.200407.3x3200x1600_tile_1_1.jpg\
world.topo.200407.3x3200x1600_tile_1_2.jpg\
world.topo.200407.3x3200x1600_tile_1_3.jpg\
world.topo.200407.3x3200x1600_tile_1_4.jpg\
world.topo.200407.3x3200x1600_tile_1_5.jpg\
world.topo.200407.3x3200x1600_tile_1_6.jpg\
world.topo.200407.3x3200x1600_tile_1_7.jpg\
world.topo.200407.3x3200x1600_tile_2_0.jpg\
world.topo.200407.3x3200x1600_tile_2_1.jpg\
world.topo.200407.3x3200x1600_tile_2_2.jpg\
world.topo.200407.3x3200x1600_tile_2_3.jpg\
world.topo.200407.3x3200x1600_tile_2_4.jpg\
world.topo.200407.3x3200x1600_tile_2_5.jpg\
world.topo.200407.3x3200x1600_tile_2_6.jpg\
world.topo.200407.3x3200x1600_tile_2_7.jpg\
world.topo.200407.3x3200x1600_tile_3_0.jpg\
world.topo.200407.3x3200x1600_tile_3_1.jpg\
world.topo.200407.3x3200x1600_tile_3_2.jpg\
world.topo.200407.3x3200x1600_tile_3_3.jpg\
world.topo.200407.3x3200x1600_tile_3_4.jpg\
world.topo.200407.3x3200x1600_tile_3_5.jpg\
world.topo.200407.3x3200x1600_tile_3_6.jpg\
world.topo.200407.3x3200x1600_tile_3_7.jpg
EXTRA_DIST = gramps.svg EXTRA_DIST = gramps.svg
world.topo.200407.3x800x400.jpg: mk_blue_marble.py
python mk_blue_marble.py

View File

@ -0,0 +1,100 @@
#!/usr/bin/python
# Script to create smaller map tiles for use in the GRAMPS MapView.
# (c) Martin Hawlisch, martin.hawlisch@gmx.de, 2006.
# I hereby put this script into the public domain.
# Images are generated by using the NASA Blue Marble next generation images.
# http://visibleearth.nasa.gov/view_set.php?categoryID=2355
# July, Blue Marble Next Generation w/ Topography and Bathymetry:
# http://visibleearth.nasa.gov/view_rec.php?id=7106
# 5400 pixel jpeg file:
# http://veimages.gsfc.nasa.gov/7106/world.topo.bathy.200407.3x5400x2700.jpg
# This images are public domain.
import os
tile_defines = []
def process_file( imagefile, image_width, image_height, map_x, map_y, map_width, outfilepattern, tile_size):
y = 0
while (y*tile_size) < image_height:
x = 0
while (x*tile_size) < image_width:
outfile = outfilepattern % (y,x)
if not os.path.isfile( outfile):
cmd = "jpegtran -optimize -crop %dx%d+%d+%d -outfile %s %s" %\
(tile_size,tile_size,x*tile_size,y*tile_size,outfile,imagefile)
print cmd
if os.system( cmd):
print "ERROR"
else:
print "tile %s already exists" % outfile
tile_width = map_width/(image_width/tile_size)
tile_x = map_x + tile_width * x
tile_y = map_y - tile_width * y
print "location: %dx%d" % (tile_x,tile_y)
tile_defines.append("self.zoom_map.add_map_source('%s', %d,%d, %d,%d, %d,%d)" %\
(outfile,tile_x,tile_y,tile_width,tile_width,tile_size,tile_size))
x = x + 1
y = y + 1
pass
def scale_down( infile, outfile, new_width):
if not os.path.isfile( outfile):
cmd = "convert %s -resize %d %s" % (infile,new_width,outfile)
print cmd
if os.system( cmd):
print "ERROR"
else:
print "scaled down image %s already exists" % outfile
def fetch_image( server, filename):
if not os.path.isfile( sourcemap_midres):
print "downloading map file %s" % filename
cmd = "wget -v %s/%s" % (server, sourcemap_midres)
print cmd
if os.system( cmd):
print "ERROR"
else:
print "mapfile %s already downloaded" % filename
server = "http://veimages.gsfc.nasa.gov/7130"
# Step 1: Fetch mid-res image
sourcemap_midres = "world.topo.200407.3x5400x2700.jpg"
fetch_image( server, sourcemap_midres)
# Step 2: Scale that down a bit (to a multiple of 16 pixels)
sourcemap_lowres = "world.topo.200407.3x3200x1600.jpg"
scale_down(sourcemap_midres,sourcemap_lowres,3200)
# Step 3: Create tiles
process_file( sourcemap_lowres, 3200, 1600, -180, 90, 360, "world.topo.200407.3x3200x1600_tile_%d_%d.jpg",400)
# Step 4: Scale down mid-res image to 2048x1024
sourcemap_lowres = "world.topo.200407.3x1600x800.jpg"
scale_down(sourcemap_midres,sourcemap_lowres,1600)
# Step 4: Tile low-res image
process_file( sourcemap_lowres, 1600, 800, -180, 90, 360, "world.topo.200407.3x1600x800_tile_%d_%d.jpg",400)
# Step 5: Scale down once more
sourcemap_thumb = "world.topo.200407.3x800x400.jpg"
scale_down(sourcemap_lowres,sourcemap_thumb,800)
# Step 5: Scale down thumb-scale image
sourcemap_thumb = "world.topo.200407.3x400x200.jpg"
scale_down(sourcemap_lowres,sourcemap_thumb,400)
# Step 5: Scale down thumb-scale image
sourcemap_thumb = "world.topo.200407.3x128x60.jpg"
scale_down(sourcemap_lowres,sourcemap_thumb,128)
for d in tile_defines:
print d