Example #1
0
class Cu_Video_TrackerDialog(QtGui.QDialog):
    def __init__(self, iface):
        QtGui.QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.iface = iface
        self.ui.sourceLoad_pushButton.clicked.connect(self.OpenButton)
        self.ui.replayPlay_pushButton.clicked.connect(self.PlayPauseButton)
        QObject.connect(self.ui.replay_mapTool_pushButton,
                        SIGNAL("toggled(bool)"), self.replayMapTool_toggled)
        self.positionMarker = None
        settings = QSettings()
        settings.beginGroup("/plugins/PlayerPlugin")
        self.replay_followPosition = settings.value("followPosition",
                                                    True,
                                                    type=bool)
        settings.setValue("followPosition", self.replay_followPosition)

        QObject.connect(self.iface.mapCanvas(),
                        SIGNAL("mapToolSet(QgsMapTool*)"), self.mapToolChanged)
        self.mapTool = ReplayMapTool(self.iface.mapCanvas(), self)
        self.mapTool_previous = None
        self.mapToolChecked = property(self.__getMapToolChecked,
                                       self.__setMapToolChecked)

        QObject.connect(self.ui.replayPosition_horizontalSlider,
                        SIGNAL('sliderMoved(int)'),
                        self.replayPosition_sliderMoved)
        QObject.connect(self.ui.addpoint_button, SIGNAL('clicked()'),
                        self.snapshot)
        QObject.connect(self.ui.ExporText_button, SIGNAL('clicked()'),
                        self.exportText)
        QObject.connect(self.ui.ExporShp_button, SIGNAL('clicked()'),
                        self.exportShp)
        QObject.connect(self.ui.ExporSqlite_button, SIGNAL('clicked()'),
                        self.exportSqlite)
        QObject.connect(self.ui.ExporKML_button, SIGNAL('clicked()'),
                        self.exportKML)
        QObject.connect(self.ui.Help, SIGNAL('clicked()'), self.Help)

        self.PlayPuase = 0  # Puase=0,Play=1
        self.Close = 0  # select video=1 , Close=0
        self.adactProjection = False
        self.createLayer = 0  # Default layer=1,create by user=2,load existent=else
        self.videoWidget = Phonon.VideoWidget(self.ui.video_widget)

    def OpenButton(self):
        if self.Close == 1:
            if self.positionMarker != None:
                self.iface.mapCanvas().scene().removeItem(self.positionMarker)
                self.positionMarker = None
            self.Close = 0
            self.ui.replay_mapTool_pushButton.setChecked(False)
            self.ui.sourceLoad_pushButton.setText('Open...')
            self.createLayer = 0
            self.timer.stop()
            ##self.timer2.stop()
            self.media_obj.stop()
            self.iface.mapCanvas().unsetMapTool(self.mapTool)
            self.close()

        else:

            self.path = QtGui.QFileDialog.getOpenFileName(
                self, self.tr("Select Video files"))
            self.csvFile = open(self.path + '.csv', "rb")
            Filereader = csv.DictReader(self.csvFile)
            self.CSVLayer = QgsVectorLayer("LineString", "GPS Tracking",
                                           "memory")

            self.latt = []
            self.lonn = []
            self.timeh = []
            self.timem = []
            self.times = []
            i = 0
            for row in Filereader:
                self.latt.append(float(row['lon']))
                self.lonn.append(float(row['lat']))
                if row['time_h'] != '':
                    self.timeh.append(int(row['time_h']))
                    self.timem.append(int(row['time_m']))
                    self.times.append(int(row['time_s']))

            #create tracker layer (line layer)
            for i in xrange(0, len(self.latt) - 1, 1):
                point_start = QgsPoint(self.latt[i], self.lonn[i])
                point_end = QgsPoint(self.latt[i + 1], self.lonn[i + 1])
                line = QgsGeometry.fromPolyline([point_start, point_end])
                self.pr = self.CSVLayer.dataProvider()
                afeature = QgsFeature()
                afeature.setGeometry(
                    QgsGeometry.fromPolyline([point_start, point_end]))
                self.pr.addFeatures([afeature])
                self.CSVLayer.updateExtents()
            QgsMapLayerRegistry.instance().addMapLayers([self.CSVLayer])

            SelectLayer, ok = QInputDialog.getItem(
                self.iface.mainWindow(), "Layer chooser", "Choose point layer",
                ('Default point layer', 'Creat new point layer',
                 'Load existent point layer'))
            if SelectLayer == 'Load existent point layer':
                self.newLayerPath = QtGui.QFileDialog.getOpenFileName()
                if not self.newLayerPath is None:
                    name = self.newLayerPath.split("/")[-1][0:-4]
                    self.vl = QgsVectorLayer(self.newLayerPath, name, "ogr")
                    self.pr = self.vl.dataProvider()
                    fields = self.pr.fields()
                    field_names = [field.name() for field in fields]
                    f = "Image link"
                    fnd = self.vl.fieldNameIndex(f)
                    fn = field_names[fnd]
                    if not fn == f:
                        self.pr.addAttributes(
                            [QgsField("Image link", QVariant.String)])

                    QgsMapLayerRegistry.instance().addMapLayer(self.CSVLayer)
                    QgsMapLayerRegistry.instance().addMapLayer(self.vl)

            elif SelectLayer == 'Default point layer':
                self.vl = QgsVectorLayer("Point?crs=epsg:4326&index=yes",
                                         "point", "memory")
                self.pr = self.vl.dataProvider()
                self.pr.addAttributes([
                    QgsField('id', QVariant.Int),
                    QgsField('Name', QVariant.String),
                    QgsField('Description', QVariant.String),
                    QgsField('Type', QVariant.String),
                    QgsField("Lon", QVariant.String),
                    QgsField("Lat", QVariant.String),
                    QgsField('East UTM', QVariant.String),
                    QgsField('North UTM', QVariant.String),
                    QgsField('Image link', QVariant.String)
                ])

                # update layer's extent
                self.vl.updateExtents()
                QgsMapLayerRegistry.instance().addMapLayer(self.CSVLayer)
                QgsMapLayerRegistry.instance().addMapLayers([self.vl])
                self.createLayer = 1

            else:
                # Creat new point layer by user
                self.createLayer = 2
                self.vl = QgsVectorLayer("Point?crs=epsg:4326&index=yes",
                                         "point", "memory")
                self.pr = self.vl.dataProvider()
                # table manager dialog
                self.dialoga = TableManager(self.iface, self.vl, self.CSVLayer)
                self.dialoga.exec_()

            #set point label
            palyr = QgsPalLayerSettings()
            palyr.readFromLayer(self.vl)
            palyr.enabled = True
            palyr.fieldName = 'id'
            palyr.placement = QgsPalLayerSettings.Upright
            palyr.setDataDefinedProperty(QgsPalLayerSettings.Size, True, True,
                                         '14', '')
            palyr.writeToLayer(self.vl)

            if self.positionMarker == None:
                self.positionMarker = PositionMarker(self.iface.mapCanvas())

            self.media_src = Phonon.MediaSource(self.path)
            self.media_obj = Phonon.MediaObject(self)
            self.media_obj.setCurrentSource(self.media_src)
            Phonon.createPath(self.media_obj, self.videoWidget)

            # set audio
            ##            audio_out = Phonon.AudioOutput(Phonon.VideoCategory, self)
            ##            Phonon.createPath(self.media_obj, audio_out)

            self.ui.video_widget.resizeEvent = self.Resize()
            self.media_obj.setTickInterval(100)
            self.timer = QtCore.QTimer()
            QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                                   self.Timer)

            self.PlayPuase = 1
            self.ui.sourceLoad_pushButton.setText('Close')
            self.Close = 1  #load file selector
            self.media_obj.play()  #phonon play
            self.timer.start(1000)

            self.ui.replayPlay_pushButton.setEnabled(True)
            self.ui.addpoint_button.setEnabled(True)

    def Resize(self):
        a = self.ui.video_widget.frameSize()
        b = self.videoWidget.frameSize()
        if a != b:
            self.videoWidget.resize(a)

    def CurrentPos(self):
        end = self.media_obj.totalTime()
        pos = self.media_obj.currentTime()
        if pos == end:
            self.timer.stop()
            self.media_obj.pause()
            if self.PlayPuase == 1:
                self.PlayPuase = 0
        else:
            Pos = pos / 1000
            self.ui.replayPosition_label.setText(
                str(datetime.timedelta(seconds=int(Pos))) + '/' +
                str(datetime.timedelta(seconds=(int(end / 1000)))))
            return int(Pos)

    def Timer(self):
        if self.PlayPuase == 1:
            self.updateReplayPosition()
            self.SetSlide()
        else:
            pass

    def TimeOffset(self):
        self.current_second = []
        self.time_offset = []

        if self.timeh != []:
            for i in xrange(0, len(self.timeh), 1):
                h_second = int(self.timeh[i]) * 60 * 60
                m_second = int(self.timem[i]) * 60
                s_second = int(self.times[i])
                c_second = h_second + m_second + s_second
                self.current_second.append(c_second)
                t_of = int(
                    int(self.current_second[i]) - int(self.current_second[0]))
                self.time_offset.append(t_of)
        else:
            #find time offset
            for i in xrange(0, len(self.latt), 1):
                # Number of record in csv
                self.NumRec = len(self.latt)
                #create new list start at 0
                self.L_Num = range(len(self.latt))
                #time interval
                self.t_interval = ((self.media_obj.totalTime() / 1000) /
                                   float(self.NumRec - 1))
                t_of = self.L_Num[i] * self.t_interval
                self.time_offset.append(t_of)
        return self.time_offset

    def updateReplayPosition(self):
        pos = self.CurrentPos()

        # find the nearest timestamp offset of position time in logging data
        TimeOffset = self.TimeOffset()
        i = min(range(len(TimeOffset)),
                key=lambda x: abs(TimeOffset[x] - ((pos))))
        if pos - 1 == (self.media_obj.totalTime() / 1000 - 1):
            self.media_obj.stop()
        if pos - TimeOffset[i] == 0:
            self.lat_new = self.latt[i]
            self.lon_new = self.lonn[i]
        else:
            if pos < TimeOffset[i]:
                Dlat = self.latt[i] - self.latt[i - 1]
                Dlon = self.lonn[i] - self.lonn[i - 1]
                Dtime = TimeOffset[i] - TimeOffset[i - 1]
            else:
                Dlat = self.latt[i + 1] - self.latt[i]
                Dlon = self.lonn[i + 1] - self.lonn[i]
                Dtime = TimeOffset[i + 1] - TimeOffset[i]

            Dti = float(pos - TimeOffset[i])
            Dlat_i = Dlat * (Dti / Dtime)
            Dlon_i = Dlon * (Dti / Dtime)
            self.lat_new = self.latt[i] + Dlat_i
            self.lon_new = self.lonn[i] + Dlon_i

        self.lat, self.lon = self.lat_new, self.lon_new
        self.Point = QgsPoint()
        self.Point.set(self.lat, self.lon)

        canvas = self.iface.mapCanvas()
        mapRenderer = canvas.mapRenderer()
        crsSrc = QgsCoordinateReferenceSystem(4326)  # WGS 84
        crsDest = mapRenderer.destinationCrs()

        xform = QgsCoordinateTransform(
            crsSrc, crsDest)  #usage: xform.transform(QgsPoint)

        self.positionMarker.setHasPosition(True)
        self.Point = xform.transform(self.Point)
        self.positionMarker.newCoords(self.Point)

        if self.replay_followPosition:
            extent = self.iface.mapCanvas().extent()

        boundaryExtent = QgsRectangle(extent)
        boundaryExtent.scale(1.0)
        if not boundaryExtent.contains(QgsRectangle(self.Point, self.Point)):
            extentCenter = self.Point
            newExtent = QgsRectangle(extentCenter.x() - extent.width() / 1.7,
                                     extentCenter.y() - extent.height() / 1.7,
                                     extentCenter.x() + extent.width() / 17,
                                     extentCenter.y() + extent.height() / 1.7)
            self.iface.mapCanvas().setExtent(newExtent)
            self.iface.mapCanvas().refresh()

        East, North, alt = self.transform_wgs84_to_utm(self.lat_new,
                                                       self.lon_new)
        self.ui.E.setText('Easting : ' + str(East))
        self.ui.N.setText('Northing : ' + str(North))
        self.ui.lat.setText('Latitude : ' + str(self.lon_new))
        self.ui.lon.setText('Longitude : ' + str(self.lat_new))

    def PlayPauseButton(self):
        if self.PlayPuase == 1:
            self.media_obj.pause()
            self.timer.stop()
            self.PlayPuase = 0
        else:
            self.media_obj.play()
            self.timer.start(0)
            self.PlayPuase = 1

    def replayMapTool_toggled(self, checked):
        """Enable/disable replay map tool"""
        self.useMapTool(checked)

    def useMapTool(self, use):
        """ afer you click on it, you can seek the video just clicking on the gps track """

        if use:
            if self.iface.mapCanvas().mapTool() != self.mapTool:
                self.mapTool_previous = self.iface.mapCanvas().mapTool()
                self.iface.mapCanvas().setMapTool(self.mapTool)
        else:
            if self.mapTool_previous != None:
                self.iface.mapCanvas().setMapTool(self.mapTool_previous)
            else:
                self.iface.mapCanvas().unsetMapTool(self.mapTool)

    def mapToolChanged(self, tool):
        """Handle map tool changes outside  plugin"""
        if (tool != self.mapTool) and self.mapToolChecked:
            self.mapTool_previous = None
            self.mapToolChecked = False

    def __getMapToolChecked(self):
        return self.replay_mapTool_pushButton.isChecked()

    def __setMapToolChecked(self, val):
        self.replay_mapTool_pushButton.setChecked(val)

    def findNearestPointInRecording(self, toPoint):
        """ Find the point nearest to the specified point (in map coordinates) """
        for i in xrange(0, len(self.latt), 1):
            if (str(self.latt[i]))[0:7] == str(toPoint.x())[0:7] and (str(
                    self.lonn[i]))[0:7] == (str(toPoint.y()))[0:7]:
                adj = (self.time_offset[i]) - (self.time_offset[0])
                lat, lon = (self.latt[i]), (self.lonn[i])
                Point = QgsPoint()
                Point.set(lat, lon)
                self.positionMarker.newCoords(Point)
                self.Seek(adj)
                break

    def Seek(self, pos):
        if self.PlayPuase == 0:
            self.timer.stop()
            self.media_obj.seek(pos * 1000)
            self.media_obj.play()
            self.timer.start(0)
            self.PlayPuase = 1
        else:
            self.media_obj.seek(pos * 1000)
            self.timer.start(1000)

    def replayPosition_sliderMoved(self, pos):
        """Handle moving of replay position slider by user"""
        self.Seek(pos)

    def SetSlide(self):
        end = self.media_obj.totalTime()
        pos = self.media_obj.currentTime()
        self.endtime = (self.media_obj.totalTime() / 1000)
        self.ui.replayPosition_horizontalSlider.setMinimum(0)
        self.ui.replayPosition_horizontalSlider.setMaximum((self.endtime))
        if not pos == end:
            pos = float(self.CurrentPos())
            self.ui.replayPosition_horizontalSlider.setValue(pos)

    def AddPoint(self, toPoint):
        if self.PlayPuase == 1:
            self.media_obj.pause()
            self.timer.stop()
            self.PlayPuase = 0
        else:
            pass

        last_desc = '///'
        fc = int(self.pr.featureCount() + 1)
        if self.createLayer == 1:
            self.vl.dataProvider()
            filename = self.path + '__' + str(self.getImageFileName()) + '.jpg'
            p = QPixmap.grabWidget(self.videoWidget)
            p.save(filename)

            (Name, ok) = QInputDialog.getText(self.iface.mainWindow(),
                                              "Attributes", "Name",
                                              QLineEdit.Normal, last_desc)

            (Description,
             ok) = QInputDialog.getText(self.iface.mainWindow(), "Attributes",
                                        "Description", QLineEdit.Normal,
                                        last_desc)

            (Type, ok) = QInputDialog.getText(self.iface.mainWindow(),
                                              "Attributes", "Type",
                                              QLineEdit.Normal, last_desc)

            # create the feature
            feature = QgsFeature()
            lat, lon = toPoint.x(), toPoint.y()
            Point = QgsPoint()
            Point.set(lat, lon)
            EastUTM, NorthUTM, alt = self.transform_wgs84_to_utm(lat, lon)
            feature.setGeometry(QgsGeometry.fromPoint(Point))

            feature.setAttributes([
                fc, Name, Description, Type, lat, lon, EastUTM, NorthUTM,
                self.path + '__' + str(self.getImageFileName()) + '.jpg'
            ])
            self.vl.startEditing()
            self.vl.addFeature(feature, True)
            self.vl.commitChanges()
            self.vl.setCacheImage(None)
            self.vl.triggerRepaint()
            os.rename(filename,
                      self.path + '__' + str(self.getImageFileName()) + '.jpg')

        elif self.createLayer == 2:
            p = QPixmap.grabWidget(self.videoWidget)
            fields = self.pr.fields()
            attributes = []
            lat, lon = toPoint.x(), toPoint.y()
            for field in fields:
                a = str(field.name())
                b = str(field.typeName())
                if a == 'id':
                    fcnr = fc
                    attributes.append(fcnr)
                elif a == 'Lon':
                    attributes.append(lat)

                elif a == 'Lat':
                    attributes.append(lon)

                else:

                    if b == 'String':
                        (a, ok) = QInputDialog.getText(self.iface.mainWindow(),
                                                       "Attributes",
                                                       a + ' = ' + b,
                                                       QLineEdit.Normal)
                        attributes.append(a)

                    elif b == 'Real':
                        (a,
                         ok) = QInputDialog.getDouble(self.iface.mainWindow(),
                                                      "Attributes",
                                                      a + ' = ' + b,
                                                      decimals=10)
                        attributes.append(a)

                    elif b == 'Integer':
                        (a, ok) = QInputDialog.getInt(self.iface.mainWindow(),
                                                      "Attributes",
                                                      a + ' = ' + b)
                        attributes.append(a)

            feature = QgsFeature()
            Point = QgsPoint()
            Point.set(lat, lon)

            #use in new table
            filename = self.path + '__' + str(self.getImageFileName()) + '.jpg'
            p.save(filename)
            attributes.append(filename)
            feature.setGeometry(QgsGeometry.fromPoint(Point))
            feature.setAttributes(attributes)
            self.vl.startEditing()
            self.vl.addFeature(feature, True)
            self.vl.commitChanges()
            self.vl.setCacheImage(None)
            self.vl.triggerRepaint()
            os.rename(filename,
                      self.path + '__' + str(self.getImageFileName()) + '.jpg')

        else:

            p = QPixmap.grabWidget(self.videoWidget)

            fields = self.pr.fields()
            attributes = []
            lat, lon = toPoint.x(), toPoint.y()
            for field in fields:
                a = str(field.name())
                b = str(field.typeName())
                if a == 'id':
                    fcnr = fc
                    attributes.append(fcnr)
                elif a == 'Lon':
                    attributes.append(lat)

                elif a == 'Lat':
                    attributes.append(lon)

                else:

                    if b == 'String':
                        (a, ok) = QInputDialog.getText(self.iface.mainWindow(),
                                                       "Attributes",
                                                       a + ' = ' + b,
                                                       QLineEdit.Normal)
                        attributes.append(a)

                    elif b == 'Real':
                        (a,
                         ok) = QInputDialog.getDouble(self.iface.mainWindow(),
                                                      "Attributes",
                                                      a + ' = ' + b,
                                                      decimals=10)
                        attributes.append(a)

                    elif b == 'Integer':
                        (a, ok) = QInputDialog.getInt(self.iface.mainWindow(),
                                                      "Attributes",
                                                      a + ' = ' + b)
                        attributes.append(a)

            feature = QgsFeature()
            Point = QgsPoint()
            Point.set(lat, lon)
            #use in existent table
            feature.setGeometry(QgsGeometry.fromPoint(Point))
            feature.setAttributes(attributes)
            filename = self.path + '__' + str(self.getImageFileName()) + '.jpg'
            p.save(filename)
            field_index = self.pr.fieldNameIndex('Image link')
            feature.setAttribute(field_index, filename)
            self.vl.startEditing()
            self.vl.addFeature(feature, True)
            self.vl.commitChanges()
            self.vl.setCacheImage(None)
            self.vl.triggerRepaint()
            os.rename(filename,
                      self.path + '__' + str(self.getImageFileName()) + '.jpg')

        self.ui.ExporText_button.setEnabled(True)
        self.ui.ExporShp_button.setEnabled(True)
        self.ui.ExporSqlite_button.setEnabled(True)
        self.ui.ExporKML_button.setEnabled(True)

    def getImageFileName(self):

        current_time_now = time.time()
        ctn_int = int(current_time_now)
        return ctn_int

    def transform_wgs84_to_utm(self, lon, lat):
        def get_utm_zone(longitude):
            return (int(1 + (longitude + 180.0) / 6.0))

        def is_northern(latitude):
            """
            Determines if given latitude is a northern for UTM
            """

            if (latitude < 0.0):
                return 0
            else:
                return 1

        utm_coordinate_system = osr.SpatialReference()
        utm_coordinate_system.SetWellKnownGeogCS(
            "WGS84")  # Set geographic coordinate system to handle lat/lon
        utm_coordinate_system.SetUTM(get_utm_zone(lon), is_northern(lat))

        wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS(
        )  # Clone ONLY the geographic coordinate system

        # create transform component
        wgs84_to_utm_transform = osr.CoordinateTransformation(
            wgs84_coordinate_system, utm_coordinate_system)  # (<from>, <to>)
        return wgs84_to_utm_transform.TransformPoint(
            lon, lat, 0)  # returns easting, northing, altitude

    def snapshot(self):
        Point = QgsPoint(self.Point)
        Point.set(self.lat, self.lon)
        self.positionMarker.newCoords(Point)
        self.AddPoint(Point)

    def Help(self):
        path_help = 'C:/Users/Administrator/.qgis2'
        os.startfile(path_help + '/python/plugins/Cu_Video_Tracker/How to.pdf')

    def exportText(self):
        toCSV = QgsVectorFileWriter.writeAsVectorFormat(
            self.vl, self.path + '_'
            'point' + '.csv', "TIS-620", None, "CSV")
        debug = self.path + '_' 'point' + '.csv'
        QtGui.QMessageBox.information(self, 'Export to', debug)

    def exportShp(self):
        toShp = QgsVectorFileWriter.writeAsVectorFormat(
            self.vl, self.path + '_'
            'point' + '.shp', "utf-8", None, "ESRI Shapefile")
        debug = self.path + '_' 'point' + '.shp'
        QtGui.QMessageBox.information(self, 'Export to', debug)

    def exportSqlite(self):
        toSql = QgsVectorFileWriter.writeAsVectorFormat(
            self.vl, self.path + '_'
            'point' + '.sqlite', "utf-8", None, "SQLite")
        debug = self.path + '_' 'point' + '.sqlite'
        QtGui.QMessageBox.information(self, 'Export to', debug)

    def exportKML(self):
        toSql = QgsVectorFileWriter.writeAsVectorFormat(
            self.vl, self.path + '_'
            'point' + '.kml', "utf-8", None, "KML")
        debug = self.path + '_' 'point' + '.kml'
        QtGui.QMessageBox.information(self, 'Export to', debug)
