連載:世界のWebサービス
第2回 Microsoft TerraService

3.TerraClientのコンパイル

田口景介
2001/03/01

 TerraClientのソースコードを以下に示す。

namespace TerraClient
{
    using System.Drawing.Imaging;
    using System.IO;

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.WinForms;
    using System.Data;


    public class Form1 : System.WinForms.Form
    {
        private System.ComponentModel.Container components;
        private System.WinForms.StatusBar statusBar;
        private System.WinForms.TextBox textLat;
        private System.WinForms.TextBox textLon;
        private System.WinForms.Label label2;
        private System.WinForms.Label label1;
        private System.WinForms.Button button1;
        private System.WinForms.PictureBox pictureBox1;

        public Form1()
        {
            InitializeComponent();
        }

        public override void Dispose()
        {
            base.Dispose();
            components.Dispose();
        }

        private void InitializeComponent()
        {
            this.components
                = new System.ComponentModel.Container ();
            this.textLat = new System.WinForms.TextBox ();
            this.label2 = new System.WinForms.Label ();
            this.label1 = new System.WinForms.Label ();
            this.pictureBox1 = new System.WinForms.PictureBox ();
            this.button1 = new System.WinForms.Button ();
            this.textLon = new System.WinForms.TextBox ();
            this.statusBar = new System.WinForms.StatusBar ();
            //@this.TrayHeight = 0;
            //@this.TrayLargeIcon = false;
            //@this.TrayAutoArrange = true;
            textLat.Location = new System.Drawing.Point (136, 352);
            textLat.Text = "37.8";
            textLat.TabIndex = 5;
            textLat.Size = new System.Drawing.Size (100, 19);
            label2.Location = new System.Drawing.Point (16, 352);
            label2.Text = "緯度";
            label2.Size = new System.Drawing.Size (100, 23);
            label2.TabIndex = 3;
            label1.Location = new System.Drawing.Point (16, 320);
            label1.Text = "経度";
            label1.Size = new System.Drawing.Size (100, 23);
            label1.TabIndex = 2;
            pictureBox1.Location = new System.Drawing.Point (16, 8);
            pictureBox1.Size = new System.Drawing.Size (500, 300);
            pictureBox1.TabIndex = 0;
            pictureBox1.TabStop = false;
            button1.Location = new System.Drawing.Point (416, 320);
            button1.Size = new System.Drawing.Size (96, 23);
            button1.TabIndex = 1;
            button1.Text = "実行";
            button1.Click
                += new System.EventHandler (this.button1_Click);
            textLon.Location = new System.Drawing.Point (136, 320);
            textLon.Text = "-122.4";
            textLon.TabIndex = 4;
            textLon.Size = new System.Drawing.Size (100, 19);
            statusBar.BackColor
                = System.Drawing.SystemColors.Control;
            statusBar.SizingGrip = false;
            statusBar.Location = new System.Drawing.Point (0, 377);
            statusBar.Size = new System.Drawing.Size (528, 20);
            statusBar.TabIndex = 6;
            statusBar.Text = "座標を入力してください";
            this.Text = "TerraService";
            this.AutoScaleBaseSize
                = new System.Drawing.Size (5, 12);
            this.ClientSize = new System.Drawing.Size (528, 397);
            this.Controls.Add (this.statusBar);
            this.Controls.Add (this.textLat);
            this.Controls.Add (this.textLon);
            this.Controls.Add (this.label2);
            this.Controls.Add (this.label1);
            this.Controls.Add (this.button1);
            this.Controls.Add (this.pictureBox1);
        }

