Исходный код для django.contrib.gis.measure

# Copyright (c) 2007, Роберт Коуп <[email protected]> 
# Все права защищены. 
# 
# Распространение и использование в исходной и двоичной формах, с модификациями или без, 
# разрешено при соблюдении следующих условий: 
# 
# 1. При повторном распространении исходного кода должно сохраняться указанное выше уведомление об авторских правах, 
# этот список условий и следующие отказ от ответственности. 
# 
# 2. При повторном распространении в двоичной форме должно воспроизводиться 
# 
указанное выше уведомление об авторских правах, этот список условий и следующий отказ от ответственности в # документации и / или других материалах, поставляемых с распространением. 
# 
# 3. Запрещается использовать название Distance или имена его участников.
# для поддержки или продвижения продуктов, созданных на основе этого программного обеспечения, без 
# специального предварительного письменного разрешения. 
# 
# НАСТОЯЩЕЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ОБЛАДАТЕЛЯМИ АВТОРСКИХ ПРАВ И ДОПОЛНИТЕЛЬНЫМИ ПРАВАМИ "КАК ЕСТЬ" И 
# ЛЮБЫМИ ЯВНЫМИ ИЛИ ПОДРАЗУМЕВАЕМЫМИ ГАРАНТИЯМИ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАясь, 
# 
ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ ТОВАРНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ # ПРЕДОСТАВЛЕНИЯ . ВЛАДЕЛЕЦ АВТОРСКИХ ПРАВ ИЛИ СОСТАВНИКИ НИ ПРИ 
КАКИХ 
ОБСТОЯТЕЛЬСТВАХ НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ПРИМЕРНЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ЗАКУПКИ ТОВАРОВ ИЛИ УСЛУГ 
ЗАМЕНЫ, ПОТЕРИ НАС ИЛИ ПРИБЫЛЬ; ИЛИ ПЕРЕРЫВ В ДЕЯТЕЛЬНОСТИ), ПО ПРИЧИНЕ И НА
# ЛЮБАЯ ТЕОРИЯ ОТВЕТСТВЕННОСТИ, ЛИБО В КОНТРАКТЕ, СТРОГОЙ ОТВЕТСТВЕННОСТИ ИЛИ ПЕРЕДАЧИ 
# (ВКЛЮЧАЯ НЕБРЕЖНОСТЬ ИЛИ ИНОЕ), ВОЗНИКАЮЩАЯ В ЛЮБОМ ПУТИ ИЗ ИСПОЛЬЗОВАНИЯ ДАННОГО 
# ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ ПРЕДНАЗНАЧЕНА ВОЗМОЖНОСТЬ ТАКОГО ПОВРЕЖДЕНИЯ. 
# 
"" " 
Объекты Distance и Area для разумного и удобного расчета 
и преобразования.

Авторы: Роберт Коуп, Джастин Бронн, Риккардо Ди Вирджилио

