示例#1
0
    def updatecanvas(self, canvas):
        """
        Update the canvas object for the legend background.
        """
        if self._lastextent == canvas.extent():
            return

        self._lastextent = canvas.extent()
        if QGis.QGIS_VERSION_INT > 20200:
            from qgis.core import QgsMapRendererParallelJob, QgsMapSettings
            settings = canvas.mapSettings()
            extent = settings.extent()
            settings.setOutputSize(self.size())
            settings.setExtent(extent)
            #settings.setFlags(QgsMapSettings.Antialiasing | QgsMapSettings.DrawLabeling )
            self.renderjob = QgsMapRendererParallelJob(settings)
            self.renderjob.finished.connect(self._renderimage)
            self.renderjob.start()
        else:
            if canvas.isDrawing():
                return

            pixmap = QPixmap(self.size())
            pixmap.fill(canvas.canvasColor())
            painter = QPainter(pixmap)
            painter.setRenderHints(QPainter.Antialiasing)
            renderer = canvas.mapRenderer()
            renderer.render(painter)
            del painter
            self.canvasimage = pixmap.toImage()
            self.update()
示例#2
0
    def updatecanvas(self, canvas):
        """
        Update the canvas object for the legend background.
        """
        if self._lastextent == canvas.extent():
            return

        self._lastextent = canvas.extent()
        if QGis.QGIS_VERSION_INT > 20200:
            from qgis.core import QgsMapRendererParallelJob, QgsMapSettings
            settings = canvas.mapSettings()
            extent = settings.extent()
            settings.setOutputSize(self.size())
            settings.setExtent(extent)
            #settings.setFlags(QgsMapSettings.Antialiasing | QgsMapSettings.DrawLabeling )
            self.renderjob = QgsMapRendererParallelJob(settings)
            self.renderjob.finished.connect(self._renderimage)
            self.renderjob.start()
        else:
            if canvas.isDrawing():
                return

            pixmap = QPixmap(self.size())
            pixmap.fill(canvas.canvasColor())
            painter = QPainter(pixmap)
            painter.setRenderHints(QPainter.Antialiasing)
            renderer = canvas.mapRenderer()
            renderer.render(painter)
            del painter
            self.canvasimage = pixmap.toImage()
            self.update()
示例#3
0
 def _runCropStep(self):
     if self._debug:
         debug('Crop')
     self._step = Georeferencer.Crop
     self._args = []
     self._command = ''
     pixmap = QPixmap(self._rawFile.absoluteFilePath())
     if pixmap.isNull():
         self._signalError('Loading of raw image failed.')
         return
     pixmap = pixmap.copy(0, 0, pixmap.width(), int(pixmap.height() * 0.84))
     image = pixmap.toImage()
     if image.isNull():
         self._signalError('Cropping of raw image failed.')
         return
     if not image.save(self._cropFile.absoluteFilePath(), 'PNG', 100):
         self._signalError('Saving of cropped image failed.')
         return
     self._signalStatus()
     self._runTranslateStep()
示例#4
0
文件: timeline.py 项目: halbbob/dff
class Timeline(QWidget, Script):
  def __init__(self):
    Script.__init__(self, 'timeline')
    QWidget.__init__(self, None)
    self.type = 'timeline'
    self.nodeCount = 0
    self.timesCount = 0
    self.timeMap = {}
    self.m = 40 # Padding
    self.lineHeight = 4 # Pixel height of line
    self.metricOk = False
    self.colors = [['blue', Qt.blue], ['red', Qt.red],
                   ['green', Qt.green], ['yellow', Qt.yellow],
                   ['magenta', Qt.magenta], ['cyan', Qt.cyan]]
    self.stateinfo = 'Initialized'
    self.dateMin = long(0xffffffffffffffff)
    self.dateMax = long(0)
    self.baseDateMin = self.dateMin
    self.baseDateMax = self.dateMax
    self.selDateMin = None
    self.selDateMax = None
    self.maxOcc = 0
    self.maxOccZoom = 0
    self.xHop = 0
    self.xRange = 0
    self.dataListsCreated = False

  def start(self, args):
    self.node = args['file'].value()
    
  def status(self):
    return 0

  def updateWidget(self):
    pass

  def g_display(self):
    self.name = 'timeline ' + QString(self.node.name())
    if not self.node.hasChildren():
        self.setStateInfo(self.node.absolute() + ' doesn\'t have any children.')
    else:
        self.vfs = vfs.vfs()

        self.vlayout = QVBoxLayout()
        self.vlayout.setMargin(0)
        self.vlayout.setSpacing(0)
        
        self.hsplitter = QSplitter()
        self.ploter = PaintArea(self)
        self.options = OptionsLayout(self)

        self.hsplitter.addWidget(self.ploter)
        self.hsplitter.addWidget(self.options)
        self.vlayout.addWidget(self.hsplitter)
        self.setLayout(self.vlayout)
        self.draw = Drawer(self)

        # CountThread compute node amount
        self.countThread = CountThread(self, self.countThreadOver)
        self.populateThread = DataThread(self, self.dataThreadOver)
        self.maxOccThread = MaxOccThread(self, self.maxOccThreadOver)
        self.workerThread = WorkerThread(self)

#comment it to avoid redraw everytime painter is resized
        self.connect(self.workerThread, SIGNAL('refresh'), self.reDraw)
        

  def fromUSec(self, usec2):
      usec = int(usec2)
      days = usec / (86400 * 1000000)
      seconds = (usec - days * 86400 * 1000000) / 1000000
      misec = usec - days * 86400 * 1000000 - seconds * 1000000
      if days >= 1 and datetime.fromordinal(days) >= datetime.fromordinal(1):
        return datetime.fromordinal(days) + timedelta(seconds = seconds, microseconds = misec)
      return None

  def toUSec(self, dtime):
    return dtime.toordinal() * 86400 * 1000000 + dtime.hour * 3600 * 1000000 + dtime.minute * 60 * 1000000 + dtime.second * 1000000 + dtime.microsecond

  def dumpTimeMap(self):
    print self.timeMap
    for k in self.timeMap.keys():
      print 'module:', k
      for attr in self.timeMap[k]:
        sAttrPath = '/'
        for v in attr[:-1]:
          sAttrPath += v + '/'
        print ' ', sAttrPath, ':', attr[-1]
      
  def countThreadOver(self):
      if not self.nodeCount:
        self.setStateInfo('No timestamp found any subset of ' + self.node.absolute())
#        self.disconnect(self.workerThread, SIGNAL('refresh'), self.reDraw)
        return
      self.setStateInfo(str(self.nodeCount) + ' nodes found')

#      self.dumpTimeMap()
# Find/virtual draw maximum size of Y text
      painter = QPainter()
      nullPixmap = QPixmap(self.ploter.width, self.ploter.height)
      painter.begin(nullPixmap)
      rect = painter.drawText(self.draw.paddingYText, 10, 0, 0, 0, str(self.nodeCount) + '.0')
      painter.end()
      self.draw.yLeftMargin = self.draw.paddingYText * 2 + rect.width()
      
      self.options.newInformations()
      self.options.createMetricTools()
      self.metricOk = True
#     self.createFullTimeLists()
      self.workerThread.render()

  def createFullTimeLists(self):
    self.populateThread = DataThread(self, self.dataThreadOver)
    self.populateThread.start()

  def dataThreadOver(self):
      self.dataListsCreated = True
      for family in self.options.configuration:
        # family[0] = extended|static|usual
        for time in family[1]:
          if time[1][5][1]:
              dateMin = time[1][6][1][0]
              dateMax = time[1][6][1][1]
              if dateMin < self.baseDateMin:
                  self.baseDateMin = dateMin
              if dateMax > self.baseDateMax:
                  self.baseDateMax = dateMax
      self.options.newInformations()
      self.workerThread.render()


  def findMaxValue(self):
      self.xRange = (self.ploter.width - self.m - self.draw.yLeftMargin) / self.lineHeight
      self.xHop = (self.baseDateMax - self.baseDateMin) / self.xRange

  def maxOccThreadOver(self):
      self.updatePaintingArea()

  def zoomMaxOcc(self):
    self.xRange = (self.ploter.width - self.m - self.draw.yLeftMargin) / self.lineHeight
    xHop = (self.selDateMax - self.selDateMin) / self.xRange
    newMaxOcc = 0
    for family in self.options.configuration:
      for time in family[1]:
        timeChecked = self.selDateMin
        if timeChecked == self.selDateMax:
# Every nodes have the same time, setting maxOcc computing time + 100usec
          occ = self.elementsInRange(time[1][5][1], timeChecked, timeChecked + 100)
          if occ > newMaxOcc:
              newMaxOcc = occ
        while timeChecked <= self.selDateMax:
          occ = self.elementsInRange(time[1][5][1], timeChecked, timeChecked + xHop)
          if occ > newMaxOcc:
            newMaxOcc = occ
          timeChecked += xHop
              
    self.maxOccZoom = newMaxOcc

  def reDraw(self, resized = False):
    if resized:
      self.updatePaintingArea(True)
      
  def updatePaintingArea(self, resized = False):
      if not self.maxOcc:
          return
      
      self.painter = QPainter()

      self.mainPixmap = QPixmap(self.ploter.width, self.ploter.height)
      self.mainPixmap.fill(Qt.white)

      self.gridPixmap = QPixmap(self.ploter.width, self.ploter.height)
      self.gridPixmap.fill(Qt.transparent)

      self.painter.begin(self.gridPixmap)

      if self.options.zoom and not self.maxOccZoom:
        self.zoomMaxOcc()
        
      self.draw.setDynamicValues(self)
      self.draw.drawInfos()
      self.draw.drawGrid()

      self.painter.end()

      for family in self.options.configuration:
          for time in family[1]:
              if resized:
                time[1][8][1][0] = True
                time[1][7][1][0] = True

              if self.options.zoom and time[1][8][1][0]:
# Create zoom pixmaps
                  time[1][8][1][1] = QPixmap(self.ploter.width, self.ploter.height)
                  time[1][8][1][1].fill(Qt.transparent)
                  penColor = None
                  for color in self.colors:
                      if color[0] == time[1][1][1]:
                          penColor = QColor(color[1])
                          penColor.setAlpha(163)
                          break
                  if penColor:
                      self.painter.begin(time[1][8][1][1])
                      pen = self.painter.pen()
                      pen.setColor(penColor)
                      pen.setWidth(self.lineHeight)
                      self.painter.setPen(pen)
                      self.draw.drawTimeline(self.painter, time[1][5][1])
                      self.painter.end()
                      time[1][8][1][0] = False
                  
              elif not time[1][7][1][1] or time[1][7][1][0]:
# Create main (original sized) pixmaps
                  time[1][7][1][1] = QPixmap(self.ploter.width, self.ploter.height)
                  time[1][7][1][1].fill(Qt.transparent)
                  penColor = None
                  for color in self.colors:
                      if color[0] == time[1][1][1]:
                          penColor = QColor(color[1])
                          penColor.setAlpha(163)
                          break
                  if penColor:
                      self.painter.begin(time[1][7][1][1])
                      pen = self.painter.pen()
                      pen.setColor(penColor)
                      pen.setWidth(self.lineHeight)
                      self.painter.setPen(pen)
                      self.draw.drawTimeline(self.painter, time[1][5][1])
                      self.painter.end()
                      time[1][7][1][0] = False

      self.painter.begin(self.mainPixmap)
# Draw grid
      self.painter.drawImage(QPointF(0, 0), self.gridPixmap.toImage(), QRectF(0, 0, self.ploter.width, self.ploter.height))
      for family in self.options.configuration:
        for time in family[1]:
# Draw each time pixmap
          if not self.options.zoom:
# Draw global view, if zoom not enabled
            if time[1][7][1][1] and time[1][0][1]:
              self.painter.drawImage(QPointF(0, 0), time[1][7][1][1].toImage(), QRectF(0, 0, self.ploter.width, self.ploter.height))
          else:
# Draw zoom pixmaps
            if time[1][8][1][1] and time[1][0][1]:
              self.painter.drawImage(QPointF(0, 0), time[1][8][1][1].toImage(), QRectF(0, 0, self.ploter.width, self.ploter.height))

      self.painter.end()

      self.ploter.scene.clear()
      self.ploter.scene.addPixmap(self.mainPixmap)
      self.ploter.setEnabled(True)
      self.update()

      
  def setStateInfo(self, sinfo):
    self.stateinfo = str(sinfo)

  def stateInfo(self):
    if self.nodeCount:
        return self.stateinfo + ' - ' + str(self.nodeCount) + ' nodes'
    else:
        return self.stateinfo

  def nodesInRange(self, x1, x2):
    if not self.selDateMin:
      timeCheck = self.baseDateMin
      timeMax = self.baseDateMax
    else:
      timeCheck = self.selDateMin
      timeMax = self.selDateMax
    count = 0
    while timeCheck < timeMax:
      for family in self.options.configuration:
        for time in family[1]:
          occ = self.elementsInRange(time[1][5][1], timeCheck, timeCheck + self.xHop)
          if occ:
              if self.lineMatched(timeCheck, occ, x1, x2) and time[1][0][1]:
                count += occ

      timeCheck += self.xHop
    if count:
      self.options.zoomButton.setEnabled(True)
      self.options.exportButton.setEnabled(True)
      if count > 1:
        self.options.selectedNodes.setText(str(count) + ' time values selected')
      else:
        self.options.selectedNodes.setText('One time value selected')
    else:
      self.options.zoomButton.setEnabled(False)
      self.options.exportButton.setEnabled(False)
      self.options.selectedNodes.setText('Nothing selected')

  def lineMatched(self, usec, occ, x1, x2):
    if not self.selDateMin:
      dateMin = self.baseDateMin
      dateMax = self.baseDateMax
    else:
      dateMin = self.selDateMin
      dateMax = self.selDateMax

    if (dateMax - dateMin) > 0:
      x = ((usec - dateMin) * (self.ploter.width - self.m - self.draw.yLeftMargin)) / (dateMax - dateMin) + self.draw.yLeftMargin
      if x <= self.draw.yLeftMargin:
        x += 3
      x_min = x - 2
      x_max = x + 2
      if x_min >= x1 and x_max <= x2:
        return True
    return False

  def elementsInRange(self, root, tMin, tMax):
    ''' Returns amount of node in a date range, given as long

    Dichotomic search, but this can be improved because we only search for
    smaller timestamp and decrease index if greather.
    '''
    if not tMin or not tMax:
      return 0
    nodesCount = 0
    iMin, iMax = 0, len(root['dates']) - 1
    iCurrent = iMax / 2
    # Sync cursor in dates list on tMin ; should be improved
    while iMin != iMax or not iMax:
      if tMin >= root['dates'][iCurrent] or not iCurrent:
        while iCurrent and tMin >= root['dates'][iCurrent]:
          # Should be improved
          iCurrent -= 1
        break
      elif tMin < root['dates'][iCurrent]:
        iMax = iCurrent
        iCurrent = iMin + ((iCurrent - iMin) / 2)

    # Count amount of nodes between tMin and tMax
    endOfList = len(root['dates'])
    while iCurrent < endOfList and tMax >= root['dates'][iCurrent]:
      if tMin <= root['dates'][iCurrent]:
        nodesCount += len(root['nodes'][iCurrent])
      iCurrent += 1
      
    return nodesCount

  def elementsInRangeToNodeList(self, root, tMin, tMax):
    ''' Returns a list of nodes pointer, made of nodes in given date range.
    
    Dichotomic search, but this can be improved because we only search for
    smaller timestamp and decrease index if greather.
    '''
    if not tMin or not tMax:
      return 0
    nodesList = []
    iMin, iMax = 0, len(root['dates']) - 1
    iCurrent = iMax / 2
    # Sync cursor in dates list on tMin ; should be improved
    while iMin != iMax or not iMax:
      if tMin >= root['dates'][iCurrent] or not iCurrent:
        while iCurrent and tMin >= root['dates'][iCurrent]:
          # Should be improved
          iCurrent -= 1
        break
      elif tMin < root['dates'][iCurrent]:
        iMax = iCurrent
        iCurrent = iMin + ((iCurrent - iMin) / 2)

    # Count amount of nodes between tMin and tMax
    endOfList = len(root['dates'])
    while iCurrent < endOfList and tMax >= root['dates'][iCurrent]:
      if tMin <= root['dates'][iCurrent]:
        nodesList.append(root['nodes'][iCurrent])
      iCurrent += 1
      
    return nodesList
 def image(self):
     pixmap = self._makePixmap(self.widthSpinBox.value(),
                               self.heightSpinBox.value())
     return QPixmap.toImage(pixmap)
示例#6
0
文件: EkdWidgets.py 项目: Ptaah/Ekd
class EkdPreview():
    """ On gère un cache des Pixmap générés
    La méthode est simple : au lieu de charger toute l'image et d'en faire une préview après
    on génère la préview au chargement de l'image. On est ainsi moins dépendant de la taille
    de l'image à prévisualiser
    Pour faire ça, on utilise le QImageReader
    On utilise également la fonction de cache pour éviter d'avoir à regénérer à chaque fois les
    apperçus"""
    def __init__(self, imagePath, width=64, height=0, quality=0, Cache=True, keepRatio=True, magnify=False):
        """
        imagePath : chemin de l'image a charger
        size : taille de la préview a générer
        quality : qualité de la preview (0=mavaise, 10=très bonne)
        keepRation : garde-t-on les proportion de l'image
        magnify : agrandit-on l'image si la preview demandée est plus grande que l'image originale
        """
        self.preview = QPixmap()
        if width == 0:
            width = 64
        if height == 0:
            height = width
        self.size = QSize(width, height)
        self.quality = quality
        self.imageName = imagePath
        self.keepRatio = keepRatio
        self.magnify = magnify
        self.cache = Cache
        QPixmapCache.setCacheLimit(50*1024)
        self.update()

    def get_preview(self):
        return self.preview

    def toggle_keepRatio(self):
        self.keepRatio = not self.keepRatio

    def get_image(self):
        return self.preview.toImage()

    def get_imageName(self):
        return self.imageName

    def set_imageName(self, path):
        self.imageName = path

    def get_size(self):
        return self.size

    def set_size(self, size):
        self.size = size

    def get_quality(self):
        return self.quality

    def set_quality(self, quality):
        self.quality = quality

    def width(self):
        return self.preview.width()

    def height(self):
        return self.preview.height()

    def origin(self):
        old_keepRatio=self.keepRatio
        self.keepRatio=False
        self.set_size(self.origineSize)
        self.update()
        self.keepRatio=old_keepRatio

    def update(self):
        """ Fonction de mise à jour de la préview :
            * Si la taille de l'image est plus petite que la taille souhaité, on n'agrandi pas l'image, on prend la plus petite des deux
            * Le cache contient en index les images+size"""
        miniImg = QImage()
        image = QImageReader(self.imageName)
        self.origineSize = image.size()
        image.setQuality(self.quality)
        if not self.magnify :
            if ( ( self.size.width() + self.size.height() ) > (image.size().width() + image.size().height() ) ) :
                self.size = image.size()

        if self.keepRatio :
            image.setScaledSize(QSize(self.size.width(), image.size().height() * self.size.width() / image.size().width() ) )
        else :
            image.setScaledSize(self.size)

        if not QPixmapCache.find(self.imageName + str(self.size), self.preview) or not self.cache:
            image.read(miniImg)
            self.preview = self.preview.fromImage(miniImg)
            if self.cache :
                QPixmapCache.insert(self.imageName + str(self.size), self.preview)
