Ejemplo n.º 1
0
    def getMinMaxValues(self):
        """Returns str"""
        if self.minValue is None or self.maxValue is None:  # if not already computed
            fmt = self.getTimeFormat()
            if self.getDateType() == DateTypes.IntegerTimestamps:
                self.minValue = self.getRawMinValue()
                self.maxValue = self.getRawMaxValue()
            else:
                # need to find min max by looking at all the unique values
                # QGIS doesn't get sorting right
                uniques = self.getUniques(self.fromTimeAttribute)

                # those can be either strings or qdate(time) values

                def vals_to_dt(vals, fmt):
                    res = []
                    for val in vals:
                        try:
                            dt = timeval_to_datetime(val, fmt)
                            res.append(dt)
                            # info("{} converted to {}".format(val, dt))
                        except Exception, e:
                            warn(
                                "Unparseable value {} in layer {} ignored. Cause {}"
                                .format(val, self.layer.name(), e))
                            pass
                    return res

                unique_vals = vals_to_dt(uniques, fmt)
                if len(unique_vals) == 0:
                    raise Exception(
                        "Could not parse any dates while trying to get time extents."
                        +
                        "None of the values (for example {}) matches the format {}"
                        .format(uniques[-1], fmt))
                minValue = datetime_to_str(min(unique_vals), fmt)
                if self.fromTimeAttribute == self.toTimeAttribute:
                    maxValue = datetime_to_str(max(unique_vals), fmt)
                else:
                    unique_vals = self.getUniques(self.toTimeAttribute)
                    unique_vals = vals_to_dt(unique_vals, fmt)
                    maxValue = datetime_to_str(max(unique_vals), fmt)

                if type(minValue) in [QtCore.QDate, QtCore.QDateTime]:
                    minValue = datetime_to_str(QDateTime_to_datetime(minValue),
                                               self.getTimeFormat())
                    maxValue = datetime_to_str(QDateTime_to_datetime(maxValue),
                                               self.getTimeFormat())
                self.minValue = minValue
                self.maxValue = maxValue
    def renderLabel(self, painter):
        """render the current timestamp on the map canvas"""
        if not self.showLabel:
            return

        labelString = datetime_to_str(QDateTime_to_datetime(self.dock.dateTimeEditCurrentTime.dateTime()),\
                      self.labelOptions.fmt)

        # Determine placement of label given cardinal directions
        flags = 0
        for direction, flag in ('N', Qt.AlignTop), ('S', Qt.AlignBottom), (
                'E', Qt.AlignRight), ('W', Qt.AlignLeft):
            if direction in self.labelOptions.placement:
                flags |= flag

        # Get canvas dimensions
        width = painter.device().width()
        height = painter.device().height()

        painter.setRenderHint(painter.Antialiasing, True)
        txt = QTextDocument()
        html = '<span style="background-color:%s; padding: 5px;"><font face="%s" size="%s" color="%s">%s</font></span>' % \
               (self.labelOptions.bgcolor, self.labelOptions.font, self.labelOptions.size, self.labelOptions.color, labelString)
        txt.setHtml(html)
        layout = txt.documentLayout()
        size = layout.documentSize()

        x = width - 5 - size.width() if flags & Qt.AlignRight else 5
        y = height - 5 - size.height() if flags & Qt.AlignBottom else 5

        painter.translate(x, y)
        layout.draw(painter, QAbstractTextDocumentLayout.PaintContext())
        painter.translate(-x, -y)  # translate back
Ejemplo n.º 3
0
    def renderLabel(self, painter):
        """render the current timestamp on the map canvas"""
        if not self.showLabel or not self.model.hasLayers():
            return

        dt = self.model.getCurrentTimePosition()
        if dt is None:
            dt = self.getTimeValueFromUI() 

        labelString = datetime_to_str(dt, self.labelOptions.fmt)

        # Determine placement of label given cardinal directions
        flags = 0
        for direction, flag in ('N', Qt.AlignTop), ('S', Qt.AlignBottom), ('E', Qt.AlignRight), ('W', Qt.AlignLeft):
            if direction in self.labelOptions.placement:
                flags |= flag

        # Get canvas dimensions
        width = painter.device().width()
        height = painter.device().height()

        painter.setRenderHint(painter.Antialiasing, True)
        txt = QTextDocument()
        html = '<span style="background-color:%s; padding: 5px;"><font face="%s" size="%s" color="%s">%s</font></span>' % \
               (self.labelOptions.bgcolor, self.labelOptions.font, self.labelOptions.size, self.labelOptions.color, labelString)
        txt.setHtml(html)
        layout = txt.documentLayout()
        size = layout.documentSize()
        
        x = width - 5 - size.width() if flags & Qt.AlignRight else 5
        y = height - 5 - size.height() if flags & Qt.AlignBottom else 5

        painter.translate(x, y)
        layout.draw(painter, QAbstractTextDocumentLayout.PaintContext())
        painter.translate(-x, -y)  # translate back
Ejemplo n.º 4
0
def build_query(start_dt, end_dt, from_attr, to_attr, date_type, date_format, query_idiom, acc):
    """Build subset query"""

    if acc:
        # features never die
        start_dt = time_util.get_min_dt()

    comparison = "<" if to_attr == from_attr else "<="

    if date_type == DateTypes.IntegerTimestamps:
        start_epoch = time_util.datetime_to_epoch(start_dt)
        end_epoch = time_util.datetime_to_epoch(end_dt)
        return INT_FORMAT.format(from_attr, comparison, end_epoch, to_attr,
                                 start_epoch)

    start_str = time_util.datetime_to_str(start_dt, date_format)
    end_str = time_util.datetime_to_str(end_dt, date_format)

    if date_type == DateTypes.DatesAsStringsArchaelogical:
        return build_query_archaelogical(start_str, end_str, from_attr, to_attr, comparison,
                                         query_idiom)

    if can_compare_lexicographically(date_format):
        if query_idiom == QueryIdioms.OGR:
            return STRINGCAST_FORMAT.format(from_attr, comparison, end_str, to_attr, start_str)
        else:
            return STRING_FORMAT.format(from_attr, comparison, end_str, to_attr, start_str)

    else:
        # thankfully, SQL & OGR syntax agree on substr and concat
        if date_type != DateTypes.DatesAsStrings:
            raise QueryBuildingException()
        ioy = date_format.find("%Y")
        iom = date_format.find("%m")
        iod = date_format.find("%d")
        ioh = date_format.find("%H")

        sub1 = create_ymd_substring(ioy, iom, iod, ioh, from_attr,
                                    quote_type='"')  # quote type for column
        # names
        sub2 = create_ymd_substring(ioy, iom, iod, ioh, end_str,
                                    quote_type='\'')  # quote type for values
        sub3 = create_ymd_substring(ioy, iom, iod, ioh, to_attr, quote_type='"')
        sub4 = create_ymd_substring(ioy, iom, iod, ioh, start_str, quote_type='\'')
        query = "CONCAT({}) {} CONCAT({}) AND CONCAT({})>=CONCAT({})".format(sub1, comparison,
                                                                             sub2, sub3, sub4)
        return query
Ejemplo n.º 5
0
    def getMinMaxValues(self):
        """Returns str"""
        if self.minValue is None or self.maxValue is None:  # if not already computed
            fmt = self.getTimeFormat()
            if self.getDateType() == DateTypes.IntegerTimestamps:
                self.minValue = self.getRawMinValue()
                self.maxValue = self.getRawMaxValue()
            else:
                # need to find min max by looking at all the unique values
                # QGIS doesn't get sorting right
                uniques = self.getUniques(self.fromTimeAttribute)
                # those can be either strings or qdate(time) values

                def vals_to_dt(vals, fmt):
                    res = []
                    for val in vals:
                        try:
                            dt = timeval_to_datetime(val, fmt)
                            res.append(dt)
                            # info("{} converted to {}".format(val, dt))
                        except Exception, e:
                            warn("Unparseable value {} in layer {} ignored. Cause {}".format(val,
                                                                                             self.layer.name(),
                                                                                             e))
                            pass
                    return res

                unique_vals = vals_to_dt(uniques, fmt)
                if len(unique_vals) == 0:
                    raise Exception("Could not parse any dates while trying to get time extents." +
                                    "None of the values (for example {}) matches the format {}"
                                    .format(uniques[-1], fmt))
                minValue = datetime_to_str(min(unique_vals), fmt)
                if self.fromTimeAttribute == self.toTimeAttribute:
                    maxValue = datetime_to_str(max(unique_vals), fmt)
                else:
                    unique_vals = self.getUniques(self.toTimeAttribute)
                    unique_vals = vals_to_dt(unique_vals, fmt)
                    maxValue = datetime_to_str(max(unique_vals), fmt)

                if type(minValue) in [QtCore.QDate, QtCore.QDateTime]:
                    minValue = datetime_to_str(QDateTime_to_datetime(minValue),
                                               self.getTimeFormat())
                    maxValue = datetime_to_str(QDateTime_to_datetime(maxValue),
                                               self.getTimeFormat())
                self.minValue = minValue
                self.maxValue = maxValue