Example #2
0
class QGisMap(QtWidgets.QWidget, Ui_Form):
    
    def __init__(self,projectfile,MainWidget):
        QtWidgets.QMainWindow.__init__(self)
        if os.name == 'nt':
            ffmpeg = os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'
            versione = 'ffmpeg.exe'
        else:
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            versione = 'ffmpeg'
        if os.path.exists(ffmpeg) == True:
            self.setupUi(self)
            self.setWindowFlags(Qt.WindowStaysOnTopHint)
            self.Main = MainWidget
            self.projectfile = projectfile
            with open(self.projectfile,'r') as File:
                    for line in File:
                        if line[0:19] == 'Video file location':
                            self.videoFile = line.split('=')[-1][1:-1]
                        elif line[0:23] == 'Video start at msecond:':
                            self.fps = (1 / (float(line.split()[7]))) * 1000
                            self.StartMsecond = int(line.split()[4])
                        elif line[0:4] == 'DB =':
                            DB = line.split('=')[-1][1:-1]
                            if DB == 'None':
                                self.DB = None
                            else:
                                self.DB = DB
                            break            
            self.pushButton_3.setCheckable(True)
            self.EnableMapTool = False
            self.ExtractTool = 0
            self.dockWidget_4.hide()
            self.GPXList = []
            self.positionMarker=PositionMarker(self.Main.iface.mapCanvas())               
            self.muteButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaVolume))
            self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPause))
            self.player = QMediaPlayer()
            self.player.setVideoOutput(self.video_frame)  
            self.playButton.clicked.connect(self.PlayPause)
            self.muteButton.clicked.connect(self.MuteUnmute)
            self.toolButton_11.clicked.connect(self.SkipBackward)
            self.toolButton_12.clicked.connect(self.SkipForward)
            self.SkipBacktoolButton_8.clicked.connect(self.BackwardFrame)
            self.SkipFortoolButton_9.clicked.connect(self.ForwardFrame)
            self.toolButton_4.clicked.connect(self.ExtractToolbar)
            self.toolButton_5.clicked.connect(self.close)   
            self.pushButtonCut_2.clicked.connect(self.ExtractCommand)
            self.pushButtonCutA_6.clicked.connect(self.ExtractFromA)
            self.pushButtonCutB_6.clicked.connect(self.ExtractToB)
            self.pushButton_5.clicked.connect(self.CancelVertex)  
            self.progressBar.hide()     
            self.Main.pushButton_2.hide()
            self.Main.pushButton_8.hide()
            self.Main.groupBox.show()
            self.Main.groupBox_4.hide()
            self.ExtractA = False
            self.ExtractB = False
            self.ExtractedDirectory = None 
            self.pushButtonCut_2.setEnabled(False)
            self.toolButton_6.setEnabled(False)
            self.LoadGPXVideoFromPrj(self.projectfile)  
        else:
            ret = QMessageBox.warning(self, "Warning", 'missing ffmpeg binaries, please download it from https://github.com/sagost/VideoUavTracker/blob/master/FFMPEG/'+versione+' and paste it in /.qgis3/python/plugins/Video_UAV_Tracker/FFMPEG/ ', QMessageBox.Ok)
            self.close()        
    def LoadGPXVideoFromPrj(self,VideoGisPrj):
        
        self.Polyline = []
        with open(VideoGisPrj,'r') as File:
            Counter = 0
            for line in File:
                if Counter < 5:
                    pass
                else:
                    line = line.split()
                    lat = float(line[0])
                    lon = float(line[1])
                    ele = float(line[2])
                    speed = float(line[3])
                    course = float(line[4])
                    time = line[5]
                    Point = [lat,lon,ele,speed,course,time]
                    qgsPoint = QgsPoint(lon,lat)
                    self.Polyline.append(qgsPoint)
                    self.GPXList.append(Point)
                Counter = Counter + 1
        self.GpsLayer = QgsVectorLayer("LineString?crs=epsg:4326", self.videoFile.split('.')[-2].split('/')[-1], "memory")
        self.pr = self.GpsLayer.dataProvider()
        feat = QgsFeature()
        feat.setGeometry(QgsGeometry.fromPolyline(self.Polyline))
        self.pr.addFeatures([feat])
        self.GpsLayer.updateExtents()
        if self.DB != None:
            try:
                self.DBLayer = QgsVectorLayer(self.DB,self.DB.split('.')[-2].split('/')[-1],'ogr')
                QgsProject.instance().addMapLayers([self.DBLayer,self.GpsLayer]) 
                self.AddPointMapTool = AddPointTool(self.Main.iface.mapCanvas(),self.DBLayer,self)
                self.toolButton_6.clicked.connect(self.AddPointTool)   
                self.toolButton_6.setEnabled(True)
            except:
                ret = QMessageBox.warning(self, "Warning", str(self.DB)+' is not a valid shapefile.', QMessageBox.Ok)
                return
        else:
            QgsProject.instance().addMapLayers([self.GpsLayer])    
        self.duration = len(self.GPXList)
        self.ExtractToB = self.duration
        self.horizontalSlider.setSingleStep(1000)
        self.horizontalSlider.setMinimum(0)
        self.horizontalSlider.setMaximum(len(self.GPXList)*1000)
        url = QUrl.fromLocalFile(str(self.videoFile))
        mc = QMediaContent(url)
        self.player.setMedia(mc)
        self.player.setPosition(self.StartMsecond)
        self.player.play()
        self.horizontalSlider.sliderMoved.connect(self.setPosition)
        self.player.stateChanged.connect(self.mediaStateChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.pushButton_3.clicked.connect(self.MapTool)
        self.skiptracktool = SkipTrackTool( self.Main.iface.mapCanvas(),self.GpsLayer , self)

    def AddPointTool(self):
        self.Main.iface.mapCanvas().setMapTool(self.AddPointMapTool) 
             
    def MapTool(self):
        if self.EnableMapTool == False:
            self.Main.iface.mapCanvas().setMapTool(self.skiptracktool)
            self.pushButton_3.setChecked(True)
            self.EnableMapTool = True
        else:
            self.Main.iface.mapCanvas().unsetMapTool(self.skiptracktool)
            self.pushButton_3.setChecked(False)
            self.EnableMapTool = False
                           
    def closeEvent(self, *args, **kwargs):
        try:
            self.player.stop()
            self.Main.iface.mapCanvas().scene().removeItem(self.positionMarker)
            self.CancelVertex()
            self.Main.pushButton_2.show()
            #self.Main.horizontalSpacer_2.show()
            self.Main.groupBox.hide()
            self.Main.pushButton_8.show()
            self.Main.groupBox_4.show()
            self.dockWidget_2.close()
        except:
            pass
        return QtWidgets.QWidget.closeEvent(self, *args, **kwargs)                      
    def mediaStateChanged(self, state):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPlay))
    
    def setPosition(self, position):
        self.player.setPosition(position+self.StartMsecond)   
    
    def secTotime(self,seconds): 
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            return "%d:%02d:%02d" % (h, m, s)   
                   
    def positionChanged(self, progress):
        if progress < self.StartMsecond:
            self.player.setPosition(self.StartMsecond)
            progress = self.StartMsecond
        AssociatedGps = round((progress - self.StartMsecond )/1000)
        self.DisplayPoint(AssociatedGps)
        totalTime = self.secTotime(self.duration)
        actualTime = self.secTotime((progress - self.StartMsecond )/1000)
        self.replayPosition_label.setText(actualTime + ' / '+totalTime)
        if not self.horizontalSlider.isSliderDown():
            self.horizontalSlider.setValue(progress - self.StartMsecond ) 

    def DisplayPoint(self,Point):
        if Point >= len(self.GPXList):
            Point = len(self.GPXList) - 1
        gpx = self.GPXList[Point]
        lat = round(gpx[0],7)
        lon = round(gpx[1],7)
        ele = gpx[2]
        speed = gpx[3]
        course = gpx[4]
        time = gpx[5]
        Point = QgsPointXY()
        Point.set(lon, lat)
        canvas = self.Main.iface.mapCanvas()
        crsSrc = QgsCoordinateReferenceSystem(4326)    # .gpx is in WGS 84
        crsDest = QgsProject.instance().crs()
        xform = QgsCoordinateTransform(crsSrc, crsDest)
        self.positionMarker.setHasPosition(True)
        self.Point = xform.transform(Point)
        self.positionMarker.newCoords(self.Point)
        self.positionMarker.angle = float(course)
        extent = canvas.extent() 
        boundaryExtent=QgsRectangle(extent)
        boundaryExtent.scale(0.7)
        if not boundaryExtent.contains(QgsRectangle(Point, self.Point)):
            extentCenter= self.Point
            newExtent=QgsRectangle(
                        extentCenter.x()-extent.width()/2,
                        extentCenter.y()-extent.height()/2,
                        extentCenter.x()+extent.width()/2,
                        extentCenter.y()+extent.height()/2
                        )
            self.Main.iface.mapCanvas().setExtent(newExtent)
            self.Main.iface.mapCanvas().refresh() 
        self.Main.label_14.setText('GPS Time: '+str(time))
        self.Main.label_15.setText('Course: '+"%.2f" % (course))
        self.Main.label_16.setText('Ele: '+"%.2f" %(ele))
        self.Main.label_17.setText('Speed m/s: '+"%.2f" %(speed))
        self.Main.label_19.setText('Lat : '+str(lat))
        self.Main.label_18.setText('Lon : '+str(lon))
                  
    def MuteUnmute(self):
        if self.player.mediaStatus() == 6 :
            if self.player.isMuted() == 1:
                self.player.setMuted(0)
                self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolume))
            elif self.player.isMuted() == 0:
                self.player.setMuted(1)
                self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolumeMuted))   
    
    def SkipForward(self): 
        position = self.player.position()
        self.player.setPosition(position+1000)
       
    def SkipBackward(self): 
        position = self.player.position()
        self.player.setPosition(position-1000)
      
    def ForwardFrame(self):  
        position = self.player.position()
        self.player.setPosition(position+int(self.fps))
      
    def BackwardFrame(self):
        position = self.player.position()
        self.player.setPosition(position-int(self.fps))
     
    def PlayPause(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        else:
            self.player.play()
            
    def findNearestPointInRecording(self, x,y):
        ClickPt = QgsPoint(x,y)
        Low =  ClickPt.distanceSquared(self.Polyline[0])
        NearPoint = 0
        Counter = 0
        for Point in self.Polyline:
            dist = ClickPt.distanceSquared(Point)
            if dist < Low:
                Low = dist
                NearPoint = Counter
                Counter = Counter + 1
            else:
                Counter = Counter + 1
        self.setPosition(NearPoint*1000)
        
    def ExtractSingleFrameOnTime(self, pos, outputfile):
        if os.name == 'nt':
            ffmpeg = ('"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"')
            os.popen(str(ffmpeg)+' -ss '+str(pos/1000)+' -i '+str('"' +self.videoFile+ '"')+ ' -t 1 '+str('"'+outputfile+'"'))
        else:
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            os.system(str(ffmpeg)+' -ss '+str(pos/1000)+' -i '+str(self.videoFile)+' -t 1 '+str(outputfile))
                 
    def AddPoint(self,x,y):
        self.Main.iface.mapCanvas().unsetMapTool(self.AddPointMapTool)
        Point = QgsPointXY(x,y)
        pos = self.player.position()
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        a = self.DBLayer.name()
        last_desc = '///'
        LayerName =str(a)
        last_desc2 = LayerName + ' Point N '
        directory = str(self.DB.split('.')[0])+'_Image/'
        if not os.path.exists(directory):
            os.makedirs(directory)
        fc = int(self.DBLayer.featureCount())
        self.ExtractSingleFrameOnTime(pos,directory+LayerName+'_'+str(fc)+'_.jpg')
        fields = self.DBLayer.fields()
        attributes = []
        lat,lon = Point.y(), Point.x()
        for field in fields:
            a = str(field.name())
            b = str(field.typeName())
            if a == 'id':
                fcnr = fc
                attributes.append(fcnr)  
            elif a == 'Lon(WGS84)':
                attributes.append(str(lon))                       
            elif a == 'Lat(WGS84)':
                attributes.append(str(lat))               
            elif a == 'Image link':
                attributes.append(str(directory+LayerName+'_'+str(fc)+'_.jpg'))                   
            else:                    
                if b == 'String':      
                    (a,ok) = QInputDialog.getText(
                                                  self.Main.iface.mainWindow(), 
                                                  "Attributes",
                                                  a + ' = String',
                                                  QLineEdit.Normal)
                    attributes.append(a)               
                elif b == 'Real':                    
                    (a,ok) = QInputDialog.getDouble(
                                                    self.Main.iface.mainWindow(), 
                                                    "Attributes",
                                                    a + ' = Real', decimals = 10)
                    attributes.append(a)
                elif b == 'Integer64':                    
                    (a,ok) = QInputDialog.getInt(
                                                 self.Main.iface.mainWindow(), 
                                                 "Attributes",
                                                 a + ' = Integer')
                    attributes.append(a)                    
        feature = QgsFeature()
        feature.setGeometry(QgsGeometry.fromPoint(Point))
        feature.setAttributes(attributes)
        self.DBLayer.startEditing()
        self.DBLayer.addFeature(feature)
        self.DBLayer.commitChanges()    
        self.DBLayer.triggerRepaint()

    def ExtractCommand(self):
        if self.ExtractToB <= self.ExtractFromA:
            ret = QMessageBox.warning(self, "Warning", '"To B" point must be after "from A" point', QMessageBox.Ok)
            self.CancelVertex()
        else:
            if os.name == 'nt':
                ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"'
            else:
                ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            Directory,_ = QFileDialog.getSaveFileName(caption= 'Save georeferenced images')
            if Directory:
                self.progressBar.show()
                self.progressBar.setValue(0)
                start = self.ExtractFromA
                if self.comboBox_6.currentText() == 'seconds':           
                    finish = self.ExtractToB - self.ExtractFromA
                    fps = self.doubleSpinBox_2.value()
                    if fps < 1.0:
                        fps = 1.0 / fps
                    elif fps > 1:
                        fps = 1.0 / fps
                        
                    if os.name == 'nt':
                        os.popen(str(ffmpeg+ ' -ss ' + str(start) + ' -i '+ str('"'+self.videoFile+'"')+ ' -t ' + str(finish) + ' -vf fps=' + str(fps) + ' ' + '"'+Directory + '_%d.png'+'"'))
                    else:
                        os.system(ffmpeg+' -ss '+ str(start) + ' -i '+ str(self.videoFile) + ' -t ' + str(finish) + ' -vf fps=' + str(fps) + ' ' + Directory + '_%d.png')
                else:
                    txtGPSFile = open(Directory + 'UTM_Coordinates.txt', 'w')
                    txtGPSFile.close()
                    txtGPSFile = open(Directory+ 'UTM_Coordinates.txt', 'a')
                    txtGPSFile.write('filename # East UTM # North UTM # Ele '+ '\n')
                    finish = self.ExtractToB
                    meters = self.doubleSpinBox_2.value()
                    Timerange = range(start, finish + 1)
                    RemainToUseMeterTotal = 0
                    if os.name == 'nt':
                        os.popen(ffmpeg+' -ss '+ str(start) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' + '"'+Directory + '_sec_' + str(start)+'.00.png'+'"')
                    else:
                        os.system(ffmpeg+' -ss '+ str(start) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(start)+'.00.png')
                    lonUTM, latUTM,quotainutile = self.transform_wgs84_to_utm(float(self.GPXList[start][1]) , float(self.GPXList[start][0]))
                    ele = float(self.GPXList[start][2])
                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(start)+'.00.png,'+' '+ str(lonUTM) + ', '+ str(latUTM) + ', ' + str(ele) + '\n')
                    for i in Timerange:
                        progessBarValue = ((i-start) * 100) // len(Timerange)
                        self.progressBar.setValue(int(progessBarValue))
                        latitude1,longitude1 = float(self.GPXList[i][0]) ,float(self.GPXList[i][1])
                        latitude2,longitude2 = float(self.GPXList[i+1][0]) ,float(self.GPXList[i+1][1])
                        ele1 = float(self.GPXList[i][2])
                        ele2 = float(self.GPXList[i+1][2])
                        Calculus = Geodesic.WGS84.Inverse(latitude1, longitude1, latitude2, longitude2)
                        DistanceBetweenPoint = Calculus['s12']    
                        Azimuth =   Calculus['azi2']                 
                        SpeedMeterSecond = DistanceBetweenPoint             #GPS refresh rate is actually 1, change parameter for different rates
                       # Time = 1                                            
                        if RemainToUseMeterTotal == 0:
                            if DistanceBetweenPoint >= meters:
                                decimalSecondToAdd = meters / DistanceBetweenPoint
                                RemainToUseMeter = DistanceBetweenPoint - meters
                                if os.name == 'nt':
                                    os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                             ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                else:
                                    os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                              ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                
                                
                                
                                
                                CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                while RemainToUseMeter > meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                if RemainToUseMeter == meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' +str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                    RemainToUseMeterTotal = 0  
                                elif RemainToUseMeter < meters:
                                    RemainToUseMeterTotal = RemainToUseMeter
                                    pass
                            else:
                                RemainToUseMeterTotal = meters - DistanceBetweenPoint       
                        elif RemainToUseMeterTotal > 0:
                            if DistanceBetweenPoint >= (meters - RemainToUseMeterTotal) :
                                decimalSecondToAdd = (meters - RemainToUseMeterTotal) / DistanceBetweenPoint
                                RemainToUseMeter = DistanceBetweenPoint - (meters - RemainToUseMeterTotal)
                                if os.name == 'nt':
                                    os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                             ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                else:
                                    os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                              ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                while RemainToUseMeter > meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                if RemainToUseMeter == meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                    RemainToUseMeterTotal = 0
                                elif RemainToUseMeter < meters:
                                    RemainToUseMeterTotal = RemainToUseMeter
                            else:
                                RemainToUseMeterTotal = (meters - DistanceBetweenPoint) + RemainToUseMeterTotal
                    txtGPSFile.close()            
            self.progressBar.hide()
            
    def ExtractFromA(self):
        
        if self.ExtractA == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractAVertex)
        self.ExtractA = False
        self.ExtractFromA = round((self.player.position()- self.StartMsecond )/1000)
        canvas = self.Main.iface.mapCanvas()
        crsSrc = QgsCoordinateReferenceSystem(4326)    # .gpx is in WGS 84
        crsDest = QgsProject.instance().crs()
        xform = QgsCoordinateTransform(crsSrc, crsDest)
        latitude,longitude = self.Polyline[self.ExtractFromA].y(), self.Polyline[self.ExtractFromA].x()
        self.ExtractAVertex = QgsVertexMarker(canvas)
        self.ExtractAVertex.setCenter(xform.transform(QgsPointXY(longitude, latitude)))
        self.ExtractAVertex.setColor(QColor(0,255,0))
        self.ExtractAVertex.setIconSize(10)
        self.ExtractAVertex.setIconType(QgsVertexMarker.ICON_X)
        self.ExtractAVertex.setPenWidth(10)
        self.ExtractA = True
        if self.ExtractB == True:
            self.pushButtonCut_2.setEnabled(True)
        else:
            self.pushButtonCut_2.setEnabled(False)
            
    def ExtractToB(self):
        if self.ExtractB == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractBVertex)
        self.ExtractB = False    
        self.ExtractToB = round((self.player.position()- self.StartMsecond )/1000)  
        if self.ExtractA == True:
            if self.ExtractToB > self.ExtractFromA:
                canvas = self.Main.iface.mapCanvas()
                crsSrc = QgsCoordinateReferenceSystem(4326)    # .gpx is in WGS 84
                crsDest = QgsProject.instance().crs()
                xform = QgsCoordinateTransform(crsSrc, crsDest)   
                latitude,longitude = self.Polyline[self.ExtractToB].y(), self.Polyline[self.ExtractToB].x()
                self.ExtractBVertex = QgsVertexMarker(canvas)
                self.ExtractBVertex.setCenter(xform.transform(QgsPointXY(longitude, latitude)))
                self.ExtractBVertex.setColor(QColor(255,0,0))
                self.ExtractBVertex.setIconSize(10)
                self.ExtractBVertex.setIconType(QgsVertexMarker.ICON_X)
                self.ExtractBVertex.setPenWidth(10)
                self.ExtractB = True
                self.pushButtonCut_2.setEnabled(True)
            else:
                self.pushButtonCut_2.setEnabled(False)
                           
    def CancelVertex(self): 
        if self.ExtractA == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractAVertex)
            self.ExtractA = False
        if self.ExtractB == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractBVertex)
            self.ExtractB = False
        self.pushButtonCut_2.setEnabled(False)
                  
    def ExtractToolbar(self):
        if self.ExtractTool == 0:
            self.dockWidget_4.show()
            self.ExtractTool = 1
        else:
            self.dockWidget_4.hide()
            self.ExtractTool = 0
            
    def transform_wgs84_to_utm(self, lon, lat): 
           
        def get_utm_zone(longitude):
            return (int(1+(longitude+180.0)/6.0))

        def is_northern(latitude):
            """
            Determines if given latitude is a northern for UTM
            """
            if (latitude < 0.0):
                return 0
            else:
                return 1
        utm_coordinate_system = osr.SpatialReference()
        utm_coordinate_system.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon  
        utm_coordinate_system.SetUTM(get_utm_zone(lon), is_northern(lat))
        wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS() # Clone ONLY the geographic coordinate system 
        wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, utm_coordinate_system) # (<from>, <to>)
        return wgs84_to_utm_transform.TransformPoint(lon, lat, 0) # returns easting, northing, altitude 
Example #3
0
class trackGps:
    
    def __init__(self, iface):

        # Save reference to the QGIS interface
        self.globalpath = os.path.dirname(os.path.abspath(__file__))
        self.iface = iface

        self.guiStarted = False # signal to destructor that this isn't actually been displayed yet        
        
        self.read = ReadGpsd(self.iface)
        
        # create dock widget from ui file
        print os.path.join(self.globalpath,"DockWidget.ui")
        self.dock = uic.loadUi(os.path.join(self.globalpath,"DockWidget.ui"))
        self.canvas = self.iface.mapCanvas()

        # Default options
        self.GPSSettings = QSettings()

        # indication that this is the first time for the plugin
        self.firstTime = self.GPSSettings.value("trackGpsGPSSettings/firstTime", True, type=bool)
        
        # index of marker for GPS position (this is the arrow)
        self.markerNumber = self.GPSSettings.value("trackGpsGPSSettings/markerNumber", 0, type=int)
        
        # default is black for marker fill color
        self.markerFillColor = QColor(self.GPSSettings.value("trackGpsGPSSettings/markerFillColor", QColor(0,0,0)))
        
        # default is yellow for marker outline color
        self.markerOutlineColor = QColor(self.GPSSettings.value("trackGpsGPSSettings/markerOutlineColor", QColor(255,255,0)))
        
        # width of tracking line
        self.trackLineWidth = self.GPSSettings.value("trackGpsGPSSettings/trackLineWidth", 3, type=int)
        
        # color of tracking line (default is red)
        self.lineColor = QColor(self.GPSSettings.value("trackGpsGPSSettings/lineColor", QColor(255,0,0)))
        
        self.saveInSHAPEFile = self.GPSSettings.value("trackGpsGPSSettings/saveInSHAPEFile", False, type=bool)
        
        # now recover/set the values for the serial port connection
        self.searchAllConnectionsSpeeds = self.GPSSettings.value("trackGpsGPSSettings/searchAllConnectionsSpeeds",
                                                                 True, type=bool)
        self.serialPortNumber = self.GPSSettings.value("trackGpsGPSSettings/serialPortNumber", 0, type=int)
        self.serialPortSpeed = self.GPSSettings.value("trackGpsGPSSettings/serialPortSpeed", 0, type=int)

        # set GPS connection values if they were recovered from a previous session
        if not self.searchAllConnectionsSpeeds: 
            self.read.setConnectionValues(self.serialPortNumber, self.serialPortSpeed)
        
        # initialize the graphic elements for the GPS position
        self.positionMarker = PositionMarker(self.canvas, self.markerNumber, self.markerFillColor, self.markerOutlineColor)
        self.rubberBand = QgsRubberBand(self.canvas)
        self.rubberBand.setColor(self.lineColor)
        self.rubberBand.setWidth(self.trackLineWidth)
        
        self.rubberBandS = []
        self.GPSPositions = [] # array of positions in current track
        self.GPSTracks = [] # array of all tracks

        
    def __del__(self):

        if self.guiStarted:
            
            # time to save plugin options as settings
            GPSSettings = QSettings()
            
            # indication that this is the first time for the plugin
            GPSSettings.setValue("trackGpsGPSSettings/firstTime", self.firstTime)
            GPSSettings.setValue("trackGpsGPSSettings/searchAllConnectionsSpeeds",
                                                                 bool(self.searchAllConnectionsSpeeds))
            GPSSettings.setValue("trackGpsGPSSettings/markerNumber", self.markerNumber)
            GPSSettings.setValue("trackGpsGPSSettings/markerFillColor", self.markerFillColor)
            GPSSettings.setValue("trackGpsGPSSettings/markerOutlineColor", self.markerOutlineColor)
            GPSSettings.setValue("trackGpsGPSSettings/trackLineWidth", self.trackLineWidth)
            GPSSettings.setValue("trackGpsGPSSettings/lineColor", self.lineColor)
            GPSSettings.setValue("trackGpsGPSSettings/saveInSHAPEFile", self.saveInSHAPEFile)
            GPSSettings.setValue("trackGpsGPSSettings/serialPortNumber", self.serialPortNumber)
            GPSSettings.setValue("trackGpsGPSSettings/serialPortSpeed", self.serialPortSpeed)
            GPSSettings.synch()
            QMessageBox.information(self.iface.mainWindow(),"Class trackGPS Ending","trackGPS is being destroyed!")

    
    def initGui(self):
        
        self.guiStarted = True # signal that the GPS dialog was displayed
        if self.firstTime:
            self.firstTime = False
            QMessageBox.information(self.iface.mainWindow(),"Track GPS location","Since this is the first time"+\
                                    " that you have used the 'Track GPS location' plugin please consult the help "+\
                                    "in the plugin menu")
            
        # Create actions for plugin
        self.actionStart = QAction(QIcon(":/plugins/trackgps/Satellite-22.png"), "Start GPS Tracking", self.iface.mainWindow())
        self.actionStart.setWhatsThis("Open GPS Connection and Start Tracking")
        self.actionStop  = QAction(QIcon(":/plugins/trackgps/Satellite-22.png"), "Stop GPS Tracking", self.iface.mainWindow())
        self.actionStop.setWhatsThis("Close the GPS Connection and Stop Tracking")
        self.actionOptions  = QAction(QIcon(":/plugins/trackgps/options.png"),"Set GPS Tracking Options", self.iface.mainWindow())
        self.actionOptions.setWhatsThis("Set the various GPS Connection/Tracking Options")
        
        # add help menu item
        self.helpAction = QAction(QIcon(":/plugins/trackgps/images/help-browser.png"), "GPS Tracking Help", self.iface.mainWindow())
     
        # New Track actions set up here
        self.dock.btnStartNewTrack.setDisabled(True) # Starting New Tracks is disabled at start
        QObject.connect(self.dock.btnStartNewTrack, SIGNAL("clicked()"), self.startNewTrack)
        
        # Connect the actions to its methods
        QObject.connect(self.actionStart, SIGNAL("activated()"), self.toogleGather)
        QObject.connect(self.actionStop,  SIGNAL("activated()"), self.toogleGather)
        QObject.connect(self.actionOptions,  SIGNAL("activated()"), self.showGPSMenuOptions)
        QObject.connect(self.dock.btnStart,  SIGNAL("clicked()"), self.toogleGather)
        QObject.connect(self.read,  SIGNAL("readCoords(PyQt_PyObject)"), self.setCoords)
        QObject.connect(self.read,  SIGNAL("connectionFailed(PyQt_PyObject)"), self.connectionFailed)
        QObject.connect(self.read,  SIGNAL("connectionMade()"), self.connectionMade)
        QObject.connect(self.helpAction, SIGNAL("activated()"), self.helpWindow)
     
        # Add menu items for action
        self.iface.addPluginToMenu("beeGPS", self.actionOptions)
        self.iface.addPluginToMenu("beeGPS", self.actionStart)
        self.iface.addPluginToMenu("beeGPS", self.helpAction)
        myPluginMenu = self.iface.pluginMenu()
        QObject.connect(myPluginMenu, SIGNAL("aboutToShow()"), self.updateTrackGPSMenu)
     
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock)


    def helpWindow(self):
        
        window = HelpForm("TheQGISGPSTrackerPlugin.html",self.iface.mainWindow())
        window.show()
    
    
    def updateTrackGPSMenu(self):
        
        if self.read.running:
            self.iface.addPluginToMenu("beeGPS", self.actionStop)
            self.iface.removePluginMenu("beeGPS", self.actionStart)
        else:
            self.iface.addPluginToMenu("beeGPS", self.actionStart)
            self.iface.removePluginMenu("beeGPS", self.actionStop)
    
    
    def startNewTrack(self):
        
        self.read.stop() # close serial port
        self.rubberBandS.append(self.rubberBand)
        self.showGPSMenuOptions() # give user opportunity to change display options
        
        #if len(self.GPSPositions) > 0: # temporary section to display positional information
        #    QMessageBox.information(self.iface.mainWindow(),"trackGPS","There are: " + str(len(self.GPSPositions)) + " GPS Positions in the current track")
        #    for i in range(len(self.GPSPositions)):
        #        QMessageBox.information(self.iface.mainWindow(),"trackGPS","Position #" + str(i) + ": Latitude=" + str(self.GPSPositions[i].latitude))

        self.rubberBand=QgsRubberBand(self.canvas) # start new rubber band
        if len(self.GPSPositions) > 0 and self.saveInSHAPEFile:
            self.GPSTracks.append(self.GPSPositions) # save GPSPositions to GPSTracks
            self.GPSPositions = [] #reset of array contenent the current position
        self.startGather() # open serial port and record new track
       
       
    def unload(self):
        # Remove the plugin menu item
        
        self.iface.removePluginMenu("beeGPS", self.actionStart)
        self.iface.removePluginMenu("beeGPS", self.actionStop)
        self.iface.removePluginMenu("beeGPS", self.actionOptions)
    
    
    def startGather(self):
        #update all of the GPS display options
        
        self.positionMarker.markerNumber = self.markerNumber
        self.positionMarker.fillColor = self.markerFillColor
        self.positionMarker.outlineColor = self.markerOutlineColor
        self.rubberBand.setColor(self.lineColor)
        self.rubberBand.setWidth(self.trackLineWidth)
        self.positionMarker.show()
        
        # get destination crs of the canvas
        dest_crs = self.canvas.mapRenderer().destinationCrs()
        
        #print "destination crs:",dest_crs.description()
        # create transform object from WGS84 (GPS) to canvas CRS
        self.transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(self.read.session.datumEPSG,\
                                                        QgsCoordinateReferenceSystem.EpsgCrsId ),dest_crs)
        self.read.start()
        self.read.exec_()
    
    
    def setCoords(self, aGPSPosition):
    
        boolDistance = True
        boolTime = True
    
        #Controllo se è la prima acquisizione valutando la dimensione di GPSPosition[] a 0, in caso positivo acquisisco.
        if len(self.GPSPositions) == 0:
            self.GPSPositions.append(aGPSPosition)
            
        else:
            #Metodo tresholdAcquisition() per l'acquisizione dei punti "live" in base alla soglia di distanza che ritorna 
            #TRUE in caso la soglia sia stata superata, altrimenti FALSE
            boolDistance = self.tresholdAcquisition(aGPSPosition)
            
        #Controllo che tresholdAcquisition() abbia ritornato TRUE altrimenti passo al punto successivo
        if boolDistance == False:
            return
            
        #Metodo timeIntervals() per l'acquisizione dei punti "live" in base alla soglia di tempo che ritorna TRUE in caso
        #la soglia sia stata superata e acquisita, altrimenti FALSE
        boolTime = self.timeIntervals(aGPSPosition)
        
        #Controllo che timeIntervals() abbia ritornato TRUE altrimenti passo al punto successivo
        if boolTime == False:
          return
        
        else:
            self.GPSPositions.append(aGPSPosition)

        # display raw values
        self.dock.date.setText(aGPSPosition.theDateTime)
        self.dock.lat.setText(str(aGPSPosition.latitude) + ' ' + aGPSPosition.latitudeNS)
        self.dock.lon.setText(str(aGPSPosition.longitude) + ' ' + aGPSPosition.longitudeEW)
        self.dock.lineBearing.setText("%5.1i"%aGPSPosition.bearing)
        self.dock.lineSpeed.setText("%5.1i"%aGPSPosition.speed)
        self.dock.lineHDOP.setText(str(aGPSPosition.hdop))
        if aGPSPosition.fixQuality == 0:
            self.dock.lineQuality.setText("Fix not available")
        elif aGPSPosition.fixQuality == 1:
            self.dock.lineQuality.setText("GPS fix")
        else:
            self.dock.lineQuality.setText("Differential GPS fix") 
        
        # display arrow on the map
        latitude = aGPSPosition.latitude if aGPSPosition.latitudeNS == 'N' else aGPSPosition.latitude * -1.0
        longitude = aGPSPosition.longitude if aGPSPosition.longitudeEW == 'E' else aGPSPosition.longitude * -1.0
        p=self.transform.transform(QgsPoint(longitude, latitude))
        self.rubberBand.addPoint(p)
        self.positionMarker.setHasPosition(True)
        self.positionMarker.newCoords(p,aGPSPosition.bearing)
        
        doRefresh = False
        if doRefresh:
            # move map to keep marker at center
            curext = self.canvas.extent()
            p1 = QgsPoint(p.x() - curext.width()/2, p.y() - curext.height()/2)
            p2 = QgsPoint(p.x() + curext.width()/2, p.y() + curext.height()/2)
            self.canvas.setExtent(QgsRectangle (p1,p2))
            self.canvas.refresh()
    
    
    def stopGather(self):
        self.read.stop()
        self.positionMarker.hide()
        if len(self.GPSPositions) > 0: # and self.saveInSHAPEFile:
            self.GPSTracks.append(self.GPSPositions) # save GPSPositions to GPSTracks
                                                                                                                                    
        # if len(self.GPSTracks) > 0 and self.saveInSHAPEFile:
        if self.saveInSHAPEFile: # this is temporary
            # option to save SHAPE file is on, prompt for filename and write the tracks to the file
            self.makeShapeFiles()
            
        if len(self.GPSTracks) > 0:
            answer = QMessageBox.question(self.iface.mainWindow(),"Erase Tracks?","Erase the currently displayed tracks?",\
                                          QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if answer == QMessageBox.Yes:
                for band in self.rubberBandS:
                    band.reset()
                self.rubberBand.reset()
                self.canvas.refresh()
                self.rubberBandS = []
            self.GPSPositions = []
            self.GPSTracks = []
    
    
    def toogleGather(self):
        
        if self.read.running:
            QMessageBox.information(self.iface.mainWindow(),"GPS Tracker","Stopping GPS Tracking",QMessageBox.Ok)
            self.stopGather()
            self.dock.btnStart.setText("Start")
            self.dock.gpsInformation.setText("Gets GPS Receiver Information")
            self.dock.btnStartNewTrack.setDisabled(True)
        else:
            self.dock.btnStart.setText("Connecting, please be patient....")
            self.startGather()
            if self.read.session.connected: 
                self.dock.btnStart.setText("Stop")
    
    
    def connectionMade(self):
        
        # QMessageBox.information(self.iface.mainWindow(),"trackGps","GPS Receiver Connected on port: %s at %i baud\n"%\
        #                     (self.read.session.portName,self.read.session.baudRate),QMessageBox.Ok,0)
        
        self.dock.gpsInformation.setText("GPS Connected on port: %s at %i baud"%(self.read.session.portName,\
                                                                                          self.read.session.baudRate))
        self.dock.btnStart.setText("Stop")
        self.dock.btnStartNewTrack.setDisabled(False)
        
        # save connection values in session parameters
        self.serialPortNumber = self.read.session.port
        self.serialPortSpeed = self.read.session.baudRates.index(self.read.session.baudRate)
        self.searchAllConnectionsSpeeds = False
        
        
    def connectionFailed(self, msg):
        
        QMessageBox.warning(self.iface.mainWindow(),"beeGPS", "Connection to GPSConnection failed\n%s"%(msg),QMessageBox.Ok,0)
        if self.read.session.connected: 
            self.read.stop()
        self.dock.btnStart.setText("Start")
        self.dock.btnStartNewTrack.setDisabled(True) # Starting New Tracks is disabled at start
    
    
    def showGPSMenuOptions(self):

        myGPSOptionsDlg = GPSTrackerOptions(self)
        isOK = myGPSOptionsDlg.exec_()
        if isOK:
            if myGPSOptionsDlg.cbxMarkerType.currentIndex() != self.markerNumber: 
                self.markerNumber = myGPSOptionsDlg.cbxMarkerType.currentIndex()
            if myGPSOptionsDlg.lineColor != self.lineColor: 
                self.lineColor = myGPSOptionsDlg.lineColor
            if myGPSOptionsDlg.markerFillColor != self.markerFillColor: 
                self.markerFillColor = myGPSOptionsDlg.markerFillColor
            if myGPSOptionsDlg.markerOutlineColor != self.markerOutlineColor: 
                self.markerOutlineColor = myGPSOptionsDlg.markerOutlineColor
            if myGPSOptionsDlg.sbxTrackWidth.value() != self.trackLineWidth: 
                self.trackLineWidth = myGPSOptionsDlg.sbxTrackWidth.value()
            if myGPSOptionsDlg.cbxSaveGPSTrack.isChecked() != self.saveInSHAPEFile: 
                self.saveInSHAPEFile = myGPSOptionsDlg.cbxSaveGPSTrack.isChecked()
    
    
    def makeShapeFiles(self):

        myFileName = QgsProject.instance().fileName()
        myFileName = str(myFileName)
        # if this is a windows OS then the filename needs to have '/' converted to '\'
        if myFileName.find('windows') != 0 or myFileName.find('Windows') != 0: 
            myFileName = os.path.normpath(myFileName)
            
        myFilePath = os.path.dirname(myFileName)

        myShapeFileNamesDlg = ShapeFileNames(myFilePath)
        isOK = myShapeFileNamesDlg.exec_()
        CRS = QgsCoordinateReferenceSystem()
        crsIsOk = CRS.createFromOgcWmsCrs("EPSG:%d" % self.GPSTracks[0][0].datumEPSG)
        if not crsIsOk: 
            QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating CRS from"+\
                                            " EPSG ID:" + str(self.GPSTracks[0][0].datumEPSG))
        if isOK and crsIsOk:
            if len(myShapeFileNamesDlg.lnePointsFileName.text()) > 0:
                # set up the fields for the Points SHAPE file
                box = QgsFields() 
                box.append(QgsField("LATITUDE", QVariant.Double , "Real", 9, 6)) 
                box.append(QgsField("LONGITUDE", QVariant.Double, "Real", 10, 6)) 
                box.append(QgsField("NUMOFSATS", QVariant.Int, "Integer", 2, 0))
                box.append(QgsField("HDOP", QVariant.Double, "Real", 4, 2))
                box.append(QgsField("DATETIME", QVariant.String, "String", 19, 0)) 
                box.append(QgsField("FIXTYPE", QVariant.String, "String", 1, 0))

                box.append(QgsField("BEARING", QVariant.Double, "Real", 6, 2))
                box.append(QgsField("SPEED-KPH", QVariant.Double, "Real", 5, 1)) 
                box.append(QgsField("TRACKNUM", QVariant.Int, "Integer", 2, 0))
                
                # set up the CRS
                # open the points SHAPE file
                pointsFile, fileOK = self.createSHAPEfile(myShapeFileNamesDlg.lnePointsFileName.text(),box,QGis.WKBPoint,CRS)
                if fileOK:
                    for j in range(len(self.GPSTracks)):
                        for i in range(len(self.GPSTracks[j])):
                            theFeature = QgsFeature()
                            latitude = self.GPSTracks[j][i].latitude
                            if self.GPSTracks[j][i].latitudeNS == 'S': 
                                latitude = -latitude
                            longitude = self.GPSTracks[j][i].longitude
                            if self.GPSTracks[j][i].longitudeEW == 'W': 
                                longitude = -longitude
                            theFeature.setGeometry(QgsGeometry.fromPoint(QgsPoint(longitude,latitude)))
                            theFeature.setAttributes([0, latitude])
                            theFeature.setAttributes([1, longitude])
                            theFeature.setAttributes([2, self.GPSTracks[j][i].numSatellites])
                            theFeature.setAttributes([3, self.GPSTracks[j][i].hdop])
                            theFeature.setAttributes([4, self.GPSTracks[j][i].theDateTime])
                            theFeature.setAttributes([5, self.GPSTracks[j][i].fixQuality])
                            theFeature.setAttributes([6, self.GPSTracks[j][i].bearing])
                            theFeature.setAttributes([7, self.GPSTracks[j][i].speed])
                            theFeature.setAttributes([8, j+1])
                            pointsFile.addFeature(theFeature)
                            
                    del pointsFile # del file object to force a flush and close
                    
            if len(myShapeFileNamesDlg.lneLinesFileName.text()) > 0:
                # set up the fields for the Lines SHAPE file
                lines_box = QgsFields()
                lines_box.append(QgsField("SDATETIME", QVariant.String, "String", 19, 0))
                lines_box.append(QgsField("EDATETIME", QVariant.String, "String", 19, 0))
                lines_box.append(QgsField("TRACKNUM", QVariant.Int, "Integer", 2, 0))
                
                linesFile, fileOK = self.createSHAPEfile(myShapeFileNamesDlg.lneLinesFileName.text(),lines_box,QGis.WKBLineString,CRS)
                if fileOK:
                    for j in range(len(self.GPSTracks)):
                        theFeature = QgsFeature()
                        pointsList = []
                        for i in range(len(self.GPSTracks[j])):
                            latitude = self.GPSTracks[j][i].latitude
                            if self.GPSTracks[j][i].latitudeNS == 'S': 
                                latitude = -latitude
                            longitude = self.GPSTracks[j][i].longitude
                            if self.GPSTracks[j][i].longitudeEW == 'W': 
                                longitude = -longitude
                            pointsList.append(QgsPoint(longitude,latitude))
                            
                        theFeature.setGeometry(QgsGeometry.fromPolyline(pointsList))
                        theFeature.setAttributes([0, self.GPSTracks[j][0].theDateTime])
                        theFeature.setAttributes([1, self.GPSTracks[j][len(self.GPSTracks[j])-1].theDateTime])
                        theFeature.setAttributes([2, j+1])
                        linesFile.addFeature(theFeature)
                        
                    del linesFile # del file object to force a flush and close
                    

    def createSHAPEfile(self,fileName, fileFields, fileType, crs):
        '''
        this function creates a new, empty shape file for use in writing points or lines
        Returns: SHAPEfile, status
            if status == True then SHAPEfile is OK to use, if False then an error occured and cannot use SHAPEFile
            
        Input Parameters:
            fileName = full name of the SHAPE file to be created
            fileFields = map of QgsFields to use for the attributes of the SHAPE file
            fileType = QGis.WKBPoint for points file <or> QGis.WKBLine for lines file
            crs = the QgsCoordinateReferenceSystem to use for the file
        '''
        
        status = True # default is no error
        SHAPEfile = QgsVectorFileWriter(fileName,"CP1250",fileFields,fileType,crs)
        typeName = 'Points' if fileType == QGis.WKBPoint else 'Lines'
        if SHAPEfile.hasError() != QgsVectorFileWriter.NoError:
            status = False # report an error
            if SHAPEfile.hasError() == QgsVectorFileWriter.ErrDriverNotFound:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrDriverNotFound\' - saving " + typeName + " is aborted")
            elif SHAPEfile.hasError() == QgsVectorFileWriter.ErrCreateDataSource:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrCreateDataSource\' - saving " + typeName + " is aborted")
            elif SHAPEfile.hasError() == QgsVectorFileWriter.ErrCreateLayer:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrCreateLayer\' - saving " + typeName + " is aborted")
            elif SHAPEfile.hasError() == QgsVectorFileWriter.ErrAttributeTypeUnsupported:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrAttributeTypeUnsupported\' - saving " + typeName + " is aborted")
            else:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'UNKOWN ERROR\' saving " + typeName + " is aborted")
        return SHAPEfile,status
        
        
    #Metodo per l'acquisizione tramite soglia di distanza
    def tresholdAcquisition(self, aGPSPosition):
    
        #Costanti per il calcolo della distanza
        R_Terra = 6372.795477598
        acquisito = False
        
        
        #Acquisisco la soglia di distanza, da input e la converto in float
        soglia = self.dock.lineTreshold.text()
        if not soglia.isnumeric():
            self.read.stop()
            self.positionMarker.hide()
            self.dock.btnStart.setText("Start")
            self.dock.gpsInformation.setText("Gets GPS Receiver Information")
            QMessageBox.warning(self.iface.mainWindow(),"ATENZIONE","Inserire solo valori numerici nella soglia di distanza.")
        else:
            soglia = float(soglia)
            soglia = soglia / 1000
    
        #Conversione dei gradi in radianti
        lat_alfa = math.radians(aGPSPosition.latitude)
        lat_beta = math.radians(self.GPSPositions[-1].latitude)
        lon_alfa = math.radians(aGPSPosition.longitude)
        lon_beta = math.radians(self.GPSPositions[-1].longitude)
        
        #Calcolo la differenza di lat e lon
        dLat = lat_alfa - lat_beta
        dLon = lon_alfa - lon_beta
            
         
        a = math.sin(dLat/2)*math.sin(dLat/2)+math.sin(dLon/2)*math.sin(dLon/2)* math.cos(lat_alfa) * math.cos(lat_beta)
            
        #Calcolo il terzo lato del triangolo sferico
        c = 2*math.atan2(math.sqrt(a),math.sqrt(1-a))
           
        distanza = c * R_Terra
           
        #Controllo con la soglia di distanza e eventualmente acquisisco
        if distanza > soglia:
            acquisito = True    
                    
        return acquisito
        
    
    #Metodo timeIntervals() per il controllo della soglia temporale
    def timeIntervals(self, aGPSPosition):
    
        #Variabile booleana di ritorno
        acquisito = False
        
        #Stringa per il formato della data 
        formato = '%Y-%m-%d %H:%M:%S'
        
        #Metto le due date, quella dell'ultima acquisizione e quella da valutare in due stringhe
        dataA = aGPSPosition.theDateTime
        dataB = self.GPSPositions[-1].theDateTime
        
        #Tramite il metodo time.strptime() realizziamo due strutte tempo per le due date
        struct_A = time.strptime(dataA,formato)
        struct_B = time.strptime(dataB,formato)
        
        #Otteniamo i valori di confronto
        confrontoA = datetime.datetime.fromtimestamp(time.mktime(struct_A))
        confrontoB = datetime.datetime.fromtimestamp(time.mktime(struct_B))
        
        #Otteniamo la differenza
        differenza = (confrontoA - confrontoB).seconds
        
        #Acquisisco la soglia di distanza temporale e gestisco eventualmente l'inserimento di valori non numerici
        intervalli = self.dock.lineTimeIntervals.text()
        if not intervalli.isnumeric():
            self.read.stop()
            self.positionMarker.hide()
            self.dock.btnStart.setText("Start")
            self.dock.gpsInformation.setText("Gets GPS Receiver Information")
            QMessageBox.warning(self.iface.mainWindow(),"ATENZIONE","Inserire solo valori numerici nella soglia temporale.")
        else:
            intervalli = float(intervalli)
        
        #Controllo se la differenza e maggiore della soglia
        if differenza > intervalli:
          acquisito = True
          
        return acquisito 
Example #4
0
class trackGps:
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.globalpath = os.path.dirname(os.path.abspath(__file__))
        self.iface = iface
        self.guiStarted = False # signal to destructor that this isn't actually been displayed yet
        self.read = ReadGpsd(self.iface)
        # create dock widget from ui file
        print os.path.join(self.globalpath,"DockWidget.ui")
        self.dock = uic.loadUi(os.path.join(self.globalpath,"DockWidget.ui"))
        self.canvas = self.iface.mapCanvas()
     
        # Default options
        self.GPSSettings = QSettings()

        # indication that this is the first time for the plugin
        self.firstTime = self.GPSSettings.value("trackGpsGPSSettings/firstTime",QVariant(bool(True))).toBool()
        # index of marker for GPS position (this is the arrow)
        self.markerNumber, isOK = self.GPSSettings.value("trackGpsGPSSettings/markerNumber",QVariant(int(0))).toInt()
        # default is black for marker fill color
        self.markerFillColor = QColor(self.GPSSettings.value("trackGpsGPSSettings/markerFillColor",QVariant(QColor(0,0,0))))
        # default is yellow for marker outline color
        self.markerOutlineColor = QColor(self.GPSSettings.value("trackGpsGPSSettings/markerOutlineColor",QVariant(QColor(255,255,0))))
        # width of tracking line
        self.trackLineWidth, isOK = self.GPSSettings.value("trackGpsGPSSettings/trackLineWidth",QVariant(int(3))).toInt()
        # color of tracking line (default is red)
        self.lineColor = QColor(self.GPSSettings.value("trackGpsGPSSettings/lineColor",QVariant(QColor(255,0,0))))
        self.saveInSHAPEFile = self.GPSSettings.value("trackGpsGPSSettings/saveInSHAPEFile",QVariant(bool(False))).toBool()
        # now recover/set the values for the serial port connection
        self.searchAllConnectionsSpeeds = self.GPSSettings.value("trackGpsGPSSettings/searchAllConnectionsSpeeds",
                                                                 QVariant(bool(True))).toBool()
        self.serialPortNumber, isOK = self.GPSSettings.value("trackGpsGPSSettings/serialPortNumber",QVariant(int(0))).toInt()
        self.serialPortSpeed, isOK = self.GPSSettings.value("trackGpsGPSSettings/serialPortSpeed",QVariant(int(0))).toInt()

        # set GPS connection values if they were recovered from a previous session
        if not self.searchAllConnectionsSpeeds: self.read.setConnectionValues(self.serialPortNumber,self.serialPortSpeed)
        
        # initialize the graphic elements for the GPS position
        self.positionMarker=PositionMarker(self.canvas, self.markerNumber, self.markerFillColor, self.markerOutlineColor)
        self.rubberBand=QgsRubberBand(self.canvas)
        self.rubberBand.setColor(self.lineColor)
        self.rubberBand.setWidth(self.trackLineWidth)
        self.rubberBandS = []
        self.GPSPositions = [] # array of positions in current track
        self.GPSTracks = [] # array of all tracks
    
    def __del__(self):
        """This method is used to save the settings for use the next time this plugin is used"""
        if self.guiStarted:
            # time to save plugin options as settings
            GPSSettings = QSettings()
        # indication that this is the first time for the plugin
            GPSSettings.setValue("trackGpsGPSSettings/firstTime",QVariant(self.firstTime))
            GPSSettings.setValue("trackGpsGPSSettings/searchAllConnectionsSpeeds",
                                                                 QVariant(bool(self.searchAllConnectionsSpeeds)))
            GPSSettings.setValue("trackGpsGPSSettings/markerNumber",QVariant(self.markerNumber))
            GPSSettings.setValue("trackGpsGPSSettings/markerFillColor",QVariant(self.markerFillColor))
            GPSSettings.setValue("trackGpsGPSSettings/markerOutlineColor",QVariant(self.markerOutlineColor))
            GPSSettings.setValue("trackGpsGPSSettings/trackLineWidth",QVariant(self.trackLineWidth))
            GPSSettings.setValue("trackGpsGPSSettings/lineColor",QVariant(self.lineColor))
            GPSSettings.setValue("trackGpsGPSSettings/saveInSHAPEFile",QVariant(self.saveInSHAPEFile))
            GPSSettings.setValue("trackGpsGPSSettings/serialPortNumber",QVariant(self.serialPortNumber))
            GPSSettings.setValue("trackGpsGPSSettings/serialPortSpeed",QVariant(self.serialPortSpeed))
            GPSSettings.synch()
            QMessageBox.information(self.iface.mainWindow(),"Class trackGPS Ending","trackGPS is being destroyed!")
    
    def initGui(self):
        self.guiStarted = True # signal that the GPS dialog was displayed
        if self.firstTime:
            self.firstTime = False
            QMessageBox.information(self.iface.mainWindow(),"Track GPS location","Since this is the first time"+\
                                    " that you have used the 'Track GPS location' plugin please consult the help "+\
                                    "in the plugin menu")
        # Create actions for plugin
        self.actionStart = QAction(QIcon(":/plugins/trackgps/Satellite-22.png"), "Start GPS Tracking", self.iface.mainWindow())
        self.actionStart.setWhatsThis("Open GPS Connection and Start Tracking")
        self.actionStop  = QAction(QIcon(":/plugins/trackgps/Satellite-22.png"), "Stop GPS Tracking", self.iface.mainWindow())
        self.actionStop.setWhatsThis("Close the GPS Connection and Stop Tracking")
        self.actionOptions  = QAction(QIcon(":/plugins/trackgps/options.png"),"Set GPS Tracking Options", self.iface.mainWindow())
        self.actionOptions.setWhatsThis("Set the various GPS Connection/Tracking Options")
        # add help menu item
        self.helpAction = QAction(QIcon(":/plugins/trackgps/images/help-browser.png"), "GPS Tracking Help", self.iface.mainWindow())
     
        # New Track actions set up here
        self.dock.btnStartNewTrack.setDisabled(True) # Starting New Tracks is disabled at start
        QObject.connect(self.dock.btnStartNewTrack, SIGNAL("clicked()"), self.startNewTrack)
        
        # Connect the actions to its methods
        QObject.connect(self.actionStart, SIGNAL("activated()"), self.toogleGather)
        QObject.connect(self.actionStop,  SIGNAL("activated()"), self.toogleGather)
        QObject.connect(self.actionOptions,  SIGNAL("activated()"), self.showGPSMenuOptions)
        QObject.connect(self.dock.btnStart,  SIGNAL("clicked()"), self.toogleGather)
        QObject.connect(self.read,  SIGNAL("readCoords(PyQt_PyObject)"), self.setCoords)
        QObject.connect(self.read,  SIGNAL("connectionFailed(PyQt_PyObject)"), self.connectionFailed)
        QObject.connect(self.read,  SIGNAL("connectionMade()"), self.connectionMade)
        QObject.connect(self.helpAction, SIGNAL("activated()"), self.helpWindow)
     
        # Add menu items for action
        self.iface.addPluginToMenu("Track GPS location", self.actionOptions)
        self.iface.addPluginToMenu("Track GPS location", self.actionStart)
        self.iface.addPluginToMenu("Track GPS location", self.helpAction)
        myPluginMenu = self.iface.pluginMenu()
        QObject.connect(myPluginMenu, SIGNAL("aboutToShow()"), self.updateTrackGPSMenu)
     
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

    def helpWindow(self):
        window = HelpForm("TheQGISGPSTrackerPlugin.html",self.iface.mainWindow())
        window.show()
    
    def updateTrackGPSMenu(self):
        if self.read.running:
            self.iface.addPluginToMenu("Track GPS location", self.actionStop)
            self.iface.removePluginMenu("Track GPS location", self.actionStart)
        else:
            self.iface.addPluginToMenu("Track GPS location", self.actionStart)
            self.iface.removePluginMenu("Track GPS location", self.actionStop)
    
    def startNewTrack(self):
        self.read.stop() # close serial port
        self.rubberBandS.append(self.rubberBand)
        self.showGPSMenuOptions() # give user opportunity to change display options
        #if len(self.GPSPositions) > 0: # temporary section to display positional information
        #    QMessageBox.information(self.iface.mainWindow(),"trackGPS","There are: " + str(len(self.GPSPositions)) + " GPS Positions in the current track")
        #    for i in range(len(self.GPSPositions)):
        #        QMessageBox.information(self.iface.mainWindow(),"trackGPS","Position #" + str(i) + ": Latitude=" + str(self.GPSPositions[i].latitude))
        self.rubberBand=QgsRubberBand(self.canvas) # start new rubber band
        if len(self.GPSPositions) > 0 and self.saveInSHAPEFile:
            self.GPSTracks.append(self.GPSPositions) # save GPSPositions to GPSTracks
            self.GPSPositions = []
        self.startGather() # open serial port and record new track
       
    def unload(self):
        # Remove the plugin menu item
        self.iface.removePluginMenu("Track GPS location", self.actionStart)
        self.iface.removePluginMenu("Track GPS location", self.actionStop)
        self.iface.removePluginMenu("Track GPS location", self.actionOptions)
    
    def startGather(self):
        #update all of the GPS display options
        self.positionMarker.markerNumber = self.markerNumber
        self.positionMarker.fillColor = self.markerFillColor
        self.positionMarker.outlineColor = self.markerOutlineColor
        self.rubberBand.setColor(self.lineColor)
        self.rubberBand.setWidth(self.trackLineWidth)
        self.positionMarker.show()
        # get destination crs of the canvas
        dest_crs = self.canvas.mapRenderer().destinationSrs()
        print "destination crs:",dest_crs.description()
        # create transform object from WGS84 (GPS) to canvas CRS
        self.transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(self.read.session.datumEPSG,\
                                                        QgsCoordinateReferenceSystem.EpsgCrsId ),dest_crs)
        self.read.start()
        self.read.exec_()
    
    def setCoords (self,aGPSPosition):
        """SLOT: show read coordinates"""
        # display raw values
        self.GPSPositions.append(aGPSPosition)
        self.dock.date.setText(aGPSPosition.theDateTime)
        self.dock.lat.setText(str(aGPSPosition.latitude) + ' ' + aGPSPosition.latitudeNS)
        self.dock.lon.setText(str(aGPSPosition.longitude) + ' ' + aGPSPosition.longitudeEW)
        self.dock.lineBearing.setText("%5.1i"%aGPSPosition.bearing)
        self.dock.lineSpeed.setText("%5.1i"%aGPSPosition.speed)
        # display arrow on the map
        latitude = aGPSPosition.latitude if aGPSPosition.latitudeNS == 'N' else aGPSPosition.latitude * -1.0
        longitude = aGPSPosition.longitude if aGPSPosition.longitudeEW == 'E' else aGPSPosition.longitude * -1.0
        p=self.transform.transform(QgsPoint(longitude, latitude))
        self.rubberBand.addPoint(p)
        self.positionMarker.setHasPosition(True)
        self.positionMarker.newCoords(p,aGPSPosition.bearing)
        # move map to keep marker at center
        curext = self.canvas.extent()
        p1 = QgsPoint(p.x()-curext.width()/2,p.y()-curext.height()/2)
        p2 = QgsPoint(p.x()+curext.width()/2,p.y()+curext.height()/2)
        self.canvas.setExtent(QgsRectangle (p1,p2))
        self.canvas.refresh()
    
    def stopGather(self):
        self.read.stop()
        self.positionMarker.hide()
        if len(self.GPSPositions) > 0: # and self.saveInSHAPEFile:
            self.GPSTracks.append(self.GPSPositions) # save GPSPositions to GPSTracks
        # if len(self.GPSTracks) > 0 and self.saveInSHAPEFile:
        if self.saveInSHAPEFile: # this is temporary
            # option to save SHAPE file is on, prompt for filename and write the tracks to the file