示例#7
0
class Timeline(QWidget, Script):
    def __init__(self):
        Script.__init__(self, 'timeline')
        QWidget.__init__(self, None)
        self.type = 'timeline'
        self.nodeCount = 0
        self.timesCount = 0
        self.timeMap = {}
        self.m = 40  # Padding
        self.lineHeight = 4  # Pixel height of line
        self.metricOk = False
        self.colors = [['blue', Qt.blue], ['red', Qt.red], ['green', Qt.green],
                       ['yellow', Qt.yellow], ['magenta', Qt.magenta],
                       ['cyan', Qt.cyan]]
        self.stateinfo = 'Initialized'
        self.dateMin = long(0xffffffffffffffff)
        self.dateMax = long(0)
        self.baseDateMin = self.dateMin
        self.baseDateMax = self.dateMax
        self.selDateMin = None
        self.selDateMax = None
        self.maxOcc = 0
        self.maxOccZoom = 0
        self.xHop = 0
        self.xRange = 0
        self.dataListsCreated = False

    def start(self, args):
        self.node = args['file'].value()

    def status(self):
        return 0

    def updateWidget(self):
        pass

    def g_display(self):
        self.name = 'timeline ' + QString(self.node.name())
        if not self.node.hasChildren():
            self.setStateInfo(self.node.absolute() +
                              ' doesn\'t have any children.')
        else:
            self.vfs = vfs.vfs()

            self.vlayout = QVBoxLayout()
            self.vlayout.setMargin(0)
            self.vlayout.setSpacing(0)

            self.hsplitter = QSplitter()
            self.ploter = PaintArea(self)
            self.options = OptionsLayout(self)

            self.hsplitter.addWidget(self.ploter)
            self.hsplitter.addWidget(self.options)
            self.vlayout.addWidget(self.hsplitter)
            self.setLayout(self.vlayout)
            self.draw = Drawer(self)

            # CountThread compute node amount
            self.countThread = CountThread(self, self.countThreadOver)
            self.populateThread = DataThread(self, self.dataThreadOver)
            self.maxOccThread = MaxOccThread(self, self.maxOccThreadOver)
            self.workerThread = WorkerThread(self)

            #comment it to avoid redraw everytime painter is resized
            self.connect(self.workerThread, SIGNAL('refresh'), self.reDraw)

    def fromUSec(self, usec2):
        usec = int(usec2)
        days = usec / (86400 * 1000000)
        seconds = (usec - days * 86400 * 1000000) / 1000000
        misec = usec - days * 86400 * 1000000 - seconds * 1000000
        if days >= 1 and datetime.fromordinal(days) >= datetime.fromordinal(1):
            return datetime.fromordinal(days) + timedelta(seconds=seconds,
                                                          microseconds=misec)
        return None

    def toUSec(self, dtime):
        return dtime.toordinal(
        ) * 86400 * 1000000 + dtime.hour * 3600 * 1000000 + dtime.minute * 60 * 1000000 + dtime.second * 1000000 + dtime.microsecond

    def dumpTimeMap(self):
        print self.timeMap
        for k in self.timeMap.keys():
            print 'module:', k
            for attr in self.timeMap[k]:
                sAttrPath = '/'
                for v in attr[:-1]:
                    sAttrPath += v + '/'
                print ' ', sAttrPath, ':', attr[-1]

    def countThreadOver(self):
        if not self.nodeCount:
            self.setStateInfo('No timestamp found any subset of ' +
                              self.node.absolute())
            #        self.disconnect(self.workerThread, SIGNAL('refresh'), self.reDraw)
            return
        self.setStateInfo(str(self.nodeCount) + ' nodes found')

        #      self.dumpTimeMap()
        # Find/virtual draw maximum size of Y text
        painter = QPainter()
        nullPixmap = QPixmap(self.ploter.width, self.ploter.height)
        painter.begin(nullPixmap)
        rect = painter.drawText(self.draw.paddingYText, 10, 0, 0, 0,
                                str(self.nodeCount) + '.0')
        painter.end()
        self.draw.yLeftMargin = self.draw.paddingYText * 2 + rect.width()

        self.options.newInformations()
        self.options.createMetricTools()
        self.metricOk = True
        #     self.createFullTimeLists()
        self.workerThread.render()

    def createFullTimeLists(self):
        self.populateThread = DataThread(self, self.dataThreadOver)
        self.populateThread.start()

    def dataThreadOver(self):
        self.dataListsCreated = True
        for family in self.options.configuration:
            # family[0] = extended|static|usual
            for time in family[1]:
                if time[1][5][1]:
                    dateMin = time[1][6][1][0]
                    dateMax = time[1][6][1][1]
                    if dateMin != None and dateMin > 0 and dateMin < 18446744073709551615 and dateMin < self.baseDateMin:
                        self.baseDateMin = dateMin
                    if dateMax != None and dateMax > 0 and dateMax < 18446744073709551615 and dateMax > self.baseDateMax:
                        self.baseDateMax = dateMax
        self.options.newInformations()
        self.workerThread.render()

    def findMaxValue(self):
        self.xRange = (self.ploter.width - self.m -
                       self.draw.yLeftMargin) / self.lineHeight
        self.xHop = (self.baseDateMax - self.baseDateMin) / self.xRange

    def maxOccThreadOver(self):
        self.updatePaintingArea()

    def zoomMaxOcc(self):
        self.xRange = (self.ploter.width - self.m -
                       self.draw.yLeftMargin) / self.lineHeight
        xHop = (self.selDateMax - self.selDateMin) / self.xRange
        newMaxOcc = 0
        for family in self.options.configuration:
            for time in family[1]:
                timeChecked = self.selDateMin
                if timeChecked == self.selDateMax:
                    # Every nodes have the same time, setting maxOcc computing time + 100usec
                    occ = self.elementsInRange(time[1][5][1], timeChecked,
                                               timeChecked + 100)
                    if occ > newMaxOcc:
                        newMaxOcc = occ
                while timeChecked <= self.selDateMax:
                    occ = self.elementsInRange(time[1][5][1], timeChecked,
                                               timeChecked + xHop)
                    if occ > newMaxOcc:
                        newMaxOcc = occ
                    timeChecked += xHop

        self.maxOccZoom = newMaxOcc

    def reDraw(self, resized=False):
        if resized:
            self.updatePaintingArea(True)

    def updatePaintingArea(self, resized=False):
        if not self.maxOcc:
            return

        self.painter = QPainter()

        self.mainPixmap = QPixmap(self.ploter.width, self.ploter.height)
        self.mainPixmap.fill(Qt.white)

        self.gridPixmap = QPixmap(self.ploter.width, self.ploter.height)
        self.gridPixmap.fill(Qt.transparent)

        self.painter.begin(self.gridPixmap)

        if self.options.zoom and not self.maxOccZoom:
            self.zoomMaxOcc()

        self.draw.setDynamicValues(self)
        self.draw.drawInfos()
        self.draw.drawGrid()

        self.painter.end()

        for family in self.options.configuration:
            for time in family[1]:
                if resized:
                    time[1][8][1][0] = True
                    time[1][7][1][0] = True

                if self.options.zoom and time[1][8][1][0]:
                    # Create zoom pixmaps
                    time[1][8][1][1] = QPixmap(self.ploter.width,
                                               self.ploter.height)
                    time[1][8][1][1].fill(Qt.transparent)
                    penColor = None
                    for color in self.colors:
                        if color[0] == time[1][1][1]:
                            penColor = QColor(color[1])
                            penColor.setAlpha(163)
                            break
                    if penColor:
                        self.painter.begin(time[1][8][1][1])
                        pen = self.painter.pen()
                        pen.setColor(penColor)
                        pen.setWidth(self.lineHeight)
                        self.painter.setPen(pen)
                        self.draw.drawTimeline(self.painter, time[1][5][1])
                        self.painter.end()
                        time[1][8][1][0] = False

                elif not time[1][7][1][1] or time[1][7][1][0]:
                    # Create main (original sized) pixmaps
                    time[1][7][1][1] = QPixmap(self.ploter.width,
                                               self.ploter.height)
                    time[1][7][1][1].fill(Qt.transparent)
                    penColor = None
                    for color in self.colors:
                        if color[0] == time[1][1][1]:
                            penColor = QColor(color[1])
                            penColor.setAlpha(163)
                            break
                    if penColor:
                        self.painter.begin(time[1][7][1][1])
                        pen = self.painter.pen()
                        pen.setColor(penColor)
                        pen.setWidth(self.lineHeight)
                        self.painter.setPen(pen)
                        self.draw.drawTimeline(self.painter, time[1][5][1])
                        self.painter.end()
                        time[1][7][1][0] = False

        self.painter.begin(self.mainPixmap)
        # Draw grid
        self.painter.drawImage(
            QPointF(0, 0), self.gridPixmap.toImage(),
            QRectF(0, 0, self.ploter.width, self.ploter.height))
        for family in self.options.configuration:
            for time in family[1]:
                # Draw each time pixmap
                if not self.options.zoom:
                    # Draw global view, if zoom not enabled
                    if time[1][7][1][1] and time[1][0][1]:
                        self.painter.drawImage(
                            QPointF(0, 0), time[1][7][1][1].toImage(),
                            QRectF(0, 0, self.ploter.width,
                                   self.ploter.height))
                else:
                    # Draw zoom pixmaps
                    if time[1][8][1][1] and time[1][0][1]:
                        self.painter.drawImage(
                            QPointF(0, 0), time[1][8][1][1].toImage(),
                            QRectF(0, 0, self.ploter.width,
                                   self.ploter.height))

        self.painter.end()

        self.ploter.scene.clear()
        self.ploter.scene.addPixmap(self.mainPixmap)
        self.ploter.setEnabled(True)
        self.update()

    def setStateInfo(self, sinfo):
        self.stateinfo = str(sinfo)

    def stateInfo(self):
        if self.nodeCount:
            return self.stateinfo + ' - ' + str(self.nodeCount) + ' nodes'
        else:
            return self.stateinfo

    def nodesInRange(self, x1, x2):
        if not self.selDateMin:
            timeCheck = self.baseDateMin
            timeMax = self.baseDateMax
        else:
            timeCheck = self.selDateMin
            timeMax = self.selDateMax
        count = 0
        while timeCheck < timeMax:
            for family in self.options.configuration:
                for time in family[1]:
                    occ = self.elementsInRange(time[1][5][1], timeCheck,
                                               timeCheck + self.xHop)
                    if occ:
                        if self.lineMatched(timeCheck, occ, x1,
                                            x2) and time[1][0][1]:
                            count += occ

            timeCheck += self.xHop
        if count:
            self.options.zoomButton.setEnabled(True)
            self.options.exportButton.setEnabled(True)
            if count > 1:
                self.options.selectedNodes.setText(
                    str(count) + ' time values selected')
            else:
                self.options.selectedNodes.setText('One time value selected')
        else:
            self.options.zoomButton.setEnabled(False)
            self.options.exportButton.setEnabled(False)
            self.options.selectedNodes.setText('Nothing selected')

    def lineMatched(self, usec, occ, x1, x2):
        if not self.selDateMin:
            dateMin = self.baseDateMin
            dateMax = self.baseDateMax
        else:
            dateMin = self.selDateMin
            dateMax = self.selDateMax

        if (dateMax - dateMin) > 0:
            x = ((usec - dateMin) *
                 (self.ploter.width - self.m - self.draw.yLeftMargin)) / (
                     dateMax - dateMin) + self.draw.yLeftMargin
            if x <= self.draw.yLeftMargin:
                x += 3
            x_min = x - 2
            x_max = x + 2
            if x_min >= x1 and x_max <= x2:
                return True
        return False

    def elementsInRange(self, root, tMin, tMax):
        ''' Returns amount of node in a date range, given as long

    Dichotomic search, but this can be improved because we only search for
    smaller timestamp and decrease index if greather.
    '''
        if not tMin or not tMax:
            return 0
        nodesCount = 0
        if root['dates'] == None:
            return 0
        iMin, iMax = 0, len(root['dates']) - 1
        iCurrent = iMax / 2
        # Sync cursor in dates list on tMin ; should be improved
        while iMin != iMax or not iMax:
            if tMin >= root['dates'][iCurrent] or not iCurrent:
                while iCurrent and tMin >= root['dates'][iCurrent]:
                    # Should be improved
                    iCurrent -= 1
                break
            elif tMin < root['dates'][iCurrent]:
                iMax = iCurrent
                iCurrent = iMin + ((iCurrent - iMin) / 2)

        # Count amount of nodes between tMin and tMax
        endOfList = len(root['dates'])
        while iCurrent < endOfList and tMax >= root['dates'][iCurrent]:
            if tMin <= root['dates'][iCurrent]:
                nodesCount += len(root['nodes'][iCurrent])
            iCurrent += 1

        return nodesCount

    def elementsInRangeToNodeList(self, root, tMin, tMax):
        ''' Returns a list of nodes pointer, made of nodes in given date range.
    
    Dichotomic search, but this can be improved because we only search for
    smaller timestamp and decrease index if greather.
    '''
        if not tMin or not tMax:
            return 0
        nodesList = []
        iMin, iMax = 0, len(root['dates']) - 1
        iCurrent = iMax / 2
        # Sync cursor in dates list on tMin ; should be improved
        while iMin != iMax or not iMax:
            if tMin >= root['dates'][iCurrent] or not iCurrent:
                while iCurrent and tMin >= root['dates'][iCurrent]:
                    # Should be improved
                    iCurrent -= 1
                break
            elif tMin < root['dates'][iCurrent]:
                iMax = iCurrent
                iCurrent = iMin + ((iCurrent - iMin) / 2)

        # Count amount of nodes between tMin and tMax
        endOfList = len(root['dates'])
        while iCurrent < endOfList and tMax >= root['dates'][iCurrent]:
            if tMin <= root['dates'][iCurrent]:
                nodesList.append(root['nodes'][iCurrent])
            iCurrent += 1

        return nodesList
