October 11, 2008

GeoPt Property 用のカスタムウィジェット

こないだ Maps API hack-a-thon Tokyo に参加してきました。その時作ったのが Google App Engine の GeoPt Property をとても扱いやすくするためのユーティリティクラスです。

この記事では、そのクラスを使って geopoint データを datastore に保存するサンプルコードをお見せします。始めるまえに、こちらのdjangoforms に関する記事を読んでおくとコードがすぐ理解できるでしょう。

まずはこの記事用のディレクトリを作ります。そして拙作の my_geopt.py をその中にコピーし、さらに新しく3つのファイルを作ります。app.yaml, main.py と index.html です。

ファイルを作成したら、開発用サーバーを機動して localhost にアクセスします。すると Google Map をクリックするだけで特定の GeoPt が指定できる事がわかります。

また ライブデモもあります(少し複雑になってますが、基本は同じです)。

Happy coding :-)

app.yaml
application: geotest
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: main.py


main.py
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

import os
import wsgiref.handlers

from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.ext.db import djangoforms
import my_geopt

class Place(db.Model):
  name = db.StringProperty()
  description = db.StringProperty()
  geopoint = db.GeoPtProperty()
  date = db.DateTimeProperty(auto_now=True)

class PlaceForm(djangoforms.ModelForm):
  class Meta:
    model = Place

class MainPage(webapp.RequestHandler):
  def post(self):
    data = PlaceForm(data=self.request.POST)
    if data.is_valid():
      # Save the data, and redirect to the view page
      entity = data.save(commit=False)
      entity.put()
      self.redirect('/')
    else:
      # Reprint the form
      contents = {'form': data}
      path = os.path.join(os.path.dirname(__file__), 'index.html')
      self.response.out.write(template.render(path, contents))
  def get(self):
    contents = {'form': PlaceForm()}
    path = os.path.join(os.path.dirname(__file__), 'index.html')
    self.response.out.write(template.render(path, contents))

application = webapp.WSGIApplication(
  [('/', MainPage),],
  debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()


index.html (Please replace 2 YOURAPIKEYs with your Maps API Key)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>GeoPtWidgets Example</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=YOURAPIKEY"
type="text/javascript"></script>
<script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=YOURAPIKEY"
type="text/javascript"></script>
<script src="http://www.google.com/uds/solutions/localsearch/gmlocalsearch.js"
type="text/javascript"></script>
<style type="text/css">
@import url("http://www.google.com/uds/css/gsearch.css");
@import url("http://www.google.com/uds/solutions/localsearch/gmlocalsearch.css");
</style>
</head>

<body onunload="GUnload()">
<h1>GeoPtWidgets Example</h1>
<form method="post" action="/">
{{ form.as_p }}
<input type="submit" value="register"/>
</form>
</body> </html>

No comments: