Exemple #1
0
def generateObsAtPixel(dem, sensor, col, lin):
    """
       Generates an observations at a given column / line of a raster.
       :param col: (int) shooter's column.
       :param lin: (int) shooter's line.
       :return: (Observation) observation at col, pix.
       """
    # handle outside points - put them back to the borders
    if col > dem.width():
        col = dem.width() - 1
    elif col < 0:
        col = 0
    if lin > dem.height():
        lin = dem.height() - 1
    elif lin < 0:
        lin = 0
    y, x = dem.pixelToCoordinates(col, lin)
    z = dem.bands()[col][lin]
    sensorY, sensorX, sensorZ = sensor['coordinates']
    dx, dy, dz = x - sensorX, y - sensorY, z - sensorZ
    if dem.isGeographic():
        # the more appropriate conversion would be a geodesic line - curve geometry
        dx = np.deg2rad(dx) * Enums.EARTH_RADIUS
        dy = np.deg2rad(dy) * np.pi * Enums.EARTH_RADIUS / 180
    azimuth = np.rad2deg(np.arctan2(np.sqrt(dy**2 + dz**2), dx))
    zenith = np.rad2deg(np.arctan2(dx, dz))
    om = ObservationsManager()
    om.addObservation(azimuth, zenith, sensor['id'])
    return zenith, azimuth
Exemple #2
0
 def __init__(self, parent=None, settings=None):
     """
     Class constructor.
     :param parent: (QWidget) any widget from Qt5 parent to this dialog.
     :param settings: (Settings) MOPA's settings database manager.
     """
     super(ObservationWidget, self).__init__(parent)
     self.setupUi(self)
     self.parent = parent
     self.settings = settings if settings is not None else Settings()
     self._obsManager = ObservationsManager(self.settings)
     self.refresh(obsList=[])
Exemple #3
0
 def getAllObsFromSensor(self, sensor=None):
     """
     Retrieves all observations made from a sensor.
     :param dem: (RasterLayer) DEM to be checked for sensors.
     :return: (list-of-Sensor)
     """
     sensor = sensor or (self.currentSensor() or \
              SensorsManager().newSensor())
     if sensor.isValid():
         return ObservationsManager().getObservationsFromSensor(
             sensor['id'])
     else:
         return ObservationsManager().allObservations()
Exemple #4
0
 def getObservationsFromSensor(self, sensorId):
     """
     Gets all observations from a given sensor.
     :param sensorId: (int) sensor ID.
     :return: (list-of-Observation) observations made from a given sensor.
     """
     return ObservationsManager().getObservationsFromSensor(sensorId)
Exemple #5
0
 def setupObservations(self):
     """
     Sets observations to GUI.
     """
     s = self.currentSensor()
     obsList = self.getAllObsFromSensor().values() if s is not None and s.isValid() \
                 else ObservationsManager().allObservations().values()
     obs = self.obsWidget.currentText()
     self.obsWidget.refresh(obsList)
     # try to keep the same selection
     self.obsWidget.setCurrentObservation(obs)
