示例#1
0
    def use_site(self, site, mapwin):
        """Given a starting site, center the map on it and show the map.
        """
        if len(site) > 3 and site[3]:
            collection = self.find_collection(site[3])
        else:
            collection = self.find_collection(self.default_collection)
        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
示例#2
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
示例#3
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
示例#4
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
示例#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
示例#6
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] == "-g":
                    try:
                        import socket
                        from gpsdPoller import GpsdPoller
                        # mapwin.gps_poller = GpsdPoller(10, self.gps_poll)
                        mapwin.gps_poller = GpsdPoller(10, mapwin.gpsd_callback)
                    except ImportError as e:
                        print(str(e))
                        print()
                        print("Can't follow GPS: python-gps isn't installed")
                        mapwin.gps_poller = None
                    except socket.error as e:
                        print(str(e))
                        print()
                        print("Can't follow GPS: can't open GPS device")
                        mapwin.gps_poller = None

                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, end=' ')
                        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].startswith("-d"):
                    try:
                        debuglevel = int(args[0][2:])
                        self.Debug = debuglevel
                    except:
                        self.Debug = 1
                    print("Debugging level", self.Debug)

                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 not mapwin.trackpoints:
                mapwin.trackpoints = TrackPoints()

            try:
                mapwin.trackpoints.read_track_file(args[0])
                args = args[1:]
                continue

            except IOError:
                print("Can't read track file", args[0])
                args = args[1:]
                continue

            # Catch a special case for a common KML error:
            except xml.parsers.expat.ExpatError:
                print("Can't read %s: syntax error." % args[0])
                lowerarg = args[0].lower()
                if lowerarg.endswith(".kml") or \
                   lowerarg.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:]
                    sys.exit(1)

            except (RuntimeError, FileNotFoundError):
                # It wasn't a track file; continue trying to parse it
                # print(args[0], "is not a track file")
                pass

            # 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_lat = float(args[0])
                    mapwin.center_lon = float(args[1])

                    # Set a pin on the specified point.
                    mapwin.pin_lat = mapwin.center_lat
                    mapwin.pin_lon = mapwin.center_lon

                    args = args[2:]

                    if args:
                        mapwin.collection = self.find_collection(args[0])
                        args = args[1:]
                    else:
                        mapwin.collection = \
                            self.find_collection(self.default_collection)
                    continue

                print("Can't make sense of argument:", args[0])
                args = args[1:]
                continue

            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 not mapwin.collection:
            print("Can't find a default Map Collection!")
            print("There may be something wrong with your pytopo.sites")
            print()
            sys.exit(1)

        mapwin.collection.Debug = self.Debug

        # If we have a collection and a track but no center point,
        # center it on the trackpoints, and set scale appropriately:
        if mapwin.trackpoints 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

        # If we're following GPS, it's okay if we don't have center coords yet;
        # the mapwin will wait for a fix.
        if mapwin.collection and mapwin.gps_poller:
            return

        raise(ArgParseException)
示例#7
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()
示例#8
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)
示例#9
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
                    print "Debugging on"
                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]
                args = args[1:]
                continue

            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)

        mapwin.collection.Debug = self.Debug

        # 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)