def get(self, request, **kwargs):

        # try to use qprof api
        # ====================

        # try to load layer
        try:
            epp = EleProDTM.objects.get(pk=kwargs['eleprodtm_pk'])
            layer = epp.layers.filter(qgs_layer_id=kwargs['qgs_layer_id'])[0]
            dem = epp.dtm_layer
        except KeyError:
            # Case qgs_layer_id not submit
            raise APIException('No qgs_layer_id parameter into url')
        except ObjectDoesNotExist as e:
            raise APIException('DTM project object not found into DB')
        except IndexError as e:
            raise APIException('Layer not set into a profile project')

        # try to get qgis_layer
        qgis_project = get_qgs_project(dem.project.qgis_file.path)
        qgis_dem = get_qgis_layer(dem)
        qgis_layer = get_qgis_layer(layer)

        # get single feature
        feature = qgis_layer.getFeature(kwargs['fid'])
        geom = feature.geometry()
        if not geom:
            raise APIException('Fid not found into layer')

        if geom.isMultipart():
            line = multipolyline_to_xytuple_list2(
                geom.asMultiPolyline())  # typedef QVector<QgsPolyline>
            # now it's a list of list of (x,y) tuples
            path_line = xytuple_l2_to_MultiLine(line).to_line()

        else:
            line = polyline_to_xytuple_list(
                geom.asPolyline())  # typedef QVector<QgsPointXY>
            path_line = xytuple_list_to_Line(line)

        multi_path_line = MultiLine([path_line
                                     ]).to_line().remove_coincident_points()

        # line resampled by sample distance
        resampled_line = multi_path_line.densify_2d_line(epp.dtm_delta)

        if qgis_layer.crs() != qgis_project.crs():
            resampled_line = resampled_line.crs_project(
                qgis_layer.crs(), qgis_project.crs())

        profile = topoline_from_dem(
            resampled_line, True, qgis_project.crs(), qgis_dem,
            QGisRasterParameters(*raster_qgis_params(qgis_dem)), epp.dtm_delta)

        self.results.update({'profile': profile})

        return Response(self.results.results)
Example #2
0
    def get(self, request, **kwargs):

        qplotly = QplotlyWidget.objects.get(pk=kwargs['pk'])

        # load settings from db
        settings = QplotlySettings()
        if not settings.read_from_model(qplotly):
            #todo: raise a API exception
            raise Exception()

        # get bbox if is sent
        rect = None
        if 'bbox' in kwargs:
            rect = QgsReferencedRectangle(
                QgsRectangle(**kwargs['bbox']),
                QgsCoordinateReferenceSystem(qplotly.project.group.srid.srid))

        # instace q QplotlyFactory
        factory = QplotlyFactoring(settings, visible_region=rect)

        # is possibile get the first layer
        factory.source_layer = get_qgis_layer(
            qplotly.layers.get(qgs_layer_id=settings.source_layer_id,
                               project_id=kwargs['project_id']))
        factory.rebuild()

        res = {'data': factory.trace}

        self.results.results.update(res)

        return Response(self.results.results)
