def make_leg(route, i, j, name=True, arrow=False, style_url=None): coord0 = route.tps[i].coord coord1 = route.tps[j].coord line_string = kml.LineString(coordinates=[coord0, coord1], altitudeMode='clampToGround', tessellate=1) multi_geometry = kml.MultiGeometry(line_string) if name: point = kml.Point(coordinates=[coord0.halfway_to(coord1)]) multi_geometry.add(point) distance = coord0.distance_to(coord1) name = kml.name('%.1fkm' % (distance / 1000.0)) if arrow: bearing = coord1.initial_bearing_to(coord0) coordinates = [ coord1.coord_at(bearing - pi / 12.0, 400.0), coord1, coord1.coord_at(bearing + pi / 12.0, 400.0) ] line_string = kml.LineString(coordinates=coordinates, altitudeMode='clampToGround', tessellate=1) multi_geometry.add(line_string) if style_url is None: style_url = globals.stock.xc_style.url() return kml.Placemark(name, multi_geometry, styleUrl=style_url)
def make_colored_track(self, globals, values, scale, altitude_mode, scale_chart=True, **folder_options): style_url = globals.stock.check_hide_children_style.url() folder = kml.Folder(name='Colored by %s' % scale.title, styleUrl=style_url, **folder_options) styles = [kml.Style(kml.LineStyle(color=color, width=self.width)) for color in scale.colors()] discrete_values = map(scale.discretize, values) for sl in util.runs(discrete_values): coordinates = self.track.coords[sl.start:sl.stop + 1] line_string = kml.LineString(coordinates=coordinates, altitudeMode=self.altitude_mode) style_url = kml.styleUrl(styles[discrete_values[sl.start]].url()) placemark = kml.Placemark(style_url, line_string) folder.add(placemark) if scale_chart: href = self.make_scale_chart(globals, scale).get_url() icon = kml.Icon(href=kml.CDATA(href)) overlay_xy = kml.overlayXY(x=0, xunits='fraction', y=1, yunits='fraction') screen_xy = kml.screenXY(x=0, xunits='fraction', y=1, yunits='fraction') size = kml.size(x=0, xunits='fraction', y=0, yunits='fraction') screen_overlay = kml.ScreenOverlay(icon, overlay_xy, screen_xy, size) folder.add(screen_overlay) return kmz.kmz(folder).add_roots(*styles)
def make_solid_track(self, globals, style, altitude_mode, extrude=None, **folder_options): line_string = kml.LineString(coordinates=self.track.coords, altitudeMode=altitude_mode) if extrude: line_string.add(extrude=1) placemark = kml.Placemark(style, line_string) style_url = globals.stock.check_hide_children_style.url() folder_options['styleUrl'] = style_url return kmz.kmz(kml.Folder(placemark, **folder_options))
def make_task_folder(globals, task): name = task.name or 'Task' rows = [] tp0 = None total = 0.0 count = -1 for sl in util.runs([tp.name for tp in task.tps]): if tp0 is None: tp0 = task.tps[sl.start] continue tp1 = task.tps[sl.stop - 1] distance = tp0.coord.distance_to(tp1.coord) th = '%s %s %s' % (tp0.name, RIGHTWARDS_ARROW, tp1.name) td = '%.1fkm' % (distance / 1000.0) rows.append((th, td)) total += distance count += 1 tp0 = tp1 rows.append(('Total', '%.1fkm' % (total / 1000.0))) table = make_table(rows) snippet = '%.1fkm via %d turnpoints' % (total / 1000.0, count) style_url = globals.stock.check_hide_children_style.url() folder = kml.Folder(name=name, description=kml.CDATA(table), Snippet=snippet, styleUrl=style_url) style_url = globals.stock.xc_style.url() done = set() for tp in task.tps: key = tp.name if key in done: continue else: done.add(key) point = kml.Point(coordinates=[tp.coord]) folder.add(kml.Placemark(point, name=tp.name, styleUrl=style_url)) done = set() for tp in task.tps: if tp.radius == 0: continue key = (tp.name, tp.radius) if key in done: continue else: done.add(key) coordinates = kml.coordinates.circle(tp.coord, tp.radius) line_string = kml.LineString(coordinates, tessellate=1) folder.add(kml.Placemark(line_string, styleUrl=style_url)) tp0 = None for sl in util.runs([tp.name for tp in task.tps]): if tp0 is None: tp0 = task.tps[sl.start] continue tp1 = task.tps[sl.stop - 1] coord0 = tp0.coord.coord_at(tp0.coord.initial_bearing_to(tp1.coord), tp0.radius) theta = tp1.coord.initial_bearing_to(tp0.coord) coord1 = tp1.coord.coord_at(theta, tp1.radius) line_string1 = kml.LineString(coordinates=[coord0, coord1], tessellate=1) coords = [ coord1.coord_at(theta - pi / 12.0, 400.0), coord1, coord1.coord_at(theta + pi / 12.0, 400.0) ] line_string2 = kml.LineString(coordinates=coords, tessellate=1) multi_geometry = kml.MultiGeometry(line_string1, line_string2) folder.add(kml.Placemark(multi_geometry, styleUrl=style_url)) tp0 = tp1 return kmz.kmz(folder)
def make_analysis_folder(self, globals, title, slices, style_url): if not self.track.elevation_data or len(slices) == 0: return kmz.kmz() folder_style_url = globals.stock.check_hide_children_style.url() folder = kml.Folder(name=title.capitalize() + "s", styleUrl=folder_style_url, visibility=0) for sl in slices: coord0 = self.track.coords[sl.start] coord1 = self.track.coords[sl.stop] coord = coord0.halfway_to(coord1) point = kml.Point(coordinates=[coord], altitudeMode='absolute') total_dz_positive = total_dz_negative = 0 peak_climb = util.Bounds(0.0) for i in xrange(sl.start, sl.stop): dz = self.track.coords[i + 1].ele - self.track.coords[i].ele dt = self.track.t[i + 1] - self.track.t[i] if dz > 0: total_dz_positive += dz elif dz < 0: total_dz_negative += dz peak_climb.update(float(dz) / dt) climb = util.Bounds(self.track.climb[sl]) dz = float(self.track.coords[sl.stop].ele - self.track.coords[sl.start].ele) dt = self.track.t[sl.stop] - self.track.t[sl.start] dp = coord0.distance_to(coord1) theta = coord0.initial_bearing_to(coord1) dict = {} dict['altitude_change'] = int(round(dz)) dict['average_climb'] = round(dz / dt, 1) dict['maximum_climb'] = round(climb.max, 1) dict['peak_climb'] = round(peak_climb.max, 1) divisor = dt * climb.max if divisor == 0: dict['efficiency'] = UP_TACK else: dict['efficiency'] = int(round(100.0 * dz / divisor)) dict['distance'] = round(dp / 1000.0, 1) average_ld = round(-dp / dz, 1) if dz < 0 else INFINITY dict['average_ld'] = average_ld dict['average_speed'] = round(3.6 * dp / dt, 1) dict['maximum_descent'] = round(climb.min, 1) dict['peak_descent'] = round(peak_climb.min, 1) dict['start_altitude'] = coord0.ele dict['finish_altitude'] = coord1.ele start_time = coord0.dt + globals.tz_offset dict['start_time'] = start_time.strftime('%H:%M:%S') stop_time = coord1.dt + globals.tz_offset dict['finish_time'] = stop_time.strftime('%H:%M:%S') duration = self.track.t[sl.stop] - self.track.t[sl.start] dict['duration'] = '%dm %02ds' % divmod(duration, 60) dict['accumulated_altitude_gain'] = total_dz_positive dict['accumulated_altitude_loss'] = total_dz_negative dict['drift_direction'] = rad_to_cardinal(theta + pi) extended_data = kml.ExtendedData.dict(dict) if title == 'thermal': name = '%dm at %.1fm/s' % (dz, dz / dt) elif title == 'glide': name = '%.1fkm at %s:1, %dkm/h' \ % (dp / 1000.0, average_ld, round(3.6 * dp / dt)) elif title == 'dive': name = '%dm at %.1fm/s' % (-dz, dz / dt) placemark = kml.Placemark(point, extended_data, name=name, Snippet=None, styleUrl=style_url) folder.add(placemark) line_string = kml.LineString(coordinates=[coord0, coord1], altitudeMode='absolute') placemark = kml.Placemark(line_string, styleUrl=style_url) folder.add(placemark) return kmz.kmz(folder)