use native_db::{native_db, ToKey};
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[native_model(id = 17, version = 5)]
#[native_db]
pub struct TagLocal {
pub id: Option<i64>,
#[primary_key]
pub id_local: Option<String>,
pub inserted_at: Option<String>,
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
pub conf: f64,
pub observation_type: super::v1::TagObservationType,
#[serde(rename = "class")]
pub class: String,
#[secondary_key]
pub event_id: Option<i64>,
#[secondary_key]
pub ancestor_id_local: Option<String>,
pub origin_location: Option<String>,
pub origin_pitch: Option<f64>,
pub origin_heading: Option<f64>,
pub origin_roll: Option<f64>,
pub sensor_pitch: Option<f64>,
pub sensor_yaw: Option<f64>,
pub sensor_roll: Option<f64>,
pub origin_height: Option<f64>,
pub subject_location: Option<String>,
pub subject_height: Option<f64>,
pub artifact_id: Option<i64>,
pub timestamp_observation: Option<String>,
pub frame_index: Option<i64>,
#[serde(default)]
pub subject_id: Option<i64>,
#[serde(default)]
pub model_id: Option<i64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Tag {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inserted_at: Option<String>,
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
pub conf: f64,
pub observation_type: super::v1::TagObservationType,
#[serde(rename = "class")]
pub class: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_pitch: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_heading: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_roll: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sensor_pitch: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sensor_yaw: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sensor_roll: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_height: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject_location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject_height: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub artifact_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp_observation: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub frame_index: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject_id: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_id: Option<i64>,
}
impl Default for TagLocal {
fn default() -> Self {
Self {
id: None,
id_local: None,
inserted_at: None,
x: 0.0,
y: 0.0,
width: 0.0,
height: 0.0,
conf: 0.0,
observation_type: super::v1::TagObservationType::Auto,
class: String::new(),
event_id: None,
ancestor_id_local: None,
origin_location: None,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
timestamp_observation: None,
frame_index: None,
subject_id: None,
model_id: None,
}
}
}
impl Default for Tag {
fn default() -> Self {
Self {
id: None,
inserted_at: None,
x: 0.0,
y: 0.0,
width: 0.0,
height: 0.0,
conf: 0.0,
observation_type: super::v1::TagObservationType::Manual,
class: String::new(),
event_id: None,
origin_location: None,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
timestamp_observation: None,
frame_index: None,
subject_id: None,
model_id: None,
}
}
}
impl super::v1::Syncable for TagLocal {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
self.id_local.clone()
}
fn set_id_local(&mut self, id_local: String) {
self.id_local = Some(id_local);
}
}
impl super::v1::Syncable for Tag {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
None
}
fn set_id_local(&mut self, _: String) {}
}
impl super::v1::AncestorLocal for TagLocal {
fn ancestor_id_local(&self) -> Option<String> {
self.ancestor_id_local.clone()
}
fn set_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
}
impl From<TagLocal> for Tag {
fn from(local: TagLocal) -> Self {
Self {
id: local.id,
inserted_at: local.inserted_at,
x: local.x,
y: local.y,
width: local.width,
height: local.height,
conf: local.conf,
observation_type: local.observation_type,
class: local.class,
event_id: local.event_id,
origin_location: local.origin_location,
origin_pitch: local.origin_pitch,
origin_heading: local.origin_heading,
origin_roll: local.origin_roll,
sensor_pitch: local.sensor_pitch,
sensor_yaw: local.sensor_yaw,
sensor_roll: local.sensor_roll,
origin_height: local.origin_height,
subject_location: local.subject_location,
subject_height: local.subject_height,
artifact_id: local.artifact_id,
timestamp_observation: local.timestamp_observation,
frame_index: local.frame_index,
subject_id: local.subject_id,
model_id: local.model_id,
}
}
}
impl From<Tag> for TagLocal {
fn from(tag: Tag) -> Self {
Self {
id: tag.id,
id_local: None,
inserted_at: tag.inserted_at,
x: tag.x,
y: tag.y,
width: tag.width,
height: tag.height,
conf: tag.conf,
observation_type: tag.observation_type,
class: tag.class,
event_id: tag.event_id,
ancestor_id_local: None,
origin_location: tag.origin_location,
origin_pitch: tag.origin_pitch,
origin_heading: tag.origin_heading,
origin_roll: tag.origin_roll,
sensor_pitch: tag.sensor_pitch,
sensor_yaw: tag.sensor_yaw,
sensor_roll: tag.sensor_roll,
origin_height: tag.origin_height,
subject_location: tag.subject_location,
subject_height: tag.subject_height,
artifact_id: tag.artifact_id,
timestamp_observation: tag.timestamp_observation,
frame_index: tag.frame_index,
subject_id: tag.subject_id,
model_id: tag.model_id,
}
}
}
impl From<super::v8::TagLocal> for TagLocal {
fn from(prev: super::v8::TagLocal) -> Self {
Self {
id: prev.id,
id_local: prev.id_local,
inserted_at: prev.inserted_at,
x: prev.x,
y: prev.y,
width: prev.width,
height: prev.height,
conf: prev.conf,
observation_type: prev.observation_type,
class: prev.class,
event_id: prev.event_id,
ancestor_id_local: prev.ancestor_id_local,
origin_location: prev.origin_location,
origin_pitch: prev.origin_pitch,
origin_heading: prev.origin_heading,
origin_roll: prev.origin_roll,
sensor_pitch: prev.sensor_pitch,
sensor_yaw: prev.sensor_yaw,
sensor_roll: prev.sensor_roll,
origin_height: prev.origin_height,
subject_location: prev.subject_location,
subject_height: prev.subject_height,
artifact_id: prev.artifact_id,
timestamp_observation: prev.timestamp_observation,
frame_index: prev.frame_index,
subject_id: prev.subject_id,
model_id: None,
}
}
}
impl Tag {
pub fn new(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
) -> Self {
Self {
x,
y,
width,
height,
conf,
observation_type,
class,
..Default::default()
}
}
pub fn new_with_location(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
latitude: f64,
longitude: f64,
) -> Self {
let mut tag = Self::new(
_class_id,
x,
y,
width,
height,
conf,
observation_type,
class,
);
tag.set_location(latitude, longitude);
tag
}
pub fn update_event_id(&mut self, event_id: i64) {
self.event_id = Some(event_id);
}
pub fn set_location(&mut self, latitude: f64, longitude: f64) {
self.origin_location = Some(Self::format_location(latitude, longitude));
}
pub fn clear_location(&mut self) {
self.origin_location = None;
}
pub fn format_location(latitude: f64, longitude: f64) -> String {
format!("POINT({} {})", longitude, latitude)
}
pub fn parse_location(location: &str) -> Option<(f64, f64)> {
if let Some(coords) = location
.strip_prefix("POINT(")
.and_then(|s| s.strip_suffix(")"))
{
let parts: Vec<&str> = coords.split_whitespace().collect();
if parts.len() == 2 {
if let (Ok(lon), Ok(lat)) = (parts[0].parse::<f64>(), parts[1].parse::<f64>()) {
return Some((lat, lon));
}
}
}
None
}
pub fn get_coordinates(&self) -> Option<(f64, f64)> {
self.origin_location
.as_ref()
.and_then(|loc| Self::parse_location(loc))
}
}
impl TagLocal {
pub fn new(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
) -> Self {
Self {
x,
y,
width,
height,
conf,
observation_type,
class,
..Default::default()
}
}
pub fn new_with_location(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
latitude: f64,
longitude: f64,
) -> Self {
let mut tag = Self::new(
_class_id,
x,
y,
width,
height,
conf,
observation_type,
class,
);
tag.set_location(latitude, longitude);
tag
}
pub fn update_event_id(&mut self, event_id: i64) {
self.event_id = Some(event_id);
}
pub fn update_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
pub fn set_location(&mut self, latitude: f64, longitude: f64) {
self.origin_location = Some(Self::format_location(latitude, longitude));
}
pub fn clear_location(&mut self) {
self.origin_location = None;
}
pub fn format_location(latitude: f64, longitude: f64) -> String {
format!("POINT({} {})", longitude, latitude)
}
pub fn parse_location(location: &str) -> Option<(f64, f64)> {
if let Some(coords) = location
.strip_prefix("POINT(")
.and_then(|s| s.strip_suffix(")"))
{
let parts: Vec<&str> = coords.split_whitespace().collect();
if parts.len() == 2 {
if let (Ok(lon), Ok(lat)) = (parts[0].parse::<f64>(), parts[1].parse::<f64>()) {
return Some((lat, lon));
}
}
}
None
}
pub fn get_coordinates(&self) -> Option<(f64, f64)> {
self.origin_location
.as_ref()
.and_then(|loc| Self::parse_location(loc))
}
}