Example #3
0
    def testGetQgisFeaturesAttributeFilters(self):
        """Test QGIS API attribute filters"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        features = get_qgis_features(qgis_layer,
                                     attribute_filters={'name': 'a point'})
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 1)

        features = get_qgis_features(
            qgis_layer, attribute_filters={'name': 'another point'})
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 2)

        features = get_qgis_features(qgis_layer,
                                     attribute_filters={
                                         'name': 'another point',
                                         'pkuid': 2
                                     })
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 2)

        features = get_qgis_features(qgis_layer,
                                     attribute_filters={
                                         'name': 'another point',
                                         'pkuid': 9999
                                     })
        self.assertEqual(len(features), 0)

        features = get_qgis_features(
            qgis_layer, attribute_filters={'name': 'not_existent'})
        self.assertEqual(len(features), 0)
Example #4
0
    def get_constraint_geometry(self):
        """Returns the geometry from the constraint layer and rule

        :return: the constraint geometry and the number of matched records
        :rtype: tuple( MultiPolygon, integer)
        """

        constraint_layer = get_qgis_layer(self.constraint.constraint_layer)
        layer = get_qgis_layer(self.constraint.layer)

        # Get the geometries from constraint layer and rule
        qgis_feature_request = QgsFeatureRequest()
        qgis_feature_request.setFilterExpression(self.rule)

        features = get_qgis_features(constraint_layer,
                                     qgis_feature_request,
                                     exclude_fields='__all__')

        if not features:
            return '', 0

        geometry = QgsMultiPolygon()

        for feature in features:
            geom = feature.geometry()
            if geom.isMultipart():
                geom = [g for g in geom.constGet()]
            else:
                geom = [geom.constGet()]

            i = 0
            for g in geom:
                geometry.insertGeometry(g.clone(), 0)
                i += 1

        # Now, transform into a GEOS geometry
        if constraint_layer.crs() != layer.crs():
            ct = QgsCoordinateTransform(
                QgsCoordinateReferenceSystem(constraint_layer.crs()),
                QgsCoordinateReferenceSystem(layer.crs()),
                QgsCoordinateTransformContext())
            geometry.transform(ct)

        constraint_geometry = MultiPolygon.from_ewkt(
            'SRID=%s;' % layer.crs().postgisSrid() + geometry.asWkt())

        return constraint_geometry, constraint_geometry.num_geom
Example #5
0
    def get(self, request, **kwargs):

        qplotly = QplotlyWidget.objects.get(pk=kwargs['pk'])

        # load settings from db
        settings = QplotlySettings()
        if not settings.read_from_model(qplotly):
            raise Exception()

        # patch for xml setting linked to layer with same datasource.
        qgs_layer_id = kwargs[
            'qgs_layer_id'] if 'qgs_layer_id' in kwargs else settings.source_layer_id

        # get bbox if is sent
        # 2021/01/12 using IntersectBBOXFilter
        rect = None
        #if 'bbox' in kwargs:
        #    rect = QgsReferencedRectangle(QgsRectangle(**kwargs['bbox']),
        #                                  QgsCoordinateReferenceSystem(qplotly.project.group.srid.srid))

        # instance a QplotlyFactory
        layer = Layer.objects.get(qgs_layer_id=qgs_layer_id,
                                  project_id=kwargs['project_id'])
        factory = QplotlyFactoring(settings,
                                   visible_region=rect,
                                   request=request,
                                   layer=layer)

        # is possible get the first layer
        factory.source_layer = get_qgis_layer(
            qplotly.layers.get(qgs_layer_id=settings.source_layer_id,
                               project_id=kwargs['project_id']))
        factory.rebuild()

        res = {'data': factory.trace}

        # if withrelations was sent add relations trace values
        # ----------------------------------------------------
        if request.method == 'POST':
            request_data = request.data
        else:
            request_data = request.query_params

        with_relations = request_data.get(WITH_RELATIONS_PARAM)
        if with_relations:
            self._get_relations(
                with_relations=with_relations.split(','),
                flayer=layer,
                ffactory=factory,
                request=request,
                res=res,
            )

        self.results.results.update(res)

        return Response(self.results.results)
Example #6
0
    def set_metadata_relations(self, request, **kwargs):

        # init relations
        self.set_relations()

        # Determine if we are using an old and bugged version of QGIS
        IS_QGIS_3_10 = Qgis.QGIS_VERSION.startswith('3.10')

        for idr, relation in list(self.relations.items()):

            # check if in relation there is referencedLayer == self layer
            if relation['referencedLayer'] == self.layer.qgs_layer_id:
                # get relation layer object
                relation_layer = self._layer_model.objects.get(
                    qgs_layer_id=relation['referencingLayer'],
                    project=self.layer.project)

                # qgis_layer is the referenced layer
                qgis_layer = self.layer.qgis_layer
                referenced_field_is_pk = [
                    qgis_layer.fields().indexFromName(
                        relation['fieldRef']['referencedField'])
                ] == qgis_layer.primaryKeyAttributes()

                # It's an old and buggy QGIS version so we cannot trust primaryKeyAttributes() and we go guessing
                if IS_QGIS_3_10:
                    field_index = qgis_layer.fields().indexFromName(
                        relation['fieldRef']['referencedField'])
                    # Safety check
                    if field_index >= 0:
                        field = qgis_layer.fields()[field_index]
                        default_clause = qgis_layer.dataProvider(
                        ).defaultValueClause(field_index)
                        constraints = qgis_layer.fieldConstraints(field_index)
                        not_null = bool(constraints & QgsFieldConstraints.ConstraintNotNull) and \
                            field.constraints().constraintStrength(
                            QgsFieldConstraints.ConstraintNotNull) == QgsFieldConstraints.ConstraintStrengthHard
                        unique = bool(constraints & QgsFieldConstraints.ConstraintUnique) and \
                            field.constraints().constraintStrength(
                            QgsFieldConstraints.ConstraintUnique) == QgsFieldConstraints.ConstraintStrengthHard
                        referenced_field_is_pk = unique and default_clause and not_null

                self.metadata_relations[
                    relation['referencingLayer']] = MetadataVectorLayer(
                        get_qgis_layer(relation_layer),
                        relation_layer.origname,
                        idr,
                        layer=relation_layer,
                        referencing_field=relation['fieldRef']
                        ['referencingField'],
                        layer_id=relation_layer.pk,
                        referenced_field_is_pk=referenced_field_is_pk)
Example #7
0
    def layer_is_empty(self, layer):
        """
        Check if a vector layer is empty (not data)

        :param layer: qdjango Layer model instance
        :return: True or False
        :rtype: boolean
        """

        qgis_layer = get_qgis_layer(layer)
        if qgis_layer.type() == QgsMapLayer.VectorLayer:
            return not bool(count_qgis_features(qgis_layer))
        else:
            return False
Example #8
0
    def testGetQgisFeaturesExcludeFields(self):
        """Test QGIS API get_qgis_features with exclude fields filter"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        features = get_qgis_features(qgis_layer, exclude_fields=['pkuid'])
        self.assertEqual(len(features), 2)
        self.assertIsNone(features[0].attribute('pkuid'))
        self.assertIsNotNone(features[0].attribute('name'))

        features = get_qgis_features(qgis_layer, exclude_fields=['name'])
        self.assertEqual(len(features), 2)
        self.assertIsNotNone(features[0].attribute('pkuid'))
        self.assertIsNone(features[0].attribute('name'))
