예제 #1
0
파일: features.py 프로젝트: fredj/mf-chsdi3
def _identify(request):
    params = IdentifyServiceValidation(request)
    response = {'results': []}
    # Determine layer types
    # Grid layers are serverless
    layersDB = []
    layersGrid = []
    isScaleDependent = has_buffer(params.imageDisplay, params.mapExtent,
                                  params.tolerance)
    scale = get_scale(params.imageDisplay,
                      params.mapExtent) if isScaleDependent else None
    if params.layers == 'all':
        model = get_bod_model(params.lang)
        query = params.request.db.query(model)
        for layer in get_layers_metadata_for_params(params, query, model):
            layerBodId = layer['layerBodId']
            models = models_from_bodid(layerBodId,
                                       scale=scale,
                                       srid=params.srid)
            if models:
                layersDB.append({layerBodId: models})
            else:
                gridSpec = get_grid_spec(layerBodId)
                if gridSpec and params.geometryType == 'esriGeometryPoint':
                    layersGrid.append({layerBodId: gridSpec})
    else:
        for layerBodId in params.layers:
            gridSpec = get_grid_spec(layerBodId)
            if gridSpec:
                if params.geometryType not in ('esriGeometryPoint',
                                               'esriGeometryEnvelope'):
                    raise exc.HTTPBadRequest(
                        'Only esriGeometryPoint or esriGeometryEnvelope'
                        'are supported for geometryType parameter for grid like data'
                    )
                layersGrid.append({layerBodId: gridSpec})
            else:
                models = models_from_bodid(layerBodId,
                                           scale=scale,
                                           srid=params.srid)
                # The layer has a model but not at the right scale
                if models is not None and len(models) == 0:
                    return response
                # There is no model for this layer
                elif models is None:
                    raise exc.HTTPBadRequest('No GeoTable was found for %s' %
                                             layerBodId)
                layersDB.append({layerBodId: models})
    featuresGrid = _identify_grid(params, layersGrid)
    featuresDB = _identify_db(params, layersDB)
    response['results'] = featuresGrid + featuresDB
    return response
예제 #2
0
파일: features.py 프로젝트: fredj/mf-chsdi3
def _get_features(params, extended=False, process=True):
    ''' Returns exactly one feature or raises
    an excpetion '''
    featureIds = params.featureIds
    scale = None
    if hasattr(params, 'imageDisplay') and hasattr(params, 'mapExtent'):
        if all((params.imageDisplay, params.mapExtent)):
            scale = get_scale(params.imageDisplay, params.mapExtent)

    models = models_from_bodid(params.layerId,
                               orderScale=scale,
                               srid=params.srid)
    gridSpec = get_grid_spec(params.layerId)
    if models is None and gridSpec is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' %
                                 params.layerId)
    for featureId in featureIds:
        if gridSpec:
            bucketName = params.request.registry.settings['vector_bucket']
            bucket = get_bucket(bucketName)
            # By convention
            if featureId.find('_') == -1:
                raise exc.HTTPBadRequest('Unexpected id formatting')
            col, row = featureId.split('_')
            grid = Grid(gridSpec.get('extent'), gridSpec.get('resolutionX'),
                        gridSpec.get('resolutionY'))
            layerProperties = get_grid_layer_properties(params.layerId)
            timestamp = layerProperties.get('timestamp')
            yield _get_feature_grid(col, row, timestamp, grid, bucket, params)
        else:
            yield _get_feature_db(featureId, params, models, process=process)
예제 #3
0
def releases(request):
    params = _get_releases_params(request)
    # For this sevice, we have to use different models based
    # on specially sorted views. We add the _meta part to the given
    # layer name
    # Note that only zeitreihen is currently supported for this service
    models = models_from_bodid(params.layer + '_meta')
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' %
                                 params.layer)

    # Default timestamp
    timestamps = []
    minYear = 9999
    for f in _get_features_for_filters(params, [models]):
        if hasattr(f, 'release_year') and f.release_year is not None:
            for x in f.release_year:
                if int(x) < minYear:
                    timestamps.append(str(x))
                    minYear = int(x)

    if len(timestamps) > 0:
        # remove duplicates
        timestamps = list(set(timestamps))
        # add day to have full timestamp
        timestamps = sorted([int(ts + '1231') for ts in timestamps])
        # transform back to string
        timestamps = [str(ts) for ts in timestamps]

    return {'results': timestamps}