#            QMessageBox.information(self.iface.mainWindow(),"trackGPS","There are: " + str(len(self.GPSTracks)) + " GPS tracks in the current track")
#            for j in range(len(self.GPSTracks)):
#                QMessageBox.information(self.iface.mainWindow(),"trackGPS","In track #" + str(j) + " There are: " + str(len(self.GPSTracks[j])) + " GPS Positions")
#                for i in range(len(self.GPSTracks[j])):
#                    QMessageBox.information(self.iface.mainWindow(),"trackGPS","Position #" + str(i) + ": Latitude=" + str(self.GPSTracks[j][i].latitude))
            self.makeShapeFiles()
        if len(self.GPSTracks) > 0:
            answer = QMessageBox.question(self.iface.mainWindow(),"Erase Tracks?","Erase the currently displayed tracks?",\
                                          QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if answer == QMessageBox.Yes:
                for band in self.rubberBandS:
                    band.reset()
                self.rubberBand.reset()
                self.canvas.refresh()
                self.rubberBandS = []
            self.GPSPositions = []
            self.GPSTracks = []
    
    def toogleGather(self):
        if self.read.running:
            QMessageBox.information(self.iface.mainWindow(),"GPS Tracker","Stopping GPS Tracking",QMessageBox.Ok)
            self.stopGather()
            self.dock.btnStart.setText("Start")
            self.dock.gpsInformation.setText("Gets GPS Receiver Information")
            self.dock.btnStartNewTrack.setDisabled(True)
        else:
            self.dock.btnStart.setText("Connecting, please be patient....")
            self.startGather()
            if self.read.session.connected: self.dock.btnStart.setText("Stop")
    
    def connectionMade(self):
        # QMessageBox.information(self.iface.mainWindow(),"trackGps","GPS Receiver Connected on port: %s at %i baud\n"%\
        #                     (self.read.session.portName,self.read.session.baudRate),QMessageBox.Ok,0)
        self.dock.gpsInformation.setText("GPS Connected on port: %s at %i baud"%(self.read.session.portName,\
                                                                                          self.read.session.baudRate))
        self.dock.btnStart.setText("Stop")
        self.dock.btnStartNewTrack.setDisabled(False)
        # save connection values in session parameters
        self.serialPortNumber = self.read.session.port
        self.serialPortSpeed = self.read.session.baudRates.index(self.read.session.baudRate)
        self.searchAllConnectionsSpeeds = False
    def connectionFailed(self,msg):
        QMessageBox.warning(self.iface.mainWindow(),"trackGps","Connection to GPSConnection failed\n%s"%(msg),QMessageBox.Ok,0)
        if self.read.session.connected: self.read.stop()
        self.dock.btnStart.setText("Start")
        self.dock.btnStartNewTrack.setDisabled(True) # Starting New Tracks is disabled at start
    
    def showGPSMenuOptions(self):
        """
        Function to handle all GPS Tracking Options
        """
        #
        myGPSOptionsDlg = GPSTrackerOptions(self)
        isOK = myGPSOptionsDlg.exec_()
        if isOK:
            if myGPSOptionsDlg.cbxMarkerType.currentIndex() != self.markerNumber: self.markerNumber = \
                                                            myGPSOptionsDlg.cbxMarkerType.currentIndex()
            if myGPSOptionsDlg.lineColor != self.lineColor: self.lineColor = myGPSOptionsDlg.lineColor
            if myGPSOptionsDlg.markerFillColor != self.markerFillColor: self.markerFillColor = \
                                                   myGPSOptionsDlg.markerFillColor
            if myGPSOptionsDlg.markerOutlineColor != self.markerOutlineColor: self.markerOutlineColor = \
                                                      myGPSOptionsDlg.markerOutlineColor
            if myGPSOptionsDlg.sbxTrackWidth.value() != self.trackLineWidth: self.trackLineWidth = \
                                                                        myGPSOptionsDlg.sbxTrackWidth.value()
            if myGPSOptionsDlg.cbxSaveGPSTrack.isChecked() != self.saveInSHAPEFile: self.saveInSHAPEFile =\
                                                                  myGPSOptionsDlg.cbxSaveGPSTrack.isChecked()
    
    def makeShapeFiles(self):
        """
        Function to save data to SHAPE files
        """
        myFileName = QgsProject.instance().fileName()
        myFileName = str(myFileName)
        # if this is a windows OS then the filename needs to have '/' converted to '\'
        if myFileName.find('windows') != 0 or myFileName.find('Windows') != 0: myFileName = os.path.normpath(myFileName)
        myFilePath = os.path.dirname(myFileName)
        #mymessage = 'QGIS Project Pathname=\'' + myFilePath + '\''
        #QMessageBox.information(self.iface.mainWindow(),"trackGps",mymessage,QMessageBox.Ok)
        myShapeFileNamesDlg = ShapeFileNames(myFilePath)
        isOK = myShapeFileNamesDlg.exec_()
        CRS = QgsCoordinateReferenceSystem()
        crsIsOk = CRS.createFromEpsg(self.GPSTracks[0][0].datumEPSG)
        if not crsIsOk: QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating CRS from"+\
                                            " EPSG ID:" + str(self.GPSTracks[0][0].datumEPSG))
        if isOK and crsIsOk:
            if len(myShapeFileNamesDlg.lnePointsFileName.text()) > 0:
                # set up the fields for the Points SHAPE file
                latf = QgsField ("LATITUDE", QVariant.Double, "Real", 9, 6)
                lonf = QgsField ("LONGITUDE", QVariant.Double, "Real", 10, 6)
                nums = QgsField ("NUMOFSATS", QVariant.Int, "Integer", 2, 0)
                hdop = QgsField ("HDOP", QVariant.Double, "Real", 4, 2)
                theDateTime = QgsField ("DATETIME", QVariant.String, "String", 19, 0)
                fixType = QgsField ("FIXTYPE", QVariant.String, "String", 1, 0)
                #fixType = QgsField ("FIXTYPE", QVariant.String)
                #fixType.setLength(1)
                bearing = QgsField ("BEARING", QVariant.Double, "Real", 6, 2)
                speed = QgsField ("SPEED-KPH", QVariant.Double, "Real", 5, 1)
                trackNumber = QgsField ("TRACKNUM", QVariant.Int, "Integer", 2, 0)
                qFields = {}
                qFields[0] = latf
                qFields[1] = lonf
                qFields[2] = nums
                qFields[3] = hdop
                qFields[4] = theDateTime
                qFields[5] = fixType
                qFields[6] = bearing
                qFields[7] = speed
                qFields[8] = trackNumber
                # set up the CRS
                # open the points SHAPE file
                # pointsFile = QgsVectorFileWriter(myShapeFileNamesDlg.lnePointsFileName.text(),"System",qFields,QGis.WKBPoint,CRS)
                pointsFile, fileOK = self.createSHAPEfile(myShapeFileNamesDlg.lnePointsFileName.text(),qFields,QGis.WKBPoint,CRS)
                if fileOK:
                    for j in range(len(self.GPSTracks)):
                        for i in range(len(self.GPSTracks[j])):
                            theFeature = QgsFeature()
                            latitude = self.GPSTracks[j][i].latitude
                            if self.GPSTracks[j][i].latitudeNS == 'S': latitude = -latitude
                            longitude = self.GPSTracks[j][i].longitude
                            if self.GPSTracks[j][i].longitudeEW == 'W': longitude = -longitude
                            theFeature.setGeometry(QgsGeometry.fromPoint(QgsPoint(longitude,latitude)))
                            theFeature.addAttribute(0, QVariant(latitude))
                            theFeature.addAttribute(1, QVariant(longitude))
                            theFeature.addAttribute(2, QVariant(self.GPSTracks[j][i].numSatellites))
                            theFeature.addAttribute(3, QVariant(self.GPSTracks[j][i].hdop))
                            theFeature.addAttribute(4, QVariant(self.GPSTracks[j][i].theDateTime))
                            theFeature.addAttribute(5, QVariant(self.GPSTracks[j][i].fixQuality))
                            theFeature.addAttribute(6, QVariant(self.GPSTracks[j][i].bearing))
                            theFeature.addAttribute(7, QVariant(self.GPSTracks[j][i].speed))
                            theFeature.addAttribute(8, QVariant(j+1))
                            pointsFile.addFeature(theFeature)
                    del pointsFile # del file object to force a flush and close
            if len(myShapeFileNamesDlg.lneLinesFileName.text()) > 0:
                # set up the fields for the Lines SHAPE file
                startDateTime = QgsField ("SDATETIME", QVariant.String, "String", 19, 0)
                endDateTime = QgsField ("EDATETIME", QVariant.String, "String", 19, 0)
                trackNumber = QgsField ("TRACKNUM", QVariant.Int, "Integer", 2, 0)
                qFields = {}
                qFields[0] = startDateTime
                qFields[1] = endDateTime
                qFields[2] = trackNumber
                linesFile, fileOK = self.createSHAPEfile(myShapeFileNamesDlg.lneLinesFileName.text(),qFields,QGis.WKBLineString,CRS)
                if fileOK:
                    for j in range(len(self.GPSTracks)):
                        theFeature = QgsFeature()
                        pointsList = []
                        for i in range(len(self.GPSTracks[j])):
                            latitude = self.GPSTracks[j][i].latitude
                            if self.GPSTracks[j][i].latitudeNS == 'S': latitude = -latitude
                            longitude = self.GPSTracks[j][i].longitude
                            if self.GPSTracks[j][i].longitudeEW == 'W': longitude = -longitude
                            pointsList.append(QgsPoint(longitude,latitude))
                        theFeature.setGeometry(QgsGeometry.fromPolyline(pointsList))
                        theFeature.addAttribute(0, QVariant(self.GPSTracks[j][0].theDateTime))
                        theFeature.addAttribute(1, QVariant(self.GPSTracks[j][len(self.GPSTracks[j])-1].theDateTime))
                        theFeature.addAttribute(2, QVariant(j+1))
                        linesFile.addFeature(theFeature)
                    del linesFile # del file object to force a flush and close

    def createSHAPEfile(self,fileName,fileFields,fileType,crs):
        '''
        this function creates a new, empty shape file for use in writing points or lines
        Returns: SHAPEfile, status
            if status == True then SHAPEfile is OK to use, if False then an error occured and cannot use SHAPEFile
            
        Input Parameters:
            fileName = full name of the SHAPE file to be created
            fileFields = map of QgsFields to use for the attributes of the SHAPE file
            fileType = QGis.WKBPoint for points file <or> QGis.WKBLine for lines file
            crs = the QgsCoordinateReferenceSystem to use for the file
        '''
        status = True # default is no error
        SHAPEfile = QgsVectorFileWriter(fileName,"CP1250",fileFields,fileType,crs)
        typeName = 'Points' if fileType == QGis.WKBPoint else 'Lines'
        if SHAPEfile.hasError() != QgsVectorFileWriter.NoError:
            status = False # report an error
            if SHAPEfile.hasError() == QgsVectorFileWriter.ErrDriverNotFound:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrDriverNotFound\' - saving " + typeName + " is aborted")
            elif SHAPEfile.hasError() == QgsVectorFileWriter.ErrCreateDataSource:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrCreateDataSource\' - saving " + typeName + " is aborted")
            elif SHAPEfile.hasError() == QgsVectorFileWriter.ErrCreateLayer:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrCreateLayer\' - saving " + typeName + " is aborted")
            elif SHAPEfile.hasError() == QgsVectorFileWriter.ErrAttributeTypeUnsupported:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'ErrAttributeTypeUnsupported\' - saving " + typeName + " is aborted")
            else:
                QMessageBox.warning(self.iface.mainWindow(),"trackGPS - makeShapeFiles","Error creating " + typeName + " SHAPE file" +\
                                            " ERROR=\'UNKOWN ERROR\' saving " + typeName + " is aborted")
        return SHAPEfile,status
Example #5
0
class FlyingTrackerDialog(QtGui.QDockWidget, FORM_CLASS):
    def __init__(self, iface, parent=None):
        """Constructor."""
        super(FlyingTrackerDialog, self).__init__(parent)

        self.setupUi(self)
        self.iface = iface

        self.course_comboBox.clear()
        self.lcdNumberWpt.display(1)

        self.GpsFixlcdNumber.display(0)
        self.SatelliteslcdNumber.display(0)

        self.pushButtonDisconnect.hide()
        self.pushButtonConnect.clicked.connect(self.Connect)
        self.pushButtonDisconnect.clicked.connect(self.Disconnect)
        self.pushCloseButton.clicked.connect(self.Close)
        self.LoadtoolButton.clicked.connect(self.FillComboBox)
        self.wptplus_toolButton.clicked.connect(self.NextWpt)
        self.wptmin_toolButton.clicked.connect(self.BackWpt)
        QtCore.QObject.connect(self.wptplus_toolButton,
                               QtCore.SIGNAL("valueChanged(int)"),
                               self.AdjNxtWpt)
        QtCore.QObject.connect(self.wptmin_toolButton,
                               QtCore.SIGNAL("valueChanged(int)"),
                               self.AdjNxtWpt)
        self.ZoomIntoolButton.clicked.connect(self.ZoomIn)
        self.ZoomOuttoolButton.clicked.connect(self.ZoomOut)

        shortcut = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_S),
                                   self.iface.mainWindow())
        shortcut.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut.activated.connect(self.ZoomIn)
        shortcut2 = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_A),
                                    self.iface.mainWindow())
        shortcut2.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut2.activated.connect(self.ZoomOut)
        shortcut3 = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_X),
                                    self.iface.mainWindow())
        shortcut3.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut3.activated.connect(self.NextWpt)
        shortcut4 = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Z),
                                    self.iface.mainWindow())
        shortcut4.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut4.activated.connect(self.BackWpt)

        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.SendSerial)

        self.NxtWptRubber = False
        self.PositionMarker = False
        self.RubberBand = False
        self.WptVertexSignal = False

        self.trackCounter = 4

    def AdjNxtWpt(self):

        if self.WptVertexSignal == True:
            self.iface.mapCanvas().scene().removeItem(self.WptVertex)
            del self.WptVertex
            self.WptVertexSignal = False

        if self.NxtWptRubber == True:
            self.iface.mapCanvas().scene().removeItem(self.rdue)
            del self.rdue
            self.iface.mapCanvas().scene().removeItem(self.rtre)
            del self.rtre
            self.NxtWptRubber = False

        canvas = self.iface.mapCanvas()
        mapRenderer = canvas.mapRenderer()
        crsSrc = QgsCoordinateReferenceSystem(4326)  # NMEA is in WGS 84
        crsDest = mapRenderer.destinationCrs()
        xform = QgsCoordinateTransform(crsSrc, crsDest)

        WptValue = int(self.lcdNumberWpt.value())

        try:
            Wpt = self.pts[WptValue - 1]

        except IndexError:
            return

        self.WptVertex = QgsVertexMarker(self.iface.mapCanvas())
        self.WptVertex.setIconSize(20)
        self.WptVertex.setIconType(QgsVertexMarker.ICON_X)
        self.WptVertex.setPenWidth(20)
        self.WptVertex.setCenter(xform.transform(Wpt))
        self.WptVertexSignal = True

        if WptValue != 1:

            Wpt2 = self.pts[WptValue - 2]
            self.rdue = QgsRubberBand(self.iface.mapCanvas(),
                                      False)  # False = not a polygon
            pointsdue = [xform.transform(Wpt), xform.transform(Wpt2)]

            self.rdue.setColor(QtGui.QColor(255, 0, 0))
            self.rdue.setWidth(8)
            self.rdue.setLineStyle(QtCore.Qt.PenStyle(QtCore.Qt.DotLine))
            self.rdue.setToGeometry(QgsGeometry.fromPolyline(pointsdue),
                                    None)  #creation of NextWayPoint rubberband

            self.rtre = QgsRubberBand(self.iface.mapCanvas(), False)
            pointstre = self.pts[0:WptValue - 1]

            for i in xrange(len(pointstre)):
                pointstre[i] = xform.transform(pointstre[i])

            self.rtre.setColor(QtGui.QColor(127, 0, 255))
            self.rtre.setWidth(8)
            self.rtre.setLineStyle(QtCore.Qt.PenStyle(QtCore.Qt.DotLine))
            self.rtre.setToGeometry(QgsGeometry.fromPolyline(pointstre), None)

            self.NxtWptRubber = True

    def Connect(self):

        try:

            self.positionMarker = PositionMarker(self.iface.mapCanvas())
            self.PositionMarker = True
            portName = self.comboBox.currentText()
            self.ser = serial.Serial(portName, 38400)
            layername = self.course_comboBox.itemData(
                self.course_comboBox.currentIndex())
            RouteLayer = QgsMapLayerRegistry.instance().mapLayer(layername)
            RouteLayer.selectAll()
            feats = RouteLayer.selectedFeatures()
            RouteLayer.removeSelection()
            feat = feats[0]
            geom = feat.geometry()
            self.pts = geom.asPolyline()
            SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])

            if SourceIntCRS != 4326:
                SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])
                SourceCRS = QgsCoordinateReferenceSystem(SourceIntCRS)
                DestCRS = QgsCoordinateReferenceSystem(4326)
                xformRouteLayer = QgsCoordinateTransform(SourceCRS, DestCRS)
                for i in xrange(len(self.pts)):
                    x = self.pts[i][0]
                    y = self.pts[i][
                        1]  #if track layer is not in WGS84 Geographic every coordinate is transformed
                    TmpPoint = QgsPoint(x, y)
                    Tmp2Point = xformRouteLayer.transform(TmpPoint)
                    self.pts[i] = Tmp2Point

            self.TrackLayer = QgsVectorLayer("Point?crs=epsg:4326&index=yes",
                                             "Flight_track", "memory")
            self.TrackLayerProvider = self.TrackLayer.dataProvider()
            self.TrackLayerProvider.addAttributes([
                QgsField("id", QtCore.QVariant.Int),
                QgsField('Time', QtCore.QVariant.String),
                QgsField('Ele', QtCore.QVariant.String),
            ])

            QgsMapLayerRegistry.instance().addMapLayer(self.TrackLayer)
            symbols = self.TrackLayer.rendererV2().symbols()
            symbol = symbols[0]
            symbol.setColor(QtGui.QColor(0, 255, 0))
            self.iface.legendInterface().refreshLayerSymbology(self.TrackLayer)

            if self.lcdNumberWpt.value() == 0:
                self.lcdNumberWpt.display(1)

            elif self.lcdNumberWpt.value() > len(self.pts):
                self.lcdNumberWpt.display(1)

            self.InRouteTolerance = float(
                self.DTrack_spinBox.value()
            )  #if we are distant from route less than this value path become green, otherwise red
            self.CompassTolerance = self.DCompass_spinBox.value(
            )  #if compass to next wpt confront to actual compass diverge less than this value projection of direction become green, otherwise red
            self.WptArrivedTolerance = float(
                self.DWpt_spinBox.value()
            )  #if we pass near a wpt less than this value (in meters) the program will set the next wpt
            self.EleTolerance = float(
                self.DHeightspinBox.value()
            )  #if our elevation diverge from planned elevation more than this value our cursor will be red, otherwise green

            canvas = self.iface.mapCanvas()
            mapRenderer = canvas.mapRenderer()
            crsSrc = QgsCoordinateReferenceSystem(4326)  # NMEA is in WGS 84
            crsDest = mapRenderer.destinationCrs()

            self.backxform = QgsCoordinateTransform(crsDest, crsSrc)

            self.xform = QgsCoordinateTransform(
                crsSrc, crsDest)  #usage: xform.transform(QgsPoint)
            self.AdjNxtWpt()
            self.timer.start(1000)

        except:
            pass

    def SendSerial(self):
        thread = Thread(target=self.ReadSerial)
        thread.start()
        thread.join()

    def Disconnect(self, serialPort):

        self.timer.stop()
        self.lcdNumberSpeed.display(0)
        self.lcdNumberCompass.display(0)
        try:
            self.iface.mapCanvas().scene().removeItem(self.WptVertex)
            self.ser.close()
            self.iface.mapCanvas().scene().removeItem(self.r)
            self.iface.mapCanvas().scene().removeItem(self.runo)
            self.iface.mapCanvas().scene().removeItem(self.positionMarker)
            del self.WptVertex
            del self.r
            del self.runo
        except:
            pass

        self.iface.mapCanvas().setRotation(0)

        self.RubberBand = False

        if self.NxtWptRubber == True:
            self.iface.mapCanvas().scene().removeItem(self.rdue)
            self.iface.mapCanvas().scene().removeItem(self.rtre)
            del self.rdue
            del self.rtre
            self.NxtWptRubber = False

        else:
            pass

        self.WptVertexSignal = False
        self.lcdNumberHeights.display(0)
        self.lcdNumberSpeed.display(0)
        self.lcdNumberCompass.display(0)
        self.lcdCompassWpt.display(0)
        self.GpsFixlcdNumber.display(0)
        self.SatelliteslcdNumber.display(0)

    def FillComboBox(self):
        try:
            self.comboBox.clear()
            portlist = []
            system_name = platform.system()
            if system_name == "Windows":
                # Scan for available ports.
                available = []
                for i in range(256):
                    try:
                        s = serial.Serial(i)
                        available.append(i)
                        s.close()
                    except serial.SerialException:  #Search for active serial port
                        pass
                #print available
                list1 = available
            elif system_name == "Darwin":
                # Mac
                #print glob.glob('/dev/tty*') + glob.glob('/dev/cu*')
                list1 = glob.glob('/dev/tty*') + glob.glob('/dev/cu*')
            else:
                # Assume Linux or something else
                #print glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')
                list1 = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')
            for i in list1:
                try:
                    serial.Serial(i).close()
                    portlist.append(i)
                except IOError:
                    pass

            for x in portlist:
                self.comboBox.addItem(x)

            self.course_comboBox.clear()

            LayerRegistryItem = QgsMapLayerRegistry.instance().mapLayers()
            for id, layer in LayerRegistryItem.iteritems():
                if layer.type() == QgsMapLayer.VectorLayer:
                    self.course_comboBox.addItem(layer.name(), id)

            layername = self.course_comboBox.itemData(
                self.course_comboBox.currentIndex())
            RouteLayer = QgsMapLayerRegistry.instance().mapLayer(layername)
            RouteLayer.selectAll()
            RouteLayer.featureCount()
            feats = RouteLayer.selectedFeatures()
            RouteLayer.removeSelection()
            feat = feats[0]
            geom = feat.geometry()
            self.pts = geom.asPolyline()
            SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])

            if SourceIntCRS != 4326:
                SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])
                SourceCRS = QgsCoordinateReferenceSystem(SourceIntCRS)
                DestCRS = QgsCoordinateReferenceSystem(4326)
                xformRouteLayer = QgsCoordinateTransform(SourceCRS, DestCRS)
                for i in xrange(len(self.pts)):
                    x = self.pts[i][0]
                    y = self.pts[i][
                        1]  #if track layer is not in WGS84 Geographic every coordinate is transformed
                    TmpPoint = QgsPoint(x, y)
                    Tmp2Point = xformRouteLayer.transform(TmpPoint)
                    self.pts[i] = Tmp2Point

            self.AdjNxtWpt()
        except:
            pass

    def Close(self):

        self.timer.stop()
        self.lcdNumberHeights.display(0)
        self.lcdNumberSpeed.display(0)
        self.lcdNumberCompass.display(0)
        self.lcdCompassWpt.display(0)

        self.course_comboBox.clear()
        if self.PositionMarker == True:
            self.iface.mapCanvas().scene().removeItem(self.positionMarker)

        if self.NxtWptRubber == True:
            self.iface.mapCanvas().scene().removeItem(self.rdue)
            self.iface.mapCanvas().scene().removeItem(self.rtre)
            del self.rdue
            del self.rtre
            self.NxtWptRubber = False

        else:
            pass

        if self.WptVertexSignal == True:
            self.iface.mapCanvas().scene().removeItem(self.WptVertex)
            del self.WptVertex
            self.WptVertexSignal = False

        self.close()

    def ZoomIn(self):
        self.iface.mapCanvas().zoomIn()

    def ZoomOut(self):
        self.iface.mapCanvas().zoomOut()

    def NextWpt(self):
        try:
            currentValue = self.lcdNumberWpt.value()
            if currentValue == len(self.pts):
                pass
            else:
                self.lcdNumberWpt.display(currentValue + 1)
                self.AdjNxtWpt()
        except:
            pass

    def BackWpt(self):
        try:
            currentValue = self.lcdNumberWpt.value()
            if currentValue >= 2:
                self.lcdNumberWpt.display(currentValue - 1)
                self.AdjNxtWpt()
        except:
            pass

    def ReadSerial(self):

        if self.trackCounter > 5:
            self.trackCounter = 4
        self.trackCounter = self.trackCounter + 1  # when it arrive to 5 a gps point is painted (default is 4)

        GPGGA = 0
        GPVTG = 0

        data = self.ser.read(1)
        n = self.ser.inWaiting()
        if n:
            data = data + self.ser.read(n)

        if re.search("\r\n", data):
            # Since we found a CRLF, split it out
            data2 = data.split("\r\n")

            for i in range(len(data2)):

                if data2[i][0:6] == '$GPGGA':
                    GPGGA = data2[i].split(',')
                    #print GPGGA

                elif data2[i][0:6] == '$GPVTG':
                    GPVTG = data2[i].split(',')
                    #print GPRMC

            if GPGGA == 0:
                #print 'mancato'
                return

            elif GPVTG == 0:
                #print 'mancato'
                return

            else:

                decimalsLat = (float(GPGGA[2][2:])) / 60
                degreeLat = float(GPGGA[2][0:2])
                decimalsLon = (float(GPGGA[4][3:])) / 60
                degreeLon = float(GPGGA[4][0:3])

                Lat = degreeLat + decimalsLat
                Lon = degreeLon + decimalsLon

                if GPGGA[5] == 'W':
                    Lon = -Lon
                if GPGGA[3] == 'S':
                    Lat = -Lat

                Ele = float(GPGGA[9])
                Compass = float(GPVTG[1])
                Speed = (float(GPVTG[7]))  # in Km/h
                GpsFix = int(GPGGA[6])
                GpsSatellites = int(GPGGA[7])

                self.ser.flushInput()
                self.ser.flushOutput()

                self.GpsFixlcdNumber.display(GpsFix)
                self.SatelliteslcdNumber.display(GpsSatellites)

                if self.RubberBand == True:
                    self.iface.mapCanvas().scene().removeItem(self.r)
                    del self.r

                    self.RubberBand = False

                Point = QgsPoint()
                Point.set(Lon, Lat)

                TransfPoint = self.xform.transform(Point)

                canvas = self.iface.mapCanvas()
                if Compass <= 180:
                    #canvas.setRotation(-(Compass-self.rotation))
                    canvas.setRotation(
                        -Compass
                    )  # set canvas rotation according to:  UP of the map = Compass Direction
                else:
                    Compass = 360 - Compass
                    canvas.setRotation(Compass)

                canvas.setCenter(TransfPoint)

                self.positionMarker.newCoords(
                    TransfPoint)  # Put the arrow on screen
                #self.positionMarker.angle = 0.0

                WptValue = int(self.lcdNumberWpt.value())
                WptE = self.pts[WptValue - 1][0]
                WptN = self.pts[WptValue - 1][1]

                GeodesicAircraftToWpt = Geodesic.WGS84.Inverse(
                    Lat, Lon, WptN, WptE)
                distance = GeodesicAircraftToWpt['s12']
                azim = GeodesicAircraftToWpt[
                    'azi1']  #determine azimuth from next wpt
                if azim < 0:
                    azim += 360

                if distance <= self.WptArrivedTolerance:  # tolerance in meter for next wpt
                    self.NextWpt()

                #feetEle = Ele * 3.2808399            #meters to feet

                if self.comboBox_2.currentText() == 'ft.':
                    feetEle = Ele * 3.2808399  #Convert if needed
                    self.lcdNumberHeights.display(feetEle)
                else:
                    self.lcdNumberHeights.display(Ele)

                if self.comboBox_3.currentText() != 'km/h':
                    Speed = Speed * 0.53995694  #Convert if needed
                    self.lcdNumberSpeed.display(float(Speed))
                else:
                    self.lcdNumberSpeed.display(float(Speed))

                self.lcdNumberCompass.display(float(Compass))
                self.lcdCompassWpt.display(azim)

                canvasInPixel = canvas.getCoordinateTransform()
                ExtentHeightInPixel = canvasInPixel.mapHeight()
                ExtentWidthInPixel = canvasInPixel.mapWidth()

                LocateCompassProjectionEndInMapUnit = canvasInPixel.toMapPoint(
                    ExtentWidthInPixel / 2.0,
                    ExtentHeightInPixel - (ExtentHeightInPixel * 0.95))

                self.r = QgsRubberBand(self.iface.mapCanvas(),
                                       False)  # False = not a polygon

                #points = [TransfPoint, QgsPoint(x,y)]							#creazione della proiezione della prua su mappa
                points = [TransfPoint, LocateCompassProjectionEndInMapUnit]
                self.r.setWidth(8)
                self.r.setToGeometry(QgsGeometry.fromPolyline(points), None)

                if abs(Compass -
                       azim) <= self.CompassTolerance:  #Compass tolerance
                    self.r.setColor(QtGui.QColor(0, 255, 0))
                else:
                    self.r.setColor(QtGui.QColor(255, 0, 0))

                self.RubberBand = True

                try:
                    self.iface.mapCanvas().scene().removeItem(
                        self.runo)  # remove track for first waypoint
                except:
                    pass

                if WptValue != 1:

                    #DistanceFromLineTolerance = 100   #meter      set distance from route

                    BackwardLat = self.rdue.asGeometry().asPolyline()[1][
                        1]  #start to design a QgsRectangle buffer around current route to confront to Point
                    BackwardLon = self.rdue.asGeometry().asPolyline()[1][0]
                    BackwardPoint = QgsPoint(BackwardLon, BackwardLat)

                    BackwardPointTransformed = self.backxform.transform(
                        BackwardPoint)

                    GeodesicWptWpt = Geodesic.WGS84.Inverse(
                        BackwardPointTransformed.y(),
                        BackwardPointTransformed.x(), WptN, WptE)
                    #GeodesicWptWpt = Geodesic.WGS84.Inverse(BackwardLat, BackwardLon, WptN, WptE)
                    WptWptCompass = GeodesicWptWpt['azi1']

                    if WptWptCompass < 0:
                        WptWptCompass += 360
                    #print WptWptCompass

                    WptWptCompassRight = WptWptCompass + 90
                    if WptWptCompassRight > 360:
                        WptWptCompassRight = WptWptCompassRight - 360
                    #print WptWptCompassRight

                    WptWptCompassLeft = WptWptCompass - 90
                    if WptWptCompassLeft < 0:
                        WptWptCompassLeft += 360
                    #print WptWptCompassLeft

                    origin = geopy.Point(WptN, WptE)
                    URBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassRight)
                    URBufferVertexPoint = QgsPoint(URBufferVertex.longitude,
                                                   URBufferVertex.latitude)

                    ULBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassLeft)
                    ULBufferVertexPoint = QgsPoint(ULBufferVertex.longitude,
                                                   ULBufferVertex.latitude)
                    del origin

                    origin = geopy.Point(BackwardPointTransformed.y(),
                                         BackwardPointTransformed.x())
                    DRBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassRight)
                    DRBufferVertexPoint = QgsPoint(DRBufferVertex.longitude,
                                                   DRBufferVertex.latitude)

                    DLBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassLeft)
                    DLBufferVertexPoint = QgsPoint(DLBufferVertex.longitude,
                                                   DLBufferVertex.latitude)
                    del origin

                    gPolygon = QgsGeometry.fromPolygon([[
                        URBufferVertexPoint, ULBufferVertexPoint,
                        DLBufferVertexPoint, DRBufferVertexPoint
                    ]])

                    if not gPolygon.contains(Point):
                        self.rdue.setColor(QtGui.QColor(255, 0, 0))
                        #print 'noncontiene'
                    else:
                        self.rdue.setColor(QtGui.QColor(0, 255, 0))
                        #print 'contiene'
                else:
                    self.runo = QgsRubberBand(self.iface.mapCanvas(), False)
                    points = [TransfPoint,
                              self.xform.transform(self.pts[0])
                              ]  # draw track for first waypoint
                    self.runo.setColor(QtGui.QColor(255, 0, 0))
                    self.runo.setWidth(6)
                    self.runo.setLineStyle(
                        QtCore.Qt.PenStyle(QtCore.Qt.DotLine))
                    self.runo.setToGeometry(QgsGeometry.fromPolyline(points),
                                            None)

                #if abs(float((self.fixedHeightspinBox.value()/ 3.2808399)) - (feetEle/ 3.2808399)) <= self.EleTolerance:         #ele tolerance expressed in meters
                if abs(self.fixedHeightspinBox.value() -
                       Ele) <= self.EleTolerance:
                    self.positionMarker.setHasPosition(
                        True)  #True or False to change color
                else:
                    self.positionMarker.setHasPosition(False)

                if self.trackCounter == 5:
                    #pass
                    fc = int(self.TrackLayerProvider.featureCount())
                    time = str(GPGGA[1])[0:2] + ':' + str(
                        GPGGA[1])[2:4] + ':' + str(
                            GPGGA[1])[4:6]  # timestamp for GPX layer

                    feature = QgsFeature()
                    feature.setGeometry(QgsGeometry.fromPoint(Point))
                    feature.setAttributes([fc, time, Ele])
                    self.TrackLayer.startEditing()
                    self.TrackLayer.addFeature(feature, True)
                    self.TrackLayer.commitChanges()
                    self.TrackLayer.setCacheImage(None)
                    self.TrackLayer.triggerRepaint()
                    self.trackCounter = 0

                return