Exemple #6
0
class ObservationWidget(QWidget, FORM_CLASS):
    observationAdded, observationEdited = pyqtSignal(Observation), pyqtSignal(
        Observation)
    selectionChanged = pyqtSignal(int)

    def __init__(self, parent=None, settings=None):
        """
        Class constructor.
        :param parent: (QWidget) any widget from Qt5 parent to this dialog.
        :param settings: (Settings) MOPA's settings database manager.
        """
        super(ObservationWidget, self).__init__(parent)
        self.setupUi(self)
        self.parent = parent
        self.settings = settings if settings is not None else Settings()
        self._obsManager = ObservationsManager(self.settings)
        self.refresh(obsList=[])

    def clear(self):
        """
        Clears observation combo box and GUI information, if any.
        """
        self.obsComboBox.clear()

    def fillObsComboBox(self, obsList):
        """
        Fills all given observations to the selection combo box.
        :param obsList: (list-of-Observation) observations to be listed on widget.
        """
        self.clear()
        self.obsComboBox.addItem(self.tr("Select an observation..."))
        self.obsComboBox.addItems(
            ["Observation {0}".format(o['id']) for o in obsList])

    def setCurrentObservation(self, obs):
        """
        Sets current observation from its text as current selection on combo box.
        :param obs: (str) observation exhibition text.
        :return: (bool) whether selection was set.
        """
        self.obsComboBox.setCurrentText(obs)
        return self.obsComboBox.currentText() == obs

    def currentText(self):
        """
        Gets current text exhibited on combo box.
        :return: (str) current text.
        """
        return self.obsComboBox.currentText()

    def refresh(self, obsList):
        """
        Resets widget to initial state.
        :param obsList: (list-of-Observation) observations to be listed on widget.
        """
        self.clear()
        self.fillObsComboBox(obsList)
        self.setObsInformation(self.currentObservation())

    def obsIdFromIndex(self, idx):
        """
        Gets the observation ID from item at the given index. If index is invalid None
        is returned.
        :param idx: (int) item index in the observation selection combo box.
        :return: (int) observation ID.
        """
        if idx > 0 and self.obsComboBox.count() > idx:
            return int(self.obsComboBox.itemText(idx).split(" ")[-1])
        return None

    def observationFromIndex(self, idx):
        """
        Gets the observation from the indicated index. If index is invalid None is returned.
        :param idx: (int) item index in the observation selection combo box.
        :return: (Observation) observation instance from the indicated index.
        """
        oid = self.obsIdFromIndex(idx)
        if oid is not None:
            return self._obsManager.observationFromId(oid)
        return None

    def obsId(self):
        """
        Gets current observation's ID. Returns None if no selection was made.
        :return: (int) observation's ID.
        """
        if self.obsComboBox.currentIndex() < 1:
            return None
        return int(self.obsComboBox.currentText().split(" ")[-1])

    def currentObservation(self):
        """
        Gets the observation object for current selection.
        :return: (Observation) an instance of Observation object for current selection.
        """
        if self.obsId() is None:
            return None  # should it be a new instance of observation obj?
        return self._obsManager.observationFromId(self.obsId())

    def setObsInformation(self, obs):
        """
        Sets observation information to widget interface.
        :param obs: (Observation) observation to have its info exposed.
        """
        obs = obs or self._obsManager.newObservation()
        self.azLabel.setText(
            self.tr("Azimuth: {0:.2f}").format(obs['azimuth']))
        self.zenLabel.setText(
            self.tr("Vertical angle: {0:.2f}").format(obs['zenith']))
        self.dateLabel.setText(
            self.tr("Observation date: {0}").format(obs['date']))
        title = self.tr("Event information")
        if obs.isValid():
            title += self.tr(" from station ID = {0}").format(obs['sensorId'])
        self.groupBox.setTitle(title)

    def isEditable(self):
        """
        Verifies whether current selection may be edited.
        :return: (bool) edition status.
        """
        return not self.obsComboBox.currentIndex() < 1

    @pyqtSlot(int, name="on_obsComboBox_currentIndexChanged")
    def checkEditButtonStatus(self, idx):
        """
        Updates the edit push button enable status.
        :param idx: (int) current index.
        """
        self.updateObservationPushButton.setEnabled(self.isEditable())
        self.setObsInformation(self.currentObservation())
        self.selectionChanged.emit(idx)

    def parametersFromForm(self, attributes):
        """
        Sets the correct variable types from form info.
        :param attributes: (dict) form's info.
        :return: (dict) values reasigned to its correct variable type. 
        """
        try:
            attributes['id'] = int(attributes['id'])
        except:
            pass
        try:
            attributes['azimuth'] = float(attributes['azimuth'])
        except:
            pass
        try:
            attributes['zenith'] = float(attributes['zenith'])
        except:
            pass
        try:
            attributes['sensorId'] = int(attributes['sensorId'])
        except:
            pass
        if not isinstance(attributes['date'], str):
            try:
                attributes['date'] = str(attributes['date'])
            except:
                pass
        return attributes

    def checkFormValidity(self, form, checkIfExists=False):
        """
        Checks form validity.
        :param form: (FeatureForm) form to have its contents checked.
        :param checkIfExists: (bool) indicates whether entry existance should be checked.
        :return: (bool) form validity status.
        """
        attr = self.parametersFromForm(form.read())
        ir = self._obsManager.newObservation().invalidationReason(attr)
        if checkIfExists and self._obsManager.idExists(attr['id']):
            ir = self.tr("Observation ID {0} already exists into the database.").\
                format(attr['id'])
        form.setInvalidationMessage(ir)
        return ir == ''

    @pyqtSlot(bool, name='on_updateObservationPushButton_clicked')
    def openEditForm(self):
        """
        Opens feature form for current selection in edition mode.
        """
        form = FeatureForm(self.currentObservation(), True, self.parent)
        form.setWindowTitle(form.tr("Edit observation's attributes"))
        form.fieldReadOnly(
            'id', True)  # since it is an EDITION, id should be kept the same.
        form.okButtonClicked.connect(self.checkFormValidity)
        if form.exec_() == Enums.Finished:
            attr = self.parametersFromForm(form.read())
            obs = self._obsManager.observationFromAttributes(attr)
            if obs.isValid():
                self._obsManager.updateObservation(obs)
                self.obsComboBox.setItemText(
                    self.obsComboBox.currentIndex(),
                    self.tr("Observation {0}").format(obs['id']))
                # and update its attributes to GUI
                self.setObsInformation(obs)
                form.blockSignals(True)
                del form
                self.observationEdited.emit(obs)

    @pyqtSlot(bool, name='on_addObservationPushButton_clicked')
    def openForm(self):
        """
        Opens attribute form to be filled in order to add a new sensor.
        """
        form = FeatureForm(self._obsManager.newObservation(), True,
                           self.parent)
        form.setWindowTitle(self.tr("Add a new observation"))
        form.okButtonClicked.connect(lambda f: self.checkFormValidity(f, True))
        if form.exec_() == Enums.Finished:
            attr = self.parametersFromForm(form.read())
            obs = self._obsManager.observationFromAttributes(attr)
            if obs.isValid():
                self._obsManager.addObservation(
                    azimuth=obs['azimuth'], zenith=obs['zenith'],\
                    sensorId=obs['sensorId']
                )
                form.blockSignals(True)
                del form
                name = self.tr("Observation {0}").format(obs['id'])
                self.obsComboBox.addItem(name)
                self.observationAdded.emit(obs)