예제 #4
0
def _get_features(params, extended=False, process=True):
    ''' Returns exactly one feature or raises
    an excpetion '''
    featureIds = params.featureIds
    scale = None
    if hasattr(params, 'imageDisplay') and hasattr(params, 'mapExtent'):
        if all((params.imageDisplay, params.mapExtent)):
            scale = get_scale(params.imageDisplay, params.mapExtent)

    models = models_from_bodid(params.layerId, orderScale=scale, srid=params.srid)
    gridSpec = get_grid_spec(params.layerId)
    if models is None and gridSpec is None:
        raise exc.HTTPBadRequest(
            'No Vector Table was found for %s' % params.layerId)
    for featureId in featureIds:
        if gridSpec:
            bucketName = params.request.registry.settings['vector_bucket']
            bucket = get_bucket(bucketName)
            # By convention
            if featureId.find('_') == -1:
                raise exc.HTTPBadRequest('Unexpected id formatting')
            col, row = featureId.split('_')
            grid = Grid(gridSpec.get('extent'),
                        gridSpec.get('resolutionX'),
                        gridSpec.get('resolutionY'))
            layerProperties = get_grid_layer_properties(params.layerId)
            timestamp = layerProperties.get('timestamp')
            yield _get_feature_grid(col, row, timestamp, grid, bucket, params)
        else:
            yield _get_feature_db(featureId, params, models, process=process)
예제 #5
0
def releases(request):
    params = IdentifyServiceValidation(request, service='releases')
    # For this sevice, we have to use different models based
    # on specially sorted views. We add the _meta part to the given
    # layer name
    # Note that only zeitreihen is currently supported for this service
    # Use scale rather than resolutions for zeitreihen like the other layers
    resolution = get_resolution(params.imageDisplay, params.mapExtent)
    models = models_from_bodid(params.layerId, resolution=resolution, srid=params.srid)
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' % params.layerId)

    minYear = float('inf')
    # Default timestamp
    timestamps = []
    # group timestamps by bgdi_order
    for f in _get_features_releases(models[0], params):
        if hasattr(f, 'array_release_years') and f.array_release_years is not None and \
                hasattr(f, 'bgdi_order') and f.bgdi_order is not None:
            # Here we use some kind of filtering technique
            # to avoid returning too many results (used in service-print only)
            for y in f.array_release_years:
                if y < minYear:
                    timestamps.append(y)
                    minYear = y

    timestamps = list(set(timestamps))
    # add day to have full timestamp
    timestamps = sorted([int(str(ts) + '1231') for ts in timestamps])
    # transform back to string
    timestamps = [str(ts) for ts in timestamps]
    return {'results': timestamps}
예제 #6
0
파일: bod.py 프로젝트: fredj/mf-chsdi3
    def layerConfig(self, params):
        config = {}
        translate = params.translate
        settings = params.request.registry.settings
        wmsHost = settings['wmshost']
        defaultResolution = 0.5
        for k in self.__dict__.keys():
            val = self.__dict__[k]
            if not k.startswith("_") and not k.startswith('geojsonUrl') and \
                    val is not None and k not in ('staging', 'srid'):
                if k == 'maps':
                    config['topics'] = val
                elif k == 'layerBodId':
                    config['label'] = translate(val)
                elif k == 'attribution':
                    config[k] = translate(val)
                elif k == 'tilematrix_resolution_max':
                    if val != defaultResolution and \
                            self.__dict__['srid'] != u'4326':
                        config[
                            'resolutions'] = self._getResolutionsFromMatrixSet(
                                val, params.srid)
                elif k == 'extent':  # Used for the shop, are still in lv03
                    if val and params.srid == 2056:
                        config['extent'] = shift_to(val, 2056)
                    else:
                        config['extent'] = val
                else:
                    config[k] = val

        if config['type'] in ('wmts', 'aggregate', 'geojson'):
            del config['singleTile']

        if not config['timeEnabled']:
            del config['timeBehaviour']

        if config['type'] == 'wms':
            config['wmsUrl'] = 'https://%s' % wmsHost
        elif config['type'] == 'geojson':
            api_url = params.request.registry.settings['api_url']
            config['styleUrl'] = make_agnostic(api_url +
                                               '/static/vectorStyles/' +
                                               self.layerBodId + '.json')
            config['geojsonUrl'] = self._getGeoJsonUrl(params.lang)
            if 'format' in config:
                del config['format']
        # sublayers don't have attributions
        if 'attribution' in config:
            config['attributionUrl'] = translate(self.__dict__['attribution'] +
                                                 '.url')

        # adding __queryable_attributes__ if they have them
        models = models_from_bodid(self.layerBodId)
        if models is not None:
            queryable_attributes = get_models_attributes_keys(
                models, params.lang, True)
            if len(queryable_attributes) > 0:
                config['queryableAttributes'] = queryable_attributes

        return {self.layerBodId: config}
