地図を複数ページで印刷したい

機能別サンプル「065 SplitPrint」を使って地図の分割印刷の方法を示します。

SplitPrint01.gif

 

地図の分割印刷は、印刷縮尺を指定した場合にのみ実行されます。縮尺の設定方法は次の 3 通りあります。

印刷縮尺 内容
現在の縮尺 現在表示している地図の中心が、印刷する紙の中心になるように、今表示している地図の縮尺で印刷します。
1ページに収まる縮尺 現在表示している地図の範囲が、印刷する紙に収まるように、地図の縮尺を計算して印刷します。 
縮尺を指定 現在表示している地図の範囲が、指定した縮尺になるように印刷します。
もし、1 枚の紙に入りきらない場合は、複数枚で印刷します。

「印刷」ボタンを押すと「印刷プレビュー」が表示されます。3 つの縮尺の設定方法で印刷プレビューを表示した場合の例を次に示します。 

SplitPrint02.gif SplitPrint03.gif SplitPrint04.gif
「現在の縮尺」で印刷 「1ページに収まる縮尺」で印刷 「縮尺を指定」で印刷

 ※縮尺を指定した場合は、複数の紙の全体の中心が地図の中心になるように配置されます。

「印刷プレビュー」ダイアログのツールバーの「プリンタ」を押すと、実際に印刷されます。印刷するプリンタの設定などは .NET Framework の API リファレンスをご参照ください。
※サンプルプログラム中では設定しておりません。デフォルトで指定されているプリンタが利用されます。

 

分割印刷の仕組み

この節では分割印刷の仕組みを説明します。

前節の使用方法では、縮尺の指定方法が 3 つあると述べましたが、印刷の仕組みは全て同じで、基本は分割印刷にあります。分割印刷さえできれば、紙が 1 枚の場合であっても、分割印刷にならないだけで同じ処理で実装可能です。

次図は分割印刷の模式図です。赤い線が地図の表示範囲で、青い線が紙の印刷領域です。この例は地図の縮尺が 1/300 としています。この地図の縮尺では、指定した地図の表示範囲がA4 の紙 1 枚におさまりません。
そのため、6 枚で印刷しています。複数枚で印刷するときは左上隅から右上隅に向かいページが進み、右上になると次段に進みます。
尚、地図の表示範囲が紙の印刷領域の中央になるように配置しています。

SplitPrint05.gif

 

サンプルコードの説明

サンプルコードは 3 つのクラスからなります。

クラス名 内容
MainForm GUI GUIを実装します。印刷縮尺などを指定します。
PrintUtility 分割印刷を実行します。GUI からはこのクラスのメソッドを呼び出します。 
PrintListener 分割印刷が実行されたとき、各ページに地図を描画する機能を実装しています。 

.NET Framework において、印刷の処理は、System.Drawing.Printing.PrintDocument クラスの PrintPage イベントのイベントハンドラを実装することで行います。
PrintListener クラスはこのイベントハンドラを実装しています。イベントハンドラの設定は、PrintListener クラスのコンストラクタで行い、解除は Dispose メソッドで行っています。そのため、PrintListener クラスを使う側(PrintUtility)では、using 句を用いています。PrintPage イベントのイベントハンドラを解除(「-=」を記述すること)を呼び出さないと、Graphics 関連の不具合が発生するので、ご注意ください。

 

サンプルコードの処理の流れ

「印刷」ボタンを押したときの処理を簡単に述べると、「必要な紙の枚数だけ、MapComponent で地図の位置を移動して印刷する」ことになります。
この様子を次図に示します。1枚目、2枚目と印刷が進むにつれて、地図の位置を移動させます。

SplitPrint06.gif

「印刷」ボタンを押したときの処理の流れは詳述すると次のようになります。ここでは、縮尺を指定した場合を説明します。

  1. 現在描画している地図の表示範囲(地図座標)を取得します。ここでは、MapComponent.GetDisplayManager() メソッドを用いて取得します。
  2. 印刷したい縮尺と地図の表示範囲などを引数に PrintUtility.Print メソッドを呼び出します。
    1. Print メソッドでは、地図の表示範囲の単位を m に統一します。
    2. プリンタの余白を除いた印刷領域を mm 単位で取得します。
    3. 地図の表示範囲を指定された縮尺で、1.2 で求めた紙を使った場合、何枚紙があれば(何ページ必要になるか)計算します。
      このとき、横方向(nXNum枚)、縦方向(nYNum枚)の紙の枚数も求めます。
    4. PrintListener のコンストラクタを呼び出します。
      1. PrintDocument のイベントハンドラを追加します。
      2. 1 枚の紙は縮尺に換算すると地図座標で何 m 表すことができるか計算します。
      3. nXNum、nYNum 枚の紙は縮尺に換算すると地図座標で何 m 表すことができるか計算します。
      4. nXNum,nYNum あるうちの1,1 (最初)の左上隅の地図座標を計算します。
    5. 印刷プレビューを表示します。
      1. 現在印刷しているページの地図の中央の座標を計算します。
        (この座標を得るために、まず、現在印刷しているページの左上の座標を取得し、中心の座標に計算しなおしています)
      2. 地図の位置を移動します。
      3. 地図を印刷します。
      4. ページ数を計算し、次ページが存在するかを判定します。
    6. Dispose メソッドを呼び出し、イベントハンドラの登録を解除します。
      (PrintUtility クラスで using 句を使用していることで、自動的に呼び出されます)

縮尺が「現在の縮尺」の場合は、「印刷」ボタンを押されたときの地図の縮尺を MapComponent より取得します。
縮尺が「1ページに収まる縮尺」で指定された場合は、PrintUtility.Print メソッドで、その縮尺を計算します。

この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています

解決できない場合はこちら お問い合わせ