Ejemplo n.º 6
0
    def refreshGuiTimeExtents(self, timeExtents):
        """Update time extents showing in labels and represented by horizontalTimeSlider
        :param timeExtents: a tuple of start and end datetimes
        """
        self.setPropagateGuiChanges(False)
        if timeExtents[
                1] is not None:  # timeExtents[0] is set in different places, so only check timeExtents[1]
            startText = time_util.datetime_to_str(timeExtents[0],
                                                  time_util.DEFAULT_FORMAT)
            endText = time_util.datetime_to_str(timeExtents[1],
                                                time_util.DEFAULT_FORMAT)
            self.guiControl.dock.labelStartTime.setText(startText)
            self.guiControl.dock.labelEndTime.setText(endText)

            timeLength = time_util.datetime_to_epoch(
                timeExtents[1]) - time_util.datetime_to_epoch(timeExtents[0])

            if timeLength > MAX_TIME_LENGTH_SECONDS_SLIDER:
                new_granularity = int(
                    math.ceil(1.0 * timeLength /
                              MAX_TIME_LENGTH_SECONDS_SLIDER))
                self.setGranularitySeconds(new_granularity)
                # trick because timeLength must fit in an integer
                # since it interfaces with a C++ class
                newTimeLength = int(
                    math.ceil(1.0 * timeLength / new_granularity))
                timeLength = newTimeLength

            else:
                self.setGranularitySeconds(conf.DEFAULT_GRANULARITY_IN_SECONDS)

            self.guiControl.dock.horizontalTimeSlider.setMinimum(0)
            self.guiControl.dock.horizontalTimeSlider.setMaximum(timeLength)

        else:  # set to default values
            self.setGranularitySeconds(conf.DEFAULT_GRANULARITY_IN_SECONDS)
            self.guiControl.dock.labelStartTime.setText('not set')
            self.guiControl.dock.labelEndTime.setText('not set')
            self.guiControl.dock.horizontalTimeSlider.setMinimum(
                conf.MIN_TIMESLIDER_DEFAULT)
            self.guiControl.dock.horizontalTimeSlider.setMaximum(
                conf.MAX_TIMESLIDER_DEFAULT)

        self.setPropagateGuiChanges(True)
Ejemplo n.º 7
0
 def getLabel(self, dt):
     if self.type=="dt":
         return datetime_to_str(dt, self.fmt)
     if self.type=="epoch":
         return "Seconds elapsed: {}".format((dt - datetime(1970,1,1,0,0)).total_seconds())
     if self.type=="beginning":
         min_dt =  self.model.getProjectTimeExtents()[0]
         return "Seconds elapsed: {}".format((dt - min_dt).total_seconds())
     else:
         raise Exception("Unsupported type {}".format(self.type))
Ejemplo n.º 8
0
    def getSaveString(self):
        """create a save string that can be put into project file"""
        tdfmt = time_util.SAVE_STRING_FORMAT
        saveListLayers = []

        try:  # test if projectTimeExtens are populated with datetimes
            time_util.datetime_to_str(self.getProjectTimeExtents()[0], tdfmt)
        except:
            return (None, None)

        saveString = conf.SAVE_DELIMITER.join([
            time_util.datetime_to_str(self.getProjectTimeExtents()[0], tdfmt),
            time_util.datetime_to_str(self.getProjectTimeExtents()[1], tdfmt),
            time_util.datetime_to_str(self.getCurrentTimePosition(), tdfmt)
        ])
        for timeLayer in self.getTimeLayerList():
            saveListLayers.append(timeLayer.getSaveString())

        return (saveString, saveListLayers)
Ejemplo n.º 9
0
 def getLabel(self, dt):
     if self.type=="dt":
         return time_util.datetime_to_str(dt, self.fmt)
     if self.type=="epoch":
         return "Seconds elapsed: {}".format((dt - datetime(1970,1,1,0,0)).total_seconds())
     if self.type=="beginning":
         min_dt =  self.model.getProjectTimeExtents()[0]
         return "Seconds elapsed: {}".format((dt - min_dt).total_seconds())
     else:
         raise Exception("Unsupported type {}".format(self.type))