Example #9
0
    def testGetQgisFeaturesAll(self):
        """Test QGIS API get_qgis_features with all features"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        # Test get all features
        features = get_qgis_features(qgis_layer)
        self.assertEqual(len(features), qgis_layer.featureCount())
        # Check has geometry
        self.assertFalse(features[0].geometry().isNull())

        # Get all features, no geometry
        features = get_qgis_features(qgis_layer, with_geometry=False)
        self.assertEqual(len(features), qgis_layer.featureCount())
        # Check has geometry
        self.assertTrue(features[0].geometry().isNull())
Example #10
0
    def set_metadata_layer(self, request, **kwargs):
        """Set the metadata layer to a QgsVectorLayer instance

        returns a dictionary with layer information and the QGIS layer instance
        """

        self.layer = self.get_layer_by_params(kwargs)

        # set layer_name
        self.layer_name = self.layer.origname

        qgis_layer = get_qgis_layer(self.layer)

        # create model and add to editing_layers
        self.metadata_layer = MetadataVectorLayer(qgis_layer,
                                                  self.layer.origname,
                                                  layer_id=self.layer.pk)
Example #11
0
    def testGetQgisFeaturesBbox(self):
        """Test QGIS API get_qgis_features with BBOX filter"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        features = get_qgis_features(qgis_layer,
                                     bbox_filter=qgis_layer.extent())
        self.assertEqual(len(features), 2)

        bbox = QgsRectangle(qgis_layer.extent().xMinimum(),
                            qgis_layer.extent().yMinimum(),
                            qgis_layer.extent().xMinimum() + 1,
                            qgis_layer.extent().yMinimum() + 1)

        features = get_qgis_features(qgis_layer, bbox_filter=bbox)
        self.assertEqual(len(features), 1)
