diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index 887a2c132..28f435735 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -3599,6 +3599,7 @@ dimstyle = .move-text-outside-first = نقل النص إلى الخارج أولًا .period = نقطة .space = مسافة + .surveyors-units = وحدات المسّاح style-manager = .alignment-spacing = تباعد المحاذاة diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index 900027361..793c311c2 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -3587,6 +3587,7 @@ dimstyle = .move-text-outside-first = Първо премести текста навън .period = Точка .space = Интервал + .surveyors-units = Геодезически единици style-manager = .alignment-spacing = Разстояние на подравняване diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index 5ba65671a..654730c42 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = Nejprve přesuňte text ven .period = Období .space = Mezerník + .surveyors-units = Zeměměřické jednotky style-manager = .alignment-spacing = Rozteč zarovnání diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index 4613c57a5..2e4326ac7 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -3585,6 +3585,7 @@ dimstyle = .move-text-outside-first = Zuerst Text nach außen verschieben .period = Punkt .space = Leerzeichen + .surveyors-units = Vermessungseinheiten style-manager = .alignment-spacing = Ausrichtungsabstand diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index a90b105d2..7a73eebd1 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -3588,6 +3588,7 @@ dimstyle = .move-text-outside-first = Move text outside first .period = Period .space = Space + .surveyors-units = Surveyor's units style-manager = .alignment-spacing = Alignment spacing diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index f525cf334..70f76226a 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -3587,6 +3587,7 @@ dimstyle = .move-text-outside-first = Mover primero el texto fuera .period = Punto .space = Espacio + .surveyors-units = Unidades de topografía style-manager = .alignment-spacing = Espaciado de alineación diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index c7a02fc60..0ad037e69 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = Siirrä teksti ensin ulos .period = Kausi .space = Välilyönti + .surveyors-units = Maanmittausyksiköt style-manager = .alignment-spacing = Tasausvälit diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index d44dbfa9a..f19223ccd 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = Déplacer d’abord le texte à l’extérieur .period = Point .space = Espace + .surveyors-units = Unités d’arpentage style-manager = .alignment-spacing = Espacement d’alignement diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 3605c51c3..dda9941b0 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -3575,6 +3575,7 @@ dimstyle = .move-text-outside-first = पहले पाठ बाहर ले जाएँ .period = दशमलव बिंदु .space = रिक्त स्थान + .surveyors-units = सर्वेक्षण इकाइयाँ style-manager = .alignment-spacing = संरेखण अंतराल diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index cec83afd6..4da10cd4c 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = Először mozgassa ki a szöveget .period = Időszak .space = Szóköz + .surveyors-units = Földmérési egységek style-manager = .alignment-spacing = Igazítási távolság diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index 085593f51..f4d5c3da8 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = Sposta prima il testo all'esterno .period = Periodo .space = Spazio + .surveyors-units = Unità topografiche style-manager = .alignment-spacing = Spaziatura di allineamento diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index 32ac87b24..d1aefb13e 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -3575,6 +3575,7 @@ dimstyle = .move-text-outside-first = 先に寸法値を外側へ移動 .period = ピリオド .space = 空白 + .surveyors-units = 測量単位 style-manager = .alignment-spacing = 位置合わせ間隔 diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index 1d5e02afd..36097d154 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = 먼저 텍스트를 외부로 이동하세요. .period = 기간 .space = 스페이스바 + .surveyors-units = 측량 단위 style-manager = .alignment-spacing = 정렬 간격 diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 9ab4a95d7..8344d0d9c 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -3587,6 +3587,7 @@ dimstyle = .move-text-outside-first = Eerst tekst naar buiten verplaatsen .period = Punt .space = Spatie + .surveyors-units = Landmeeteenheden style-manager = .alignment-spacing = Uitlijningsafstand diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index 48f6eeca3..b1374b8f7 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -3586,6 +3586,7 @@ dimstyle = .move-text-outside-first = Najpierw przenieś tekst na zewnątrz .period = Okres .space = Spacja + .surveyors-units = Jednostki geodezyjne style-manager = .alignment-spacing = Rozstaw wyrównania diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index 2569877e3..406731e2a 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -3587,6 +3587,7 @@ dimstyle = .move-text-outside-first = Mover primeiro o texto para fora .period = Ponto .space = Espaço + .surveyors-units = Unidades de agrimensura style-manager = .alignment-spacing = Espaçamento de alinhamento diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index d52f53b18..779113fad 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -3590,6 +3590,7 @@ dimstyle = .move-text-outside-first = Сначала вынести текст .period = Точка .space = Пробел + .surveyors-units = Геодезические единицы style-manager = .alignment-spacing = Интервал выравнивания diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index b22e844fd..7a757079b 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -3511,6 +3511,7 @@ dimstyle = .move-text-outside-first = Önce metni dışarı taşı .period = Nokta .space = Boşluk + .surveyors-units = Haritacılık birimleri style-manager = .alignment-spacing = Hizalama aralığı diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 1d2df873e..d93c789ba 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -3570,6 +3570,7 @@ dimstyle = .move-text-outside-first = 优先将文字移到外部 .period = 句点 .space = 空格 + .surveyors-units = 测量单位 style-manager = .alignment-spacing = 对齐间距 diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index 1e3297546..89f6ab211 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -3582,6 +3582,7 @@ dimstyle = .move-text-outside-first = 優先將文字移到外部 .period = 句點 .space = 空白鍵 + .surveyors-units = 測量單位 style-manager = .alignment-spacing = 對齊間距 diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index 1de68c733..730cb421c 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -6602,6 +6602,8 @@ fn format_angular_value(measurement_deg: f64, style: Option<&DimStyle>) -> Strin swap_decimal_sep(&apply_angular_zero_suppression(&raw, azin), decimal_separator) ) } + // 4 = Surveyor's units + 4 => format_surveyor(measurement_deg, adec, azin, decimal_separator), // 0 or unknown = Decimal Degrees _ => { let raw = format!("{:.*}", adec, measurement_deg); @@ -6613,6 +6615,48 @@ fn format_angular_value(measurement_deg: f64, style: Option<&DimStyle>) -> Strin } } +/// Surveyor's units (DIMAUNIT 4): a bearing away from north or south toward +/// east or west, so the quoted angle never exceeds a quarter turn. Due north, +/// south, east and west have no bearing to quote and are written as the single +/// letter, which is also what keeps a quarter turn from reading as a +/// contradictory `N 90d0'0" E`. The bearing is DMS, so it carries DIMADEC, +/// DIMAZIN and DIMDSEP the same way the DMS format does. +fn format_surveyor(deg: f64, sec_dec: usize, azin: i16, decimal_separator: i16) -> String { + // Quantise before choosing a cardinal or a quadrant, so a value a hair + // under a cardinal direction does not print a quarter-turn bearing. + let scale = 3600.0 * 10f64.powi(sec_dec.min(8) as i32); + let turn = 360.0 * scale; + let ticks = (deg.rem_euclid(360.0) * scale).round().rem_euclid(turn); + let at = |d: f64| (ticks - d * scale).abs() < 0.5; + if at(0.0) { + return "E".into(); + } + if at(90.0) { + return "N".into(); + } + if at(180.0) { + return "W".into(); + } + if at(270.0) { + return "S".into(); + } + let d = ticks / scale; + // Measured from the nearer pole, toward the side the angle falls on. + let (pole, bearing, side) = if d < 90.0 { + ("N", 90.0 - d, "E") + } else if d < 180.0 { + ("N", d - 90.0, "W") + } else if d < 270.0 { + ("S", 270.0 - d, "W") + } else { + ("S", d - 270.0, "E") + }; + format!( + "{pole} {} {side}", + format_dms(bearing, sec_dec, azin, decimal_separator) + ) +} + fn format_dms(deg: f64, sec_dec: usize, azin: i16, decimal_separator: i16) -> String { let sign = if deg < 0.0 { "-" } else { "" }; let scale = 10_u64.pow(sec_dec.min(8) as u32) as f64; @@ -7305,6 +7349,41 @@ mod dimtad_tests { } } +#[cfg(test)] +mod angular_unit_tests { + use super::format_angular_value; + use acadrust::tables::DimStyle; + + fn style(dimaunit: i16, dimadec: i16) -> DimStyle { + let mut s = DimStyle::standard(); + s.dimaunit = dimaunit; + s.dimadec = dimadec; + s + } + + // DIMAUNIT 4 is Surveyor's units. It used to fall through to the decimal + // branch, so an angular dimension in a drawing authored with surveyor + // units read as plain degrees while AUNITS=4 elsewhere wrote a bearing. + #[test] + fn surveyor_units_write_a_bearing() { + assert_eq!(format_angular_value(45.0, Some(&style(4, 0))), "N 45\u{b0}0'0\" E"); + assert_eq!(format_angular_value(135.0, Some(&style(4, 0))), "N 45\u{b0}0'0\" W"); + assert_eq!(format_angular_value(200.0, Some(&style(4, 0))), "S 70\u{b0}0'0\" W"); + assert_eq!(format_angular_value(300.0, Some(&style(4, 0))), "S 30\u{b0}0'0\" E"); + // A hair under a cardinal must not quote a quarter-turn bearing. + assert_eq!(format_angular_value(89.99999, Some(&style(4, 0))), "N"); + assert_eq!(format_angular_value(90.0, Some(&style(4, 0))), "N"); + assert_eq!(format_angular_value(0.0, Some(&style(4, 0))), "E"); + } + + // The other unit formats are untouched. + #[test] + fn other_angular_units_unchanged() { + assert_eq!(format_angular_value(45.5, Some(&style(1, 0))), "45\u{b0}30'0\""); + assert_eq!(format_angular_value(90.0, Some(&style(2, 1))), "100.0g"); + } +} + #[cfg(test)] mod dim_color_override_tests { use super::dim_color_index; diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index 5de56c86a..510dd9adf 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -3224,6 +3224,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static "Suppress second extension line" => Some(("dimstyle", "suppress-second-extension-line")), "Suppress zero feet and zero inches" => Some(("dimstyle", "suppress-zero-feet-and-inches")), "Suppress zero feet; show zero inches" => Some(("dimstyle", "suppress-zero-feet-show-zero-inches")), + "Surveyor's units" => Some(("dimstyle", "surveyors-units")), "Symbols and Arrows" => Some(("dimstyle", "symbols-and-arrows")), "Symmetrical" => Some(("dimstyle", "symmetrical")), "Text background" => Some(("dimstyle", "text-background")), diff --git a/src/ui/style/dimstyle.rs b/src/ui/style/dimstyle.rs index d7eda2a22..aed2e9b74 100644 --- a/src/ui/style/dimstyle.rs +++ b/src/ui/style/dimstyle.rs @@ -956,7 +956,7 @@ pub fn view_window<'a>( t!("Unit format"), DsField::Dimaunit, vals.dimaunit, - &[("0", "Decimal degrees"), ("1", "Degrees, minutes, seconds"), ("2", "Gradians"), ("3", "Radians")], + &[("0", "Decimal degrees"), ("1", "Degrees, minutes, seconds"), ("2", "Gradians"), ("3", "Radians"), ("4", "Surveyor's units")], ), row![lbl(t!("Precision")), mk_field(DsField::Dimadec, vals.dimadec)] .spacing(8).align_y(iced::Center),