예제 #7
0
파일: __init__.py 프로젝트: fredj/mf-chsdi3
 def getRandomFeatureId(self, bodId):
     models = models_from_bodid(bodId)
     with self.getSession() as session:
         t = session.query(models[0]).limit(500).subquery('t')
         query = session.query(t).order_by(func.random()).limit(1)
         reslt = query.one()
     return reslt[0]
예제 #8
0
def _get_features(params, extended=False):
    ''' Returns exactly one feature or raises
    an excpetion '''
    featureIds = params.featureIds.split(',')
    models = models_from_bodid(params.layerId)
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' % params.layerId)

    for featureId in featureIds:
        # One layer can have several models
        for model in models:
            query = params.request.db.query(model)
            query = query.filter(model.id == featureId)
            try:
                feature = query.one()
            except (NoResultFound, DataError):
                feature = None
            except MultipleResultsFound:
                raise exc.HTTPInternalServerError('Multiple features found for the same id %s' % featureId)

            if feature is not None:
                vectorModel = model
                break

        if feature is None:
            raise exc.HTTPNotFound('No feature with id %s' % featureId)
        feature = _process_feature(feature, params)
        feature = {'feature': feature}
        yield feature, vectorModel
예제 #9
0
def _attributes(request):
    ''' This service exposes preview values based on a layer Id
    and an attribute name (mapped in the model) '''
    MAX_ATTR_VALUES = 50
    attributesValues = []
    params = _get_attributes_params(request)

    models = models_from_bodid(params.layerId)

    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' % params.layerId)

    # Check that the attribute provided is found at least in one model
    modelToQuery = None
    for model in models:
        attributes = model().getAttributesKeys()
        if params.attribute in attributes:
            modelToQuery = model
            break
    if modelToQuery is None:
        raise exc.HTTPBadRequest('No attribute %s was found for %s' % (params.attribute, params.layerId))

    col = modelToQuery.get_column_by_property_name(params.attribute)
    colType = str(col.type)
    if colType in ['DATE', 'INTEGER', 'NUMERIC']:
        query = request.db.query(func.max(col).label('max'), func.min(col).label('min'))
        res = query.one()
        return {'values': [res.min, res.max]}
    else:
        query = request.db.query(col).distinct().order_by(col)
        query = query.limit(MAX_ATTR_VALUES)
        for attr in query:
            if len(attr):
                attributesValues.append(attr[0])
        return {'values': sorted(attributesValues)}
예제 #10
0
 def getRandomFeatureId(self, bodId):
     models = models_from_bodid(bodId)
     with self.getSession() as session:
         t = session.query(models[0]).limit(500).subquery('t')
         query = session.query(t).order_by(func.random()).limit(1)
         reslt = query.one()
     return reslt[0]
예제 #11
0
def releases(request):
    params = _get_releases_params(request)
    # For this sevice, we have to use different models based
    # on specially sorted views. We add the _meta part to the given
    # layer name
    # Note that only zeitreihen is currently supported for this service
    models = models_from_bodid(params.layer + '_meta')
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' % params.layer)

    # Default timestamp
    timestamps = []
    minYear = 9999
    for f in _get_features_for_filters(params, [models]):
        if hasattr(f, 'release_year') and f.release_year is not None:
            for x in f.release_year:
                if int(x) < minYear:
                    timestamps.append(str(x))
                    minYear = int(x)

    if len(timestamps) > 0:
        # remove duplicates
        timestamps = list(set(timestamps))
        # add day to have full timestamp
        timestamps = sorted([int(ts + '1231') for ts in timestamps])
        # transform back to string
        timestamps = [str(ts) for ts in timestamps]

    return {'results': timestamps}
