WPFアプリケーションで地図を描く

最近、生産の必要性が生じました-ロシアの地図を地域の詳細とともにフォームに表示する。 この場合、次のものが必要です。







品質要件は、ベクターグラフィックスを使用して簡単に達成できます。 そして、WPFを使用するというアイデアを得ましたが、それはExpression Blendで絵を描いて、WPFコントロールのセットを取得することです。 残り-「インタラクティブ」を追加するには-技術の問題。

したがって、最初に行う必要があるのは、画像自体を取得することでした。 私たちの国は広く、もちろん美しいですが、私たち自身で多くの要素を描きたいという願望はありませんでした。 これは必須ではありませんでした-ウィキメディアでロシアの地図の素晴らしい例が見つかりました:

ウィキメディアカード

これはまさにあなたが必要とするものです! 1つのポイントはSVGファイルです。 何らかの形でXAMLに変換する必要がありました。 検索の結果、 XamlTuneキットに出会いました。 このキットには、svg2xamlという名前のコンソールユーティリティがあります。 彼女は仕事をうまくこなし、すぐに私たちの国を表す多くのネストされたパス要素を持つキャンバスを手に入れました。 結果のXAMLは次のとおりです。

< Canvas x:Key ="svg2" Width ="1091.9919" Height ="630.11902" ClipToBounds ="True" >

< Canvas Name ="State_Outline" >

< Path Stroke ="#FF000000" StrokeMiterLimit ="4" Name ="polygon81" >

< Path.Data >

< PathGeometry FillRule ="Nonzero" Figures ="M715.671,134.212L715.368,133.002 717.637,134.061 718.771,132.926 720.359,131.338 722.704,128.994 724.141,130.733 724.897,130.733 726.787,128.843 728.527,126.801 731.854,125.289 734.274,127.104 732.913,130.885 732.913,133.002 731.325,134.59 728.829,135.725 726.107,136.784 723.385,136.784 721.343,138.826 718.091,137.691 716.427,135.271 715.671,134.212z" />

</ Path.Data >

</ Path >

<!-- ... -->

</ Canvas >

<!-- ... -->

</ Canvas >







明らかに、州と主題の境界線を描くために、キャンバスのいくつかのコピーが使用されます。

ものは小さい-画面にカードを表示するために残っています。 すべてが非常にシンプルであるように思えます-キャンバスをフォームに置いて楽しんでください。 それだけです。非常に堅実な寸法に気づくのはあなただけです:幅= "1091.99"高さ= "630.119"。 スケーリングする方法は? たとえば、フォームのサイズを変更するときにキャンバスをグリッドに置き換えると、マップのすべての部分が「離れて」しまいます。 これを回避するには、Viewboxコントロールを使用します。 次のようにフォームに配置します。

< Viewbox Child ="{StaticResource svg2}" Stretch ="Uniform" />







ここで、キー「svg2」を使用してリソースにマップを含むキャンバスを配置したことに注意してください。 ViewBoxコンテナの現在の寸法に対する比率を維持しながら、キャンバスが圧縮されます。 同時に、キャンバス内の絶対座標は有効なままであり、マップのレイアウトは「移動」しません。 スタイルでは、マウスクリックハンドラーを次のように設定できます。

< Style TargetType ="{x:Type Path}" >

< EventSetter Event ="MouseDown" Handler ="mouseDownHandler" />

</ Style >






T.O. すべてのPath要素にクリックハンドラーが設定されます。 まあ、など-スタイルでは、トリガーを定義し、プロパティを設定し、それによって必要な外観と動作を保証できます。さらなるアクションはタスクと想像力に依存します。 たとえば、マウスを置いたときに領域の境界を強調表示したり、イベントが発生したときに背景を強調表示したりできます。

インタラクティブな地図、つまり そのため、次のような個々の部分で作業できます。 ユーザー入力を受け入れます。 これが不要な場合は、マップでキャンバスをVisualBrushとして使用できます。 これは、たとえば次のように実行できます。

< Window x:Class ="WpfApplication46.Window1" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" Title ="Window1" Height ="300" Width ="300" >

< Window.Resources >

< Canvas x:Key ="svg2" Width ="1091.99" Height ="630.119" >

<!-- ... ... -->

</ Canvas >

</ Window.Resources >

< Grid >

< Border Margin ="20" >

< Border.Background >

< VisualBrush Stretch ="Uniform" Visual ="{StaticResource svg2}" />

</ Border.Background >

</ Border >

</ Grid >

</ Window >






キャンバスの元の縦横比をマップとともに保持するために、ブラシのStretchプロパティにUniform値が設定されました。 もちろん、VisualBrushを使用する場合は、速度が向上します。CPUリソースとRAMが少なくて済みます。 これを確認するために、Visual Studio 2010スイートのプロファイラーからのデータ(グラフの青い線はCPU負荷です):

1) VisualBrushのオプション (マネージメモリの割り当て〜11.36Mb):

画像

2) ViewBoxを使用したオプション (マネージメモリの割り当て〜14.83Mb):

画像

したがって、ユーザー入力処理が不要な場合は、VisualBrushアプローチが適しています。



そのため、地理マップを操作する問題を解決するのは非常に簡単で迅速です。 このような状況で、WPFテクノロジーの全機能を理解し始めるのです。 最も簡単なタスクではなく、インタラクティブで「ゴム」(つまり、サイズ変更に耐性のある)カードを取得することは、ユーティリティを使用してスタイルを「ねじ込む」ことになりました。 私の意見では、非常に示唆的です。



ソースコード例



All Articles