| 
      
       | 
      | 
		 1.目次 
		2.目的 3.参考書 
		4.作り方 5.まとめ 
       | 
      | 
      
       | 
      | 
      
	   
	  W-Zero3では、位置データ(緯度、経度、郵便番号)を基地局から取得できます。この位置データを利用することにして、Google Map 
			のような地図や、天気図を表示したり、郵便番号から住所を取り出すなど、いろいろな応用ができます。 
	  ここでは、位置データ(緯度、経度、郵便番号)から、Amedas 
			の気温を取得するアプリケーションを作ります。そのための準備段階として、緯度、経度から、最近傍のアメダスの観測所のIDを返す XML 
			Web Serviceを作ります。 
	  http://uchukamen.com/amedas.asmx 
       | 
      | 
      
       | 
      
      
		  - 
		  C#研究室.Live 
		Space / W-ZERO3
 
		  - デジタル台風:アメダス統計
 
	   
       | 
      | 
      
       | 
	
      | 
        | 
    
      
      4.1 基本動作
       | 
	
      | 
       緯度、経度がわかれば、そこの気温を知ろうと思えば、いちばん近いアメダスの観測所のデータを取得すればよいことになります。これをW-Zero3 
		のアプリケーションで組めばよいわけです。ここで問題になってくるのが、アメダス観測所のデータをどのように持たせ、処理するかです。アメダスの観測所は2000か所以上あります。単純に1か所に、ID...4バイト、地名...100バイト、緯度...8バイト、経度...8バイトで、約128バイトとして、256KB程度になります。 
	  
		  
			  | 方法 | 
			  メリット | 
			  デメリット | 
		   
		  
			  | WZero3 側でEXCEL / SQL CEでデータをもつ | 
			  
			  
				  - 観測所データを取得するために通信の必要がない。(しかし、現在の天気情報を取得するには、通信が必要。)
 
			   
			   | 
			  
			  
				  - データを更新する場合、クライアントでデータを更新しなければならないので、数が多いと常に最新のデータにするための管理が大変。
 
				  - データ処理のためにW-Zero3側に処理負荷がかかる。
 
			   
			   | 
		   
		  
			  | XML Web Service でサーバー側でデータをもつ | 
			  
			  
				  - クライアント側でデータを持つ必要がない
 
				  - データの更新はサーバ側だけ
 
			   
			     | 
			  
			  
			   | 
		   
	   
	  ということで、ここではアメダスの観測所のデータをXML Web Service で取得することにします。 
		 | 
    
      
      4.2 Amedas観測所データの作成
       | 
	
      | 
       まずは、ローカルネットにSQLサーバーを用意して、そこでAmedas観測所データの作成を行います。 
	  全国のアメダス観測所は、2000以上あります。このデータはたとえば東京のように、降水量、風向、風速、気温、日照時間を知ることができます。ところが、このデジタル台風の横浜のデータを見ると、場所によっては、データが測定されていない場所があります。そこで、現在の緯度、経度から、温度を知るためには、観測所ID、観測所の名前、緯度、経度、温度を計測しているかどうか、最低5項目が必要になります。 
	  そこで、SQLサーバーに次のようなテーブルを作成します。 
	  
		  
			  
				  | キー | 
				  列名 | 
				  データ型 | 
				  長さ | 
			   
		  
		  
			  
			    | 
			  ID | 
			  int | 
			  4 | 
		   
		  
			  |   | 
			  地名 | 
			  nvarchar | 
			  50 | 
		   
		  
			  |   | 
			  緯度 | 
			  float | 
			  8 | 
		   
		  
			  |   | 
			  経度 | 
			  float | 
			  8 | 
		   
		  
			  |   | 
			  気温フラグ | 
			  tinyint | 
			  1 | 
		   
	   
	  あとは、次のように観測所のデータを入力します。気温計測フラグは1が気温を計測している、0は計測していないという意味です。下の例ですと、船泊は気温を計測していない観測所ということになります。 
	  
		  
			  
				  | ID | 
				  地名 | 
				  緯度 | 
				  経度 | 
				  気温フラグ | 
			   
		  
		  
			  | 11001 | 
			  宗谷岬 | 
			  45.52 | 
			  141.935 | 
			  1 | 
		   
		  
			  | 11011 | 
			  船泊 | 
			  45.437 | 
			  141.035 | 
			  0 | 
		   
		  
			  | 11012 | 
			  幌泊 | 
			  45.455 | 
			  141.038 | 
			  1 | 
		   
		  
			  | 11016 | 
			  稚内 | 
			  45.415 | 
			  141.678 | 
			  1 | 
		   
	   
		 | 
    
      
      4.3 緯度、経度から最近傍の観測所IDを返すストアドを作る
       | 
	
      | 
       ローカルのSQLサーバーに上記 Amedas 
		テーブルができたところで、緯度、経度から最近傍の観測所IDを返すストアドを作ります。緯度、経度から正確な距離を出すためには、地球の形状を考慮した三角関数での処理が必要ですが、ここでは距離が十分に近く、直線で近似できることを前提に 緯度の差の2乗+経度の差の2乗 が最小になる観測所、かつ気温フラグが1の観測所のIDを返します。 
	  CREATE PROCEDURE GetNearestAmedasCode