Example #12
0
    def get(self, request, project_id, qgs_layer_id, **kwargs):

        try:
            layer = Layer.objects.get(project_id=project_id,
                                      qgs_layer_id=qgs_layer_id)

            rts = RTS(get_qgis_layer(layer))

            # Check if is valid
            if not rts.isValid():
                self.results.result = False
                self.results.error = f'{qgs_layer_id} is not a instance of QgsRasterLayer'
                return Response(self.results.results)

            # Check if layer raster time series is activated
            if not QRasterTimeSeriesLayer.is_activated(layer):
                self.results.result = False
                self.results.error = f'{qgs_layer_id} is not activated for time series'
                return Response(self.results.results)

            # translate Qdate to python date
            pydate = []
            for d in rts.dates():
                pydate.append(d.toPyDate())

            self.results.results.update({
                'dates':
                pydate,
                'names':
                rts.bands(),
                'wavelength':
                rts.wavelength(),
                'numberofbands':
                rts.numberOfBands(),
                'numberofobservations':
                rts.numberOfObservations()
            })

        except Exception as e:
            logger.error(f'[QRTSeries] {e}')
            self.results.result = False
            self.results.error = str(e)

        return Response(self.results.results)
Example #13
0
    def testGetQgisFeaturesSearch(self):
        """Test QGIS API get_qgis_features with search filter"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        features = get_qgis_features(qgis_layer, search_filter='1')
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 1)

        features = get_qgis_features(qgis_layer, search_filter='another')
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 2)

        features = get_qgis_features(qgis_layer, search_filter='point')
        self.assertEqual(len(features), 2)

        # not existent
        features = get_qgis_features(qgis_layer, search_filter='not_exists')
        self.assertEqual(len(features), 0)
Example #14
0
    def testGetQgisFeaturesCombinedFilters(self):
        """Test QGIS API attribute combined filters"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        features = get_qgis_features(qgis_layer, attribute_filters={
            'name': 'a point'
        }, search_filter='not_existent')
        self.assertEqual(len(features), 0)

        features = get_qgis_features(qgis_layer, attribute_filters={
            'name': 'another point'
        }, search_filter='1')
        self.assertEqual(len(features), 0)

        features = get_qgis_features(qgis_layer, attribute_filters={
            'name': 'another point'
        }, search_filter='2')
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 2)
Example #15
0
    def testGetQgisFeaturesExtraSubsetString(self):
        """Test QGIS API get_qgis_features with subset string filter"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        features = get_qgis_features(qgis_layer)
        self.assertEqual(len(features), 2)

        features = get_qgis_features(
            qgis_layer, extra_subset_string='name != \'another point\'')
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0]['name'], 'a point')

        # Check if restored
        features = get_qgis_features(qgis_layer)
        self.assertEqual(len(features), 2)

        features = get_qgis_features(
            qgis_layer, extra_subset_string='name == \'another point\'')
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0]['name'], 'another point')

        # Check if original subset string is ANDed
        qgis_layer_clone = qgis_layer.clone()
        qgis_layer_clone.setSubsetString('name == \'another point\'')
        features = get_qgis_features(qgis_layer_clone)
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0]['name'], 'another point')

        features = get_qgis_features(
            qgis_layer_clone, extra_subset_string='name != \'another point\'')
        self.assertEqual(len(features), 0)

        # Check if restored
        qgis_layer_clone.setSubsetString('name == \'another point\'')
        features = get_qgis_features(qgis_layer_clone)
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0]['name'], 'another point')
Example #16
0
    def form_valid(self, form):
        if form.cleaned_data['active']:
            if not self.activated:
                self.activated = QRasterTimeSeriesLayer.objects.create(layer=self.layer)
            else:
                self.activated.save()

            # Add start date and end date
            rts = RTS(get_qgis_layer(self.layer))
            dates = rts.dates()
            start_date = dates[0].toPyDate()
            end_date = dates[-1].toPyDate()

            self.activated.start_date = start_date
            self.activated.end_date = end_date
            self.activated.save()

        else:
            if self.activated:
                self.activated.delete()

        return super().form_valid(form)
Example #17
0
    def testGetQgisFeaturesPagination(self):
        """Test QGIS API get_qgis_features with pagination"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        # Test get first page
        features = get_qgis_features(qgis_layer, page=1, page_size=1)
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 1)

        # second page
        features = get_qgis_features(qgis_layer, page=1, page_size=1)
        self.assertEqual(len(features), 1)
        self.assertTrue(features[0].id(), 2)

        # out of range offset
        features = get_qgis_features(qgis_layer, page=100, page_size=1)
        self.assertEqual(len(features), 0)

        # out of range feature_count
        features = get_qgis_features(qgis_layer, page_size=1000)
        self.assertEqual(len(features), 2)
