Example #1
0
    def features(self, query):
        '''
        '''
        logging.debug('Rendering %s' % str(query.bbox))
        
        tiles = list_tiles(query, self.zoom_adjust)
        features = []
        seen = set()
        
        for (wkb, props) in load_features(8, self.host, self.port, self.path, tiles):
            if not self.clipped:
                # not clipped means get rid of inevitable dupes
                key = (wkb, tuple(sorted(props.items())))
                
                if key in seen:
                    continue

                seen.add(key)
            
            features.append((wkb, utf8_keys(props)))
            
        if self.sort:
            logging.debug('Sorting by %s %s' % (self.sort, 'descending' if self.reverse else 'ascending'))
            key_func = lambda wkb_props: wkb_props[1].get(self.sort, None)
            features.sort(reverse=self.reverse, key=key_func)
        
        if len(features) == 0:
            return PythonDatasource.wkb_features(keys=[], features=[])
        
        # build a set of shared keys
        props = zip(*features)[1]
        keys = [set(prop.keys()) for prop in props]
        keys = reduce(lambda a, b: a & b, keys)

        return PythonDatasource.wkb_features(keys=keys, features=features)
Example #2
0
    def features(self, query):
        '''
        '''
        logging.debug('Rendering %s' % str(query.bbox))
        
        tiles = list_tiles(query, self.zoom_adjust)
        features = []
        seen = set()
        
        for (wkb, props) in load_features(8, self.host, self.port, self.path, tiles):
            if not self.clipped:
                # not clipped means get rid of inevitable dupes
                key = (wkb, tuple(sorted(props.items())))
                
                if key in seen:
                    continue

                seen.add(key)
            
            features.append((wkb, utf8_keys(props)))
            
        if self.sort:
            logging.debug('Sorting by %s %s' % (self.sort, 'descending' if self.reverse else 'ascending'))
            key_func = lambda wkb_props: wkb_props[1].get(self.sort, None)
            features.sort(reverse=self.reverse, key=key_func)
        
        if len(features) == 0:
            return PythonDatasource.wkb_features(keys=[], features=[])
        
        # build a set of shared keys
        props = list(zip(*features))[1]
        keys = [set(prop.keys()) for prop in props]
        keys = reduce(lambda a, b: a & b, keys)

        return PythonDatasource.wkb_features(keys=keys, features=features)
Example #3
0
    def __init__(self, template, sort_key=None, clipped='true'):
        ''' Make a new Datasource.
        
            Parameters:
        
              template:
                Required URL template with placeholders for tile zoom, x and y,
                e.g. "http://example.com/layer/{z}/{x}/{y}.json".
        
              sort_key:
                Optional field name to use when sorting features for rendering.
                E.g. "name" or "name ascending" to sort ascending by name,
                "name descending" to sort descending by name.
              
              clipped:
                Optional boolean flag to determine correct behavior for
                duplicate geometries. When tile data is not clipped, features()
                will check geometry uniqueness and throw out duplicates.

                Setting clipped to false for actually-clipped geometries has no
                effect but wastes time. Setting clipped to false for unclipped
                geometries will result in possibly wrong-looking output.

                Default is "true".
        '''
        scheme, host, path, p, query, f = urlparse(template)
        
        self.host = host
        self.port = 443 if scheme == 'https' else 80
        
        self.path = path + ('?' if query else '') + query
        self.path = self.path.replace('%', '%%')
        self.path = self.path.replace('{Z}', '{z}').replace('{z}', '%(z)d')
        self.path = self.path.replace('{X}', '{x}').replace('{x}', '%(x)d')
        self.path = self.path.replace('{Y}', '{y}').replace('{y}', '%(y)d')
        
        if sort_key is None:
            self.sort, self.reverse = None, None
        
        elif sort_key.lower().endswith(' descending'):
            logging.debug('Will sort by %s descending' % sort_key)
            self.sort, self.reverse = sort_key.split()[0], True
        
        else:
            logging.debug('Will sort by %s ascending' % sort_key)
            self.sort, self.reverse = sort_key.split()[0], False
        
        self.clipped = clipped.lower() not in ('false', 'no', '0')
        
        bbox = Box2d(-diameter/2, -diameter/2, diameter/2, diameter/2)
        PythonDatasource.__init__(self, envelope=bbox)