예제 #12
0
파일: features.py 프로젝트: fredj/mf-chsdi3
def releases(request):
    params = IdentifyServiceValidation(request, service='releases')
    # For this sevice, we have to use different models based
    # on specially sorted views. We add the _meta part to the given
    # layer name
    # Note that only zeitreihen is currently supported for this service
    # Use scale rather than resolutions for zeitreihen like the other layers
    resolution = get_resolution(params.imageDisplay, params.mapExtent)
    models = models_from_bodid(params.layerId,
                               resolution=resolution,
                               srid=params.srid)
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' %
                                 params.layerId)

    minYear = float('inf')
    # Default timestamp
    timestamps = []
    # group timestamps by bgdi_order
    for f in _get_features_releases(models[0], params):
        if hasattr(f, 'array_release_years') and f.array_release_years is not None and \
                hasattr(f, 'bgdi_order') and f.bgdi_order is not None:
            # Here we use some kind of filtering technique
            # to avoid returning too many results (used in service-print only)
            for y in f.array_release_years:
                if y < minYear:
                    timestamps.append(y)
                    minYear = y

    timestamps = list(set(timestamps))
    # add day to have full timestamp
    timestamps = sorted([int(str(ts) + '1231') for ts in timestamps])
    # transform back to string
    timestamps = [str(ts) for ts in timestamps]
    return {'results': timestamps}
예제 #13
0
def _get_features(params, extended=False):
    ''' Returns exactly one feature or raises
    an excpetion '''
    featureIds = params.featureIds.split(',')
    models = models_from_bodid(params.layerId)
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' %
                                 params.layerId)

    for featureId in featureIds:
        # One layer can have several models
        for model in models:
            query = params.request.db.query(model)
            query = query.filter(model.id == featureId)
            try:
                feature = query.one()
            except (NoResultFound, DataError):
                feature = None
            except MultipleResultsFound:
                raise exc.HTTPInternalServerError(
                    'Multiple features found for the same id %s' % featureId)

            if feature is not None:
                vectorModel = model
                break

        if feature is None:
            raise exc.HTTPNotFound('No feature with id %s' % featureId)
        feature = _process_feature(feature, params)
        feature = {'feature': feature}
        yield feature, vectorModel
예제 #14
0
파일: bod.py 프로젝트: geoadmin/mf-chsdi3
    def layerConfig(self, params):
        config = {}
        translate = params.translate
        settings = params.request.registry.settings
        wmsHost = settings['wmshost']
        defaultResolution = 0.5
        for k in self.__dict__.keys():
            val = self.__dict__[k]
            if not k.startswith("_") and not k.startswith('geojsonUrl') and \
                    val is not None and k not in ('staging', 'srid'):
                if k == 'maps':
                    config['topics'] = val
                elif k == 'layerBodId':
                    config['label'] = translate(val)
                elif k == 'attribution':
                    config[k] = translate(val)
                elif k == 'tilematrix_resolution_max':
                    if val != defaultResolution and \
                            self.__dict__['srid'] != u'4326':
                        config['resolutions'] = self._getResolutionsFromMatrixSet(
                            val, params.srid)
                elif k == 'extent':  # Used for the shop, are still in lv03
                    if val and params.srid == 2056:
                        config['extent'] = shift_to(val, 2056)
                    else:
                        config['extent'] = val
                else:
                    config[k] = val

        if config['type'] in ('wmts', 'aggregate', 'geojson'):
            del config['singleTile']

        if not config['timeEnabled']:
            del config['timeBehaviour']

        if config['type'] == 'wms':
            config['wmsUrl'] = 'https://%s' % wmsHost
        elif config['type'] == 'geojson':
            api_url = params.request.registry.settings['api_url']
            config['styleUrl'] = make_agnostic(
                api_url + '/static/vectorStyles/' + self.layerBodId + '.json')
            config['geojsonUrl'] = self._getGeoJsonUrl(params.lang)
            if 'format' in config:
                del config['format']
        # sublayers don't have attributions
        if 'attribution' in config:
            config['attributionUrl'] = translate(self.__dict__['attribution'] + '.url')

        # adding __queryable_attributes__ if they have them
        models = models_from_bodid(self.layerBodId)
        if models is not None:
            queryable_attributes = get_models_attributes_keys(models, params.lang, True)
            if len(queryable_attributes) > 0:
                config['queryableAttributes'] = queryable_attributes

        return {self.layerBodId: config}
