File: apr.py

package info (click to toggle)
thuban 1.2.2-14
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 9,176 kB
  • sloc: python: 30,410; ansic: 6,181; xml: 4,234; cpp: 1,595; makefile: 145
file content (225 lines) | stat: -rw-r--r-- 8,072 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# Copyright (C) 2003-2005 by Intevation GmbH
# Authors:
# Jan-Oliver Wagner <jan@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with Thuban for details.

"""
Classes for ArcView Objects as in '.apr'-files.

The classes are only added to this module if they
are considered to be complete and whenever possible
accompanied by unit tests (see tests/).
Experimental classes should remain in importAPR.py.
"""

__version__ = "$Revision: 2629 $"

from math import ceil

from Thuban.Model.color import Color, Transparent, Black
from Thuban.Model.range import Range
from Thuban.Model.classification import ClassGroupProperties

from odb import ODBBaseObject

class APR_BLnSym(ODBBaseObject):
    """Line symbol object.
    Always references a color object TClr via 'Color'.

    The stroke width 'Width' is always given, but the scale is
    unclear so far (e.g. which width is actually meant with value '0.1'?).
    Meanwhile, the ceiling of 'Width' is applied to be stroke width
    in pixels.

    Finally, there seems always to be a 'Pattern'-List consisting of
    float values. No idea so far, how to interpret this (Thuban does
    not support pattern yet anyway).
    """
    _obj_refs = [ 'Color' ]
    _values = [ 'Width', 'Pattern' ]

    def GetThubanProp(self):
        """Create a Thuban ClassGroupProperty from this object and
        return it.
        """
        prop = ClassGroupProperties()
        prop.SetLineColor(self.Get('Color').GetThubanColor())
        prop.SetLineWidth(int(ceil(float(self.Get('Width')))))
        return prop

class APR_BMkSym(ODBBaseObject):
    """Point symbol object.
    Always references a Color and a Background Color via 'Color', 'BgColor'.
    For Thuban, Color is interpreted as line color and BGColor is
    interpreted as fill color.

    Next, there is always a 'Font' reference. Probably this defines
    the font for the label. This is not interpreted for Thuban.

    There is always a Size element. It is not clear how 'size'
    defined in ArcView.

    There is always a Angle element, but I don't know how this is
    defined. I only sighted the value of 360 so far.


    Finally, there seems always to be a 'Pattern'-List consisting of
    float values. No idea so far, how to interpret this (Thuban does
    not support pattern yet anyway).
    """

    _obj_refs = [ 'Color', 'BgColor', 'Font' ]
    _values = [ 'Angle', 'Size', 'Pattern' ]

    def GetThubanProp(self):
        """Create a Thuban ClassGroupProperty from this object and
        return it.

        In Thuban, the points have all the same size,
        but we can vary the width of the line.
        """
        prop = ClassGroupProperties()
        prop.SetSize(int(ceil(float(self.Get('Size')))))
        prop.SetLineColor(self.Get('Color').GetThubanColor())
        prop.SetFill(self.Get('BgColor').GetThubanColor())
        return prop

class APR_BShSym(ODBBaseObject):
    """Polygon symbol object, either filled with a single color or
    with a pattern.
    .
    Always references TClr objects via 'Color', 'OutlineColor' and 'BgColor'.
    Always has attributes 'OutlineWidth' and 'Outline'.

    OutlineColor is interpreted to be the Thuban line color, OutlineWidth
    as the Thuban line width.
    'Color' is interpreted to be the Thuban fill color.
    'BgColor' is not interpreted and probably has something to do with
    patterns (Stripple).
    'Stripple' ist not interpreted in Thuban. It is a pattern definition
    based on a bitpattern. Thuban has no Patterns yet.

    It is unclear what 'Outline' defines and thus is not used for Tuban.
    """
    _obj_refs = [ 'Color', 'OutlineColor', 'BgColor', 'Stripple' ]
    _values = [ 'OutlineWidth', 'Outline' ]

    def GetThubanProp(self):
        """Create a Thuban ClassGroupProperty from this object and
        return it.
        """
        prop = ClassGroupProperties()
        prop.SetLineWidth(int(ceil(float(self.Get('OutlineWidth')))))
        prop.SetLineColor(self.Get('OutlineColor').GetThubanColor())
        prop.SetFill(self.Get('Color').GetThubanColor())
        return prop