Example #6
0
class GatherPlugin(QObject):
	"""
	Main Gahterer plugin class - handles interaction with QGis and 
	organizes all the recording stuff.
	"""

	def __init__(self, iface):
		QObject.__init__(self)
		self.iface = iface
		
	
	def initGui(self):
		""" Initialize plugin's UI """

		self.initLogging()
		self.recording=False
		self.loadPlugins()
		self.loadConfiguration()
		self.rubberBand=None
		self.lastPosition=None
		self.timer=None
		self.previousPaths=[] #previews of previously recorded paths
		
		self.gpsDaemon=GpsDaemon(self, self)
		self.canvas=self.iface.mapCanvas()
		
		self.gatherer=None
		self.dockWidget=None
		self.dockWidget_simple=None
    
		self.dockWidget=DockWidget(self)
		self.dockWidget_simple=DockWidget_simple(self)
		
		self.actionDockWidget=QAction("Show Gatherer dock widget",self.iface.mainWindow())
		self.actionDockWidget.setCheckable(True)
		QObject.connect(self.actionDockWidget, SIGNAL("triggered()"), self.showHideDockWidget)
		self.iface.addPluginToMenu("Qgis-&mapper", self.actionDockWidget)
		QObject.connect(self.dockWidget, SIGNAL("visibilityChanged(bool)"), lambda : self.__dockwidgetVisibilityChanged(0))
		QObject.connect(self.dockWidget_simple, SIGNAL("visibilityChanged(bool)"), lambda : self.__dockwidgetVisibilityChanged(1))
		
		SourcePlugins.initializeUI(self.dockWidget.dataInputPlugins_tabWidget)
		
		self.curDockWidget=None
		self.showInterface(self.interface_simple)
		
		self.canvas=self.iface.mapCanvas()
		self.positionMarker=PositionMarker(self.canvas)
		self.connect(self.gpsDaemon, SIGNAL("newTrackPoint(PyQt_PyObject)"), self.gotNewTrackPoint)

	def unload(self):
		""" Cleanup and unload the plugin """

		self.canvas.scene().removeItem(self.positionMarker)
		self.positionMarker=None
		
		if self.recording:
			self.recordingStop()
		
		self.saveConfiguration()
		SourcePlugins.unloadPlugins()

		self.gpsDaemon.terminate()
		
		self.dockWidget.unload()
		self.showInterface(None)
		
		del self.dockWidget
		del self.dockWidget_simple
		
		self.iface.removePluginMenu("Qgis-&mapper",self.actionDockWidget)
		del self.actionDockWidget
		
		logging.debug("Plugin terminated.")

	def initLogging(self):
		""" set up rotating log file handler with custom formatting """
		handler = logging.handlers.RotatingFileHandler(logFilePath, maxBytes=1024*1024*10, backupCount=5)
		formatter = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s")
		handler.setFormatter(formatter)
		logger = logging.getLogger() # root logger
		logger.setLevel(logging.DEBUG)
		logger.addHandler(handler)
		logging.debug("Plugin started.")

	def loadPlugins(self):
		"""Load all existing plugins"""
		SourcePlugins.loadPlugins(self)
	
	def loadConfiguration(self):
		""" Load configuration from settings """

		self.last_preview_scale=25

		settings = QSettings()
		settings.beginGroup("/plugins/GatherPlugin")

		# GUI
		self.interface_simple = settings.value("interface/simple", QVariant(False)).toBool()
		# output directory must be a python string
		self.output_directory = str( settings.value("output/directory", QVariant(os.path.expanduser("~/qgismapper/data/"))).toString() )
		self.output_append = settings.value("output/append", QVariant(0)).toInt()[0]
		self.preview_followPosition = settings.value("preview/followPosition", QVariant(True)).toBool()
		self.preview_scale = settings.value("preview/scale", QVariant(25)).toInt()[0]
		self.preview_keepPaths = settings.value("preview/keepPaths", QVariant(True)).toBool()

		# gps
		self.gps_source = settings.value("gps/source", QVariant("serial")).toString()
		self.gps_reconnectInterval = settings.value("gps/reconnectInterval", QVariant(2)).toInt()[0]
		self.gps_attemptsDuringRecording = settings.value("gps/attemptsDuringRecording", QVariant(3)).toInt()[0]
		self.gps_initFile = settings.value("gps/initFile", QVariant()).toString()
		self.gps_serial = settings.value("gps/serial/device", QVariant("/dev/rfcomm0")).toString()
		self.gps_serialBauds = settings.value("gps/serial/bauds", QVariant(38400)).toInt()[0]
		self.gps_file = settings.value("gps/file/path", QVariant(os.path.expanduser("~/nmea_log"))).toString()
		self.gps_fileCharsPerSecond = settings.value("gps/file/charsPerSecond", QVariant(300)).toInt()[0]
		self.gps_gpsdHost = settings.value("gps/gpsd/host", QVariant("localhost")).toString()
		self.gps_gpsdPort = settings.value("gps/gpsd/port", QVariant(2947)).toInt()[0]

		# compass
		self.compass_use = settings.value("compass/use", QVariant(False)).toBool()
		self.compass_device = settings.value("compass/device", QVariant("/dev/ttyUSB0")).toString()
		self.compass_bauds = settings.value("compass/bauds", QVariant(19200)).toInt()[0]
			
	def saveConfiguration(self):
		""" Save configuration to settings """

		settings = QSettings()
		settings.beginGroup("/plugins/GatherPlugin")

		# GUI
		settings.setValue("interface/simple", QVariant(self.interface_simple))
		settings.setValue("output/directory", QVariant(self.output_directory))
		settings.setValue("output/append", QVariant(self.output_append))
		settings.setValue("preview/followPosition", QVariant(self.preview_followPosition))
		settings.setValue("preview/scale", QVariant(self.preview_scale))
		settings.setValue("preview/keepPaths", QVariant(self.preview_keepPaths))

		# gps
		settings.setValue("gps/source", QVariant(self.gps_source))
		settings.setValue("gps/reconnectInterval", QVariant(self.gps_reconnectInterval))
		settings.setValue("gps/attemptsDuringRecording", QVariant(self.gps_attemptsDuringRecording))
		settings.setValue("gps/initFile", QVariant(self.gps_initFile))
		settings.setValue("gps/serial/device", QVariant(self.gps_serial))
		settings.setValue("gps/serial/bauds", QVariant(self.gps_serialBauds))
		settings.setValue("gps/file/path", QVariant(self.gps_file))
		settings.setValue("gps/file/charsPerSecond", QVariant(self.gps_fileCharsPerSecond))
		settings.setValue("gps/gpsd/host", QVariant(self.gps_gpsdHost))
		settings.setValue("gps/gpsd/port", QVariant(self.gps_gpsdPort))

		# compass
		settings.setValue("compass/use", QVariant(self.compass_use))
		settings.setValue("compass/device", QVariant(self.compass_device))
		settings.setValue("compass/bauds", QVariant(self.compass_bauds))

		
	def recordingStart(self):
		""" Start new recording (only call if there isn't any). """

		# check that we have gps input
		if not self.isGpsConnected():
			QMessageBox.warning(self.dockWidget, self.tr("Warning"), self.tr("GPS device isn't connected!\n\nPlease configure GPS input."))
			self.dockWidget.recording = False
			return
		# check we have position
		if self.getNmeaParser().fix == "none":
			if QMessageBox.warning(self.dockWidget, self.tr("Warning"),
					    self.tr("GPS doesn't have a valid position.\n\nDo you really want to start recording?"),
					    QMessageBox.Yes|QMessageBox.No) != QMessageBox.Yes:
				self.dockWidget.recording = False
				return

		self.recordingStartPathPreview()
		if not self.recordingStartGatherer():
			self.recordingStop()
			QMessageBox.information(self.dockWidget, self.tr("Warning"), self.tr("Recording was cancelled during initialization..."), self.tr("Ok"))
			return
		
		self.dockWidget.recording=True
		self.dockWidget_simple.recording=True
		
		#start a timer to keep the thread running...
		self.timer = QTimer()
		QObject.connect(self.timer, SIGNAL("timeout()"), self.runStatusTicker)
		self.timer.start(10)
		
		self.recording=True
		
	def recordingStop(self):
		""" Stop ongoing recording (only call if there is some). """
		self.recordingStopGatherer()
		if self.timer!=None:
			self.timer.stop()
			self.timer=None
			
		#we need to correctly terminate recording by processing events,
		#this leads to processGathererEvent_recordingTerminated()
		QCoreApplication.processEvents()
		
		self.recordingStopPathPreview()
		self.dockWidget.recording=False
		self.dockWidget_simple.recording=False
		self.recording=False
	
	def recordingStartGatherer(self):
		"""Start data gatherer thread"""
		self.gatherer=Gatherer.Gatherer(self)
		
		if not self.gatherer.alive:
			self.gatherer=None #don't try to stop the thread, as it's not running/alive
			return False
		
		QObject.connect(self.gatherer, SIGNAL("gathererEvent(PyQt_PyObject)"), self.processGathererEvent)
		
		self.gatherer.start()
		return True
		
	def recordingStopGatherer(self):
		"""Terminate data gatherer thread"""
		if self.gatherer!=None:
			self.gatherer.stop()
		
		#QObject.disconnect(gathererEvent) is done automatically...
			
	def recordingStartPathPreview(self):
		"""Initialize previewing recorded path"""
		self.rubberBand=QgsRubberBand(self.canvas)
		self.rubberBand.setColor(Qt.red)
		self.rubberBand.setWidth(3)
		self.rubberBand.reset(False)
	
	def recordingStopPathPreview(self):
		"""Terminate previewing recorded path"""
		self.rubberBand.setColor(Qt.green)
		self.previousPaths.append(self.rubberBand)
		self.rubberBand=None
		
		if not self.preview_keepPaths:
			self.removePathPreviews()
		else:
			self.canvas.refresh()
		
	def removePathPreviews(self):
		"""Remove recorded path previews from the map canvas"""
		for rb in self.previousPaths:
			self.canvas.scene().removeItem(rb)
		SourcePlugins.callMethodOnEach("clearMapCanvasItems", ())
		self.previousPaths=[]
		self.canvas.refresh()
	
	def recordingSwitch(self):
		""" If recording is on, turn it of - and the opposite :-) """
		if self.recording==False:
			self.recordingStart()
		else:
			self.recordingStop()
	
	def runStatusTicker(self):
		"""
		Make it possible for python to switch threads and
		if the gathering thread is not alive anymore, let
		the user know.
		"""
		if self.gatherer!=None:
			self.gatherer.msleep(1)

	def getLastDataSubdirectory(root):
		"""
			Returns last used data directory (including the time postfix). If no
			directory can be found, it returns empty string. The root parameter
			is data directory (specified by user), where the recordings are stored.
		"""
		dirs=[f for f in sorted(os.listdir(root))
			if os.path.isdir(os.path.join(root, f))]
			
		r=re.compile("[0-9]*-[0-9]*-[0-9]*_[0-9]*-[0-9]*-[0-9]*")
		dirs=[f for f in dirs if r.match(f)!=None]
		if len(dirs)!=0:
			return root+dirs[-1]+"/"
		else:
			return ""
	getLastDataSubdirectory=staticmethod(getLastDataSubdirectory)

	def processGathererEvent(self, data):
		try:
			apply(getattr(self, "processGathererEvent_"+data[0]), data[1:])
		except:
			traceback.print_exc(file=sys.stdout)
	
	def processGathererEvent_newTrackPoint(self, lat, lon, angle):
		"""Process 'new track point' event from gatherer."""
		try:
			if self.rubberBand and (lat!=0 or lon!=0):
				self.rubberBand.addPoint(QgsPoint(lon, lat))
		except:
			traceback.print_exc(file=sys.stdout)
	
	def gotNewTrackPoint(self, pt):
		""" update position marker """
		(lat, lon, angle, fix)=pt
		if lat!=0 or lon!=0:
			self.lastPosition=QgsPoint(lon, lat)
			self.lastAngle=angle
			self.lastFix=fix
			self.updatePositionMarker()
			self.updateExtent()
		
	
	def processGathererEvent_recordingTerminated(self, onUserRequest):
		"""Process 'recording terminated' event from gatherer."""
		self.gatherer.terminateAndCleanup()
		self.gatherer=None
		if not onUserRequest:
			self.recordingStop()
			QMessageBox.information(self.dockWidget,
				self.tr("Warning"),
				self.tr("Recording was cancelled by the gatherer thread (probably because of some communication error)..."),
				self.tr("Ok")
			)
			
	def updateExtent(self):
		"""Set correct map canvas extent for the current position and redraw."""
		extent=self.canvas.extent()
		if not self.preview_followPosition or self.lastPosition==None:
			pos=extent.center()
		else:
			boundaryExtent=QgsRectangle(extent)
			boundaryExtent.scale(0.5)
			if not boundaryExtent.contains(QgsRectangle(self.lastPosition, self.lastPosition)):
				pos=self.lastPosition
			else:
				pos=extent.center()
		
		if self.preview_scale!=self.last_preview_scale or pos!=extent.center():
			scale=pow(float(self.preview_scale)/99, 2)*0.4+0.0001
			newExtent=QgsRectangle(pos.x()-scale/2, pos.y()-scale/2, pos.x()+scale/2, pos.y()+scale/2)
			
			self.last_preview_scale=self.preview_scale
			
			self.canvas.setExtent(newExtent)
			self.canvas.refresh()

	def updatePositionMarker(self):
		"""Update position marker for the current position/orientation"""
		if self.positionMarker is None:
			return
		self.positionMarker.setHasPosition(self.lastFix)
		self.positionMarker.newCoords(self.lastPosition)
		self.positionMarker.angle=self.lastAngle
	
	def getNmeaParser(self):
		"""Returns the NMEA gps data parser object (useful to gather current pos. info)"""
		return self.gpsDaemon.nmeaParser
	
	def isGpsConnected(self):
		"""Returns, whether the gatherer is connected to gps device"""
		return self.gpsDaemon.isGpsConnected()

	def showInterface(self, simple):
		"""Show the specified version (simple or full) of user interface"""
		self.interface_simple=simple
		if self.curDockWidget!=None:
			self.iface.removeDockWidget(self.curDockWidget)
		
		if simple:
			self.curDockWidget=self.dockWidget_simple
		else:
			self.curDockWidget=self.dockWidget
		
		if simple!=None:
			self.iface.addDockWidget(Qt.RightDockWidgetArea, self.curDockWidget)
	
	def getRecordingEnabledAuxCheckbox(self, source):
		"""
		Returns checkbox widget for the specified source (string, e.g. 'Audio'),
		that informs user about recording status in the simple version of interface.
		Returns None, if specified source's checkbox isn't available.
		"""
		return self.dockWidget_simple.getRecordingEnabledCheckbox(source)
	
	def showHideDockWidget(self):
		if self.curDockWidget.isVisible():
			self.curDockWidget.hide()
		else:
			self.curDockWidget.show()

	def __dockwidgetVisibilityChanged(self, which):
		if self.curDockWidget.isVisible():
			self.actionDockWidget.setChecked(True)
		else:
			self.actionDockWidget.setChecked(False)
