メッシュ標高データを使って地図を作成します。
データは XML で、ある緯度経度のエリアを、縦横5mごとの格子に分割した標高データが格納されています。
南北と東西がいくつの格子からなっているかは、low要素と high要素から判別します。
サンプルでは、南北が 0から149まで、東西が0から224 までなので 225列×150行の合計33750個の格子が存在ます。
どの格子が標高何メートルなのかは、tupleList要素を見ます。 各格子の標高が改行区切りで格納さています。順番は、最初が1行目の1列目で、2、3列目とつづき、225列目までいったら、226個目が2行目の1列目です。
1つのXMLファイルで、東西が5m×225=1125mのエリアの地図が描けることになります。
各格子の標高が0mから50mなら色の濃淡をつけて、50m以上なら黒、マイナスなら水色にしています。
5mメッシュ標高データは、国土地理院の基盤地図情報のダウンロードページから入手できます。 (http://fgd.gsi.go.jp/download/)
ログイン後、基盤地図情報 数値標高モデル JPGIS (GML)形式
→ 5mメッシュ → 沖縄 → 3927 → 392715
を選択して、沖縄県糸満市周辺のデータをダウンロードします。
サンプルでは、ダウンロードした FG-GML-3927-15-DEM5B.zipを 解凍してできたファイル「FG-GML-3927-15-02-DEM5B-20110915.xml」を読み込んでいます。
Google Map でみた同じ場所
MainWindow.xaml
<Window x:Class="GisTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="380" Width="480">
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="OpenCommandHandler"/>
</Window.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Command="Open" />
</Menu>
<Canvas Grid.Row="1" Name="canvas1" Margin="3">
<Canvas.Resources>
<Style TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="0" />
<Setter Property="Width" Value="2" />
<Setter Property="Height" Value="2" />
</Style>
</Canvas.Resources>
</Canvas>
</Grid>
</Window>
MainWindow.xaml.cs
using Microsoft.Win32;
using System;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Xml;
namespace GisTest
{
public partial class MainWindow :
Window
{
public MainWindow()
{
InitializeComponent();
}
private void OpenCommandHandler(
object sender,
ExecutedRoutedEventArgs e)
{
OpenFileDialog ofd =
new OpenFileDialog();
if (ofd.ShowDialog() ==
true)
{
XmlDocument xdoc =
new XmlDocument();
xdoc.Load(ofd.FileName);
XmlNamespaceManager xnm =
new XmlNamespaceManager(xdoc.NameTable);
xnm.AddNamespace(
"gml",
"http://www.opengis.net/gml/3.2");
XmlElement dataXe = (
XmlElement)xdoc.SelectSingleNode(
"//gml:tupleList", xnm);
XmlElement lowXe = (
XmlElement)xdoc.SelectSingleNode(
"//gml:low", xnm);
XmlElement highXe = (
XmlElement)xdoc.SelectSingleNode(
"//gml:high", xnm);
string[] lowPoint = lowXe.InnerText.Split(
' ');
string[] highPoint = highXe.InnerText.Split(
' ');
int xSize =
int.Parse(highPoint[0]) -
int.Parse(lowPoint[0]) + 1;
int ySize =
int.Parse(highPoint[1]) -
int.Parse(lowPoint[1]) + 1;
string data = dataXe.InnerText;
DrawMap(xSize, ySize, data);
}
}
private void DrawMap(
int xSize,
int ySize,
string data)
{
float[,] heights =
new float[xSize, ySize];
Regex regex =
new Regex(
"[^,\\r\\n]+,[^,\\r\\n]+");
MatchCollection mc = regex.Matches(data);
int index = 0;
foreach (
Match m
in mc)
{
string[] unit = m.Value.Split(
',');
heights[index % xSize, index / xSize] =
float.Parse(unit[1]);
index++;
}
this.canvas1.Children.Clear();
for (
int x = 0; x < xSize; x++)
{
for (
int y = 0; y < ySize; y++)
{
Rectangle r =
new Rectangle();
r.SetValue(
Canvas.LeftProperty, (
double)x * 2);
r.SetValue(
Canvas.TopProperty, (
double)y * 2);
double height =
Math.Floor(heights[x, y] * 5);
Color fillColor;
if (height <= 0)
{
fillColor =
Colors.AliceBlue;
}
else if (height > 255)
{
fillColor =
Colors.Black;
}
else
{
byte colorValue =
byte.Parse((255 - height).ToString());
fillColor =
Color.FromRgb(colorValue, colorValue, colorValue);
}
r.Fill =
new SolidColorBrush(fillColor);
this.canvas1.Children.Add(r);
}
}
}
}
}