class APR_LClass(ODBBaseObject):
    """This object describes the range and label of a class
    within a legend.

    'IsText' determines whether 'MinStr'/'MaxStr' are given, else
    'MinNum'/'MaxNum' should be there.
    So far, only String-Ranges with identical 'MinStr'/'MaxStr' have
    been sighted.

    'MinNum' may not be there. In this case assume it to be -oo.

    There are objects with 'IsNoData' set to 1. Not yet sure how to
    treat them.

    However, objects have been sighted that only have 'IsText' and
    'Precision': We assume an empty label and a full range.

    No referenced objects.
    """
    _obj_refs = [ ]
    _values = [ 'IsText', 'MinStr', 'MaxStr', 'MinNum', 'MaxNum', 'Label',
                'Precision', 'IsNoData' ]

    def GetThubanRange(self):
        """Return a Thuban range that corresponds to this object.

        The returned object is a
        - Range-Object in case of a numerical range.
        - String-Object in case of a text range (assuming that
          text objects occur only with 'MinStr' == 'MaxStr'.
        """
        if hasattr(self, 'IsText'):
            if hasattr(self, 'MinStr'):
                return self.MinStr
            else:
                return ''

        # build range
        if hasattr(self, 'MinNum'):
            range_str = ']' + self.MinNum + ';'
        else:
            range_str = ']-oo;'
        if hasattr(self, 'MaxNum'):
            range_str = range_str + self.MaxNum + ']'
        else:
            range_str = None

        if hasattr(self, 'MinNum') and hasattr(self, 'MaxNum'):
            if self.MinNum == self.MaxNum:
                range_str = '[' + self.MinNum + ';' + self.MaxNum + ']'
        return Range(range_str)

    def GetLabel(self):
        """Return the label string.
        Return an  empty string if there is no 'Label'.
        """
        if hasattr(self, 'Label'):
            return self.Label
        else:
            return ''


class APR_TClr(ODBBaseObject):
    """Color object. Appears in 3 styles:
    1. no attributes: (so far assumed as black)
    2. only 'Name': a string that describes the color.
       Seen only "Transparent".
    3. 'Red', 'Green', 'Blue': RGB code. Each value in '0xffff' style.
       3.1 Only one or two of the colors are defined. It is assumed
           that in this case the rest is equal to 0x0000
       3.2 Some hex-codes are incomplete (eg. 0xff). It is assumed
           that the missing digits are "0".

    No referenced objects.
    """
    _obj_refs = [ ]
    _values = [ 'Name', 'Red', 'Green', 'Blue' ]

    def GetThubanColor(self):
        """Return a Thuban Color object; returns None if a problem
        occurred.
        """
        if hasattr(self, 'Red') or hasattr(self, 'Green') or \
            hasattr(self, 'Blue'):
            rgb = { 'Red': 0, 'Green': 0, 'Blue': 0 } # default for missing
                                                      # parts: 0x0000

            for color in [ 'Red', 'Green', 'Blue' ]:
                if hasattr(self, color):
                    s = getattr(self, color)
                    # It seems that ArcView sometimes uses only
                    # 2 bytes for a color definition, eg. 0xff.
                    # It is assumed that this is the same as
                    # 0x00ff (and not the same as 0xff00). At
                    # least color comparison shows this.
                    # Thus we do not need to append "00" if length
                    # of s is < 6. The following conversion does is
                    # right even for the short strings.
                    rgb[color] = int(s, 16)/float(int('0xffff', 16))
            return Color(rgb['Red'], rgb['Green'], rgb['Blue'])
        elif hasattr(self, 'Name'):
            if self.Name == 'Transparent':
                return Transparent
            else:
                return None
        else:
            return Black