@緯度 float,
@経度 float AS
SELECT TOP 1 MIN (POWER((@緯度 - 緯度), 2) + POWER((@経度 - 経度),2 ) ) 
  AS DIST, ID, 緯度, 経度, 地名 
FROM amedas
WHERE 気温フラグ=1 
GROUP BY ID, 緯度, 経度, 地名 
ORDER BY DIST 
では、次のように、宗谷岬と船泊の座標で実行して確認します。 
EXEC GetNearestAmedasCode 45.52, 141.935
EXEC GetNearestAmedasCode 45.5437, 141.035 
	  結果は次のようになります。 
	  
		  
			  
				  | DIST | 
				  ID | 
				  緯度 | 
				  経度 | 
				  地名 | 
			   
		  
		  
			  | 0 | 
			  11001 | 
			  45.52 | 
			  141.935 | 
			  宗谷岬 | 
		   
	   
	  1 処理行数
		  
			  
				  | DIST | 
				  ID | 
				  緯度 | 
				  経度 | 
				  地名 | 
			   
		  
		  
			  | 7.8766900000006E-03 | 
			  11012 | 
			  45.455 | 
			  141.038 | 
			  幌泊 | 
		   
	   
	  1 処理行数2つ目のクエリは、船泊ではなく、幌泊が帰ってきます。 
		 | 
	
      
      4.4 緯度、経度から最近傍の観測所IDを返す XML Web Service を作る
       | 
	
      
      
		  - 
		  Visual Studioの新規サービスで、[新しいプロジェクト]→[Web]→[ASP.NET Web サービスアプリケーション]で、WebServiceAmedas 
		プロジェクトを作ります。
  
		    
		     
		  - Web.config の設定
 ローカルの SQL サーバーに接続に必要な接続文字列を Web.config に設定します。
			  
				  ... <configuration> <appSettings/> <connectionStrings> <add
				  name="uchukamen_comConnectionString1"
				  connectionString=".... 
				適切な接続文字列をセット..." /> ... </connectionStrings> .... | 
			   
		   
		    
		   
		  - Amedas.asmx の実装
  緯度、経度より、最も至近のAmedasの観測所IDを取得する次のメソッド 
		       public int GetNearestCode(float latitude, float longitude) 
		   を実装します。実装自体は、典型的なADO.NET接続型なので説明は不要と思います。  
			  
				  
				  using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Configuration;
using System.Data.SqlClient;
namespace WebServiceAmedas
{
    /// 
    /// WebServiceAmedas の概要の説明です
    /// 
    [WebService(Namespace = "http://uchukamen.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class Amedas : System.Web.Services.WebService
    {
        /// 
        /// 緯度、経度より、最も至近のAmedasの観測所IDを取得する。
        /// 
        /// 緯度
        /// 経度
        /// 
        [WebMethod]
        public int GetNearestCode(float latitude, float longitude)
        {
            string connectionString 
               = ConfigurationManager.ConnectionStrings
               ["uchukamen_comConnectionString1"].ConnectionString;
            using (SqlConnection sqlConn 
         = new SqlConnection(connectionString))
            using (SqlCommand sqlCmdStored 
         = new SqlCommand("GetNearestAmedasCode"))
            {
                sqlCmdStored.CommandType 
                   = CommandType.StoredProcedure;
                SqlParameter sqlLatitude 
          = new SqlParameter("@緯度", SqlDbType.Float);
                sqlLatitude.Value = latitude;
                sqlCmdStored.Parameters.Add(sqlLatitude);
                SqlParameter sqlLongitude 
          = new SqlParameter("@経度", SqlDbType.Float);
                sqlLongitude.Value = longitude;
                sqlCmdStored.Parameters.Add(sqlLongitude);
                sqlConn.Open();
                sqlCmdStored.Connection = sqlConn;
                using (SqlDataReader dr 
                   = sqlCmdStored.ExecuteReader())
                {
                    if (dr.Read())
                    {
                        return (int)dr["ID"];
                    }
                }
            }
            return 0;
        }
    }
}
				   | 
			   
		   
		     
		  - では、実装ができたところで実行してみます。すると、次のようにIEが立ち上がり、サービスの説明画面が表示されます。
 
		  
		    
		   Amedasのリンクをクリックすると、次のような IE 
			が開き、テストができます。値のところにたとえば、好きな場所の緯度、経度情報を入れて起動ボタンを押して、動作を確認してください。 
		   
		    
		   期待した結果が帰ってくればOKです。 
	   
		 | 
    
      
      4.5 ホスティングサーバーへの移行
       | 
	
      | 
       ここまでは、ローカルネットワーク内の作業なので、インターネットにこのサービスを配置する必要があります。以下は、ホスティングサーバーをお持ちということを前提の作業です。 
	  
		  - SQLサーバーのテーブルをデーターセンター側のSQL サーバーにコピーします。
 
		  - Web.config で、接続文字列をデーターセンター側のSQL サーバーにあわせて書き換えます。
 
		  - XML Web Service の発行
 [メインメニュー]→[ビルド]→[WebServiceAmedas の発行]で、ターゲットの場所を指定して、発行します。 
		  
		    
		   うまくいけば、次のようなメッセージが出力ウィンドウに表示されます。------ 
			ビルド開始: プロジェクト: WebServiceAmedas, 構成: Debug Any CPU ------ 
		  中略 
		  コンパイルの完了-- エラー0、警告0 
		  WebServiceAmedas -> C:\Users\uchukamen\Documents\Visual Studio 
			2005\Projects\WebServiceAmedas\WebServiceAmedas\bin\WebServiceAmedas.dll 
		  ------ 発行の開始: プロジェクト: WebServiceAmedas, 構成: Debug Any CPU 
			------ 
		  http://uchukamen.com/ に接続しています... 
		  フォルダ/ を発行しています... 
		  フォルダbin を発行しています... 
		  ========== ビルド: 1 正常終了または最新の状態、失敗、スキップ========== 
		  ========== 発行: 1 正常終了、失敗、スキップ==========  
	   
		
		  | 
	
      
      4.6 テスト用アプリケーションの作成
       | 
	
      | 
       簡単に動作を確認するアプリケーションを作っておくと便利かもしれません。 
	    
	  実装は極めて簡単で、次の通りです。 
	  
		  - 新しいプロジェクトで Windows.Forms を作成する。
 
		  - Web参照の追加で、http://uchukamen.com/amedas.asmx 
			を追加する。
 
		  - 上のようなコントロールを追加。
 
		  - ボタンを押したら、次のように XML Web Service を呼び出して、結果を表示する。
 
		  private 
		  void 
			button1_Click(object 
			sender, EventArgs 
			e) {     float 
			lat = float.Parse(textBoxLatitude.Text);     
		  float 
			lon = float.Parse(textBoxLongitude.Text);     com.uchukamen.Amedas 
			amedas = new 
			com.uchukamen.Amedas();     textBoxCode.Text = amedas.GetNearestCode(lat, lon).ToString(); } 
	   
	  クリックワンスで実行できるようにしておきました。 
	  
	  AmedasWebServiceTest 
		http://uchukamen.com/AmedasWebServiceTest/publish.htm 
		 | 
    
      | 
      
		 | 
      | 
       以上で、緯度、経度からアメダスの温度を取得することができるようになりました。次回は、ようやく 
		 
		 
	  W-Zero3からこのサービスを利用して、現在の位置、時間の気温を取得するアプリケーションを作成します。 
		 |