スポンサーサイト

-------- --:--:-- --

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【Python】pythonで地理情報を検索する【geomodel】【GoogleAppEngine】

2011-08-08 23:59:39 Mon

GoogleAppEngine/Python で指定の緯度経度(latitude, longitude)内にあるデータを検索する方法の一つにgeomodelを利用する方法がある。
※普通に緯度経度の範囲検索で検索できるとは思います。
それの「境界ボックス クエリ」を試してみたのでメモ。
GeoModel
GeoModelPythonLibrary
参考URL

Webアプリの動き


・ルートにアクセス→index.html
・緯度と経度を入力してsendボタンを押下
・/postにPOSTされるのでこれをDatastoreに保存
・/postをGETするとクエリを投げて検索

ちゃんとクライアントへレスポンスするようなイイモノになっていません…
すみません。。。
なので、デバッグしたりしてデータがちゃんと取得できているか確認して下さいませ。

ソース



index.html


<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
  function init() {
    // 現在位置を取得
    navigator.geolocation.getCurrentPosition(function(position) {
        var coords = position.coords;
        document.getElementById('latitude').value = coords.latitude;
        document.getElementById('longitude').value = coords.longitude;
        console.log('緯度 : ' + coords.latitude);
        console.log('経度 : ' + coords.longitude);
        // 取得した現在位置で、Google Mapsの緯度経度情報を生成
        var latlng = new google.maps.LatLng(coords.latitude, coords.longitude);
        var myOptions = {
          zoom: 14,
          center: latlng,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        // マップを生成
        var map = new google.maps.Map(document.getElementById("map"), myOptions);
        // 地図にマーカーをつける
        var marker = new google.maps.Marker({
            position: latlng,
            map: map
        });
        var infowindow = new google.maps.InfoWindow({
          content: "イマココ!"
        });
        infowindow.open(map, marker);
    });
  }
</script>
</head>
<body onload="init()">
<div id="root" style="position:relative;">
<div id="map" style="width:400px; height:400px;float:left;"></div>
<div style="float:left;">
<form action="./post" method="POST">
<label>緯度:<input type="text" id="latitude" name="latitude" value=""></input></label>
<label>経度:<input type="text" id="longitude" name="longitude" value=""></input></label>
<input type="submit" value="send"></input>
</form>
</div>
</div>
</body>
</html>


Models.py

'''
Created on 2011/08/08

@author: hoge
'''
from google.appengine.ext import db
from geo.geomodel import GeoModel

class GeoModelTest(GeoModel):
date = db.DateTimeProperty(auto_now_add=True)


def __init__(selfparams):
'''
Constructor
'''


control.py


# -*- coding: utf-8 -*-
from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from jp.co.hoge.db.model.Models import GeoModelTest
import os.path
from geo.geotypes import Box

class MainPage(webapp.RequestHandler):


def get(self):
template_values = {}
path = os.path.join(os.path.dirname('../../../../../template/'), './index.html')
self.response.out.write(template.render(path, template_values))

class PostGeo(webapp.RequestHandler):
def post(self):
latitude = float(self.request.get("latitude"))
longitude = float(self.request.get("longitude"))
geopoint = db.GeoPt( latitude , longitude )

model = GeoModelTest(location=geopoint)
model.update_location()
model.put()

path = os.path.join(os.path.dirname('../../../../../template/'), './index.html')
self.response.out.write(template.render(path, None))

def get(self):
# north: A float indicating the box's North latitude.
# east: A float indicating the box's East longitude.
# south: A float indicating the box's South latitude.
# west: A float indicating the box's West longitude.
box = Box(north=float('45'), east=float('150'), south=float('19'), west=float('124'))
results = GeoModelTest.bounding_box_fetch(
GeoModelTest.all(), # 検索対象クエリ
box, # 検索範囲
max_results=1000) # 最大取得件数
print results

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


def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()



app.yaml


application: sample-app
version: 1
runtime: python
api_version: 1

handlers:
- url: /*
script: jp/co/hoge/webapp/control/control.py

- url: /post
script: jp/co/hoge/webapp/control/control.py



WS000166.jpg

ポイント



■データモデルクラス


・geo.geomodel.GeoModelをインポートする
・データモデルクラスはgeo.geomodel.GeoModelを継承する(GeoModelはdb.Modelを継承している)


from google.appengine.ext import db
from geo.geomodel import GeoModel

class GeoModelTest(GeoModel):
date = db.DateTimeProperty(auto_now_add=True)




■データ登録処理


・db.GeoPt(float,float)を生成する
・GeoPtオブジェクトをlocationプロパティに代入する
・update_location()を実行し、location_geocellsを更新する


from geo.geotypes import Box



class PostGeo(webapp.RequestHandler):
def post(self):
latitude = float(self.request.get("latitude"))
longitude = float(self.request.get("longitude"))
geopoint = db.GeoPt( latitude , longitude )

model = GeoModelTest(location=geopoint)
model.update_location()
model.put()

path = os.path.join(os.path.dirname('../../../../../template/'), './index.html')
self.response.out.write(template.render(path, None))





■データ検索処理


・geo.geotypes.Boxをインポートする
・geo.geotypes.Boxを生成する。コンストラクタ引数は下記のnorth,east,south,westの値
・それぞれ緯度(横線)経度(縦線)の値で北と南が緯度の値、東と西が経度の値を入れてBoxのなのように四角で囲む→これが検索範囲


def get(self):
# north: A float indicating the box's North latitude.
# east: A float indicating the box's East longitude.
# south: A float indicating the box's South latitude.
# west: A float indicating the box's West longitude.
box = Box(north=float('45'), east=float('150'), south=float('19'), west=float('124'))
results = GeoModelTest.bounding_box_fetch(
GeoModelTest.all(), # 検索対象クエリ。とりあえず全部。
box, # 検索範囲
max_results=1000) # 最大取得件数。たぶん1000が限界。
print results




こんな感じで四角く囲った範囲内のデータをフィルタすることができる。
スポンサーサイト

⇒comment

Secret

名言集
全記事(数)表示
全タイトルを表示
ブログ内検索
Loading
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。