def currentHistoryChanged(self, current, previous):
     self.new_geometry.reset()
     self.old_geometry.reset()
     self.tblChanges.model().removeRows()
     if not current.isValid():
         return
     item = current.data(Qt.UserRole)
     if item is None:
         data = {}
     else:
         data = current.data(Qt.UserRole).getDetails()
     with SetLocale_CtxDec():
         extent = None
         if data.get('new_geometry'):
             wkt = CreateGeometryFromJson( json.dumps(data['new_geometry']) ).ExportToWkt()
             geom = QgsGeometry.fromWkt( wkt )
             l = QgsVectorLayer('Point?crs=epsg:4326', 'asd', 'memory')
             self.new_geometry.setToGeometry( geom, l )
             extent = QgsRectangle(geom.boundingBox())
         if data.get('old_geometry'):
             wkt = CreateGeometryFromJson( json.dumps(data['old_geometry']) ).ExportToWkt()
             geom = QgsGeometry.fromWkt( wkt )
             l = QgsVectorLayer('Point?crs=epsg:4326', 'asd', 'memory')
             self.old_geometry.setToGeometry( geom, l )
             if extent is None:
                 extent = QgsRectangle(geom.boundingBox())
             else:
                 extent.combineExtentWith( geom.boundingBox() )
         if extent is not None:
             extent.grow(0.01)
             self.mapCanvas.setExtent( extent )
             self.mapCanvas.refresh()
     if data.get('what_attributes', []):
         self.tblChanges.model().insertRows( 0, data.get('what_attributes', []) )
Exemplo n.º 2
0
    def testRasterBlock(self):
        """Test raster block with extent"""

        path = os.path.join(unitTestDataPath(), 'landsat_4326.tif')
        raster_layer = QgsRasterLayer(path, 'test')
        self.assertTrue(raster_layer.isValid())

        extent = QgsRectangle(17.94284482577178252, 30.23021770271909503,
                              17.94407867909909626, 30.23154272264058307)
        block = raster_layer.dataProvider().block(1, extent, 2, 3)
        self.checkBlockContents(block, [
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            124.0,
        ])

        full_content = [
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            124.0,
            125.0,
            126.0,
            127.0,
            127.0,
        ]

        extent = raster_layer.extent()
        block = raster_layer.dataProvider().block(1, extent, 3, 4)
        self.checkBlockContents(block, full_content)

        extent = raster_layer.extent()
        extent.grow(-0.0001)
        block = raster_layer.dataProvider().block(1, extent, 3, 4)
        self.checkBlockContents(block, full_content)

        row_height = raster_layer.extent().height() / raster_layer.height()

        for row in range(raster_layer.height()):
            extent = raster_layer.extent()
            extent.setYMaximum(extent.yMaximum() - row_height * row)
            extent.setYMinimum(extent.yMaximum() - row_height)
            block = raster_layer.dataProvider().block(1, extent, 3, 1)
            self.checkBlockContents(block, full_content[row * 3:row * 3 + 3])
Exemplo n.º 3
0
 def jump_to(self, item):
     data = item.data(32)
     if not data:
         return
     layername, fid = data[0], data[1]
     layer = roam.api.utils.layer_by_name(layername)
     feature = layer.getFeatures(QgsFeatureRequest(fid)).next()
     box = feature.geometry().boundingBox()
     xmin, xmax, ymin, ymax = box.xMinimum(), box.xMaximum(), box.yMinimum(), box.yMaximum()
     xmin -= 5
     xmax += 5
     ymin -= 5
     ymax += 5
     box = QgsRectangle(xmin, ymin, xmax, ymax)
     box.grow(20)
     self.api.mainwindow.canvas.setExtent(box)
     self.api.mainwindow.canvas.refresh()
     self.api.mainwindow.showmap()
     RoamEvents.selectionchanged.emit({layer: [feature]})
