Skip to content
Snippets Groups Projects
profilevisualization.py 78.6 KiB
Newer Older
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        # Define a which (new) bands need to be loaded for each sensor
        if LUT_bandIndices is None:
            LUT_bandIndices = dict()
            for sensor in self.TS.Sensors:
                LUT_bandIndices[sensor] = self.plotSettingsModel.requiredBandsIndices(sensor)
Benjamin Jakimow's avatar
Benjamin Jakimow committed

        assert isinstance(LUT_bandIndices, dict)
        for sensor in self.TS.Sensors:
            assert sensor in LUT_bandIndices.keys()
Benjamin Jakimow's avatar
Benjamin Jakimow committed

        #update new / existing points
        if isinstance(spatialPoints, SpatialPoint):
            spatialPoints = [spatialPoints]

        for spatialPoint in spatialPoints:
            assert isinstance(spatialPoint, SpatialPoint)
            TP = self.tpCollection.fromSpatialPoint(spatialPoint)
            if not isinstance(TP, TemporalProfile):
                TP = TemporalProfile(self.TS, spatialPoint)
                self.tpCollection.insertTemporalProfiles(TP)
            TPs.append(TP)
            theGeometries.append(TP.mCoordinate)

Benjamin Jakimow's avatar
Benjamin Jakimow committed
        TP_ids = [TP.mID for TP in TPs]
        #each TSD is a Task
        #a Task defines which bands are to be loaded
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            #do not load from invisible TSDs
            if not tsd.isVisible():
                continue

            #which bands do we need to load?
            requiredIndices = set(LUT_bandIndices[tsd.sensor])
            if len(requiredIndices) == 0:
                continue
            else:
                s = ""

            missingIndices = set()
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            for TP in TPs:
                assert isinstance(TP, TemporalProfile)
                existingBandKeys = [k for k in TP.data(tsd).keys() if PlotSettingsModel.regBandKeyExact.search(k)]
                existingBandIndices = set([bandKey2bandIndex(k) for k in existingBandKeys])