Example #4
0
    def __init__(self, template, sort_key=None, clipped='true', zoom_data='single'):
        ''' Make a new Datasource.
        
            Parameters:
        
              template:
                Required URL template with placeholders for tile zoom, x and y,
                e.g. "http://example.com/layer/{z}/{x}/{y}.json".
        
              sort_key:
                Optional field name to use when sorting features for rendering.
                E.g. "name" or "name ascending" to sort ascending by name,
                "name descending" to sort descending by name.
              
              clipped:
                Optional boolean flag to determine correct behavior for
                duplicate geometries. When tile data is not clipped, features()
                will check geometry uniqueness and throw out duplicates.

                Setting clipped to false for actually-clipped geometries has no
                effect but wastes time. Setting clipped to false for unclipped
                geometries will result in possibly wrong-looking output.

                Default is "true".
              
              zoom_data:
                Optional keyword specifying single or double zoom data tiles.
                Works especially well with relatively sparse label layers.
                
                When set to "double", tiles will be requested at one zoom level
                out from the map view, e.g. double-sized z13 tiles will be used
                to render a normal z14 map.

                Default is "single".
        '''
        scheme, host, path, p, query, f = urlparse(template)
        
        self.host = host
        self.port = 443 if scheme == 'https' else 80
        
        if ':' in host:
            self.host = host.split(':', 1)[0]
            self.port = int(host.split(':', 1)[1])
        
        self.path = path + ('?' if query else '') + query
        self.path = self.path.replace('%', '%%')
        self.path = self.path.replace('{Z}', '{z}').replace('{z}', '%(z)d')
        self.path = self.path.replace('{X}', '{x}').replace('{x}', '%(x)d')
        self.path = self.path.replace('{Y}', '{y}').replace('{y}', '%(y)d')
        
        if sort_key is None:
            self.sort, self.reverse = None, None
        
        elif sort_key.lower().endswith(' descending'):
            logging.debug('Will sort by %s descending' % sort_key)
            self.sort, self.reverse = sort_key.split()[0], True
        
        else:
            logging.debug('Will sort by %s ascending' % sort_key)
            self.sort, self.reverse = sort_key.split()[0], False
        
        self.clipped = clipped.lower() not in ('false', 'no', '0')
        self.zoom_adjust = {'double': 1}.get(zoom_data.lower(), 0)
        
        bbox = Box2d(-diameter/2, -diameter/2, diameter/2, diameter/2)
        PythonDatasource.__init__(self, envelope=bbox)
Example #5
0
    def __init__(self,
                 template,
                 sort_key=None,
                 clipped='true',
                 zoom_data='single'):
        ''' Make a new Datasource.
        
            Parameters:
        
              template:
                Required URL template with placeholders for tile zoom, x and y,
                e.g. "http://example.com/layer/{z}/{x}/{y}.json".
        
              sort_key:
                Optional field name to use when sorting features for rendering.
                E.g. "name" or "name ascending" to sort ascending by name,
                "name descending" to sort descending by name.
              
              clipped:
                Optional boolean flag to determine correct behavior for
                duplicate geometries. When tile data is not clipped, features()
                will check geometry uniqueness and throw out duplicates.

                Setting clipped to false for actually-clipped geometries has no
                effect but wastes time. Setting clipped to false for unclipped
                geometries will result in possibly wrong-looking output.

                Default is "true".
              
              zoom_data:
                Optional keyword specifying single or double zoom data tiles.
                Works especially well with relatively sparse label layers.
                
                When set to "double", tiles will be requested at one zoom level
                out from the map view, e.g. double-sized z13 tiles will be used
                to render a normal z14 map.

                Default is "single".
        '''
        scheme, host, path, p, query, f = urlparse(template)

        self.host = host
        self.port = 443 if scheme == 'https' else 80

        if ':' in host:
            self.host = host.split(':', 1)[0]
            self.port = int(host.split(':', 1)[1])

        self.path = path + ('?' if query else '') + query
        self.path = self.path.replace('%', '%%')
        self.path = self.path.replace('{Z}', '{z}').replace('{z}', '%(z)d')
        self.path = self.path.replace('{X}', '{x}').replace('{x}', '%(x)d')
        self.path = self.path.replace('{Y}', '{y}').replace('{y}', '%(y)d')

        if sort_key is None:
            self.sort, self.reverse = None, None

        elif sort_key.lower().endswith(' descending'):
            logging.debug('Will sort by %s descending' % sort_key)
            self.sort, self.reverse = sort_key.split()[0], True

        else:
            logging.debug('Will sort by %s ascending' % sort_key)
            self.sort, self.reverse = sort_key.split()[0], False

        self.clipped = clipped.lower() not in ('false', 'no', '0')
        self.zoom_adjust = {'double': 1}.get(zoom_data.lower(), 0)

        bbox = Box2d(-diameter / 2, -diameter / 2, diameter / 2, diameter / 2)
        PythonDatasource.__init__(self, envelope=bbox)