예제 #15
0
def _identify(request):
    params = IdentifyServiceValidation(request)
    response = {'results': []}
    # Determine layer types
    # Grid layers are serverless
    layersDB = []
    layersGrid = []
    isScaleDependent = has_buffer(params.imageDisplay, params.mapExtent, params.tolerance)
    scale = get_scale(params.imageDisplay, params.mapExtent) if isScaleDependent else None
    if params.layers == 'all':
        model = get_bod_model(params.lang)
        query = params.request.db.query(model)
        for layer in get_layers_metadata_for_params(params, query, model):
            layerBodId = layer['layerBodId']
            models = models_from_bodid(layerBodId, scale=scale, srid=params.srid)
            if models:
                layersDB.append({layerBodId: models})
            else:
                gridSpec = get_grid_spec(layerBodId)
                if gridSpec and params.geometryType == 'esriGeometryPoint':
                    layersGrid.append({layerBodId: gridSpec})
    else:
        for layerBodId in params.layers:
            gridSpec = get_grid_spec(layerBodId)
            if gridSpec:
                if params.geometryType not in ('esriGeometryPoint', 'esriGeometryEnvelope'):
                    raise exc.HTTPBadRequest(
                        'Only esriGeometryPoint or esriGeometryEnvelope'
                        'are supported for geometryType parameter for grid like data')
                layersGrid.append({layerBodId: gridSpec})
            else:
                models = models_from_bodid(layerBodId, scale=scale, srid=params.srid)
                # The layer has a model but not at the right scale
                if models is not None and len(models) == 0:
                    return response
                # There is no model for this layer
                elif models is None:
                    raise exc.HTTPBadRequest('No GeoTable was found for %s' % layerBodId)
                layersDB.append({layerBodId: models})
    featuresGrid = _identify_grid(params, layersGrid)
    featuresDB = _identify_db(params, layersDB)
    response['results'] = featuresGrid + featuresDB
    return response
예제 #16
0
def _identify(request):
    params = _get_features_params(request)

    if params.layers == 'all':
        model = get_bod_model(params.lang)
        query = params.request.db.query(model)
        layerIds = []
        for layer in get_layers_metadata_for_params(params, query, model):
            layerIds.append(layer['layerBodId'])
    else:
        layerIds = params.layers

    models = [
        models_from_bodid(layerId) for layerId in layerIds
        if models_from_bodid(layerId) is not None
    ]
    if models is None:
        raise exc.HTTPBadRequest('No GeoTable was found for %s' %
                                 ' '.join(layerIds))

    maxFeatures = 201
    features = []
    feature_gen = _get_features_for_filters(params,
                                            models,
                                            maxFeatures=maxFeatures,
                                            where=params.where)
    while True:
        try:
            feature = next(feature_gen)
        except InternalError as e:
            raise exc.HTTPBadRequest(
                'Your request generated the following database error: %s' % e)
        except StopIteration:
            break
        else:
            f = _process_feature(feature, params)
            features.append(f)

            if len(features) >= maxFeatures:
                break

    return {'results': features}
예제 #17
0
파일: layers.py 프로젝트: fredj/mf-chsdi3
def feature_attributes(request):
    ''' This service is used to expose the
    attributes of vector layers. '''
    params = BaseLayersValidation(request)
    layerId = request.matchdict.get('layerId')
    models = models_from_bodid(layerId, srid=params.srid)
    # Models for the same layer have the same attributes
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' % layerId)

    # Take into account all models and remove duplicated keys
    attributes = get_models_attributes_keys(models, params.lang, False)
    trackAttributesNames = []
    fields = []

    def insert_value_at(field, attrName, value):
        if field['name'] == attrName:
            if len(field['values']) < MAX_ATTRIBUTES_VALUES and \
               value not in field['values']:
                field['values'].append(value)
                field['values'].sort()
        return field

    for model in models:
        query = params.request.db.query(model)
        query = query.limit(SAMPLE_SIZE)

        for rowIndex, row in enumerate(query):
            # attrName as defined in the model
            for attrIndex, attrName in enumerate(attributes):
                featureAttrs = row.get_attributes(exclude_pkey=False)
                if attrName not in trackAttributesNames and \
                   attrName in featureAttrs:
                    fieldType = _find_type(model(), attrName)
                    fields.append({
                        'name':
                        attrName,
                        'type':
                        str(fieldType),
                        'alias':
                        params.translate("%s.%s" % (layerId, attrName)),
                        'values': []
                    })
                    trackAttributesNames.append(attrName)
                if attrName in featureAttrs:
                    for fieldsIndex, field in enumerate(fields):
                        value = featureAttrs[attrName]
                        if isinstance(value, (decimal.Decimal, datetime.date,
                                              datetime.datetime)):
                            value = str(value)
                        fields[fieldsIndex] = insert_value_at(
                            field, attrName, value)

    return {'id': layerId, 'name': params.translate(layerId), 'fields': fields}