Exemplo n.º 4
0
 def jump_to(self, item):
     data = item.data(32)
     if not data:
         return
     layername, fid = data[0], data[1]
     layer = roam.api.utils.layer_by_name(layername)
     feature = layer.getFeatures(QgsFeatureRequest(fid)).next()
     box = feature.geometry().boundingBox()
     xmin, xmax, ymin, ymax = box.xMinimum(), box.xMaximum(), box.yMinimum(
     ), box.yMaximum()
     xmin -= 5
     xmax += 5
     ymin -= 5
     ymax += 5
     box = QgsRectangle(xmin, ymin, xmax, ymax)
     box.grow(20)
     self.api.mainwindow.canvas.setExtent(box)
     self.api.mainwindow.canvas.refresh()
     self.api.mainwindow.showmap()
     RoamEvents.selectionchanged.emit({layer: [feature]})
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        grib_layerfile = self.parameterAsFile(parameters, self.GRIB, context)
        grib_layer = self.parameterAsLayer(parameters, self.GRIB, context)
        wind_ds = self.parameterAsInt(parameters, self.WIND_DATASET_INDEX,
                                      context)
        polar_filename = self.polar_names[self.parameterAsEnum(
            parameters, self.POLAR, context)]
        polar = Polar(
            os.path.join(self.polars_dir, self.polars[polar_filename]))
        start = self.parameterAsDateTime(parameters, self.START_TIME, context)
        start_point = self.parameterAsPoint(parameters,
                                            self.START_POINT,
                                            context,
                                            crs=grib_layer.crs())
        end_point = self.parameterAsPoint(parameters,
                                          self.END_POINT,
                                          context,
                                          crs=grib_layer.crs())

        print("grib_layerfile", grib_layerfile)
        print("grib_layer", grib_layer)
        print("wind_ds", wind_ds)
        print("polar", polar)

        track = ((start_point.y(), start_point.x()), (end_point.y(),
                                                      end_point.x()))
        geo_context = QgsRectangle(start_point.x(), start_point.y(),
                                   end_point.x(), end_point.y())
        track_dist = QgsPointXY(start_point.x(), start_point.y()).sqrDist(
            end_point.x(), end_point.y())
        geo_context.grow(
            (track_dist /
             2) if track_dist < 1 else 0.5)  #limit grow to 0.5 degree
        checkValidity = in_sea_checker(geo_context)
        grib_reader = grib_sampler(grib_layer, wind_ds)

        #test
        #print ("TESTGRIB",grib_reader.getWindAt(datetime.strptime("02/02/21 18:00", "%d/%m/%y %H:%M"),39.31064,5.06086))

        print("track", track)

        route_process = Routing(
            LinearBestIsoRouter,
            polar,
            track,
            grib_reader,
            start.toPyDateTime(),
            lineValidity=checkValidity.path_in_sea_xy,
        )
        step = 1
        execution = "ok"
        while not route_process.end:
            if feedback.isCanceled():
                break
            try:
                res = route_process.step()
                step += 1
                feedback.pushInfo("step %d: %s" % (step, str(res.time)))
                if feedback.isCanceled():
                    return {"result": "terminated by user"}
                if res.time > grib_reader.end_time:
                    execution = "terminated: out of grib temporal scope"
            except Exception as e:
                feedback.pushInfo("Error: %s" % e.message)

        if res.path:
            waypfields = QgsFields()
            waypfields.append(QgsField("wayp_id", QVariant.Int))
            waypfields.append(QgsField("timestamp", QVariant.String, len=25))
            waypfields.append(QgsField("time", QVariant.DateTime))
            waypfields.append(QgsField("twd", QVariant.Double, len=10, prec=3))
            waypfields.append(QgsField("tws", QVariant.Double, len=10, prec=3))
            waypfields.append(
                QgsField("knots", QVariant.Double, len=10, prec=3))
            waypfields.append(
                QgsField("heading", QVariant.Double, len=10, prec=3))
            routefields = QgsFields()
            routefields.append(
                QgsField("start_tracking", QVariant.String, len=25))
            routefields.append(
                QgsField("end_tracking", QVariant.String, len=25))

            (sink_waypoints, dest_waypoints_id) = self.parameterAsSink(
                parameters, self.OUTPUT_WAYPOINTS, context, waypfields,
                QgsWkbTypes.Point, QgsCoordinateReferenceSystem(4326))
            (sink_route, dest_route_id) = self.parameterAsSink(
                parameters, self.OUTPUT_ROUTE, context, routefields,
                QgsWkbTypes.LineString, QgsCoordinateReferenceSystem(4326))

            # Compute the number of steps to display within the progress bar and
            # get features from source
            tr = []
            for wp in res.path:
                if len(wp) == 3:
                    tr.append((wp[0], wp[1], str(wp[2]), 0, 0, 0, 0))
                else:
                    tr.append(
                        (wp[0], wp[1], str(wp[4]), wp[5], wp[6], wp[7], wp[8]))
            if execution == "ok":
                tr.append((*track[-1], dateutil.parser.parse(tr[-1][2]) +
                           timedelta(hours=1), 0, 0, 0, 0))

            print(tr)
            route_polyline = []

            for order, wayp in enumerate(tr):
                # Stop the algorithm if cancel button has been clicked
                print(wayp[1], wayp[0], wayp[2])
                if feedback.isCanceled():
                    break
                print(wayp[2], type(wayp[2]))
                new_feat = QgsFeature(waypfields)
                new_feat.setAttribute('wayp_id', order)
                new_feat.setAttribute(
                    'timestamp',
                    str(wayp[2])[:25])  #.isoformat(timespec='minutes')
                new_feat.setAttribute('time', str(wayp[2]))
                new_feat.setAttribute('twd', math.degrees(wayp[3]))
                new_feat.setAttribute('tws', wayp[4])
                new_feat.setAttribute('knots', wayp[5])
                new_feat.setAttribute('heading', wayp[6])
                waypoint = QgsPointXY(wayp[1], wayp[0])
                route_polyline.append(waypoint)
                new_geom = QgsGeometry.fromPointXY(waypoint)
                new_feat.setGeometry(new_geom)
                sink_waypoints.addFeature(new_feat, QgsFeatureSink.FastInsert)

            new_route_feat = QgsFeature(routefields)
            new_route_feat.setAttribute('start_tracking', tr[0][2][:25])
            new_route_feat.setAttribute('end_tracking', tr[-2][2][:25])
            new_route_feat.setGeometry(
                QgsGeometry.fromPolylineXY(route_polyline))
            sink_route.addFeature(new_route_feat, QgsFeatureSink.FastInsert)

            return {
                self.OUTPUT_WAYPOINTS: dest_waypoints_id,
                self.OUTPUT_ROUTE: dest_route_id,
                "result": execution
            }
        else:
            return {"result", "no_path"}
    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)