Exemple #7
0
        lin = dem.height() - 1
    elif lin < 0:
        lin = 0
    y, x = dem.pixelToCoordinates(col, lin)
    z = dem.bands()[col][lin]
    sensorY, sensorX, sensorZ = sensor['coordinates']
    dx, dy, dz = x - sensorX, y - sensorY, z - sensorZ
    if dem.isGeographic():
        # the more appropriate conversion would be a geodesic line - curve geometry
        dx = np.deg2rad(dx) * Enums.EARTH_RADIUS
        dy = np.deg2rad(dy) * np.pi * Enums.EARTH_RADIUS / 180
    azimuth = np.rad2deg(np.arctan2(np.sqrt(dy**2 + dz**2), dx))
    zenith = np.rad2deg(np.arctan2(dx, dz))
    om = ObservationsManager()
    om.addObservation(azimuth, zenith, sensor['id'])
    return zenith, azimuth


s = Settings()
sm = SensorsManager(s)
sensor = sm.getSensorFromId(3)
om = ObservationsManager(s)

demPath = ".dev/testing_data/sf-23-z-b/rj_srtm_90m_sirgas2000-23s.tif"
dem = RasterLayer(demPath)
generateObsAtPixel(dem, sensor, 102, 101)
obs = om.getObservationsFromSensor(3)[17]
sf = ShooterFinder(s)
sf.findShooter(1, sensor, obs, dem)
print(om.getObservationsFromSensor(3))