Benjamin Jakimow's avatar
Benjamin Jakimow committed
                need2load = requiredIndices.difference(existingBandIndices)
                missingIndices = missingIndices.union(need2load)
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            missingIndices = sorted(list(missingIndices))
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            if len(missingIndices) > 0:
                task = PixelLoaderTask(tsd.pathImg, theGeometries,
                                       bandIndices=missingIndices,
                                       temporalProfileIDs=TP_ids)
                tasks.append(task)
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        if len(tasks) > 0:
            aGoodDefault = 2 if len(self.TS) > 25 else 1

            self.pixelLoader.setNumberOfProcesses(SETTINGS.value('profileloader_threads', aGoodDefault))
            if DEBUG:
                print('Start loading for {} geometries from {} sources...'.format(
                    len(theGeometries), len(tasks)
                ))
            self.pixelLoader.startLoading(tasks)

        else:
            if DEBUG:
                print('Data for geometries already loaded')
    def setVisibility(self, sensorPlotStyle):
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        assert isinstance(sensorPlotStyle, TemporalProfilePlotStyle)
        self.setVisibility2D(sensorPlotStyle)
    def setVisibility2D(self, sensorPlotStyle):
    def addData(self, sensorView = None):

        if sensorView is None:
            for sv in self.plotSettingsModel.items:
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            assert isinstance(sensorView, TemporalProfilePlotStyle)
    @QtCore.pyqtSlot()
    def onDataUpdate(self):


        for plotSetting in self.plotSettingsModel:
            assert isinstance(plotSetting, TemporalProfilePlotStyle)
            if plotSetting.temporalProfile().updated():
                for pdi in plotSetting.mPlotItems:
                    assert isinstance(pdi, TemporalProfilePlotDataItem)
                    pdi.updateDataAndStyle()
                plotSetting.temporalProfile().resetUpdated()

        for i in self.plot2D.getPlotItem().dataItems:
            i.updateItems()


        if not self.plot2D.xAxisInitialized:
            x0 = x1 = None
            for plotSetting in self.plotSettingsModel:
                assert isinstance(plotSetting, TemporalProfilePlotStyle)
                for pdi in plotSetting.mPlotItems:
                    assert isinstance(pdi, TemporalProfilePlotDataItem)
                    if x0 is None:
                        x0 = pdi.xData.min()
                        x1 = pdi.xData.max()
                    else:
                        x0 = min(pdi.xData.min(), x0)
                        x1 = max(pdi.xData.max(), x1)

            if x0 is not None:
                self.plot2D.getPlotItem().setXRange(x0, x1)
                self.plot2D.xAxisInitialized = True

    @QtCore.pyqtSlot()
    def updatePlot3D(self):
        if OPENGL_AVAILABLE:
            from pyqtgraph.opengl import GLViewWidget
            import pyqtgraph.opengl as gl
            assert isinstance(self.plot3D, GLViewWidget)
            w = self.plot3D

            #we need the data from all bands



            del self.glPlotDataItem[:]
            idx = self.ui.cbTemporalProfile3D.currentIndex()
            if idx >= 0:
                self.ui.cbTemporalProfile3D.currentIndex()
                tp = self.ui.cbTemporalProfile3D.itemData(idx, role=Qt.UserRole)
                assert isinstance(tp, TemporalProfile)

                #1. ensure that data from all bands will be loaded
                LUT_bandIndices = dict()
                for sensor in self.TS.sensors():
                    assert isinstance(sensor, SensorInstrument)
                    LUT_bandIndices[sensor] = list(range(sensor.nb))

                self.loadCoordinate(tp.mCoordinate, LUT_bandIndices=LUT_bandIndices)

                #2. visualize already loaded data
                profileData = {}

                #x =
                #y =

                for sensor in tp.mTimeSeries.sensors():
                    profileData[sensor] = {'x':[],'y':[],'z':[]}
                for tsd in tp.mTimeSeries:
                    data = tp.data(tsd)
                    bandKeys = sorted([k for k in data.keys() if k.startswith('b') and data[k] != None], key=lambda k: bandKey2bandIndex(k))

                    t = date2num(tsd.date)
                    return

                    n = len(bandKeys)

                    pos = np.ones((n,3), dtype=np.float)

                    pos = 2
                    #pos = (N,3) array of floats specifying point locations.

                    plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i, n * 1.3)), width=(i + 1) / 10.,
                                            antialias=True)
                    w.addItem(plt)
                """
                for sensor, values in data.items():
                    if len(values['z']) > 0:
                        x = values['x']
                        y = values['y']
                        z = values['z']
                        
                        p2 = gl.GLSurfacePlotItem(x=x, y=y, z=z, shader='normalColor')
                        p2.translate(-10, -10, 0)
                        w.addItem(p2)
                """

    @QtCore.pyqtSlot()
    def updatePlot2D(self):
        if isinstance(self.plotSettingsModel, PlotSettingsModel):
            if DEBUG:
Benjamin Jakimow's avatar
Benjamin Jakimow committed
                print('Update plot...')
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            pi = self.plot2D.getPlotItem()
            piDataItems = pi.listDataItems()
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            locations = set()
            for plotSetting in self.plotSettingsModel:
                assert isinstance(plotSetting, TemporalProfilePlotStyle)
                locations.add(plotSetting.temporalProfile().mCoordinate)
Benjamin Jakimow's avatar
Benjamin Jakimow committed
                for pdi in plotSetting.mPlotItems:
                    assert isinstance(pdi, TemporalProfilePlotDataItem)
                    pdi.updateDataAndStyle()

            #for i in pi.dataItems:
            #    i.updateItems()

            #self.plot2D.update()
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            #2. load pixel data
            self.loadCoordinate(list(locations))
Benjamin Jakimow's avatar
Benjamin Jakimow committed
            # https://github.com/pyqtgraph/pyqtgraph/blob/5195d9dd6308caee87e043e859e7e553b9887453/examples/customPlot.py
            return
