y-matsui::weblog

電子楽器、音楽、コンピュータ、プログラミング、雑感。面倒くさいオヤジの独り言

緯度経度から住所を応答するWebサービス

”緯度経度を引数に、近傍を検索する機能”のため、街区レベル位置参照情報のデータベースをpostgreSQL上に構築し、幾何データ検索によって、指定範囲のポイントを検索できるところまで来た。
今回は次の段階として、これをWebサービスとして利用できるようにした。
初めてのASP.NETWebサービス開発だ。心なしかドキドキする。
ドキドキして始めたはいいが、
「なーんだ、コーディングする側からすれば単なるクラスじゃん」ってこと。
開発環境(VisualWebDeveloper2008Express)やフレームワークが隠ぺいしてくれているおかげ。
100行足らずのソースコードで、緯度経度から近傍検索Webサービスができた。

次はWindows Mobile GPSクライアントからWebサービスを参照して、XMLをパース→ドロップダウンリストやデータグリッドに表示する部分だー。いよいよ佳境ですな。

■getAddress.asmx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;
using Npgsql; //postgreSQLへネイティブ接続するライブラリ

namespace gis
{
///


/// gisUtils の概要の説明です
///

[WebService(Namespace = "http://maps.dbcenter.ne.jp/gisUtils/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// この Web サービスを、スクリプトから ASP.NET AJAX を使用して呼び出せるようにするには、次の行のコメントを解除します。
[System.Web.Script.Services.ScriptService]
public class gisUtils : System.Web.Services.WebService
{

[WebMethod(Description="緯度経度(百分率表記)と半径(メートル)を引数にして、街区レベル位置参照情報の住所(平成18年度)を応答します。現在は愛知県のみのサービスです。")]
public string getAddress(string lat,string lon,double level)
{
string ConnectionString = "Server=[サーバアドレスをここに書く];Port=5432;Database=[データベース名をここに書く];Encoding=UNICODE;User Id=[ユーザ名];Password=[パスワード];";
string s="";
string q = ""; //query
string w = ""; //where
string o = ""; //order
double r = 0; //半径
int limit = 100; //返却する最大件数
int i = 0;


//デフォルトの位置
if *1
{
lat = "35.********";
}
if *2
{
lon = "136.********";
}

//
//1m=0.0000092秒と近似して半径を計算する(厳密には緯度経度によって1秒のメートル数=22メートル〜28メートルと誤差がある)
if(level>0)
{
r=level*0.0000092;
}


//接続を開く
NpgsqlConnection conn = new NpgsqlConnection(ConnectionString);
try
{
conn.Open();
}
catch (Exception ex)
{
s += ex.Message + "\r\n";
return s;
}

//検索条件
w = " circle(p_latlon,0) @ circle(point(" + lat + "," + lon + ")," + r.ToString() + ")";
o = " ORDER BY p_latlon <-> point(" + lat + "," + lon + ")";
q = "SELECT * from tbl_address where" + w + o;

NpgsqlDataAdapter da;
DataTable dt;
da = new NpgsqlDataAdapter(q, conn);
dt = new DataTable();
da.Fill(dt);
s += "\n";
if (dt.Rows.Count > 0)
{
// s += "" + lat +"," + lon +"," +level+"\n";
// s+= "" + dt.Rows.Count.ToString() + "\n";
foreach (DataRow row in dt.Rows)
{
s+= "\t

\n";
s += "\t\t"+ row["c_prefname"].ToString() + "\n";
s += "\t\t" + row["c_cityname"].ToString() + "\n";
s += "\t\t" + row["c_townname"].ToString() + "\n";
s += "\t\t"+ row["c_streetname"].ToString() + "\n";
s += "\t\t" + row["n_lat"].ToString()+"," +row["n_lon"].ToString() + "\n";
s += "\t
\n";
i+=1;
if (i > limit)
{
s += "件数が" + i + "を超えました。";
break; //foreachループを抜ける
}
}
}
s+="\n";

//閉じる
conn.Close();

return s;
}
}
}



※ポイントは、postgresに接続するためのネイティブドライバnpgsql.dllの利用
→参考サイト:
npgsql.dllダウンロード
NpgsqlでPostgreSQLに接続する

*1:lat==null)||(lat==""

*2:lon==null)||(lon==""