Ejemplo n.º 10
0
def build_query(start_dt, end_dt, from_attr, to_attr, date_type, date_format, query_idiom, acc):
    """Build subset query"""
    if acc: # features never die
        start_dt = time_util.get_min_dt()
    
    comparison = "<" # simplified because of: https://github.com/anitagraser/TimeManager/issues/235 
    #                  (original: # comparison = "<" if to_attr == from_attr else "<=")    

    if date_type == time_util.DateTypes.IntegerTimestamps:
        start_epoch = time_util.datetime_to_epoch(start_dt)
        end_epoch = time_util.datetime_to_epoch(end_dt)
        return INT_FORMAT.format(from_attr, comparison, end_epoch, to_attr, start_epoch)
    
    start_str = time_util.datetime_to_str(start_dt, date_format)
    end_str = time_util.datetime_to_str(end_dt, date_format)    
    
    if date_type == time_util.DateTypes.DatesAsStringsArchaelogical:
        # kept <= option here since I'm not sure about implications in archaelogical mode 
        comparison = "<" if to_attr == from_attr else "<=" 
        return build_query_archaelogical(start_str, end_str, from_attr, to_attr, comparison, query_idiom)
    
    if can_compare_lexicographically(date_format):
        if query_idiom == QueryIdioms.OGR:
            return STRINGCAST_FORMAT.format(from_attr, comparison, end_str, to_attr, start_str)
        else:
            return STRING_FORMAT.format(from_attr, comparison, end_str, to_attr, start_str)
    else:
        # thankfully, SQL & OGR syntax agree on substr and concat
        if date_type != time_util.DateTypes.DatesAsStrings:
            raise QueryBuildingException()
        ioy = date_format.find("%Y")
        iom = date_format.find("%m")
        iod = date_format.find("%d")
        ioh = date_format.find("%H")

        sub1 = create_ymd_substring(ioy, iom, iod, ioh, from_attr, quote_type='"')  # quote type for column names
        sub2 = create_ymd_substring(ioy, iom, iod, ioh, end_str, quote_type='\'')  # quote type for values
        sub3 = create_ymd_substring(ioy, iom, iod, ioh, to_attr, quote_type='"')
        sub4 = create_ymd_substring(ioy, iom, iod, ioh, start_str, quote_type='\'')
        query = "CONCAT({}) {} CONCAT({}) AND CONCAT({})>=CONCAT({})".format(sub1, comparison, sub2, sub3, sub4)
        return query
Ejemplo n.º 11
0
def build_query(start_dt, end_dt, from_attr, to_attr, date_type, date_format,
                query_idiom):
    """Build subset query"""

    comparison = "<" if to_attr == from_attr else "<="

    if date_type == DateTypes.IntegerTimestamps:
        start_epoch = time_util.datetime_to_epoch(start_dt)
        end_epoch = time_util.datetime_to_epoch(end_dt)
        return INT_FORMAT.format(from_attr, comparison, end_epoch, to_attr,
                                 start_epoch)

    start_str = time_util.datetime_to_str(start_dt, date_format)
    end_str = time_util.datetime_to_str(end_dt, date_format)

    if can_compare_lexicographically(date_format):
        if query_idiom == QueryIdioms.OGR:
            return STRINGCAST_FORMAT.format(from_attr, comparison, end_str,
                                            to_attr, start_str)
        else:
            return STRING_FORMAT.format(from_attr, comparison, end_str,
                                        to_attr, start_str)

    else:
        # thankfully, SQL & OGR syntax agree on substr and concat
        if date_type != DateTypes.DatesAsStrings:
            raise QueryBuildingException()
        ioy = date_format.find("%Y")
        iom = date_format.find("%m")
        iod = date_format.find("%d")
        sub1 = create_ymd_substring(ioy, iom, iod, from_attr, quote_type='"')
        sub2 = create_ymd_substring(ioy, iom, iod, end_str, quote_type='\'')
        sub3 = create_ymd_substring(ioy, iom, iod, to_attr, quote_type='"')
        sub4 = create_ymd_substring(ioy, iom, iod, start_str, quote_type='\'')
        return "CONCAT({}) {} CONCAT({}) AND CONCAT({})>=CONCAT({})".format(
            sub1, comparison, sub2, sub3, sub4)
