Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fastkml
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Aurélien Vermylen
fastkml
Commits
a2b94a48
Commit
a2b94a48
authored
Jun 22, 2012
by
Christian Ledermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add geometry processing
parent
c9ef8d55
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
295 additions
and
17 deletions
+295
-17
fastkml/kml.py
fastkml/kml.py
+202
-9
fastkml/tests.py
fastkml/tests.py
+92
-8
setup.py
setup.py
+1
-0
No files found.
fastkml/kml.py
View file @
a2b94a48
# -*- coding: utf-8 -*-
from
shapely.geometry
import
Point
,
LineString
,
Polygon
from
shapely.geometry
import
MultiPoint
,
MultiLineString
,
MultiPolygon
from
shapely.geometry.polygon
import
LinearRing
import
logging
logger
=
logging
.
getLogger
(
'fastkml'
)
try
:
from
lxml
import
etree
LXML
=
True
except
ImportError
:
import
xml.etree.ElementTree
as
etree
LXML
=
False
class
KML
(
object
):
""" represents a KML File """
...
...
@@ -19,7 +29,9 @@ class KML(object):
self
.
from_string
(
f
.
read
())
f
.
close
()
def
from_string
(
self
,
xml_string
):
""" create a KML object from a xml string"""
element
=
etree
.
XML
(
xml_string
)
if
element
.
tag
.
endswith
(
'kml'
):
ns
=
element
.
tag
.
rstrip
(
'kml'
)
...
...
@@ -68,20 +80,36 @@ class _Feature(object):
subclasses are:
Container (Document, Folder),
Placemark,
NetworkLink,
GroundOverlay,
PhotoOverlay,
ScreenOverlay
#
NetworkLink,
#
GroundOverlay,
#
PhotoOverlay,
#
ScreenOverlay
"""
id
=
None
name
=
None
#User-defined text displayed in the 3D viewer as the label for the
#object (for example, for a Placemark, Folder, or NetworkLink).
description
=
None
#User-supplied content that appears in the description balloon.
visibility
=
1
#Boolean value. Specifies whether the feature is drawn in the 3D
#viewer when it is initially loaded. In order for a feature to be
#visible, the <visibility> tag of all its ancestors must also be
#set to 1.
isopen
=
0
#Boolean value. Specifies whether a Document or Folder appears
#closed or open when first loaded into the Places panel.
#0=collapsed (the default), 1=expanded.
styleUrl
=
None
#URL of a <Style> or <StyleMap> defined in a Document.
#If the style is in the same file, use a # reference.
#If the style is defined in an external file, use a full URL
#along with # referencing.
#atom_author = None
#atom_link = None
#styleUrl = None
def
__init__
(
self
,
ns
,
id
=
None
,
name
=
None
,
description
=
None
):
...
...
@@ -155,7 +183,6 @@ class _Container(_Feature):
def
etree_element
(
self
):
element
=
super
(
_Container
,
self
).
etree_element
()
for
feature
in
self
.
features
():
assert
(
feature
!=
self
)
element
.
append
(
feature
.
etree_element
())
return
element
...
...
@@ -192,7 +219,7 @@ class Document(_Container):
class
Folder
(
_Container
):
"""
A Folder is used to arrange other Features hierarchically
(Folders, Placemarks,
NetworkLinks, or
Overlays).
(Folders, Placemarks,
#NetworkLinks, or #
Overlays).
"""
__name__
=
"Folder"
...
...
@@ -210,9 +237,175 @@ class Folder(_Container):
self
.
append
(
feature
)
class
Placemark
(
_Feature
):
__name__
=
"Placemark"
styleUrl
=
None
geometry
=
None
pass
def
_get_coordinates
(
self
,
element
):
coordinates
=
element
.
find
(
'%scoordinates'
%
self
.
ns
)
if
coordinates
is
not
None
:
latlons
=
coordinates
.
text
.
strip
().
split
()
coords
=
[]
for
latlon
in
latlons
:
coords
.
append
([
float
(
c
)
for
c
in
latlon
.
split
(
','
)])
return
coords
def
_get_linear_ring
(
self
,
element
):
# LinearRing
lr
=
element
.
find
(
'%sLinearRing'
%
self
.
ns
)
if
lr
is
not
None
:
coords
=
self
.
_get_coordinates
(
lr
)
return
LinearRing
(
coords
)
def
_get_geometry
(
self
,
element
):
# Point, LineString,
# Polygon,
point
=
element
.
find
(
'%sPoint'
%
self
.
ns
)
if
point
is
not
None
:
coords
=
self
.
_get_coordinates
(
point
)
return
Point
(
coords
[
0
])
line
=
element
.
find
(
'%sLineString'
%
self
.
ns
)
if
line
is
not
None
:
coords
=
self
.
_get_coordinates
(
line
)
return
LineString
(
coords
)
polygon
=
element
.
find
(
'%sPolygon'
%
self
.
ns
)
if
polygon
is
not
None
:
outer_boundary
=
polygon
.
find
(
'%souterBoundaryIs'
%
self
.
ns
)
ob
=
self
.
_get_linear_ring
(
outer_boundary
)
inner_boundaries
=
polygon
.
findall
(
'%sinnerBoundaryIs'
%
self
.
ns
)
ibs
=
[]
for
inner_boundary
in
inner_boundaries
:
ibs
.
append
(
self
.
_get_linear_ring
(
inner_boundary
))
return
Polygon
(
ob
,
ibs
)
return
self
.
_get_linear_ring
(
element
)
def
_get_multigeometry
(
self
,
element
):
# MultiGeometry
multigeometry
=
element
.
find
(
'%sMultiGeometry'
%
self
.
ns
)
geoms
=
[]
if
multigeometry
is
not
None
:
points
=
multigeometry
.
findall
(
'%sPoint'
%
self
.
ns
)
if
points
:
for
point
in
points
:
geoms
.
append
(
Point
(
self
.
_get_coordinates
(
point
)))
return
MultiPoint
(
geoms
)
linestrings
=
multigeometry
.
findall
(
'%sLineString'
%
self
.
ns
)
if
linestrings
:
for
ls
in
linestrings
:
geoms
.
append
(
LineString
(
self
.
_get_coordinates
(
ls
)))
return
MultiLineString
(
geoms
)
polygons
=
multigeometry
.
findall
(
'%sPolygon'
%
self
.
ns
)
if
polygons
:
for
polygon
in
polygons
:
outer_boundary
=
polygon
.
find
(
'%souterBoundaryIs'
%
self
.
ns
)
ob
=
self
.
_get_linear_ring
(
outer_boundary
)
inner_boundaries
=
polygon
.
findall
(
'%sinnerBoundaryIs'
%
self
.
ns
)
ibs
=
[]
for
inner_boundary
in
inner_boundaries
:
ibs
.
append
(
self
.
_get_linear_ring
(
inner_boundary
))
geoms
.
append
(
Polygon
(
ob
,
ibs
))
return
MultiPolygon
(
geoms
)
def
from_element
(
self
,
element
):
super
(
Placemark
,
self
).
from_element
(
element
)
mgeom
=
self
.
_get_multigeometry
(
element
)
geom
=
self
.
_get_geometry
(
element
)
if
mgeom
is
not
None
:
self
.
geometry
=
mgeom
elif
geom
is
not
None
:
self
.
geometry
=
geom
else
:
logger
.
warn
(
'No geometries found'
)
def
_etree_coordinates
(
self
,
coordinates
):
element
=
etree
.
Element
(
"coordinates"
)
if
len
(
coordinates
[
0
])
==
2
:
tuples
=
(
'%f,%f,0.0'
%
tuple
(
c
)
for
c
in
coordinates
)
elif
len
(
coordinates
[
0
])
==
3
:
tuples
=
(
'%f,%f,%f'
%
tuple
(
c
)
for
c
in
coordinates
)
else
:
raise
ValueError
(
"Invalid dimensions"
)
element
.
text
=
' '
.
join
(
tuples
)
return
element
def
_etree_point
(
self
,
point
):
element
=
etree
.
Element
(
"Point"
)
coords
=
list
(
point
.
coords
)
element
.
append
(
self
.
_etree_coordinates
(
coords
))
return
element
def
_etree_linestring
(
self
,
linestring
):
element
=
etree
.
Element
(
"LineString"
)
coords
=
list
(
linestring
.
coords
)
element
.
append
(
self
.
_etree_coordinates
(
coords
))
return
element
def
_etree_linearring
(
self
,
linearring
):
element
=
etree
.
Element
(
"LinearRing"
)
coords
=
list
(
linearring
.
coords
)
element
.
append
(
self
.
_etree_coordinates
(
coords
))
return
element
def
_etree_polygon
(
self
,
polygon
):
element
=
etree
.
Element
(
"Polygon"
)
outer_boundary
=
etree
.
SubElement
(
element
,
"outerBoundaryIs"
)
outer_boundary
.
append
(
self
.
_etree_linearring
(
polygon
.
exterior
))
for
ib
in
polygon
.
interiors
:
inner_boundary
=
etree
.
SubElement
(
element
,
"innerBoundaryIs"
)
inner_boundary
.
append
(
self
.
_etree_linearring
(
ib
))
return
element
def
_etree_multipoint
(
self
,
points
):
element
=
etree
.
Element
(
"MultiGeometry"
)
for
point
in
points
.
geoms
:
element
.
append
(
self
.
_etree_point
(
point
))
return
element
def
_etree_multilinestring
(
self
,
linestrings
):
element
=
etree
.
Element
(
"MultiGeometry"
)
for
linestring
in
linestrings
.
geoms
:
element
.
append
(
self
.
_etree_linestring
(
linestring
))
return
element
def
_etree_multipolygon
(
self
,
polygons
):
element
=
etree
.
Element
(
"MultiGeometry"
)
for
polygon
in
polygons
.
geoms
:
element
.
append
(
self
.
_etree_polygon
(
polygon
))
return
element
def
_etree_geometry
(
self
):
if
isinstance
(
self
.
geometry
,
Point
):
return
self
.
_etree_point
(
self
.
geometry
)
elif
isinstance
(
self
.
geometry
,
LineString
):
return
self
.
_etree_linestring
(
self
.
geometry
)
elif
isinstance
(
self
.
geometry
,
LinearRing
):
return
self
.
_etree_linearring
(
self
.
geometry
)
elif
isinstance
(
self
.
geometry
,
Polygon
):
return
self
.
_etree_polygon
(
self
.
geometry
)
elif
isinstance
(
self
.
geometry
,
MultiPoint
):
return
self
.
_etree_multipoint
(
self
.
geometry
)
elif
isinstance
(
self
.
geometry
,
MultiLineString
):
return
self
.
_etree_multilinestring
(
self
.
geometry
)
elif
isinstance
(
self
.
geometry
,
MultiPolygon
):
return
self
.
_etree_multipolygon
(
self
.
geometry
)
def
etree_element
(
self
):
element
=
super
(
Placemark
,
self
).
etree_element
()
if
self
.
geometry
is
not
None
:
element
.
append
(
self
.
_etree_geometry
())
else
:
logger
.
warn
(
'Object does not have a geometry'
)
return
element
fastkml/tests.py
View file @
a2b94a48
This diff is collapsed.
Click to expand it.
setup.py
View file @
a2b94a48
...
...
@@ -19,6 +19,7 @@ Create and read KML Files""",
zip_safe
=
False
,
install_requires
=
[
# -*- Extra requirements: -*-
'shapely'
,
],
entry_points
=
"""
# -*- Entry points: -*-
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment