* 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:
parent
a6ccb47a55
commit
83a6d06277
@ -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>
|
||||
* src/GrampsDb/_ReadGedcom.py: LDS fixes.
|
||||
* src/Editors/_EditLdsOrd.py: LDS fixes.
|
||||
|
@ -30,6 +30,7 @@ import gc
|
||||
import re
|
||||
import logging
|
||||
import os
|
||||
import math
|
||||
|
||||
log = logging.getLogger(".")
|
||||
|
||||
@ -51,6 +52,7 @@ import RelLib
|
||||
import PageView
|
||||
import const
|
||||
|
||||
# Some initial places for debugging
|
||||
glob_loc_data = [ # (Name, longitude, latitude)
|
||||
("_Center", 0,0),
|
||||
("_North",0,90),
|
||||
@ -67,7 +69,12 @@ glob_loc_data = [ # (Name, longitude, latitude)
|
||||
("Rio de Janeiro",-43.28,-22.88),
|
||||
("Tokyo",139.75,35.67),
|
||||
("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
|
||||
@ -79,13 +86,19 @@ class GuideMap(gtk.DrawingArea):
|
||||
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:
|
||||
@ -101,6 +114,14 @@ class GuideMap(gtk.DrawingArea):
|
||||
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):
|
||||
@ -118,32 +139,117 @@ class GuideMap(gtk.DrawingArea):
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
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())
|
||||
py = int((90-float(y)) / 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)
|
||||
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:
|
||||
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
|
||||
class ZoomMap( gtk.DrawingArea):
|
||||
def __init__(self, map_pixbuf, place_marker_pixbuf,
|
||||
hightlight_marker_pixbuf):
|
||||
def __init__( self, place_marker_pixbuf, hightlight_marker_pixbuf):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
self.map_pixbuf = map_pixbuf
|
||||
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.old_size = (-1,-1)
|
||||
self.current_pixel_size = (-1,-1)
|
||||
self.zoom_pos = (0,0)
|
||||
self.current_area = (0,0,0,0)
|
||||
self.magnifer = 0.5
|
||||
self.magnifer = 0.0 # in pixel per degree
|
||||
self.guide = None
|
||||
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
|
||||
def set_guide( self, guide):
|
||||
self.guide = guide
|
||||
@ -154,6 +260,21 @@ class ZoomMap( gtk.DrawingArea):
|
||||
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:
|
||||
@ -163,15 +284,28 @@ class ZoomMap( gtk.DrawingArea):
|
||||
if not self.backbuf:
|
||||
self.size_allocate_cb( self,self.get_allocation())
|
||||
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
|
||||
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():
|
||||
#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,
|
||||
@ -180,11 +314,11 @@ class ZoomMap( gtk.DrawingArea):
|
||||
# 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)
|
||||
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
|
||||
@ -197,78 +331,100 @@ class ZoomMap( gtk.DrawingArea):
|
||||
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, long, lat):
|
||||
px = int(self.backbuf.get_width() / self.current_map_area[2] *
|
||||
(float(long) - self.current_map_area[0]))
|
||||
py = int(self.backbuf.get_height() / self.current_map_area[3] *
|
||||
(-float(lat) + self.current_map_area[1]))
|
||||
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.old_size or not self.backbuf:
|
||||
self.old_size = new_size
|
||||
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))
|
||||
|
||||
# Desired midpoint in map
|
||||
pw = int(self.old_size[0]*self.magnifer)
|
||||
ph = int(self.old_size[1]*self.magnifer)
|
||||
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
|
||||
|
||||
px = int((float(self.zoom_pos[0]) + 180.0) / 360.0
|
||||
* self.map_pixbuf.get_width())
|
||||
py = int((90-float(self.zoom_pos[1])) / 180.0
|
||||
* self.map_pixbuf.get_height())
|
||||
|
||||
px = max( pw/2, px)
|
||||
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
|
||||
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 = ( 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
|
||||
if self.guide:
|
||||
self.guide.hightlight_spot( self.zoom_pos)
|
||||
self.queue_draw()
|
||||
|
||||
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.queue_draw()
|
||||
|
||||
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.queue_draw()
|
||||
|
||||
def zoom_normal(self):
|
||||
self.magnifer = 1
|
||||
self.magnifer = 1.0
|
||||
self.magnifer = self.selected_map_scale
|
||||
self.backbuf = None
|
||||
self.queue_draw()
|
||||
|
||||
def zoom_fit(self):
|
||||
self.magnifer = 2
|
||||
self.magnifer = self.current_pixel_size[0] / 360.0
|
||||
self.backbuf = None
|
||||
self.queue_draw()
|
||||
|
||||
@ -400,10 +556,54 @@ class MapView(PageView.PageView):
|
||||
|
||||
no = gtk.Image()
|
||||
# The large zoomable map
|
||||
self.zoom_map = ZoomMap(
|
||||
gtk.gdk.pixbuf_new_from_file(os.path.join(const.image_dir,"land_shallow_topo_2048.jpg")),
|
||||
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")))
|
||||
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)
|
||||
hbox.pack_start( self.zoom_map, True, True, 0)
|
||||
|
||||
@ -413,7 +613,7 @@ class MapView(PageView.PageView):
|
||||
|
||||
# The small guide map
|
||||
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)
|
||||
vbox.pack_start( self.guide_map, False, True, 0)
|
||||
|
||||
|
@ -12,8 +12,6 @@ dist_pkgdata_DATA = \
|
||||
flist.svg\
|
||||
good.png\
|
||||
gramps.png\
|
||||
land_shallow_topo_2048.jpg\
|
||||
land_shallow_topo_350.jpg\
|
||||
locked.png\
|
||||
logo.png\
|
||||
media.svg\
|
||||
@ -32,6 +30,55 @@ dist_pkgdata_DATA = \
|
||||
stock_lock.png\
|
||||
tools.png\
|
||||
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
|
||||
|
||||
world.topo.200407.3x800x400.jpg: mk_blue_marble.py
|
||||
python mk_blue_marble.py
|
||||
|
||||
|
100
src/images/mk_blue_marble.py
Normal file
100
src/images/mk_blue_marble.py
Normal 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
|
||||
|
Loading…
Reference in New Issue
Block a user