def examplePixelLoader():

    # prepare QGIS environment
    if sys.platform == 'darwin':
        PATH_QGS = r'/Applications/QGIS.app/Contents/MacOS'
        os.environ['GDAL_DATA'] = r'/usr/local/Cellar/gdal/1.11.3_1/share'
    else:
        # assume OSGeo4W startup
        PATH_QGS = os.environ['QGIS_PREFIX_PATH']
    assert os.path.exists(PATH_QGS)

    qgsApp = QgsApplication([], True)
    QApplication.addLibraryPath(r'/Applications/QGIS.app/Contents/PlugIns')
    QApplication.addLibraryPath(r'/Applications/QGIS.app/Contents/PlugIns/qgis')
    qgsApp.setPrefixPath(PATH_QGS, True)
    qgsApp.initQgis()


    gb = QGroupBox()
    gb.setTitle('Sandbox')

    PL = PixelLoader()
    PL.setNumberOfThreads(2)

    if False:
        files = ['observationcloud/testdata/2014-07-26_LC82270652014207LGN00_BOA.bsq',
                 'observationcloud/testdata/2014-08-03_LE72270652014215CUB00_BOA.bsq'
                 ]
    else:
        from timeseriesviewer.utils import file_search
        searchDir = r'H:\LandsatData\Landsat_NovoProgresso'
        files = file_search(searchDir, '*227065*band4.img', recursive=True)
        #files = files[0:3]

    lyr = QgsRasterLayer(files[0])
    coord = lyr.extent().center()
    crs = lyr.crs()

    l = QVBoxLayout()

    btnStart = QPushButton()
    btnStop = QPushButton()
    prog = QProgressBar()
    tboxResults = QPlainTextEdit()
    tboxResults.setMaximumHeight(300)
    tboxThreads = QPlainTextEdit()
    tboxThreads.setMaximumHeight(200)
    label = QLabel()
    label.setText('Progress')

    def showProgress(n,m,md):
        prog.setMinimum(0)
        prog.setMaximum(m)
        prog.setValue(n)

        info = []
        for k, v in md.items():
            info.append('{} = {}'.format(k,str(v)))
        tboxResults.setPlainText('\n'.join(info))
        #tboxThreads.setPlainText(PL.threadInfo())
        qgsApp.processEvents()

    PL.sigPixelLoaded.connect(showProgress)
    btnStart.setText('Start loading')
    btnStart.clicked.connect(lambda : PL.startLoading(files, coord, crs))
    btnStop.setText('Cancel')
    btnStop.clicked.connect(lambda: PL.cancelLoading())
    lh = QHBoxLayout()
    lh.addWidget(btnStart)
    lh.addWidget(btnStop)
    l.addLayout(lh)
    l.addWidget(prog)
    l.addWidget(tboxThreads)
    l.addWidget(tboxResults)

    gb.setLayout(l)
    gb.show()
    #rs.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);')
    #rs.handle.setStyleSheet('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);')
    qgsApp.exec_()
    qgsApp.exitQgis()

if __name__ == '__main__':
    import site, sys
    from timeseriesviewer import utils
    qgsApp = utils.initQgisApplication()
Benjamin Jakimow's avatar
Benjamin Jakimow committed
    DEBUG = True
    if False: #the ultimative test for floating point division correctness, at least on a DOY-level
        date1 = np.datetime64('1960-12-31','D')
        assert date1 == num2date(date2num(date1))
        #1960 - 12 - 31
        for year in  range(1960, 2057):
            for doy in range(1, daysPerYear(year)+1):
                dt = datetime.timedelta(days=doy - 1)
                date1 = np.datetime64('{}-01-01'.format(year)) + np.timedelta64(doy-1,'D')
                date2 = datetime.date(year=year, month=1, day=1) + datetime.timedelta(days=doy-1)

                assert date1 == num2date(date2num(date1), dt64=True), 'date1: {}'.format(date1)
                assert date2 == num2date(date2num(date2), dt64=False), 'date2: {}'.format(date1)
    ui = ProfileViewDockUI()
    ui.show()
Benjamin Jakimow's avatar
Benjamin Jakimow committed

Benjamin Jakimow's avatar
Benjamin Jakimow committed
    if True:
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        STVis = SpectralTemporalVisualization(ui)
        STVis.setTimeSeries(TS)
        import example.Images
        from timeseriesviewer import file_search
        files = file_search(os.path.dirname(example.Images.__file__), '*.tif')
        TS.addFiles(files)
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        ext = TS.getMaxSpatialExtent()
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        cp1 = SpatialPoint(ext.crs(),ext.center())
        cpND = SpatialPoint(ext.crs(), 681151.214,-752388.476)
        #cp2 = SpatialPoint(ext.crs(), ext.center())
        #cp3 = SpatialPoint(ext.crs(), ext.center().x()+500, ext.center().y()+250)
Benjamin Jakimow's avatar
Benjamin Jakimow committed

        STVis.loadCoordinate(cpND)
        #STVis.loadCoordinate(cp2)
        #STVis.loadCoordinate(cp3)
Benjamin Jakimow's avatar
Benjamin Jakimow committed
        STVis.createNewPlotStyle()
        if False:
            for tp in STVis.tpCollection:
                assert isinstance(tp, TemporalProfile)
                tp.plot()
Benjamin Jakimow's avatar
Benjamin Jakimow committed
    qgsApp.exec_()
    qgsApp.exitQgis()