initial
This commit is contained in:
219
.venv/lib/python3.12/site-packages/ezdxf/units.py
Normal file
219
.venv/lib/python3.12/site-packages/ezdxf/units.py
Normal file
@@ -0,0 +1,219 @@
|
||||
# Copyright (c) 2019-2023 Manfred Moitzi
|
||||
# License: MIT License
|
||||
from typing import Optional
|
||||
from ezdxf.enums import InsertUnits
|
||||
|
||||
# Documentation: https://ezdxf.mozman.at/docs/concepts/units.html#insunits
|
||||
|
||||
MSP_METRIC_UNITS_FACTORS = {
|
||||
# length in units / factor = length in meters
|
||||
# length in meters * factor = length in units
|
||||
"km": 0.001,
|
||||
"m": 1.0,
|
||||
"dm": 10.0,
|
||||
"cm": 100.0,
|
||||
"mm": 1000.0,
|
||||
"µm": 1000000.0,
|
||||
"yd": 1.093613298,
|
||||
"ft": 3.280839895,
|
||||
"in": 39.37007874,
|
||||
"mi": 0.00062137119,
|
||||
}
|
||||
|
||||
IN = 1
|
||||
FT = 2
|
||||
MI = 3
|
||||
MM = 4
|
||||
CM = 5
|
||||
M = 6
|
||||
KM = 7
|
||||
YD = 10
|
||||
DM = 14
|
||||
|
||||
IMPERIAL_UNITS = {
|
||||
InsertUnits.Inches,
|
||||
InsertUnits.Feet,
|
||||
InsertUnits.Miles,
|
||||
InsertUnits.Microinches,
|
||||
InsertUnits.Mils,
|
||||
InsertUnits.Yards,
|
||||
InsertUnits.USSurveyFeet,
|
||||
InsertUnits.USSurveyInch,
|
||||
InsertUnits.USSurveyYard,
|
||||
InsertUnits.USSurveyMile,
|
||||
}
|
||||
|
||||
# Conversion factor from meters to unit
|
||||
# 1 meter is ... [unit]
|
||||
METER_FACTOR = [
|
||||
None, # 0 = Unitless - not supported
|
||||
39.37007874, # 1 = Inches
|
||||
3.280839895, # 2 = Feet
|
||||
0.00062137119, # 3 = Miles
|
||||
1000.0, # 4 = Millimeters
|
||||
100.0, # 5 = Centimeters
|
||||
1.0, # 6 = Meters
|
||||
0.001, # 7 = Kilometers
|
||||
None, # 8 = Microinches = 1e-6 in
|
||||
None, # 9 = Mils = 0.001 in
|
||||
1.093613298, # 10 = Yards
|
||||
10000000000.0, # 11 = Angstroms = 1e-10m
|
||||
1000000000.0, # 12 = Nanometers = 1e-9m
|
||||
1000000.0, # 13 = Microns = 1e-6m
|
||||
10.0, # 14 = Decimeters = 0.1m
|
||||
0.1, # 15 = Decameters = 10m
|
||||
0.01, # 16 = Hectometers = 100m
|
||||
0.000000001, # 17 = Gigameters = 1e+9 m
|
||||
1.0 / 149597870700, # 18 = Astronomical units = 149597870700m
|
||||
1.0 / 9.46e15, # 19 = Light years = 9.46e15 m
|
||||
1.0 / 3.09e16, # 20 = Parsecs = 3.09e16 m
|
||||
None, # 21 = US Survey Feet
|
||||
None, # 22 = US Survey Inch
|
||||
None, # 23 = US Survey Yard
|
||||
None, # 24 = US Survey Mile
|
||||
]
|
||||
|
||||
|
||||
class DrawingUnits:
|
||||
def __init__(self, base: float = 1.0, unit: str = "m"):
|
||||
self.base = float(base)
|
||||
self.unit = unit.lower()
|
||||
self._units = MSP_METRIC_UNITS_FACTORS
|
||||
self._msp_factor = base * self._units[self.unit]
|
||||
|
||||
def factor(self, unit: str = "m") -> float:
|
||||
return self._msp_factor / self._units[unit.lower()]
|
||||
|
||||
def __call__(self, unit: str) -> float:
|
||||
return self.factor(unit)
|
||||
|
||||
|
||||
class PaperSpaceUnits:
|
||||
def __init__(self, msp=DrawingUnits(), unit: str = "mm", scale: float = 1):
|
||||
self.unit = unit.lower()
|
||||
self.scale = scale
|
||||
self._msp = msp
|
||||
self._psp = DrawingUnits(1, self.unit)
|
||||
|
||||
def from_msp(self, value: float, unit: str):
|
||||
drawing_units = value * self._msp(unit.lower())
|
||||
return drawing_units / (self._msp(self.unit) * self.scale)
|
||||
|
||||
def to_msp(self, value: float, unit: str):
|
||||
paper_space_units = value * self.scale * self._psp.factor(unit)
|
||||
model_space_units = paper_space_units * self._msp.factor(self.unit)
|
||||
return model_space_units
|
||||
|
||||
|
||||
# Layout units are stored as enum in the associated BLOCK_RECORD: BlockRecord.dxf.units
|
||||
# or as optional XDATA for all DXF versions
|
||||
# 1000: "ACAD"
|
||||
# 1001: "DesignCenter Data" (optional)
|
||||
# 1002: "{"
|
||||
# 1070: Autodesk Design Center version number
|
||||
# 1070: Insert units: like 'units'
|
||||
# 1002: "}"
|
||||
|
||||
# The units of the modelspace block record is always 0, the real modelspace
|
||||
# units and therefore the document units are stored as enum in the header var
|
||||
# $INSUNITS
|
||||
|
||||
# units stored as enum in BlockRecord.dxf.units
|
||||
# 0 = Unitless
|
||||
# 1 = Inches
|
||||
# 2 = Feet
|
||||
# 3 = Miles
|
||||
# 4 = Millimeters
|
||||
# 5 = Centimeters
|
||||
# 6 = Meters
|
||||
# 7 = Kilometers
|
||||
# 8 = Microinches = 1e-6 in
|
||||
# 9 = Mils = 0.001 in
|
||||
# 10 = Yards
|
||||
# 11 = Angstroms = 1e-10m
|
||||
# 12 = Nanometers = 1e-9m
|
||||
# 13 = Microns = 1e-6m
|
||||
# 14 = Decimeters = 0.1m
|
||||
# 15 = Decameters = 10m
|
||||
# 16 = Hectometers = 100m
|
||||
# 17 = Gigameters = 1e+9 m
|
||||
# 18 = Astronomical units = 149597870700m = 1.58125074e−5 ly = 4.84813681e−6 Parsec
|
||||
# 19 = Light years = 9.46e15 m
|
||||
# 20 = Parsecs = 3.09e16 m
|
||||
# 21 = US Survey Feet
|
||||
# 22 = US Survey Inch
|
||||
# 23 = US Survey Yard
|
||||
# 24 = US Survey Mile
|
||||
_unit_spec = [
|
||||
None,
|
||||
"in",
|
||||
"ft",
|
||||
"mi",
|
||||
"mm",
|
||||
"cm",
|
||||
"m",
|
||||
"km",
|
||||
"µin",
|
||||
"mil",
|
||||
"yd",
|
||||
"Å",
|
||||
"nm",
|
||||
"µm",
|
||||
"dm",
|
||||
"dam",
|
||||
"hm",
|
||||
"gm",
|
||||
"au",
|
||||
"ly",
|
||||
"pc",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
]
|
||||
|
||||
|
||||
def decode(enum: int) -> Optional[str]:
|
||||
return _unit_spec[int(enum)]
|
||||
|
||||
|
||||
def conversion_factor(
|
||||
source_units: InsertUnits, target_units: InsertUnits
|
||||
) -> float:
|
||||
"""Returns the conversion factor to represent `source_units` in
|
||||
`target_units`.
|
||||
|
||||
E.g. millimeter in centimeter :code:`conversion_factor(MM, CM)` returns 0.1,
|
||||
because 1 mm = 0.1 cm
|
||||
|
||||
"""
|
||||
try:
|
||||
source_factor = METER_FACTOR[source_units]
|
||||
target_factor = METER_FACTOR[target_units]
|
||||
if source_factor is None or target_factor is None:
|
||||
raise TypeError("Unsupported conversion.")
|
||||
return target_factor / source_factor
|
||||
|
||||
except IndexError:
|
||||
raise ValueError("Invalid unit enum.")
|
||||
|
||||
|
||||
def unit_name(enum: int) -> str:
|
||||
"""Returns the name of the unit enum."""
|
||||
try:
|
||||
return InsertUnits(enum).name
|
||||
except ValueError:
|
||||
return "unitless"
|
||||
|
||||
|
||||
ANGLE_UNITS = {
|
||||
0: "Decimal Degrees",
|
||||
1: "Degrees/Minutes/Seconds",
|
||||
2: "Grad",
|
||||
3: "Radians",
|
||||
}
|
||||
|
||||
|
||||
def angle_unit_name(enum: int) -> str:
|
||||
"""Returns the name of the angle unit enum."""
|
||||
return ANGLE_UNITS.get(enum, f"unknown unit <{enum}>")
|
||||
Reference in New Issue
Block a user