Esempio n. 1
0
    def _parse_utfgrid(self, json_grid):
        """Parse geocache coordinates from UTFGrid

        Consume json-decoded UTFGrid data from MechanicalSoup browser.
        Calculate waypoint coordinates and return generator object of
        Cache instances.

        Geocaching.com UTFGrids do not follow UTFGrid specification [2]
        in grid contents and key values.  List "grid" contains valid
        code pixels that are individual, but list "keys" contain a list
        of coordinates as "(x, y)" for points where there are geocaches
        on the grid.  Code pixels can however be decoded to produce
        index of coordinate point in list "keys".  Grid resolution is
        64x64 and coordinates run from northwest corner.  Dictionary
        "data" has key-value pairs, where keys are same coordinates as
        previously described and values are lists of dictionaries each
        containing geocache waypoint code and name in form {"n": name,
        "i": waypoint}.  Waypoints seem to appear nine times each, if
        the cache is not cut out from edges.

        [2] https://github.com/mapbox/utfgrid-spec"""

        logging.debug("Parsing UTFGrid")
        caches = {}   # {waypoint: [<Cache>, <GridCoordinateBlock>]}
        size = len(json_grid["grid"])
        assert len(json_grid["grid"][1]) == size   # square grid
        if size != self.size:
            logging.warning("GC.com UTFGrid specs seem to have changed: "
                            "grid resolution is not 64!")
            self.size = size
        caches = {}
        for coordinate_key in json_grid["data"]:
            cache_list = json_grid["data"][coordinate_key]
            x_i, y_i = (int(i) for i in coordinate_key.strip(" ()").split(","))
            # Store all caches to dictionary
            for cache_dic in cache_list:
                waypoint = cache_dic["i"]
                # Store all found coordinate points
                if waypoint not in caches:
                    c = Cache(waypoint, self._gc, name=cache_dic["n"])
                    caches[waypoint] \
                        = [c, GridCoordinateBlock(self, (x_i, y_i),)]
                else:
                    caches[waypoint][1].add((x_i, y_i))
        # Try to determine grid coordinate block size
        GridCoordinateBlock.determine_block_size(
            *[len(caches[wp][1].points) for wp in caches])
        # Calculate geocache coordinates and yield objects
        for waypoint in caches:
            c, coord_block = caches[waypoint]
            c.location = coord_block.get_location()
            yield c
        logging.info("Found {} caches".format(len(caches)))
Esempio n. 2
0
    def _parse_utfgrid(self, json_grid):
        """Parse geocache coordinates from UTFGrid

        Consume json-decoded UTFGrid data from MechanicalSoup browser.
        Calculate waypoint coordinates and return generator object of
        Cache instances.

        Geocaching.com UTFGrids do not follow UTFGrid specification [2]
        in grid contents and key values.  List "grid" contains valid
        code pixels that are individual, but list "keys" contain a list
        of coordinates as "(x, y)" for points where there are geocaches
        on the grid.  Code pixels can however be decoded to produce
        index of coordinate point in list "keys".  Grid resolution is
        64x64 and coordinates run from northwest corner.  Dictionary
        "data" has key-value pairs, where keys are same coordinates as
        previously described and values are lists of dictionaries each
        containing geocache waypoint code and name in form {"n": name,
        "i": waypoint}.  Waypoints seem to appear nine times each, if
        the cache is not cut out from edges.

        [2] https://github.com/mapbox/utfgrid-spec"""

        logging.debug("Parsing UTFGrid")
        caches = {}  # {waypoint: [<Cache>, <GridCoordinateBlock>]}
        size = len(json_grid["grid"])
        assert len(json_grid["grid"][1]) == size  # square grid
        if size != self.size:
            logging.warning("GC.com UTFGrid specs seem to have changed: " "grid resolution is not 64!")
            self.size = size
        caches = {}
        for coordinate_key in json_grid["data"]:
            cache_list = json_grid["data"][coordinate_key]
            x_i, y_i = (int(i) for i in coordinate_key.strip(" ()").split(","))
            # Store all caches to dictionary
            for cache_dic in cache_list:
                waypoint = cache_dic["i"]
                # Store all found coordinate points
                if waypoint not in caches:
                    c = Cache(waypoint, self._gc, name=cache_dic["n"])
                    caches[waypoint] = [c, GridCoordinateBlock(self, (x_i, y_i))]
                else:
                    caches[waypoint][1].add((x_i, y_i))
        # Try to determine grid coordinate block size
        GridCoordinateBlock.determine_block_size(*[len(caches[wp][1].points) for wp in caches])
        # Calculate geocache coordinates and yield objects
        for waypoint in caches:
            c, coord_block = caches[waypoint]
            c.location = coord_block.get_location()
            yield c
        logging.info("Found {} caches".format(len(caches)))