예제 #18
0
def _identify(request):
    params = _get_features_params(request)

    if params.layers == 'all':
        model = get_bod_model(params.lang)
        query = params.request.db.query(model)
        layerIds = []
        for layer in get_layers_metadata_for_params(params, query, model):
            layerIds.append(layer['layerBodId'])
    else:
        layerIds = params.layers

    models = [
        models_from_bodid(layerId) for
        layerId in layerIds
        if models_from_bodid(layerId) is not None
    ]
    if models is None:
        raise exc.HTTPBadRequest('No GeoTable was found for %s' % ' '.join(layerIds))

    maxFeatures = 201
    features = []
    feature_gen = _get_features_for_filters(params, models, maxFeatures=maxFeatures, where=params.where)
    while True:
        try:
            feature = next(feature_gen)
        except InternalError as e:
            raise exc.HTTPBadRequest('Your request generated the following database error: %s' % e)
        except StopIteration:
            break
        else:
            f = _process_feature(feature, params)
            features.append(f)

            if len(features) >= maxFeatures:
                break

    return {'results': features}
예제 #19
0
 def ilayersWithFeatures(self):
     for layer in self.ilayers(queryable=True):
         models = models_from_bodid(layer)
         assert (models is not None and len(models) > 0), layer
         model = models[0]
         query = self.session.query(model.primary_key_column())
         # Depending on db size, random row is slow
         if self.randomFeatures:
             query = query.order_by(func.random())
         if isinstance(self.nrOfFeatures, (int, long)):
             query = query.limit(self.nrOfFeatures)
         hasExtended = model.__extended_info__ if hasattr(model, '__extended_info__') else False
         for q in query:
             yield (layer, str(q[0]), hasExtended)
예제 #20
0
 def ilayersWithFeatures(self):
     for layer in self.ilayers(queryable=True):
         models = models_from_bodid(layer)
         assert (models is not None and len(models) > 0), layer
         model = models[0]
         query = self.session.query(model.primary_key_column())
         # Depending on db size, random row is slow
         if self.randomFeatures:
             query = query.order_by(func.random())
         if isinstance(self.nrOfFeatures, (int, long)):
             query = query.limit(self.nrOfFeatures)
         hasExtended = model.__extended_info__ if hasattr(
             model, '__extended_info__') else False
         for q in query:
             yield (layer, str(q[0]), hasExtended)
예제 #21
0
 def ilayersAllModels(self):
     for layer in self.ilayers(tooltip=True, geojson=False):
         gridSpec = get_grid_spec(layer)
         if gridSpec is None and layer not in self.emptyGeoTables:
             models = models_from_bodid(layer)
             assert (models is not None and len(models) > 0), layer
             for model in models:
                 primaryKeyColumn = model.primary_key_column()
                 with self.getSession() as session:
                     query = session.query(primaryKeyColumn)
                     query = query.limit(1)
                     try:
                         featureId = query.one()[0]
                     except NoResultFound:
                         featureId = None
                 yield layer, featureId, model, primaryKeyColumn
예제 #22
0
 def ilayersAllModels(self):
     for layer in self.ilayers(tooltip=True, geojson=False):
         gridSpec = get_grid_spec(layer)
         if gridSpec is None and layer not in self.emptyGeoTables:
             models = models_from_bodid(layer)
             assert (models is not None and len(models) > 0), layer
             for model in models:
                 primaryKeyColumn = model.primary_key_column()
                 with self.getSession() as session:
                     query = session.query(primaryKeyColumn)
                     query = query.limit(1)
                     try:
                         featureId = query.one()[0]
                     except NoResultFound:
                         featureId = None
                 yield layer, featureId, model, primaryKeyColumn
