Ejemplo n.º 1
0
 def get_next_maplet(self, fullpathname, dX, dY):
     """Given a maplet's pathname, get the next or previous one.
     Does not currently work for jumps more than 1 in any direction.
     Returns pixbuf, newpath (either may be None).
     """
     pathname, filename = os.path.split(fullpathname)
     if (self.Debug):
         print "Generic get_next_maplet", filename, dX, dY
     name, ext = os.path.splitext(filename)
     # traceback.print_stack()
     mapb = int(name[-self.numdigits:])
     if self.usedash:
         mapa = int(name[-self.numdigits * 2 - 1: -self.numdigits - 1])
     else:
         mapa = int(name[-self.numdigits * 2: -self.numdigits])
     if self.latfirst:
         newa = MapUtils.ohstring(mapa + dX, self.numdigits)
         newb = MapUtils.ohstring(mapb + dY, self.numdigits)
     else:
         newa = MapUtils.ohstring(mapa + dY, self.numdigits)
         newb = MapUtils.ohstring(mapb + dX, self.numdigits)
     if self.usedash:
         newname = self.prefix + newa + "-" + newb
     else:
         newname = self.prefix + newa + newb
     newpath = os.path.join(self.location, newname + ext)
     if filename is None or not os.access(filename, os.R_OK):
         return None, newpath
     pixbuf = MapWindow.load_image_from_file(newpath)
     return pixbuf, newpath
Ejemplo n.º 2
0
 def coords_to_filename(self, longitude, latitude):
     """Given coordinates in decimal degrees, map to the closest filename"""
     if self.left_longitude > longitude or self.top_latitude < latitude:
         return None
     x_grid = MapUtils.int_trunc((longitude - self.left_longitude) *
                                 self.xscale / self.img_width)
     y_grid = MapUtils.int_trunc((self.top_latitude - latitude) *
                                 self.yscale / self.img_height)
     if not self.latfirst:
         temp = x_grid
         x_grid = y_grid
         y_grid = temp
     retstr = os.path.join(self.location,
                           self.prefix + MapUtils.ohstring(x_grid,
                                                           self.numdigits))
     if self.usedash:
         retstr = retstr + "-"
     retstr = retstr + MapUtils.ohstring(y_grid, self.numdigits) + self.ext
     return retstr
Ejemplo n.º 3
0
    def coords_to_filename(self, longitude, latitude):
        """Given a pair of coordinates in deg.mmss, map to the
        containing filename, e.g. q37122c2/012t0501.gif.
        """

        latDeg = MapUtils.int_trunc(latitude)
        longDeg = MapUtils.int_trunc(-longitude)
        latMin = (latitude - latDeg) * 60.
        longMin = (-longitude - longDeg) * 60.

        # The 7.5 here is because of the 7.5 in the directory names above
        # (we're getting the offset of this image from the origin of
        # the 7.5-series map covered by the directory),
        # not the map series we're actually plotting now.
        longMinOrd = MapUtils.int_trunc(longMin / 7.5)
        latMinOrd = MapUtils.int_trunc(latMin / 7.5)

        dirname = "q" + MapUtils.ohstring(latDeg, 2) \
            + MapUtils.ohstring(longDeg, 3) \
            + chr(ord('a') + latMinOrd) + str(longMinOrd + 1)

        # Find the difference between our desired coordinates
        # and the origin of the map this directory represents.
        # The 7.5 here is because of the 7.5 in the directory names above.
        latMinDiff = latMin - (latMinOrd * 7.5)
        longMinDiff = longMin - (longMinOrd * 7.5)

        latOffset = MapUtils.int_trunc(latMinDiff * 10 / self.series)
        longOffset = MapUtils.int_trunc(longMinDiff * 10 / self.series)

        # Now calculate the current filename.
        # Note that series is either 7.5 or 15
        if (self.series > 13):
            fileprefix = "024t"
            numcharts = 5
        else:
            fileprefix = "012t"
            numcharts = 10
        filename = fileprefix + MapUtils.ohstring(numcharts - longOffset, 2) \
                   + MapUtils.ohstring(numcharts - latOffset, 2) + self.img_ext

        return self.location + "/" + dirname + "/" + filename
