Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F62102602
positional_object.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, May 10, 22:24
Size
5 KB
Mime Type
text/x-python
Expires
Sun, May 12, 22:24 (2 d)
Engine
blob
Format
Raw Data
Handle
17603804
Attached To
rNIETZSCHEPYTHON nietzsche-python
positional_object.py
View Options
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" This class can be used to represent an object with positional information.
"""
# Copyright (C) University of Basel 2019 {{{1
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/> 1}}}
__author__
=
"Christian Steiner"
__maintainer__
=
__author__
__copyright__
=
'University of Basel'
__email__
=
"christian.steiner@unibas.ch"
__status__
=
"Development"
__license__
=
"GPL v3"
__version__
=
"0.0.1"
from
lxml
import
etree
as
ET
import
sys
from
.matrix
import
Matrix
from
.attachable_object
import
AttachableObject
sys
.
path
.
append
(
'py2ttl'
)
from
class_spec
import
SemanticClass
class
PositionalObject
(
AttachableObject
,
SemanticClass
):
"""
This (super) class represents an object with positional information.
Args:
id (int): object id
matrix (datatypes.Matrix): matrix containing information about conversion.
height (float): height of
width (float): width of object
x (float): x position of object
y (float): y position of object
"""
XML_TAG
=
'positional-object'
floatKeys
=
[
'height'
,
'width'
,
'left'
,
'top'
,
'bottom'
]
intKeys
=
[
]
stringKeys
=
[
]
def
__init__
(
self
,
node
=
None
,
id
=
0
,
height
=
0.0
,
width
=
0.0
,
x
=
0.0
,
y
=
0.0
,
matrix
=
None
,
tag
=
XML_TAG
):
self
.
floatKeys
=
[]
self
.
floatKeys
+=
PositionalObject
.
floatKeys
self
.
intKeys
=
[]
self
.
intKeys
+=
PositionalObject
.
intKeys
self
.
stringKeys
=
[
'id'
]
self
.
stringKeys
+=
PositionalObject
.
stringKeys
self
.
attachable_objects
=
[]
if
node
is
not
None
:
self
.
id
=
str
(
node
.
get
(
'id'
))
self
.
height
=
float
(
node
.
get
(
'height'
))
self
.
width
=
float
(
node
.
get
(
'width'
))
self
.
left
=
float
(
node
.
get
(
'left'
))
self
.
top
=
float
(
node
.
get
(
'top'
))
self
.
bottom
=
float
(
node
.
get
(
'bottom'
))
self
.
transform
=
Matrix
(
node
.
get
(
'transform'
))
if
bool
(
node
.
get
(
'transform'
))
and
'matrix('
in
node
.
get
(
'transform'
)
else
None
self
.
tag
=
node
.
tag
else
:
self
.
id
=
str
(
id
)
self
.
height
=
round
(
height
,
3
)
self
.
width
=
round
(
width
,
3
)
self
.
left
=
round
(
x
,
3
)
self
.
top
=
round
(
y
,
3
)
self
.
bottom
=
round
(
y
+
height
,
3
)
self
.
transform
=
matrix
self
.
tag
=
tag
def
attach_object_to_tree
(
self
,
target_tree
):
"""Attach object to tree.
"""
if
target_tree
.
__class__
.
__name__
==
'_ElementTree'
:
target_tree
=
target_tree
.
getroot
()
obj_node
=
target_tree
.
xpath
(
'.//'
+
self
.
tag
+
'[@id="
%s
"]'
%
self
.
id
)[
0
]
\
if
(
len
(
target_tree
.
xpath
(
'.//'
+
self
.
tag
+
'[@id="
%s
"]'
%
self
.
id
))
>
0
)
\
else
ET
.
SubElement
(
target_tree
,
self
.
tag
)
for
key
in
self
.
floatKeys
:
if
self
.
__dict__
[
key
]
is
not
None
:
obj_node
.
set
(
key
.
replace
(
'_'
,
'-'
),
str
(
round
(
self
.
__dict__
[
key
],
3
)))
for
key
in
self
.
intKeys
+
self
.
stringKeys
:
if
self
.
__dict__
[
key
]
is
not
None
:
obj_node
.
set
(
key
.
replace
(
'_'
,
'-'
),
str
(
self
.
__dict__
[
key
]))
if
self
.
transform
is
not
None
and
self
.
transform
.
isRotationMatrix
():
obj_node
.
set
(
'transform'
,
self
.
transform
.
toString
())
for
attachable_object
in
self
.
attachable_objects
:
attachable_object
.
attach_object_to_tree
(
obj_node
)
@classmethod
def
get_semantic_dictionary
(
cls
):
""" Creates a semantic dictionary as specified by SemanticClass.
"""
dictionary
=
{}
class_dict
=
cls
.
get_class_dictionary
()
properties
=
{}
for
intKey
in
cls
.
intKeys
:
properties
.
update
(
cls
.
create_semantic_property_dictionary
(
intKey
,
int
))
for
floatKey
in
cls
.
floatKeys
:
properties
.
update
(
cls
.
create_semantic_property_dictionary
(
floatKey
,
float
,
cardinality
=
1
))
for
stringKey
in
cls
.
stringKeys
:
properties
.
update
(
cls
.
create_semantic_property_dictionary
(
stringKey
,
str
,
cardinality
=
1
))
properties
.
update
(
cls
.
create_semantic_property_dictionary
(
'transform'
,
str
))
dictionary
.
update
({
'class'
:
class_dict
})
dictionary
.
update
({
'properties'
:
properties
})
return
dictionary
@staticmethod
def
POSITIONS_OVERLAP_HORIZONTALLY
(
position_a
,
position_b
):
"""Returns whether position a and b overlap horizontally.
"""
return
(
position_a
.
left
<
position_b
.
left
+
position_b
.
width
)
\
and
(
position_a
.
left
+
position_a
.
width
>
position_b
.
left
)
@staticmethod
def
POSITIONS_OVERLAP_VERTICALLY
(
position_a
,
position_b
):
"""Returns whether position a and b overlap vertically.
"""
return
(
position_a
.
top
<
position_b
.
bottom
)
\
and
(
position_a
.
bottom
>
position_b
.
top
)
@staticmethod
def
POSITIONS_ARE_STACKED
(
position_a
,
position_b
):
"""Returns whether position a and b are stacked, i.e. are above each other.
"""
return
PositionalObject
.
POSITIONS_OVERLAP_HORIZONTALLY
(
position_a
,
position_b
)
\
and
(
not
PositionalObject
.
POSITIONS_OVERLAP_VERTICALLY
(
position_a
,
position_b
)
\
or
abs
(
position_a
.
top
-
position_b
.
top
)
>
(
position_a
.
height
/
4
+
position_b
.
height
/
4
))
Event Timeline
Log In to Comment