예제 #23
0
    def layerConfig(self, params):
        config = {}
        translate = params.translate
        wmsHost = params.request.registry.settings['wmshost']
        for k in self.__dict__.keys():
            val = self.__dict__[k]
            if not k.startswith("_") and not k.startswith('geojsonUrl') and \
                    val is not None and k not in ('staging', 'srid'):
                if k == 'maps':
                    config['topics'] = val
                elif k == 'layerBodId':
                    config['label'] = translate(val)
                elif k == 'attribution':
                    config[k] = translate(val)
                elif k == 'matrixSet':
                    if val != self.defaultMatrixSet21781 and \
                            self.__dict__['srid'] != '4326':
                        config['resolutions'] = self._getResolutionsFromMatrixSet(
                            val)
                else:
                    config[k] = val

        layerStaging = self.__dict__['staging']
        if config['type'] in ('wmts', 'aggregate', 'geojson'):
            del config['singleTile']

        if config['type'] == 'wms':
            if layerStaging != 'prod':
                config['wmsUrl'] = make_agnostic(
                    config['wmsUrl'].replace('wms.geo.admin.ch', wmsHost))
        elif config['type'] == 'geojson':
            api_url = params.request.registry.settings['api_url']
            config['styleUrl'] = make_agnostic(
                api_url + '/static/vectorStyles/' + self.layerBodId + '.json')
            config['geojsonUrl'] = self._getGeoJsonUrl(params.lang)
        # sublayers don't have attributions
        if 'attribution' in config:
            config['attributionUrl'] = translate(self.__dict__['attribution'] + '.url')

        # adding __queryable_attributes__ if they have them
        models = models_from_bodid(self.layerBodId)
        if models is not None:
            queryable_attributes = get_models_attributes_keys(models, params.lang, True)
            if len(queryable_attributes) > 0:
                config['queryableAttributes'] = queryable_attributes

        return {self.layerBodId: config}
예제 #24
0
def feature_attributes(request):
    ''' This service is used to expose the
    attributes of vector layers. '''
    params = BaseLayersValidation(request)
    layerId = request.matchdict.get('layerId')
    models = models_from_bodid(layerId, srid=params.srid)
    # Models for the same layer have the same attributes
    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' % layerId)

    # Take into account all models and remove duplicated keys
    attributes = get_models_attributes_keys(models, params.lang, False)
    trackAttributesNames = []
    fields = []

    def insert_value_at(field, attrName, value):
        if field['name'] == attrName:
            if len(field['values']) < MAX_ATTRIBUTES_VALUES and \
               value not in field['values']:
                field['values'].append(value)
                field['values'].sort()
        return field

    for model in models:
        query = params.request.db.query(model)
        query = query.limit(SAMPLE_SIZE)

        for rowIndex, row in enumerate(query):
            # attrName as defined in the model
            for attrIndex, attrName in enumerate(attributes):
                featureAttrs = row.get_attributes(exclude_pkey=False)
                if attrName not in trackAttributesNames and \
                   attrName in featureAttrs:
                    fieldType = _find_type(model(), attrName)
                    fields.append({'name': attrName, 'type': str(fieldType),
                                   'alias': params.translate("%s.%s" % (layerId, attrName)),
                                   'values': []
                                   })
                    trackAttributesNames.append(attrName)
                if attrName in featureAttrs:
                    for fieldsIndex, field in enumerate(fields):
                        value = featureAttrs[attrName]
                        if isinstance(value, (decimal.Decimal, datetime.date, datetime.datetime)):
                            value = str(value)
                        fields[fieldsIndex] = insert_value_at(field, attrName, value)

    return {'id': layerId, 'name': params.translate(layerId), 'fields': fields}
예제 #25
0
 def ilayersWithFeatures(self):
     for layer in self.ilayers(tooltip=True, geojson=False):
         gridSpec = get_grid_spec(layer)
         if gridSpec is None and layer not in self.emptyGeoTables:
             models = models_from_bodid(layer)
             assert (models is not None and len(models) > 0), layer
             model = models[0]
             with self.getSession() as session:
                 query = session.query(model.primary_key_column())
                 # Depending on db size, random row is slow
                 if self.randomFeatures:
                     query = query.order_by(func.random())
                 if isinstance(self.nrOfFeatures, (int, long)):
                     query = query.limit(self.nrOfFeatures)
                 hasExtended = model.__extended_info__ if hasattr(model, '__extended_info__') else False
                 for q in query:
                     yield (layer, str(q[0]), hasExtended)