Ejemplo n.º 4
0
    def use_site(self, site, mapwin):
        collection = self.find_collection(site[3])
        if not collection:
            return False
        mapwin.collection = collection

        # site[1] and site[2] are the long and lat in deg.minutes
        # print site[0], site[1], site[2]
        mapwin.center_lon = MapUtils.deg_min2dec_deg(site[1])
        mapwin.center_lat = MapUtils.deg_min2dec_deg(site[2])
        mapwin.pin_lon = mapwin.center_lon
        mapwin.pin_lat = mapwin.center_lat
        # print "Center in decimal degrees:", centerLon, centerLat
        if (self.Debug):
            print site[0] + ":", \
                MapUtils.dec_deg2deg_min_str(mapwin.center_lon), \
                MapUtils.dec_deg2deg_min_str(mapwin.center_lat)
        if len(site) > 4 and collection.zoom_to:
            collection.zoom_to(site[4])
        mapwin.draw_map()
        return True
Ejemplo n.º 5
0
    def get_maplet(self, longitude, latitude):
        """Get the maplet containing the specified coordinates.
        Returns pixbuf, x_offset, y_offset, filename
        where offsets are pixels from top left of the specified coords
        and pixbuf or (less often) filename may be None.
        """

        filename = self.coords_to_filename(longitude - self.lon_correction,
                                           latitude - self.lat_correction)
        if (self.Debug):
            print "T1MC get_maplet(", MapUtils.dec_deg2deg_min_str(longitude),
            print ",", MapUtils.dec_deg2deg_min_str(latitude), "):", filename

        # Calculate offsets.
        # Maplets are self.series minutes wide and tall,
        # so any offset from that is an offset into the maplet:
        # the number of pixels in X and Y that have to be added
        # to get from the maplet's upper left corner to the
        # indicated coordinates.
        # But then we have to correct to get to WGS84 coordinates.
        # XXX the WGS84 part doesn't work right yet.

        # longitude increases rightward:
        x_off = int((longitude - MapUtils.truncate2frac(longitude, self.frac)
                     - self.lon_correction) * self.xscale)
        if (self.Debug):
            print "truncated", MapUtils.dec_deg2deg_min_str(longitude), "to",
            print MapUtils.dec_deg2deg_min_str(MapUtils.truncate2frac(longitude,
                                                                     self.frac))

        # Latitude decreases downward:
        y_off = int((MapUtils.truncate2frac(latitude, self.frac) +
                     self.frac - latitude - self.lat_correction) * self.yscale)

        if (self.Debug):
            print "truncated", MapUtils.dec_deg2deg_min_str(latitude), "to",
            print MapUtils.dec_deg2deg_min_str(MapUtils.truncate2frac(latitude,
                                                                     self.frac))
            print "y_off is", y_off

        if not os.access(filename, os.R_OK):
            return None, x_off, y_off, filename
        pixbuf = MapWindow.load_image_from_file(filename)

        return pixbuf, x_off, y_off, filename
