[
http://golfadept.com]
This example is called TripKML. It reads pre-recorded GeoPt records and generates KML for Google Maps/Earth. The basic webapp is as normal:
class TripKML(webapp.RequestHandler):
def get(self):
try:
...
except DeadlineExceededError:
self.response.clear()
self.response.set_status(500)
self.message("This operation could not be completed in time...")
application = webapp.WSGIApplication([('/service/tripKML', TripKML)], debug = True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
First we parse the command line:
self.traveller = User.fromId(int(self.request.get('traveller')))
trip = self.request.get('trip')
As the code creates KML, tell the browser what do do with it:
self.response.headers['Content-Type'] = 'application/vnd.google-earth.kml+xml'
I have attached my lightweight class for generating XML. You give it the root XML tag name and attributes. Wrap everything in a folder for clarity in the tree. The last line is XML to be inserted (saved as )
rootElement = self.kml = xml('kml', xmlns = 'http://www.opengis.net/kml/2.2')
self.kml = rootElement.Folder
self.kml.name(trip)
self.kml.Style.IconStyle(id = 'noteStyle').Icon.href(iconUrl)
My style is to read the records and have factory code to call methods based on the record type. Because most records will be of one or two types, I have cached the parser method:
parsers = dict()
query = Record.gql(
'WHERE userId=:1 AND trip=:2 ORDER BY time', self.traveller.id, trip)
for self.record in query:
try:
parser = parsers[self.record.type]
except KeyError:
method = self.record.type + "RecordProcessor";
parser = getattr(self, method, self.defaultRecordProcessor)
parsers[self.record.type] = parser
parser()
A record type called "notes" generates a note indicated by an icon on the map:
def notesRecordProcessor(self):
self.kml.Placemark.name(self.record.title).styleUrl('noteStyle').\
description(self.record.notes).Point.coordinates(
"%f,%f" % (self.record.location.lon, self.record.location.lat))()
The “here” record processor does more work as it collects coordinates to make a line.
Back to the TripKml class, I also overlay kml generated by Picasa to display images:
albums = Album.forTrip(self.traveller.id, trip)
for album in albums:
try:
self.kml.NetworkLink.name(trip).Link.refreshMode('onInterval').\
refreshInterval(3600).hreflang(\
album.feedUri + '&alt=kml&kind=photo')
except Exception, e:
logging.warning('Can\'t access Picasa album for trip %s: %s' % (trip.name, e.message))
The last thing we need to do is generate the KML and send it to the browser:
self.response.out.write(str(self.kml))
I have attached TripKML.py as it is in use and xml.py for generating the XML.
--
Posted By Paul Marrington to
Adept Software Development at 11/16/2009 11:05:00 AM