class Cu_Video_TrackerDialog(QtGui.QDialog):
    def __init__(self, iface):
        QtGui.QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.iface = iface
        self.ui.sourceLoad_pushButton.clicked.connect(self.OpenButton)
        self.ui.replayPlay_pushButton.clicked.connect(self.PlayPauseButton)
        QObject.connect(self.ui.replay_mapTool_pushButton, SIGNAL("toggled(bool)"), self.replayMapTool_toggled)
        self.positionMarker=None
        settings = QSettings()
        settings.beginGroup("/plugins/PlayerPlugin")
        self.replay_followPosition = settings.value("followPosition", True, type=bool)
        settings.setValue("followPosition", self.replay_followPosition)

        QObject.connect(self.iface.mapCanvas(), SIGNAL("mapToolSet(QgsMapTool*)"), self.mapToolChanged)
        self.mapTool=ReplayMapTool(self.iface.mapCanvas(), self)
        self.mapTool_previous=None
        self.mapToolChecked = property(self.__getMapToolChecked, self.__setMapToolChecked)

        QObject.connect(self.ui.replayPosition_horizontalSlider, SIGNAL( 'sliderMoved(int)'), self.replayPosition_sliderMoved)
        QObject.connect(self.ui.addpoint_button, SIGNAL('clicked()'),self.snapshot)
        QObject.connect(self.ui.ExporText_button, SIGNAL('clicked()'),self.exportText)
        QObject.connect(self.ui.ExporShp_button, SIGNAL('clicked()'),self.exportShp)
        QObject.connect(self.ui.ExporSqlite_button, SIGNAL('clicked()'),self.exportSqlite)
        QObject.connect(self.ui.ExporKML_button, SIGNAL('clicked()'),self.exportKML)
        QObject.connect(self.ui.Help, SIGNAL('clicked()'),self.Help)

        self.PlayPuase = 0 # Puase=0,Play=1
        self.Close = 0 # select video=1 , Close=0
        self.adactProjection = False
        self.createLayer = 0 # Default layer=1,create by user=2,load existent=else
        self.videoWidget = Phonon.VideoWidget(self.ui.video_widget)

    def OpenButton(self):
        if self.Close == 1:
            if self.positionMarker != None:
                self.iface.mapCanvas().scene().removeItem(self.positionMarker)
                self.positionMarker = None
            self.Close = 0
            self.ui.replay_mapTool_pushButton.setChecked(False)
            self.ui.sourceLoad_pushButton.setText('Open...')
            self.createLayer = 0
            self.timer.stop()
            ##self.timer2.stop()
            self.media_obj.stop()
            self.iface.mapCanvas().unsetMapTool(self.mapTool)
            self.close()

        else:

            self.path = QtGui.QFileDialog.getOpenFileName(self,self.tr("Select Video files"))
            self.csvFile = open(self.path + '.csv',"rb")
            Filereader = csv.DictReader(self.csvFile)
            self.CSVLayer = QgsVectorLayer("LineString","GPS Tracking","memory")

            self.latt = []
            self.lonn = []
            self.timeh = []
            self.timem = []
            self.times = []
            i=0
            for row in Filereader:
                self.latt.append(float(row['lon']))
                self.lonn.append(float(row['lat']))
                if row['time_h'] != '':
                    self.timeh.append(int(row['time_h']))
                    self.timem.append(int(row['time_m']))
                    self.times.append(int(row['time_s']))

            #create tracker layer (line layer)
            for i in xrange(0,len(self.latt)-1,1):
                point_start = QgsPoint(self.latt[i],self.lonn[i])
                point_end = QgsPoint(self.latt[i+1],self.lonn[i+1])
                line = QgsGeometry.fromPolyline([point_start,point_end])
                self.pr = self.CSVLayer.dataProvider()
                afeature = QgsFeature()
                afeature.setGeometry(QgsGeometry.fromPolyline([point_start,point_end]))
                self.pr.addFeatures( [ afeature ] )
                self.CSVLayer.updateExtents()
            QgsMapLayerRegistry.instance().addMapLayers([self.CSVLayer])

            SelectLayer,ok = QInputDialog.getItem(self.iface.mainWindow(),"Layer chooser","Choose point layer",('Default point layer','Creat new point layer','Load existent point layer'))
            if SelectLayer == 'Load existent point layer':
                self.newLayerPath = QtGui.QFileDialog.getOpenFileName()
                if not self.newLayerPath is None:
                    name = self.newLayerPath.split("/")[-1][0:-4]
                    self.vl = QgsVectorLayer(self.newLayerPath, name, "ogr")
                    self.pr = self.vl.dataProvider()
                    fields = self.pr.fields()
                    field_names = [field.name() for field in fields]
                    f = "Image link"
                    fnd = self.vl.fieldNameIndex(f)
                    fn = field_names[fnd]
                    if not fn == f:
                        self.pr.addAttributes([QgsField("Image link", QVariant.String)])

                    QgsMapLayerRegistry.instance().addMapLayer(self.CSVLayer)
                    QgsMapLayerRegistry.instance().addMapLayer(self.vl)

            elif SelectLayer == 'Default point layer':
                self.vl = QgsVectorLayer("Point?crs=epsg:4326&index=yes","point", "memory")
                self.pr = self.vl.dataProvider()
                self.pr.addAttributes( [ QgsField('id', QVariant.Int),
                                         QgsField('Name', QVariant.String),
                                         QgsField('Description', QVariant.String),
                                         QgsField('Type', QVariant.String),
                                         QgsField("Lon",  QVariant.String),
                                         QgsField("Lat", QVariant.String),
                                         QgsField('East UTM', QVariant.String),
                                         QgsField('North UTM',QVariant.String),
                                         QgsField('Image link', QVariant.String)] )


                # update layer's extent
                self.vl.updateExtents()
                QgsMapLayerRegistry.instance().addMapLayer( self.CSVLayer )
                QgsMapLayerRegistry.instance().addMapLayers([self.vl])
                self.createLayer = 1

            else:
                # Creat new point layer by user
                self.createLayer = 2
                self.vl = QgsVectorLayer("Point?crs=epsg:4326&index=yes","point", "memory")
                self.pr = self.vl.dataProvider()
                # table manager dialog
                self.dialoga = TableManager(self.iface, self.vl,self.CSVLayer)
                self.dialoga.exec_()



            #set point label
            palyr = QgsPalLayerSettings()
            palyr.readFromLayer(self.vl)
            palyr.enabled = True
            palyr.fieldName = 'id'
            palyr.placement= QgsPalLayerSettings.Upright
            palyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'14','')
            palyr.writeToLayer(self.vl)

            if self.positionMarker==None:
                self.positionMarker=PositionMarker(self.iface.mapCanvas())

            self.media_src = Phonon.MediaSource(self.path)
            self.media_obj = Phonon.MediaObject(self)
            self.media_obj.setCurrentSource(self.media_src)
            Phonon.createPath(self.media_obj, self.videoWidget)


            # set audio