Ejemplo n.º 6
0
    def get_next_maplet(self, fullpathname, dX, dY):
        """Given a maplet's pathname, get the next or previous one.
        Does not currently work for jumps more than 1 in any direction.
        Returns pixbuf, newpath (either may be None).
        """

        if (self.Debug):
            print "get_next_maplet:", fullpathname, dX, dY
        pathname, filename = os.path.split(fullpathname)
        collecdir, mapdir = os.path.split(pathname)
        maplat = int(mapdir[1:3])
        maplon = int(mapdir[3:6])
        name, ext = os.path.splitext(filename)
        xdir = int(mapdir[-1])
        ydir = ord(mapdir[-2]) - ord('a')     # convert from letter a-h
        if self.series == 7.5:
            serstr = self.ser7prefix
            grid = 10
        else:
            serstr = self.ser15prefix
            grid = 5

        x = int(name[-4:-2]) + dX
        y = int(name[-2:]) + dY

        if x < 1:
            x = grid
            xdir = xdir + 1
            if xdir > 8:
                xdir = 1
                if self.Debug:
                    print mapdir, name, ": wrapping mapdir coordinates -x",
                    print maplon
                maplon = str(int(maplon) + 1)
        if x > grid:
            x = 1
            xdir = xdir - 1
            if xdir < 1:
                xdir = 8
                if self.Debug:
                    print mapdir, name, ": wrapping mapdir coordinates +x",
                    print maplon
                maplon = str(int(maplon) - 1)

        if y > grid:
            y = 1
            ydir = ydir - 1
            if ydir < 0:
                ydir = 7
                if self.Debug:
                    print mapdir, name, ": wrapping mapdir coordinates +y",
                    print maplat
                maplat = str(int(maplat) - 1)

        if y < 1:
            y = grid
            ydir = ydir + 1
            if ydir > 7:
                ydir = 0
                if self.Debug:
                    print mapdir, name, ": wrapping mapdir coordinates -y",
                    print maplat
                maplat = str(int(maplat) + 1)

        # We're ready to piece the filename back together!
        newpath = os.path.join(collecdir,
                               "q" + MapUtils.ohstring(maplat, 2)
                                   + MapUtils.ohstring(maplon, 3)
                                   + chr(ydir + ord('a')) + str(xdir),
                               serstr + MapUtils.ohstring(x, 2)
                                   + MapUtils.ohstring(y, 2) + ext)
        if not os.access(newpath, os.R_OK):
            if self.Debug:
                print "get_next_maplet(", fullpathname, dX, dY, ")"
                print "  Can't open", newpath
            return None, newpath

        pixbuf = MapWindow.load_image_from_file(newpath)
        return pixbuf, newpath