Example #18
0
    def set_metadata_layer(self, request, **kwargs):
        """Set the metadata layer to a QgsRasterLayer instance

        returns a dictionary with layer information and the QGIS layer instance
        """

        self.layer = self._layer_model.objects.get(project_id=kwargs['project_id'], qgs_layer_id=kwargs['layer_name'])

        # set layer_name
        self.layer_name = self.layer.origname

        qgis_layer = get_qgis_layer(self.layer)

        # Only raster layer
        if qgis_layer.type() != QgsMapLayerType.RasterLayer:
            raise APIException(f"Layer with id {self.layer.qgs_layer_id}: is not a raster layer")

        # create model and add to editing_layers
        self.metadata_layer = MetadataRasterLayer(
            qgis_layer,
            self.layer.origname,
            layer_id=self.layer.pk
        )
Example #19
0
    def testGetQgisFeaturesOrdering(self):
        """Test QGIS API get_qgis_features with ordering"""

        qgis_layer = get_qgis_layer(self.layer)
        self.assertTrue(qgis_layer.isValid())

        # Test get first page
        features = get_qgis_features(qgis_layer, ordering='name')
        self.assertEqual(len(features), 2)
        self.assertTrue(features[0].id(), 1)

        # second page
        features = get_qgis_features(qgis_layer, ordering='name')
        self.assertEqual(len(features), 2)
        self.assertTrue(features[0].id(), 2)

        # Test get first page
        features = get_qgis_features(qgis_layer, ordering='-name')
        self.assertEqual(len(features), 2)
        self.assertTrue(features[0].id(), 2)

        # not existent field (ignored)
        features = get_qgis_features(qgis_layer, ordering='not_exists')
        self.assertEqual(len(features), 2)