Ejemplo n.º 12
0
    def getMinMaxValues(self):
        """Returns str"""
        if self.minValue is None or self.maxValue is None:  # if not already computed
            provider = self.layer.dataProvider()
            fmt = self.getTimeFormat()
            fromTimeAttributeIndex = provider.fieldNameIndex(
                self.fromTimeAttribute)
            toTimeAttributeIndex = provider.fieldNameIndex(
                self.toTimeAttribute)
            if query_builder.can_compare_lexicographically(fmt):
                minValue = provider.minimumValue(fromTimeAttributeIndex)
                maxValue = provider.maximumValue(toTimeAttributeIndex)
            else:
                # need to find min max by looking at all the unique values
                # QGIS doesn't get sorting right

                unique_vals = provider.uniqueValues(fromTimeAttributeIndex)
                unique_vals = map(lambda x: str_to_datetime(x, fmt),
                                  unique_vals)
                minValue = datetime_to_str(min(unique_vals), fmt)
                if fromTimeAttributeIndex == toTimeAttributeIndex:
                    maxValue = datetime_to_str(max(unique_vals), fmt)
                else:
                    unique_vals = provider.uniqueValues(toTimeAttributeIndex)
                    unique_vals = map(lambda x: str_to_datetime(x, fmt),
                                      unique_vals)
                    maxValue = datetime_to_str(max(unique_vals), fmt)

            if type(minValue) in [QtCore.QDate, QtCore.QDateTime]:
                minValue = datetime_to_str(QDateTime_to_datetime(minValue),
                                           self.getTimeFormat())
                maxValue = datetime_to_str(QDateTime_to_datetime(maxValue),
                                           self.getTimeFormat())
            self.minValue = minValue
            self.maxValue = maxValue
        return self.minValue, self.maxValue
Ejemplo n.º 13
0
    def writeSettings(self):
        """Write all relevant settings to the project file XML """
        if not self.getTimeLayerManager().isEnabled():
            return
        (timeLayerManagerSettings,
         timeLayerList) = self.getTimeLayerManager().getSaveString()

        if timeLayerManagerSettings is not None:
            settings = {
                'animationFrameLength':
                self.animationFrameLength,
                'playBackwards':
                self.playBackwards,
                'loopAnimation':
                self.loopAnimation,
                'timeLayerManager':
                timeLayerManagerSettings,
                'timeLayerList':
                timeLayerList,
                'currentMapTimePosition':
                time_util.datetime_to_str(
                    self.getTimeLayerManager().getCurrentTimePosition(),
                    time_util.DEFAULT_FORMAT),
                'timeFrameType':
                self.getTimeLayerManager().getTimeFrameType(),
                'timeFrameSize':
                self.getTimeLayerManager().getTimeFrameSize(),
                'active':
                self.getTimeLayerManager().isEnabled(),
                'mode':
                int(time_util.is_archaelogical()),
                'digits':
                time_util.getArchDigits(),
                'labelFormat':
                self.guiControl.getLabelFormat(),
                'labelFont':
                self.guiControl.getLabelFont(),
                'labelSize':
                self.guiControl.getLabelSize(),
                'labelColor':
                self.guiControl.getLabelColor(),
                'labelBgColor':
                self.guiControl.getLabelBgColor(),
                'labelPlacement':
                self.guiControl.getLabelPlacement()
            }

            TimeManagerProjectHandler.writeSettings(settings)
Ejemplo n.º 14
0
 def animation_datetime(values, feature, parent):
     """called by QGIS to determine the current animation time"""
     return time_util.datetime_to_str(control.getTimeLayerManager().getCurrentTimePosition(),
                                      time_util.DEFAULT_FORMAT)
Ejemplo n.º 15
0
def epoch_to_str(seconds_from_epoch):
    return time_util.datetime_to_str(
        time_util.epoch_to_datetime(seconds_from_epoch))
Ejemplo n.º 16
0
 def animation_datetime(values, feature, parent):
     """called by QGIS to determine the current animation time"""
     return time_util.datetime_to_str(
         control.getTimeLayerManager().getCurrentTimePosition(),
         time_util.DEFAULT_FORMAT)
Ejemplo n.º 17
0
 def animation_end_datetime(values, feature, parent):
     """Last time stamp"""
     return time_util.datetime_to_str(
         control.getTimeLayerManager().getProjectTimeExtents()[1],
         time_util.DEFAULT_FORMAT)