Ejemplo n.º 1
0
    def testExpressionContext(self):
        req = QgsFeatureRequest()
        self.assertEqual(req.expressionContext().scopeCount(), 0)

        context = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        scope.setVariable('a', 6)
        context.appendScope(scope)
        req.setExpressionContext(context)

        self.assertEqual(req.expressionContext().scopeCount(), 1)
        self.assertEqual(req.expressionContext().variable('a'), 6)
Ejemplo n.º 2
0
    def testAssignment(self):
        req = QgsFeatureRequest().setFilterFids([8, 9]).setFilterRect(
            QgsRectangle(1, 2, 3, 4)).setInvalidGeometryCheck(
                QgsFeatureRequest.GeometrySkipInvalid).setLimit(6).setFlags(
                    QgsFeatureRequest.ExactIntersect).setSubsetOfAttributes(
                        [1, 4]).setTimeout(6).setRequestMayBeNested(True)

        context = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        scope.setVariable('a', 6)
        context.appendScope(scope)
        req.setExpressionContext(context)
        method = QgsSimplifyMethod()
        method.setMethodType(QgsSimplifyMethod.PreserveTopology)
        req.setSimplifyMethod(method)
        context = QgsCoordinateTransformContext()
        req.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'),
                              context)

        req2 = QgsFeatureRequest(req)
        self.assertEqual(req2.limit(), 6)
        self.assertCountEqual(req2.filterFids(), [8, 9])
        self.assertEqual(req2.filterRect(), QgsRectangle(1, 2, 3, 4))
        self.assertEqual(req2.spatialFilterType(),
                         Qgis.SpatialFilterType.BoundingBox)
        self.assertEqual(req2.invalidGeometryCheck(),
                         QgsFeatureRequest.GeometrySkipInvalid)
        self.assertEqual(req2.expressionContext().scopeCount(), 1)
        self.assertEqual(req2.expressionContext().variable('a'), 6)
        self.assertEqual(
            req2.flags(), QgsFeatureRequest.ExactIntersect
            | QgsFeatureRequest.SubsetOfAttributes)
        self.assertEqual(req2.subsetOfAttributes(), [1, 4])
        self.assertEqual(req2.simplifyMethod().methodType(),
                         QgsSimplifyMethod.PreserveTopology)
        self.assertEqual(req2.destinationCrs().authid(), 'EPSG:3857')
        self.assertEqual(req2.timeout(), 6)
        self.assertTrue(req2.requestMayBeNested())

        # copy distance within request
        req = QgsFeatureRequest().setDistanceWithin(
            QgsGeometry.fromWkt('LineString( 0 0, 10 0, 11 2)'), 1.2)
        req2 = QgsFeatureRequest(req)
        self.assertEqual(req2.spatialFilterType(),
                         Qgis.SpatialFilterType.DistanceWithin)
        self.assertEqual(req2.referenceGeometry().asWkt(),
                         'LineString (0 0, 10 0, 11 2)')
        self.assertEqual(req2.distanceWithin(), 1.2)
        self.assertEqual(req2.filterRect(),
                         QgsRectangle(-1.2, -1.2, 12.2, 3.2))
    def doStart(self):
        # first see if we can pull data from the predictions layer
        startTime = self.datetime
        endTime = self.datetime.addDays(1)

        featureRequest = QgsFeatureRequest()
        stationPt = QgsPointXY(self.stationFeature.geometry().vertexAt(0))
        searchRect = QgsRectangle(stationPt, stationPt)
        searchRect.grow(
            0.01 / 60
        )  # in the neighborhood of .01 nm as 1/60 = 1 arc minute in this proj.
        featureRequest.setFilterRect(searchRect)

        # Create a time based query
        ctx = featureRequest.expressionContext()
        scope = QgsExpressionContextScope()
        scope.setVariable('startTime', startTime)
        scope.setVariable('endTime', endTime)
        scope.setVariable('station', self.stationFeature['station'])
        ctx.appendScope(scope)
        featureRequest.setFilterExpression(
            "station = @station and time >= @startTime and time < @endTime")
        featureRequest.addOrderBy('time')

        savedFeatureIterator = self.manager.predictionsLayer.getFeatures(
            featureRequest)
        savedFeatures = list(savedFeatureIterator)
        if len(savedFeatures) > 0:
            # We have some features, so go ahead and stash them in the layer and resolve this promise
            print('{}: retrieved {} features from layer'.format(
                self.stationFeature['station'], len(savedFeatures)))
            self.predictions = savedFeatures
            self.resolve()
        else:
            # The layer didn't have what we wanted, so we must request the data we need.
            # At this point, the situation falls into several possible cases.

            # Case 1: A Harmonic station with known flood/ebb directions. Here
            # we need two requests which can simply be combined and sorted:
            #   1a: EventType, i.e. slack, flood and ebb
            #   1b: SpeedDirType, as velocity can be calculated by projecting along flood/ebb
            #
            # Case 2: A Harmonic station with unknown flood and/or ebb.
            # We actually need to combine 3 requests:
            #   2a: EventType
            #   2b: SpeedDirType, which only provides vector magnitude/angle
            #   2c: VelocityMajorType, which only provides current velocity (but for same times as 2b)

            # Here we set up requests for cases 1 and 2
            if self.stationFeature['type'] == 'H':
                self.speedDirRequest = CurrentPredictionRequest(
                    self.manager, self.stationFeature, startTime, endTime,
                    CurrentPredictionRequest.SpeedDirectionType)
                self.addDependency(self.speedDirRequest)

                self.eventRequest = CurrentPredictionRequest(
                    self.manager, self.stationFeature, startTime, endTime,
                    CurrentPredictionRequest.EventType)
                self.addDependency(self.eventRequest)

                floodDir = self.stationFeature['meanFloodDir']
                ebbDir = self.stationFeature['meanEbbDir']
                if floodDir == NULL or ebbDir == NULL:
                    self.velocityRequest = CurrentPredictionRequest(
                        self.manager, self.stationFeature, startTime, endTime,
                        CurrentPredictionRequest.VelocityMajorType)
                    self.addDependency(self.velocityRequest)
                else:
                    self.velocityRequest = None

            # Case 3: A Subordinate station which only knows its events. Here we need the following:
            #   3a: PredictionEventPromises for this station in a 3-day window surrounding the date of interest
            #   3b: PredictionDataPromises for the reference station in the same 3-day window.
            else:
                self.eventPromises = []
                self.refPromises = []
                refStation = self.manager.getStation(
                    self.stationFeature['refStation'])
                if refStation is None:
                    print("Could not find ref station {} for {}".format(
                        self.stationFeature['refStation'],
                        self.stationFeature['station']))
                else:
                    for dayOffset in [-1, 0, 1]:
                        windowDate = self.localDate.addDays(dayOffset)
                        dataPromise = self.manager.getDataPromise(
                            refStation, windowDate)
                        self.refPromises.append(dataPromise)
                        self.addDependency(dataPromise)
                        eventPromise = self.manager.getEventPromise(
                            self.stationFeature, windowDate)
                        self.eventPromises.append(eventPromise)
                        self.addDependency(eventPromise)