Example #20
0
    def to_representation(self, instance):
        ret = super(WidgetSerializer, self).to_representation(instance)
        ret['type'] = instance.widget_type

        # get edittype
        edittypes = eval(self.layer.edittypes)

        if ret['type'] == 'search':
            body = json.loads(instance.body)
            ret['options'] = {
                'queryurl': None,
                'title': body['title'],
                'results': body['results'],
                'filter': [],
                'dozoomtoextent': body['dozoomtoextent'],
                #'zoom': body['zoom'],
            }
            for field in body['fields']:

                # if widgettype is selectbox, get values
                if 'widgettype' in field and field['widgettype'] == 'selectbox':

                    qgis_layer = get_qgis_layer(self.layer)

                    uniques = qgis_layer.uniqueValues(
                        qgis_layer.fields().indexOf(field['name']))
                    values = []
                    for u in uniques:
                        try:
                            values.append(
                                json.loads(QgsJsonUtils.encodeValue(u)))
                        except Exception as e:
                            logger.error(f'Response vector widget unique: {e}')
                            continue

                    field['input']['type'] = 'selectfield'
                    if 'dependance' not in field['input']['options']:

                        # check if field has a widget edit type
                        # todo: add 'ValueRelation' case
                        if field['name'] in edittypes and \
                                edittypes[field['name']]['widgetv2type'] in ('ValueMap'):
                            field['input']['options']['values'] = edittypes[
                                field['name']]['values']
                        else:
                            field['input']['options']['values'] = values
                    else:
                        field['input']['options']['values'] = []

                #For AutoccOmpleteBox imput type
                if 'widgettype' in field and field[
                        'widgettype'] == 'autocompletebox':
                    field['input']['type'] = 'autocompletefield'

                input = field['input']
                input['options']['blanktext'] = field['blanktext']
                ret['options']['filter'].append({
                    'op':
                    field['filterop'],
                    'attribute':
                    field['name'],
                    'label':
                    field['label'],
                    'input':
                    input,
                    'logicop':
                    field.get('logicop', 'AND').upper()
                })
        else:
            ret['body'] = json.loads(instance.body)
        return ret
Example #21
0
    def _add_extrafields(self, request, filepath, filename):
        """
        Add extra fields to layer properties if sbp parameters are in http query parameters.
        """

        # check for fields data in GET OR POST
        if request.method == 'POST':
            request_data = request.data
        else:
            request_data = request.query_params

        if 'sbp_qgs_layer_id' in request_data and 'sbp_fid' in request_data:

            try:
                vlayer = QgsVectorLayer(filepath+'.shp', filename, "ogr")

                if not vlayer:
                    raise Exception(f'Failed to load layer {filepath}')

                # Try to add the layer feature of SearchByPolygon widget
                sbp_layer = get_qgis_layer(
                    self.layer.project.layer_set.filter(qgs_layer_id=request_data['sbp_qgs_layer_id'])[0])
                sbp_feature = sbp_layer.getFeature(
                    int(request_data['sbp_fid']))

                original_attributes_count = len(vlayer.fields())

                assert vlayer.startEditing()

                # Add prefix to field name to avoid repeated names
                # Use 'p' as polygon
                prefix = 'p_'
                for f in sbp_feature.fields():

                    f.setName(prefix + f.name())
                    vlayer.addAttribute(f)

                # Save attributes
                if not vlayer.commitChanges():

                    # OGR returns an error if fields were renamed (for example when they are too long)
                    # ignore the error in that case
                    if 'ERROR: field with index' in str(vlayer.commitErrors()):
                        vlayer.commitChanges()
                    else:
                        err_msg = f'Commit error for layer {filepath}'
                        # Check for commit errors
                        errs = vlayer.commitErrors()
                        if len(errs) > 0:
                            errs_msg = ', '.join(errs)
                            err_msg = err_msg + f': {errs_msg}'

                        raise Exception(err_msg)

                # Now add new attribute values
                assert vlayer.startEditing()

                # Add values to new fields
                features = [f for f in vlayer.getFeatures()]
                for feature in features:
                    added_fields = {}
                    field_index = original_attributes_count
                    for f in sbp_feature.fields():
                        added_fields.update(
                            {field_index: sbp_feature[f.name()]})
                        field_index += 1
                    vlayer.changeAttributeValues(feature.id(), added_fields)

                # Commit new fields and exit from editing
                if not vlayer.commitChanges():

                    err_msg = f'Commit error for layer {filepath}'
                    # Check for commit errors
                    errs = vlayer.commitErrors()
                    if len(errs) > 0:
                        errs_msg = ', '.join(errs)
                        err_msg = err_msg + f': {errs_msg}'

            except Exception as e:
                logger.error(e)