Вдохновленный GeoPy (https://github.com/geopy/geopy) 
и доктором наук Джеффа Биггса, работает над размерными блоками для робототехники. 
«»» 
От  десятичного  импорта  Decimal 
из  functools  импортирует  total_ordering

__all__  =  [ 'A' ,  'Площадь' ,  'D' ,  'Расстояние' ]

NUMERIC_TYPES  =  ( INT ,  поплавок ,  Decimal ) 
AREA_PREFIX  =  "sq_"


def  pretty_name ( obj ): 
    вернуть  объект . __name__,  если  объект . __class__  ==  type  else  obj . __class__ . __название__


@total_ordering 
класс  MeasureBase : 
    STANDARD_UNIT  =  None 
    ALIAS  =  {} 
    UNITS  =  {} 
    LALIAS  =  {}

    def  __init__ ( self ,  default_unit = None ,  ** kwargs ): 
        значение ,  self . _default_unit  =  self . default_units ( kwargs ) 
        setattr ( self ,  self . STANDARD_UNIT ,  value ), 
        если  default_unit  и  isinstance ( default_unit ,  str ): 
            self . _default_unit  =  default_unit

    def  _get_standard ( self ): 
        вернуть  getattr ( self ,  self . STANDARD_UNIT )

    def  _set_standard ( self ,  значение ): 
        setattr ( self ,  self . STANDARD_UNIT ,  значение )

    стандарт  =  свойство ( _get_standard ,  _set_standard )

    def  __getattr__ ( self ,  name ): 
        если  имя  в  self . ЕДИНИЦЫ : 
            вернуть  себе . стандарт  /  сам . UNITS [ имя ] 
        else : 
            поднять  AttributeError ( 'Неизвестный тип устройства: % s '  %  name )

    def  __repr__ ( self ): 
        return  ' % s ( % s = % s )'  %  ( pretty_name ( self ),  self . _default_unit ,  getattr ( self ,  self . _default_unit ))

    def  __str__ ( self ): 
        вернуть  ' % s % s ' % ( getattr ( self , self . _default_unit ), self . _default_unit )     

    # **** Методы сравнения ****

    def  __eq__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            вернуть  self . стандарт  ==  другое . стандарт 
        else : 
            return  NotImplemented

    def  __lt__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            вернуть  self . стандартный  <  другой . стандарт 
        else : 
            return  NotImplemented

    # **** Операторы методы ****

    def  __add__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            вернуть  self . __class__ ( 
                default_unit = self . _default_unit , 
                ** { self . STANDARD_UNIT :  ( self . standard  +  other . standard )} 
            ) 
        else : 
            поднять  TypeError ( ' % (class) sнеобходимо добавить с помощью % (class) s '  %  { "class" :  pretty_name ( self )})

    def  __iadd__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            self . стандарт  + =  другое . стандартный 
            возврат  self 
        else : 
            raise  TypeError ( ' % (class) s должен быть добавлен с % (class) s '  %  { "class" :  pretty_name ( self )})

    def  __sub__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            вернуть  self . __class__ ( 
                default_unit = self . _default_unit , 
                ** { self . STANDARD_UNIT :  ( self . standard  -  other . standard )} 
            ) 
        else : 
            поднять  TypeError ( ' % (class) sдолжно быть вычтено из % (class) s '  %  { "class" :  pretty_name ( self )})

    def  __isub__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            self . стандарт  - =  другое . стандартный 
            возврат  self 
        else : 
            raise  TypeError ( ' % (class) s необходимо вычесть из % (class) s '  %  { "class" :  pretty_name ( self )})

    def  __mul__ ( self ,  other ): 
        if  isinstance ( other ,  NUMERIC_TYPES ): 
            вернуть  self . __class__ ( 
                default_unit = self . _default_unit , 
                ** { self . STANDARD_UNIT :  ( self . standard  *  other )} 
            ) 
        else : 
            raise  TypeError ( ' % (class) s необходимо умножить на число'  %  {"class" :  pretty_name ( self )})

    def  __imul__ ( self ,  other ): 
        if  isinstance ( other ,  NUMERIC_TYPES ): 
            self . standard  * =  float ( other ) 
            return  self 
        else : 
            raise  TypeError ( ' % (class) s необходимо умножить на число'  %  { "class" :  pretty_name ( self )})

    def  __rmul__ ( self ,  other ): 
        вернуть  self  *  other

    def  __truediv__ ( self ,  other ): 
        if  isinstance ( other ,  self . __class__ ): 
            вернуть  self . стандартное  /  другое . стандартный, 
        если  isinstance ( другой ,  NUMERIC_TYPES ): 
            вернуть  себя . __class__ ( 
                default_unit = self . _default_unit , 
                ** { self . STANDARD_UNIT :  ( self, стандартный  /  другой )} 
            ) 
        else : 
            raise  TypeError ( ' % (class) s должен быть разделен на число или % (class) s '  %  { "class" :  pretty_name ( self )})

    def  __itruediv__ ( self ,  other ): 
        if  isinstance ( other ,  NUMERIC_TYPES ): 
            self . standard  / =  float ( other ) 
            return  self 
        else : 
            raise  TypeError ( ' % (class) s должен быть разделен на число'  %  { "class" :  pretty_name ( self )})

    Защиту  __bool__ ( самостоятельно ): 
        возврат  BOOL ( самостоятельно . стандарт )

    def  default_units ( self ,  kwargs ): 
        "" " 
        Возвращает значение единицы измерения и единицы измерения по умолчанию, указанные 
        из заданного словаря аргументов ключевого слова. 
        " "" 
        val  =  0.0 
        default_unit  =  self . STANDARD_UNIT 
        для  единицы ,  значение  в  кваргах . items (): 
            if  not  isinstance ( value ,  float ): 
                value  =  float ( value ) 
            if  unit в  себе . ЕДИНИЦЫ : 
                val  + =  self . UNITS [ unit ]  *  value 
                default_unit  =  unit 
            elif  unit  in  self . НИКНЕЙМЫ : 
                u  =  self . НИКНЕЙМЫ [ unit ] 
                val  + =  self . UNITS [ u ]  *  значение 
                default_unit  =  u 
            else : 
                lower  =  unit . нижний ()
                если  ниже  в  себе . ЕДИНИЦЫ : 
                    val  + =  self . UNITS [ lower ]  *  значение 
                    default_unit  =  lower 
                elif  lower  in  self . ЛАЛИАС : 
                    u  =  я . ЛАЛИАС [ нижний ] 
                    val  + =  self . UNITS [ u ]  *  значение 
                    default_unit  =  u 
                else : 
                    поднять  AttributeError( 'Неизвестный тип единицы: % s '  %  unit ) 
        return  val ,  default_unit

    @classmethod 
    def  unit_attname ( cls ,  unit_str ): 
        "" " 
        Получить имя атрибута единицы для заданной строки единицы измерения. 
        Например, если данная строка единицы измерения -" метр ", вернуть" m ". 
        Вызвать исключение, если атрибут не может быть найдено. 
        "" " 
        lower  =  unit_str . lower (), 
        если  unit_str  в  cls . UNITS : 
            вернуть  unit_str 
        elif  ниже  в  cls . ЕДИНИЦЫ : 
            вернуть  нижний 
        элиф  нижний в  cls . ЛАЛИАС : 
            вернуть  cls . LALIAS [ lower ] 
        else : 
            raise  Exception ( 'Не удалось найти ключевое слово юнита, связанное с " % s "'  %  unit_str )


[DOCS] класс Расстояние ( MeasureBase ): STANDARD_UNIT = "м" ЕДИНИЦЫ = { 'цепь' : 20,1168 , 'chain_benoit' : 20,116782 , 'chain_sears' : 20.1167645 , 'british_chain_benoit' : 20.1167824944 , 'british_chain_sears' : 20.1167651216 , 'british_chain_sears_truncated' : 20,116756 , «см» : 0,01 , «британский_фт» : 0.304799471539 , г. 'british_yd' : 0,914398414616 , 'clarke_ft' : 0,3047972654 , 'clarke_link' : 0,201166195164 , 'сажень' : 1,8288 , 'фут' : 0,3048 , 'Ферлонг' : 201.168 , 'german_m' : 1.0000135965 , 'gold_coast_ft' : 0.304799710181508 , «indian_yd ' : 0,914398530744 , ' дюйм ' : 0,0254 , ' км ' : 1000,0 , 'ссылка ' : 0.201168 , 'link_benoit' : 0.20116782 , 'link_sears' : 0.20116765 , 'm' : 1.0 , 'mi' : 1609.344 , 'mm' : 0.001 , 'nm' : 1852.0 , 'nm_uk' : 1853.184 , 'rod' : 5.0292 , sears_yd : 0.91439841 , Survey_ft : 0.304800609601 , um : 0.000001 , yd : 0,9144 , } # Псевдонимы единиц для терминов UNIT, встречающиеся в пространственной привязке WKT. ALIAS = { 'сантиметр' : 'см' , 'фут' : 'фут' , 'дюймы' : 'дюйм' , 'километр' : 'км' , 'километр' : 'км' , 'метр' : 'м' , «метр» : «м» , «микрометр» : «эм» , «микрометр» : «эм» , «миллиметр» 'мм' , 'миля' : 'mi' , 'ярд' : 'ярд' , 'британская цепочка (Benoit 1895 B)' : 'british_chain_benoit' , 'британская цепочка (Sears 1922)' : 'british_chain_sears' , 'британская цепочка (Sears 1922 усечено ) ' : ' british_chain_sears_truncated ' , ' British foot (Sears 1922) ' : ' british_ft ' , ' British Foot ' : ' british_ft ' , ' British Yard (Sears 1922) ' : ' british_yd ' , 'Британский двор' : 'british_yd' , "Clarke's Foot" : 'clarke_ft' , "Clarke's link" : 'clarke_link' , 'Chain (Benoit)' : 'chain_benoit' , 'Chain (Sears)' : 'chain_sears' , 'Foot (International)' : 'ft' , 'Furrow Long' : 'furlong' , 'German legal meter' : 'german_m' , 'Gold Coast foot' : 'gold_coast_ft' , 'индийский двор' : 'indian_yd' , 'Ссылка (Бенуа) ' : ' link_benoit ' , ' Ссылка (Sears) ' : 'link_sears' , 'Nautical Mile' : 'нм' , 'Nautical Mile (Великобритания)' : 'nm_uk' , 'США опрос лапка' : 'survey_ft' , 'США Foot' : 'survey_ft' , 'Yard (индийский)' : 'indian_yd' , 'Yard (Sears)' : 'sears_yd' } LALIAS = { k . понизить (): V для к , V в АЛИАС . items ()} def __mul__ ( self , other ): if isinstance ( other , self . __class__ ): return Area ( default_unit = AREA_PREFIX + self . _default_unit , ** { AREA_PREFIX + self . STANDARD_UNIT : ( self . standard * other . standard )} ) elif isinstance ( другое , NUMERIC_TYPES ): вернуть себя . __class__ ( default_unit = self . _default_unit , ** { self . STANDARD_UNIT : ( self . standard * other )} ) else : raise TypeError ( ' % (расстояние) s должно быть умножено на число или % (расстояние) s ' % { " расстояние " : pretty_name ( self . __class__ ), })
[документы] класс Area ( MeasureBase ): STANDARD_UNIT = AREA_PREFIX + Distance . STANDARD_UNIT # Получение значений квадратных единиц и словаря псевдонимов. UNITS = { ' % s% s ' % ( AREA_PREFIX , k ): v ** 2 для k , v в расстоянии . ЕДИНИЦЫ . items ()} АЛИАС = { k : ' % s% s ' % ( AREA_PREFIX , v ) для k , v в Distance . НИКНЕЙМЫ . items ()} LALIAS = { k . понизить (): V для к , V в АЛИАС . items ()} def __truediv__ ( self , other ): if isinstance ( other , NUMERIC_TYPES ): вернуть self . __class__ ( default_unit = self . _default_unit , ** { self . STANDARD_UNIT : ( self . standard / other )} ) else : raise TypeError ( ' % (class) s должен быть разделен на число' % {"class" : pretty_name ( self )})
# Ярлыки D = Расстояние A = Площадь

Copyright ©2020 All rights reserved