示例#8
0
 def image(self):
     pixmap = self._makePixmap(self.widthSpinBox.value(),
                               self.heightSpinBox.value())
     return QPixmap.toImage(pixmap)
class ClickableImage(QLabel):
    clicked = pyqtSignal(str)

    def __init__(self, image_path, name=None):
        super(ClickableImage, self).__init__()
        self.pixmap = QPixmap(image_path)
        self.path = image_path
        if name is None:
            base = os.path.basename(image_path)
            if len(os.path.splitext(base)) > 1:
                self.name = os.path.splitext(base)[0]
            # TODO: Throw exception
        else:
            self.name = name
        self.setPixmap(self.pixmap)
        self.setObjectName(self.name)
        self.reset_timer = QTimer()
        self.reset_timer.setSingleShot(True)
        self.reset_timer.timeout.connect(self.reset_default_image)

    def set_temp_opencv_image(self, image, delay):
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = QImage(image, image.shape[1], \
                       image.shape[0], image.shape[1] * 3,
                       QImage.Format_RGB888)
        pixmap = QPixmap(image)
        self.setPixmap(pixmap)
        self.reset_timer.start(delay)

    def reset_default_image(self):
        self.setPixmap(self.pixmap)

    # def to_opencv_image(self, share_memory=False):
    #     """ Creates a numpy array from a QImage.
    #
    #         If share_memory is True, the numpy array and the QImage is shared.
    #         Be careful: make sure the numpy array is destroyed before the image,
    #         otherwise the array will point to unreserved memory!!
    #     """
    #     img = self.pixmap.toImage()
    #     assert isinstance(img, QtGui.QImage), "img must be a QtGui.QImage object"
    #     assert img.format() == QtGui.QImage.Format_RGB32, \
    #         "img format must be QImage.Format.Format_RGB32, got: {}".format(img.format())
    #
    #     img_size = img.size()
    #     buffer = img.bits()
    #
    #     # Sanity check
    #     n_bits_buffer = len(buffer) * 8
    #     n_bits_image = img_size.width() * img_size.height() * img.depth()
    #     assert n_bits_buffer == n_bits_image, \
    #         "size mismatch: {} != {}".format(n_bits_buffer, n_bits_image)
    #
    #     assert img.depth() == 32, "unexpected image depth: {}".format(img.depth())
    #
    #     # Note the different width height parameter order!
    #     arr = np.ndarray(shape=(img_size.height(), img_size.width(), img.depth() // 8),
    #                      buffer=buffer,
    #                      dtype=np.uint8)
    #
    #     if share_memory:
    #         return arr
    #     else:
    #         return copy.deepcopy(arr)

    def to_opencv_image(self):
        image = self.pixmap.toImage()
        new_image = image.convertToFormat(QtGui.QImage.Format_RGB32)

        width = image.width()
        height = image.height()
        depth = image.depth() // 8

        ptr = new_image.bits()
        s = ptr.asstring(width * height * image.depth() // 8)
        arr = np.fromstring(s, dtype=np.uint8).reshape((height, width, depth))

        return arr

    def mousePressEvent(self, event):
        self.clicked.emit(self.name)