Ejemplo n.º 7
0
    def parse_args(self, mapwin, args):
        """Parse runtime arguments."""

        args = args[1:]

        while len(args) > 0:
            if args[0][0] == '-' and not args[0][1].isdigit():
                if args[0] == "-v" or args[0] == "--version":
                    print self.get_version()
                    sys.exit(0)
                elif args[0] == "-h" or args[0] == "--help":
                    self.Usage()

                # Next clause is impossible because of the prev isdigit check:
                # if args[0] == "-15":
                #    series = 15
                elif args[0] == "-p":
                    self.print_sites()
                elif args[0] == "-c":
                    # Specify a collection:
                    if len(args) < 2:
                        print "-c must specify collection"
                        self.Usage()
                    mapwin.collection = self.find_collection(args[1])
                    if mapwin.collection is None:
                        self.error_out("Can't find a map collection called "
                                        + args[1])
                    # Start initially at top left, but subsequent args
                    # may change this:
                    mapwin.center_lon, mapwin.center_lat = \
                        mapwin.collection.get_top_left()
                    if (self.Debug):
                        print "Collection", mapwin.collection.name,
                        print "Starting at", \
                            MapUtils.dec_deg2deg_min_str(mapwin.center_lon), \
                            ", ", \
                            MapUtils.dec_deg2deg_min_str(mapwin.center_lat)
                    args = args[1:]

                elif args[0] == "-d":
                    self.Debug = True
                elif args[0] == "-r":
                    self.reload_tiles = time.time()
                elif args[0] == "-t" and len(args) > 1:
                    if mapwin.trackpoints is None:
                        mapwin.trackpoints = TrackPoints()

                    # Is it a known track?
                    for tr in self.KnownTracks:
                        if args[1] == tr[0]:
                            if self.Debug:
                                print "Reading known track", tr[0], tr[1]
                            args[1] = tr[1]
                            break

                    try:
                        mapwin.trackpoints.read_track_file(args[1])
                    except IOError:
                        print "Can't read track file", args[1]
                    args = args[1:]
                else:
                    self.error_out("Unknown flag " + args[0])

                # Done processing this flag
                args = args[1:]
                continue

            # args[0] doesn't start with '-'. Is it a track file?
            if args[0].endswith(".gpx") \
               or args[0].endswith(".kml") \
               or args[0].endswith(".kmz") \
               or args[0].endswith("json"):
                try:
                    if mapwin.trackpoints:
                        mapwin.trackpoints.read_track_file(args[0])
                    else:
                        trackpoints = TrackPoints()
                        trackpoints.read_track_file(args[0])
                        mapwin.trackpoints = trackpoints
                except IOError:
                    print "Can't read track file", args[0]
                except xml.parsers.expat.ExpatError:
                    print "Can't read %s: syntax error." % args[0]
                    if args[0].lower().endswith(".kml") or \
                       args[0].lower().endswith(".kmz"):
                        print """
Is this a KML made with ArcGIS?
It may have an illegal xsi:schemaLocation.
If so, try changing xsi:schemaLocation to just schemaLocation."""
                args = args[1:]
                continue

            # Try to match a known site:
            for site in self.KnownSites:
                if args[0] == site[0]:
                    if not self.use_site(site, mapwin):
                        continue
                    break

            if mapwin.collection and mapwin.center_lon and mapwin.center_lat:
                args = args[1:]
                continue

            # Doesn't match a known site. Maybe the args are coordinates?
            try:
                if len(args) >= 2 and \
                   len(args[0]) > 1 and args[0][1].isdigit() and \
                   len(args[1]) > 1 and args[1][1].isdigit():
                    mapwin.center_lon = MapUtils.deg_min2dec_deg(float(args[0]))
                    mapwin.center_lat = MapUtils.deg_min2dec_deg(float(args[2]))
                    mapwin.collection = self.find_collection(args[3])
                    args = args[2:]
                    continue
                print "Can't make sense of argument:", args[0]
                self.Usage()

            except ValueError:
                print "Couldn't parse coordinates"
                self.Usage()

            # If we get here, we still have an argument but it doesn't
            # match anything we know: flag, collection, site or coordinate.
            print "Problem parsing arguments. Remaining args:", args
            self.Usage()

        # Now we've parsed all the arguments.
        # If we didn't get a collection, use the default, if any:
        if not mapwin.collection and self.default_collection:
            mapwin.collection = self.find_collection(self.default_collection)

        # If we have a collection and a track but no center point,
        # center it on the trackpoints, and set scale appropriately:
        if mapwin.trackpoints is not None and mapwin.collection is not None \
                and not (mapwin.center_lat and mapwin.center_lon):
            minlon, minlat, maxlon, maxlat = mapwin.trackpoints.get_bounds()
            mapwin.center_lon = (maxlon + minlon) / 2
            mapwin.center_lat = (maxlat + minlat) / 2
            mapwin.collection.zoom_to_bounds(minlon, minlat, maxlon, maxlat)

        if self.reload_tiles and 'set_reload_tiles' in dir(mapwin.collection):
            mapwin.collection.set_reload_tiles(self.reload_tiles)
        elif self.reload_tiles:
            print "Collection can't re-download tiles"

        # By now, we hope we have the mapwin positioned with a collection
        # and starting coordinates:
        if mapwin.collection and mapwin.center_lon and mapwin.center_lat:
            return

        # Didn't match any known run mode:
        # start in GUI mode choosing a location:
        if not mapwin.selection_window():
            sys.exit(0)
Ejemplo n.º 8
0
    def draw_map(self, center_lon, center_lat, mapwin):
        """Draw maplets at the specified coordinates, to fill the mapwin."""

        self.mapwin = mapwin

        # Get the current window size:
        win_width, win_height = mapwin.get_size()
        if (self.Debug):
            print("Window is", win_width, "x", win_height)

        # Now that we have a latitude, call zoom so we can finally
        # set the x and y scales accurately.
        self.zoom(0, center_lat)

        # Find the coordinate boundaries for the set of maps to draw.
        # This may (indeed, usually will) include maps partly off the screen,
        # so the coordinates will span a greater area than the visible window.
        if (self.Debug):
            print("Calculating boundaries: min =", \
                MapUtils.dec_deg2deg_min_str(center_lon), \
                center_lon, "+/-", win_width, \
                "/", self.xscale, "/ 2")
        min_lon = center_lon - win_width / self.xscale / 2
        max_lon = center_lon + win_width / self.xscale / 2
        min_lat = center_lat - win_height / self.yscale / 2
        max_lat = center_lat + win_height / self.yscale / 2

        if (self.Debug):
            print("Map from", min_lon, MapUtils.dec_deg2deg_min_str(min_lon), \
                MapUtils.dec_deg2deg_min_str(min_lat), \
                "to", MapUtils.dec_deg2deg_min_str(max_lon), \
                MapUtils.dec_deg2deg_min_str(max_lat))

        # Start from the upper left: min_lon, max_lat

        # pdb.set_trace()
        curlat = max_lat
        cur_y = 0
        y_maplet_name = None
        initial_x_off = None
        while cur_y < win_height:
            curlon = min_lon
            cur_x = 0
            x_maplet_name = None
            while cur_x < win_width:

                # Reset the expected image size:
                w = self.img_width
                h = self.img_height

                # Is it the first maplet in this row?
                if x_maplet_name is None:

                    # Is it the first maplet in the map --
                    # usually the one in the upper left corner?
                    # Then we need to specify coordinates.
                    if y_maplet_name is None:
                        pixbuf, x_off, y_off, x_maplet_name = \
                            self.get_maplet(curlon, curlat)

                        # Save the x offset: we'll need it for the
                        # beginning of each subsequent row.
                        initial_x_off = x_off

                    # Not upper left corner --
                    # must be the beginning of a new row.
                    # Get the maplet below the beginning of the last row.
                    else:
                        pixbuf, x_maplet_name = \
                            self.get_next_maplet(y_maplet_name, 0, 1)
                        x_off = initial_x_off
                        y_off = 0

                    # Either way, whether or not we got a pixbuf,
                    # if we're at the beginning of a row, save the
                    # beginning-of-row maplet name and the offset:
                    if cur_x == 0:
                        y_maplet_name = x_maplet_name

                # Continuing an existing row.
                # Get the maplet to the right of the last one.
                else:
                    pixbuf, x_maplet_name = self.get_next_maplet(
                        x_maplet_name, 1, 0)
                    x_off = 0

                if self.Debug:
                    print("    ", x_maplet_name)

                x = cur_x
                y = cur_y

                w, h = self.draw_tile_at_position(pixbuf, mapwin, x, y, x_off,
                                                  y_off)
                # You may ask, why not just do this subtraction before
                # draw_pixbuf so we don't have to subtract w and h twice?
                # Alas, we may not have the real w and h until we've done
                # pixbuf.get_width(), so we'd be subtracting the wrong thing.
                # XXX Not really true any more, since we're assuming fixed
                # XXX tile size. Revisit this!
                cur_x += w
                curlon += float(w) / self.xscale

            if (self.Debug):
                print(" ")
                print("New row: adding y =", h, end=' ')
                print("Subtracting lat", float(h) / self.yscale)

            cur_y += h
            curlat -= float(h) / self.yscale
            # curlat -= float(self.img_height) / self.yscale

        # Free all pixbuf data. Just letting pixbuf go out of scope
        # isn't enough; it's necessary to force garbage collection
        # otherwise Python will let the process grow until it
        # fills all of memory.
        # http://www.daa.com.au/pipermail/pygtk/2003-December/006499.html
        # (At this indentation level, we free after drawing the whole map.)
        gc.collect()

        # If we queued any downloads and aren't currently downloading,
        # schedule a function to take care of that:
        if len(self.download_tiles) > 0 and self.download_func is None:
            gobject.timeout_add(300, self.download_more)