예제 #26
0
 def ilayersWithFeatures(self):
     for layer in self.ilayers(tooltip=True, geojson=False):
         gridSpec = get_grid_spec(layer)
         if gridSpec is None and layer not in self.emptyGeoTables:
             models = models_from_bodid(layer)
             assert (models is not None and len(models) > 0), layer
             model = models[0]
             with self.getSession() as session:
                 query = session.query(model.primary_key_column())
                 # Depending on db size, random row is slow
                 if self.randomFeatures:
                     query = query.order_by(func.random())
                 if isinstance(self.nrOfFeatures, (int, long)):
                     query = query.limit(self.nrOfFeatures)
                 hasExtended = model.__extended_info__ if hasattr(
                     model, '__extended_info__') else False
                 for q in query:
                     yield (layer, str(q[0]), hasExtended)
예제 #27
0
    def checkSearch(self, layer):
        models = models_from_bodid(layer)
        assert (models is not None and len(models) > 0), layer
        model = models[0]
        expectedStatus = 200
        # Special treatment for non-distributed sphinx indices (single model)
        if len(models) == 1:
            query = self.session.query(model.primary_key_column())
            # we expect 404 errors for searchable layers without any data (no sphinx index)
            if query.first() is None:
                expectedStatus = 404

        # If it fails here, it most probably means given layer does not have sphinx index available
        link = '/rest/services/all/SearchServer?features=' + layer + '&bbox=600818.7808825106,197290.49919797093,601161.2808825106,197587.99919797093&type=featuresearch&searchText=dummy'
        resp = self.testapp.get(link, status=expectedStatus)
        # If there are no features, we don't expect a sphinx index present
        if expectedStatus == 404:
            assert 'unknown local index' in resp.body
예제 #28
0
    def checkSearch(self, layer):
        models = models_from_bodid(layer)
        assert (models is not None and len(models) > 0), layer
        model = models[0]
        expectedStatus = 200
        # Special treatment for non-distributed sphinx indices (single model)
        if len(models) == 1:
            query = self.session.query(model.primary_key_column())
            # we expect 404 errors for searchable layers without any data (no sphinx index)
            if query.first() is None:
                expectedStatus = 404

        # If it fails here, it most probably means given layer does not have sphinx index available
        link = '/rest/services/all/SearchServer?features=' + layer + '&bbox=600818.7808825106,197290.49919797093,601161.2808825106,197587.99919797093&type=featuresearch&searchText=dummy'
        resp = self.testapp.get(link, status=expectedStatus)
        # If there are no features, we don't expect a sphinx index present
        if expectedStatus == 404:
            assert 'unknown local index' in resp.body
예제 #29
0
def _attributes(request):
    ''' This service exposes preview values based on a layer Id
    and an attribute name (mapped in the model) '''
    MAX_ATTR_VALUES = 50
    attributesValues = []
    params = _get_attributes_params(request)

    models = models_from_bodid(params.layerId)

    if models is None:
        raise exc.HTTPBadRequest('No Vector Table was found for %s' %
                                 params.layerId)

    # Check that the attribute provided is found at least in one model
    modelToQuery = None
    for model in models:
        attributes = model().getAttributesKeys()
        if params.attribute in attributes:
            modelToQuery = model
            break
    if modelToQuery is None:
        raise exc.HTTPBadRequest('No attribute %s was found for %s' %
                                 (params.attribute, params.layerId))

    col = modelToQuery.get_column_by_property_name(params.attribute)
    colType = str(col.type)
    if colType in ['DATE', 'INTEGER', 'NUMERIC']:
        query = request.db.query(
            func.max(col).label('max'),
            func.min(col).label('min'))
        res = query.one()
        return {'values': [res.min, res.max]}
    else:
        query = request.db.query(col).distinct().order_by(col)
        query = query.limit(MAX_ATTR_VALUES)
        for attr in query:
            if len(attr):
                attributesValues.append(attr[0])
        return {'values': sorted(attributesValues)}