##            audio_out = Phonon.AudioOutput(Phonon.VideoCategory, self)
##            Phonon.createPath(self.media_obj, audio_out)

            self.ui.video_widget.resizeEvent = self.Resize()
            self.media_obj.setTickInterval(100)
            self.timer = QtCore.QTimer()
            QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.Timer)

            self.PlayPuase =1
            self.ui.sourceLoad_pushButton.setText('Close')
            self.Close = 1   #load file selector
            self.media_obj.play()  #phonon play
            self.timer.start(1000)

            self.ui.replayPlay_pushButton.setEnabled(True)
            self.ui.addpoint_button.setEnabled(True)

    def Resize(self):
        a = self.ui.video_widget.frameSize()
        b = self.videoWidget.frameSize()
        if a != b:
            self.videoWidget.resize(a)

    def CurrentPos(self):
        end = self.media_obj.totalTime()
        pos = self.media_obj.currentTime()
        if pos == end:
            self.timer.stop()
            self.media_obj.pause()
            if self.PlayPuase == 1:
                self.PlayPuase = 0
        else:
            Pos = pos/1000
            self.ui.replayPosition_label.setText(str(datetime.timedelta(seconds=int(Pos))) + '/' + str(datetime.timedelta(seconds=(int(end/1000)))))
            return int(Pos)

    def Timer(self):
        if self.PlayPuase == 1:
            self.updateReplayPosition()
            self.SetSlide()
        else:
            pass

    def TimeOffset(self):
        self.current_second =[]
        self.time_offset =[]

        if self.timeh != []:
            for i in xrange(0,len(self.timeh),1):
                    h_second = int(self.timeh[i])*60*60
                    m_second = int(self.timem[i])*60
                    s_second = int(self.times[i])
                    c_second = h_second + m_second + s_second
                    self.current_second.append(c_second)
                    t_of = int(int(self.current_second[i]) -int(self.current_second[0]))
                    self.time_offset.append(t_of)
        else:
            #find time offset
            for i in xrange(0,len(self.latt),1):
                # Number of record in csv
                self.NumRec = len(self.latt)
                #create new list start at 0
                self.L_Num = range(len(self.latt))
                #time interval
                self.t_interval = ((self.media_obj.totalTime()/1000)/float(self.NumRec - 1))
                t_of = self.L_Num[i] * self.t_interval
                self.time_offset.append(t_of)
        return self.time_offset

    def updateReplayPosition(self):
        pos = self.CurrentPos()

        # find the nearest timestamp offset of position time in logging data
        TimeOffset = self.TimeOffset()
        i = min(range(len(TimeOffset)),key=lambda x: abs(TimeOffset[x]-((pos))))
        if pos-1 == (self.media_obj.totalTime()/1000-1):
            self.media_obj.stop()
        if pos - TimeOffset[i] == 0:
            self.lat_new = self.latt[i]
            self.lon_new = self.lonn[i]
        else:
            if pos < TimeOffset[i]:
                Dlat = self.latt[i]- self.latt[i-1]
                Dlon = self.lonn[i]- self.lonn[i-1]
                Dtime = TimeOffset[i] - TimeOffset[i-1]
            else:
                Dlat = self.latt[i+1]- self.latt[i]
                Dlon = self.lonn[i+1]- self.lonn[i]
                Dtime = TimeOffset[i+1] - TimeOffset[i]

            Dti = float(pos -TimeOffset[i])
            Dlat_i = Dlat*(Dti/Dtime)
            Dlon_i = Dlon*(Dti/Dtime)
            self.lat_new = self.latt[i]+ Dlat_i
            self.lon_new = self.lonn[i] + Dlon_i

        self.lat,self.lon = self.lat_new,self.lon_new
        self.Point = QgsPoint()
        self.Point.set(self.lat,self.lon)

        canvas = self.iface.mapCanvas()
        mapRenderer = canvas.mapRenderer()
        crsSrc = QgsCoordinateReferenceSystem(4326)    # WGS 84
        crsDest = mapRenderer.destinationCrs()

        xform = QgsCoordinateTransform(crsSrc, crsDest) #usage: xform.transform(QgsPoint)

        self.positionMarker.setHasPosition(True)
        self.Point = xform.transform(self.Point)
        self.positionMarker.newCoords(self.Point)

        if self.replay_followPosition:
            extent=self.iface.mapCanvas().extent()

        boundaryExtent=QgsRectangle(extent)
        boundaryExtent.scale(1.0)
        if not boundaryExtent.contains(QgsRectangle(self.Point, self.Point)):
            extentCenter= self.Point
            newExtent=QgsRectangle(extentCenter.x()-extent.width()/1.7,extentCenter.y()-extent.height()/1.7,extentCenter.x()+extent.width()/17,extentCenter.y()+extent.height()/1.7)
            self.iface.mapCanvas().setExtent(newExtent)
            self.iface.mapCanvas().refresh()

        East,North,alt = self.transform_wgs84_to_utm(self.lat_new,self.lon_new)
        self.ui.E.setText ('Easting : ' + str(East))
        self.ui.N.setText ('Northing : ' + str(North))
        self.ui.lat.setText ('Latitude : ' + str(self.lon_new))
        self.ui.lon.setText('Longitude : ' + str(self.lat_new))

    def PlayPauseButton(self):
        if self.PlayPuase == 1:
            self.media_obj.pause()
            self.timer.stop()
            self.PlayPuase = 0
        else:
            self.media_obj.play()
            self.timer.start(0)
            self.PlayPuase = 1

    def replayMapTool_toggled(self, checked):
        """Enable/disable replay map tool"""
        self.useMapTool(checked)

    def useMapTool(self, use):
        """ afer you click on it, you can seek the video just clicking on the gps track """

        if use:
            if self.iface.mapCanvas().mapTool()!=self.mapTool:
                self.mapTool_previous=self.iface.mapCanvas().mapTool()
                self.iface.mapCanvas().setMapTool(self.mapTool)
        else:
            if self.mapTool_previous!=None:
                self.iface.mapCanvas().setMapTool(self.mapTool_previous)
            else:
                self.iface.mapCanvas().unsetMapTool(self.mapTool)

    def mapToolChanged(self, tool):
        """Handle map tool changes outside  plugin"""
        if (tool!=self.mapTool) and self.mapToolChecked:
            self.mapTool_previous=None
            self.mapToolChecked=False

    def __getMapToolChecked(self):
        return self.replay_mapTool_pushButton.isChecked()

    def __setMapToolChecked(self, val):
        self.replay_mapTool_pushButton.setChecked(val)

    def findNearestPointInRecording(self, toPoint):
        """ Find the point nearest to the specified point (in map coordinates) """
        for i in xrange(0,len(self.latt),1):
            if(str(self.latt[i]))[0:7] == str(toPoint.x())[0:7]and (str(self.lonn[i]))[0:7]==(str(toPoint.y()))[0:7]:
                adj = (self.time_offset[i]) - (self.time_offset[0])
                lat,lon =(self.latt[i]) , (self.lonn[i])
                Point = QgsPoint()
                Point.set(lat,lon)
                self.positionMarker.newCoords(Point)
                self.Seek(adj)
                break

    def Seek (self, pos):
        if self.PlayPuase == 0:
            self.timer.stop()
            self.media_obj.seek(pos*1000)
            self.media_obj.play()
            self.timer.start(0)
            self.PlayPuase =1
        else:
            self.media_obj.seek(pos*1000)
            self.timer.start(1000)

    def replayPosition_sliderMoved(self,pos):
        """Handle moving of replay position slider by user"""
        self.Seek(pos)

    def SetSlide(self):
        end = self.media_obj.totalTime()
        pos = self.media_obj.currentTime()
        self.endtime = (self.media_obj.totalTime()/1000)
        self.ui.replayPosition_horizontalSlider.setMinimum(0)
        self.ui.replayPosition_horizontalSlider.setMaximum((self.endtime))
        if not pos == end:
            pos = float(self.CurrentPos())
            self.ui.replayPosition_horizontalSlider.setValue(pos)

    def AddPoint (self,toPoint):
        if self.PlayPuase == 1:
            self.media_obj.pause()
            self.timer.stop()
            self.PlayPuase = 0
        else:
            pass

        last_desc = '///'
        fc = int(self.pr.featureCount()+1)
        if self.createLayer == 1:
            self.vl.dataProvider()
            filename = self.path + '__'+ str(self.getImageFileName()) + '.jpg'
            p= QPixmap.grabWidget(self.videoWidget)
            p.save(filename)

            (Name,ok) = QInputDialog.getText(
                        self.iface.mainWindow(),
                        "Attributes",
                        "Name",
                        QLineEdit.Normal,
                        last_desc)

            (Description,ok) = QInputDialog.getText(
                         self.iface.mainWindow(),
                         "Attributes",
                         "Description",
                         QLineEdit.Normal,
                         last_desc)

            (Type,ok) = QInputDialog.getText(
                         self.iface.mainWindow(),
                         "Attributes",
                         "Type",
                         QLineEdit.Normal,
                         last_desc)

            # create the feature
            feature = QgsFeature()
            lat,lon = toPoint.x(), toPoint.y()
            Point = QgsPoint()
            Point.set(lat,lon)
            EastUTM,NorthUTM,alt= self.transform_wgs84_to_utm(lat, lon)
            feature.setGeometry(QgsGeometry.fromPoint(Point))

            feature.setAttributes([fc,Name,Description,Type,lat,lon,EastUTM,NorthUTM,self.path + '__'+ str(self.getImageFileName()) + '.jpg'])
            self.vl.startEditing()
            self.vl.addFeature(feature, True)
            self.vl.commitChanges()
            self.vl.setCacheImage(None)
            self.vl.triggerRepaint()
            os.rename(filename,self.path + '__'+ str(self.getImageFileName()) + '.jpg')

        elif self.createLayer == 2:
            p= QPixmap.grabWidget(self.videoWidget)
            fields = self.pr.fields()
            attributes = []
            lat,lon = toPoint.x(), toPoint.y()
            for field in fields:
                    a = str(field.name())
                    b = str(field.typeName())
                    if a == 'id':
                        fcnr = fc
                        attributes.append(fcnr)
                    elif a == 'Lon':
                        attributes.append(lat)

                    elif a == 'Lat':
                        attributes.append(lon)

                    else:

                        if b == 'String':
                            (a,ok) = QInputDialog.getText(
                                                          self.iface.mainWindow(),
                                                          "Attributes",
                                                          a + ' = ' + b,
                                                          QLineEdit.Normal)
                            attributes.append(a)


                        elif b == 'Real':
                            (a,ok) = QInputDialog.getDouble(
                                                            self.iface.mainWindow(),
                                                            "Attributes",
                                                            a + ' = ' + b, decimals = 10)
                            attributes.append(a)

                        elif b == 'Integer':
                            (a,ok) = QInputDialog.getInt(
                                                         self.iface.mainWindow(),
                                                         "Attributes",
                                                         a + ' = ' + b)
                            attributes.append(a)

            feature = QgsFeature()
            Point = QgsPoint()
            Point.set(lat,lon)

            #use in new table
            filename = self.path + '__'+ str(self.getImageFileName()) + '.jpg'
            p.save(filename)
            attributes.append(filename)
            feature.setGeometry(QgsGeometry.fromPoint(Point))
            feature.setAttributes(attributes)
            self.vl.startEditing()
            self.vl.addFeature(feature, True)
            self.vl.commitChanges()
            self.vl.setCacheImage(None)
            self.vl.triggerRepaint()
            os.rename(filename,self.path + '__'+ str(self.getImageFileName()) + '.jpg')

        else:

            p= QPixmap.grabWidget(self.videoWidget)

            fields = self.pr.fields()
            attributes = []
            lat,lon = toPoint.x(), toPoint.y()
            for field in fields:
                    a = str(field.name())
                    b = str(field.typeName())
                    if a == 'id':
                        fcnr = fc
                        attributes.append(fcnr)
                    elif a == 'Lon':
                        attributes.append(lat)

                    elif a == 'Lat':
                        attributes.append(lon)

                    else:

                        if b == 'String':
                            (a,ok) = QInputDialog.getText(
                                                          self.iface.mainWindow(),
                                                          "Attributes",
                                                          a + ' = ' + b,
                                                          QLineEdit.Normal)
                            attributes.append(a)


                        elif b == 'Real':
                            (a,ok) = QInputDialog.getDouble(
                                                            self.iface.mainWindow(),
                                                            "Attributes",
                                                            a + ' = ' + b, decimals = 10)
                            attributes.append(a)

                        elif b == 'Integer':
                            (a,ok) = QInputDialog.getInt(
                                                         self.iface.mainWindow(),
                                                         "Attributes",
                                                         a + ' = ' + b)
                            attributes.append(a)

            feature = QgsFeature()
            Point = QgsPoint()
            Point.set(lat,lon)
            #use in existent table
            feature.setGeometry(QgsGeometry.fromPoint(Point))
            feature.setAttributes(attributes)
            filename = self.path + '__'+ str(self.getImageFileName()) + '.jpg'
            p.save(filename)
            field_index = self.pr.fieldNameIndex('Image link')
            feature.setAttribute(field_index, filename)
            self.vl.startEditing()
            self.vl.addFeature(feature, True)
            self.vl.commitChanges()
            self.vl.setCacheImage(None)
            self.vl.triggerRepaint()
            os.rename(filename,self.path + '__'+ str(self.getImageFileName()) + '.jpg')

        self.ui.ExporText_button.setEnabled(True)
        self.ui.ExporShp_button.setEnabled(True)
        self.ui.ExporSqlite_button.setEnabled(True)
        self.ui.ExporKML_button.setEnabled(True)


    def getImageFileName(self):

        current_time_now = time.time()
        ctn_int = int(current_time_now)
        return ctn_int


    def transform_wgs84_to_utm(self, lon, lat):
        def get_utm_zone(longitude):
            return (int(1+(longitude+180.0)/6.0))

        def is_northern(latitude):
            """
            Determines if given latitude is a northern for UTM
            """

            if (latitude < 0.0):
                return 0
            else:
                return 1

        utm_coordinate_system = osr.SpatialReference()
        utm_coordinate_system.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon
        utm_coordinate_system.SetUTM(get_utm_zone(lon), is_northern(lat))

        wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS() # Clone ONLY the geographic coordinate system

        # create transform component
        wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, utm_coordinate_system) # (<from>, <to>)
        return wgs84_to_utm_transform.TransformPoint(lon, lat, 0) # returns easting, northing, altitude

    def snapshot(self):
        Point = QgsPoint(self.Point)
        Point.set(self.lat,self.lon)
        self.positionMarker.newCoords(Point)
        self.AddPoint(Point)

    def Help(self):
        path_help = 'C:/Users/Administrator/.qgis2'
        os.startfile(path_help + '/python/plugins/Cu_Video_Tracker/How to.pdf')

    def exportText(self):
        toCSV = QgsVectorFileWriter.writeAsVectorFormat(self.vl, self.path + '_''point'+'.csv', "TIS-620", None, "CSV")
        debug = self.path + '_''point'+'.csv'
        QtGui.QMessageBox.information(self, 'Export to', debug )

    def exportShp(self):
        toShp = QgsVectorFileWriter.writeAsVectorFormat(self.vl, self.path + '_''point'+'.shp',"utf-8",None,"ESRI Shapefile")
        debug = self.path + '_''point'+'.shp'
        QtGui.QMessageBox.information(self, 'Export to', debug )

    def exportSqlite(self):
        toSql = QgsVectorFileWriter.writeAsVectorFormat(self.vl, self.path + '_''point'+'.sqlite',"utf-8",None,"SQLite")
        debug = self.path + '_''point'+'.sqlite'
        QtGui.QMessageBox.information(self, 'Export to', debug )

    def exportKML(self):
        toSql = QgsVectorFileWriter.writeAsVectorFormat(self.vl, self.path + '_''point'+'.kml',"utf-8",None,"KML")
        debug = self.path + '_''point'+'.kml'
        QtGui.QMessageBox.information(self, 'Export to', debug )