geography : some minor tweaks for kml and prepare for feature request 08428

This commit is contained in:
SNoiraud 2015-03-17 19:35:58 +01:00
parent fdc42a9693
commit bb30862c1b

View File

@ -54,6 +54,7 @@ from gi.repository import Pango, PangoCairo
# Gramps Modules # Gramps Modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from .libkml import Kml
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -72,15 +73,14 @@ class KmlLayer(GObject.GObject, osmgpsmap.MapLayer):
* Allowed : points, paths and polygons. * Allowed : points, paths and polygons.
* One point : name, (latitude, longitude) * One point : name, (latitude, longitude)
* One path : name, [ (latitude, longitude), (latitude, longitude), ...] * One path : name, type, color, transparency, [ (latitude, longitude), (latitude, longitude), ...]
* One polygon : name, fill, [ (latitude, longitude), (latitude, longitude), ...] * One polygon : name, type, color, transparency, [ (latitude, longitude), (latitude, longitude), ...]
""" """
def __init__(self): def __init__(self):
""" """
Initialize the layer Initialize the layer
""" """
GObject.GObject.__init__(self) GObject.GObject.__init__(self)
self.dots = []
self.paths = [] self.paths = []
self.polygons = [] self.polygons = []
self.tag = "" self.tag = ""
@ -92,158 +92,86 @@ class KmlLayer(GObject.GObject, osmgpsmap.MapLayer):
""" """
reset the layer attributes. reset the layer attributes.
""" """
self.dots = []
self.paths = [] self.paths = []
self.polygons = [] self.polygons = []
self.name = "" self.name = ""
def polygon(self, attributes):
self.points = []
for subAttribute in attributes:
if subAttribute.tag == self.tag + 'outerBoundaryIs':
for subsubAttribute in subAttribute:
if subsubAttribute.tag == self.tag + 'LinearRing':
for subsubsubAttribute in subsubAttribute:
if subsubsubAttribute.tag == self.tag + 'coordinates':
for point in subsubsubAttribute.text.split():
try:
(longitude, latitude, altitude) = point.split(',')
except:
(longitude, latitude) = point.split(',')
self.points.append((float(latitude), float(longitude)))
if subAttribute.tag == self.tag + 'innerBoundaryIs':
for subsubAttribute in subAttribute:
if subsubAttribute.tag == self.tag + 'LinearRing':
for subsubsubAttribute in subsubAttribute:
if subsubsubAttribute.tag == self.tag + 'coordinates':
for point in subsubsubAttribute.text.split():
try:
(longitude, latitude, altitude) = point.split(',')
except:
(longitude, latitude) = point.split(',')
self.points.append((float(latitude), float(longitude)))
if subAttribute.tag == self.tag + 'LinearRing':
for subsubAttribute in subAttribute:
if subsubAttribute.tag == self.tag + 'coordinates':
for point in subsubAttribute.text.split():
try:
(longitude, latitude, altitude) = point.split(',')
except:
(longitude, latitude) = point.split(',')
self.points.append((float(latitude), float(longitude)))
def add_kml(self, kml_file): def add_kml(self, kml_file):
""" """
Add a kml file. Add a kml file.
The access right and validity must be verified before this method. The access right and validity must be verified before this method.
""" """
tree = ETree.parse(kml_file) self.kml = Kml(kml_file)
root = tree.getroot() (paths, polygons) = self.kml.add_kml()
self.tag = root.tag.replace('}kml','}') if paths != []:
_LOG.debug("Tag version of kml file %s is %s" % (kml_file, self.tag)) self.paths.append(paths)
fname, extension = os.path.splitext(kml_file) if polygons != []:
fdir, kmlfile = os.path.split(fname) self.polygons.append(polygons)
self.index = -1
lineStrings = tree.findall('.//' + self.tag + 'Placemark')
for attributes in lineStrings:
for subAttribute in attributes:
if subAttribute.tag == self.tag + 'name':
self.name = subAttribute.text
if subAttribute.tag == self.tag + 'Polygon':
self.type = 'Polygon'
self.points = []
self.polygon(subAttribute)
if self.name == "":
self.polygons.append((kmlfile, self.points))
else:
self.polygons.append((self.name, self.points))
if subAttribute.tag == self.tag + 'Point':
self.type = 'Point'
self.points = []
for subsubAttribute in subAttribute:
if subsubAttribute.tag == self.tag + 'coordinates':
for point in subsubAttribute.text.split():
try:
(longitude, latitude, altitude) = point.split(',')
except:
(longitude, latitude) = point.split(',')
self.points.append((float(latitude), float(longitude)))
if self.name == "":
self.dots.append((kmlfile, self.points))
else:
self.dots.append((self.name, self.points))
if subAttribute.tag == self.tag + 'LineString':
self.type = 'Path'
self.points = []
for subsubAttribute in subAttribute:
if subsubAttribute.tag == self.tag + 'coordinates':
for point in subsubAttribute.text.split():
try:
(longitude, latitude, altitude) = point.split(',')
except:
(longitude, latitude) = point.split(',')
self.points.append((float(latitude), float(longitude)))
if self.name == "":
self.paths.append((kmlfile, self.points))
else:
self.paths.append((self.name, self.points))
def do_draw(self, gpsmap, ctx): def do_draw(self, gpsmap, ctx):
""" """
Draw all the messages Draw all the surfaces and paths
""" """
color1 = Gdk.color_parse('red') color1 = Gdk.color_parse('red')
color2 = Gdk.color_parse('blue') color2 = Gdk.color_parse('blue')
# We don't display self.dots. use markers. for polygons in self.polygons:
for polygon in self.polygons: for polygon in polygons:
(name, points) = polygon (name, ptype, color, transparency, points) = polygon
map_points = [] map_points = []
for point in points: for point in points:
conv_pt = osmgpsmap.MapPoint.new_degrees(point[0], point[1]) conv_pt = osmgpsmap.MapPoint.new_degrees(point[0], point[1])
coord_x, coord_y = gpsmap.convert_geographic_to_screen(conv_pt) coord_x, coord_y = gpsmap.convert_geographic_to_screen(conv_pt)
map_points.append((coord_x, coord_y)) map_points.append((coord_x, coord_y))
first = True first = True
ctx.save() ctx.save()
ctx.set_source_rgba(float(color2.red / 65535.0), ctx.set_source_rgba(float(color2.red / 65535.0),
float(color2.green / 65535.0), float(color2.green / 65535.0),
float(color2.blue / 65535.0), float(color2.blue / 65535.0),
0.3) # transparency 0.3) # transparency
ctx.set_line_cap(cairo.LINE_CAP_ROUND) ctx.set_line_cap(cairo.LINE_CAP_ROUND)
ctx.set_line_join(cairo.LINE_JOIN_ROUND) ctx.set_line_join(cairo.LINE_JOIN_ROUND)
ctx.set_line_width(3) ctx.set_line_width(3)
ctx.new_path() ctx.new_path()
for idx_pt in range(0, len(map_points)): for idx_pt in range(0, len(map_points)):
if first: if first:
first = False first = False
ctx.move_to(map_points[idx_pt][0], map_points[idx_pt][1]) ctx.move_to(map_points[idx_pt][0], map_points[idx_pt][1])
else: else:
ctx.line_to(map_points[idx_pt][0], map_points[idx_pt][1]) ctx.line_to(map_points[idx_pt][0], map_points[idx_pt][1])
ctx.close_path() ctx.close_path()
ctx.fill() if ptype == "Polygon":
ctx.restore() ctx.stroke()
for path in self.paths: if ptype == "OuterPolygon":
(name, points) = path ctx.fill()
map_points = [] if ptype == "InnerPolygon":
for point in points: ctx.set_source_rgba(1.0, 1.0, 1.0, 0.3)
conv_pt = osmgpsmap.MapPoint.new_degrees(point[0], point[1]) ctx.set_operator(cairo.OPERATOR_ADD)
coord_x, coord_y = gpsmap.convert_geographic_to_screen(conv_pt) ctx.fill()
map_points.append((coord_x, coord_y)) ctx.restore()
first = True for paths in self.paths:
ctx.save() for path in paths:
ctx.set_source_rgba(float(color1.red / 65535.0), (name, ptype, color, transparency, points) = path
float(color1.green / 65535.0), map_points = []
float(color1.blue / 65535.0), for point in points:
0.5) # transparency conv_pt = osmgpsmap.MapPoint.new_degrees(point[0], point[1])
ctx.set_line_width(5) coord_x, coord_y = gpsmap.convert_geographic_to_screen(conv_pt)
ctx.set_operator(cairo.OPERATOR_ATOP) map_points.append((coord_x, coord_y))
for idx_pt in range(0, len(map_points)): first = True
if first: ctx.save()
first = False ctx.set_source_rgba(float(color1.red / 65535.0),
ctx.move_to(map_points[idx_pt][0], map_points[idx_pt][1]) float(color1.green / 65535.0),
else: float(color1.blue / 65535.0),
ctx.line_to(map_points[idx_pt][0], map_points[idx_pt][1]) 0.5) # transparency
ctx.stroke() ctx.set_line_width(5)
ctx.restore() ctx.set_operator(cairo.OPERATOR_ATOP)
for idx_pt in range(0, len(map_points)):
if first:
first = False
ctx.move_to(map_points[idx_pt][0], map_points[idx_pt][1])
else:
ctx.line_to(map_points[idx_pt][0], map_points[idx_pt][1])
ctx.stroke()
ctx.restore()
def do_render(self, gpsmap): def do_render(self, gpsmap):
""" """