        // 「実行」ボタンのクリックイベントハンドラ
        protected void button1_Click
                        (object sender, System.EventArgs e)
        {
            LonLatPt center = new LonLatPt();
            Theme theme     = new Theme();
            Scale scale     = new Scale();
            Int32 mapWidth;
            Int32 mapHeight;

            button1.Text = "読み込み中";
            statusBar.Text = "読み込み中";

            try
            {
                // テキストボックスに入力された座標を取得する
                center.Lon = textLon.Text.ToDouble();
                center.Lat = textLat.Text.ToDouble();
            }
            catch
            {
                // 数値以外が入力されると例外が発生
                statusBar.Text = "座標は実数で入力してください";
                button1.Text = "実行";
                return;
            }

            // 画像の種類を指定する
            // Theme.Photo  航空写真
            // Theme.Topo   絵地図
            // Theme.Relief レリーフ

            theme = Theme.Photo;
            // 縮尺を指定する。ここでは32m/ドットに固定
            // WinForms.Scaleクラスとの競合を避けるため、
            // パッケージ名を含めて指定する

            scale = TerraClient.Scale.Scale32m;

            // ピクチャボックスのサイズで地図を取得する
            mapWidth = pictureBox1.Size.Width;
            mapHeight = pictureBox1.Size.Height;

            TerraService ts;
            AreaBoundingBox abb;
            try
            {
                // Webサービスオブジェクトを作成し、タイルを取得する
                ts = new TerraService();
                abb = ts.GetAreaFromPt
                        (center, theme, scale, mapWidth, mapHeight);
            }
            catch
            {
                statusBar.Text = "その座標に画像はありません";
                button1.Text = "実行";
                return;
            }

            // 地図画像を読み込み、ピクチャボックスに設定する
            // Imageオブジェクトを作成する

            PixelFormat pf = PixelFormat.Format32bppRGB;
            Image compositeImage
                = new Bitmap(mapWidth, mapHeight, pf);
            Graphics compositeGraphics
                = Graphics.FromImage(compositeImage);

            // 取得したタイルを元にサーバから地図画像を読み込み、
            // Imageオブジェクトに描画する

            Int32 xStart = abb.NorthWest.TileMeta.ID.X;
            Int32 yStart = abb.NorthWest.TileMeta.ID.Y;
            for (Int32 x = xStart;
                    x <= abb.NorthEast.TileMeta.ID.X; x++) {
                for (Int32 y = yStart;
                        y >= abb.SouthWest.TileMeta.ID.Y; y--) {
                    TileId tid = abb.NorthWest.TileMeta.ID;

                    tid.X = x;
                    tid.Y = y;

                    Image tileImage
                        = Image.FromStream
                            (new MemoryStream(ts.GetTile(tid)));
                    compositeGraphics.DrawImage(tileImage,
                        (x - xStart) * tileImage.Width
                            - (Int32) abb.NorthWest.Offset.XOffset,
                        (yStart - y) * tileImage.Height
                            - (Int32) abb.NorthWest.Offset.YOffset,
                        tileImage.Width, tileImage.Height);
                    tileImage.Dispose();
                }
            }

            // 地図画像を描画したImageオブジェクトを
            // ピクチャボックスに設定する

            pictureBox1.Image = compositeImage;

            statusBar.Text = "画像が表示されました";
            button1.Text = "実行";
        }

        public static void Main(string[] args)
        {
            Application.Run(new Form1());
        }
    }
}

 ソースコードをコンパイルする前に、WebServiceUtilを使用して、プログラムからWebサービスを呼び出すためのプロキシ・クラスを生成する必要がある(このプロキシ・クラスは、Webサービスの呼び出し時に必要なパラメータなどをSOAPのメッセージにしてサーバに送信し、返ってきたXMLのメッセージを取得してアプリケーションに渡す。プロキシ・クラスの詳細については、別稿の「.NET Framework入門」を参照)。具体的にはまず、次のコマンドを実行し、TerraService.csを作成する。このコマンドを実行すると、WebサービスをホストしているWWWサーバへアクセスするので、インターネットへ接続可能な状態にしておく必要がある。

WebServiceUtil /c:proxy /out:TerraService.cs /n:TerraClient
/pa:http://terraserver.microsoft.net/TerraService.asmx?SDL

 次に、以下のコマンドを実行して、プログラムをコンパイルする。正常にコンパイルが終了すれば、カレント・ディレクトリにTerraClient.exeが生成される。

csc /t:winexe /out:TerraClient.exe /r:System.XML.Serialization.dll
/r:System.Web.Services.dll;System.Drawing.dll /r:System.WinForms.dll
/r:Microsoft.Win32.Interop.dll /r:System.dll /r:System.Data.dll
TerraService.cs TerraClient.cs

 今回はごく単純に航空画像を表示するためだけにTerraServiceを利用したが、本来Webサービスはそれ単体で完結するものではなく、アプリケーションのビルディング・ブロックとして生かすためのものだ。安価に広く利用できるTerraServiceのような地図サービスがあれば、乗り換え案内、ロード・ナビゲーション、観光案内、不動産案内など、さまざまなサービスを築くきっかけになるはずだ。こうしたインフラとなるサービスの充実に期待したい。End of Article

関連記事(Insider.NET内)
特集
.NET Framework入門
関連リンク
Microsoft TerraServiceのページ
SPIN-2のホームページ
 
 

 INDEX
  [連載]世界のWebサービス―― 究極のWebサービスを求めて ――
  第2回 Microsoft TerraService
    1.世界地図データベースTerraServer
    2.TerraClientのしくみ
  3.TerraClientのコンパイル

「世界のWebサービス」

 



Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間