GIS奮闘記

現役GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

ArcMap で横書きの漢字のアノテーションを縦書きにする方法

本日はArcMapの小ネタについて書いてみようと思います。「横書きの漢字を縦書きにしたい!」でも、「やり方がわからない」「そもそもそんなことできるのか?」と思われている方もいらっしゃるかと思います。今回はそのやり方について書いてみようと思います。

環境

ArcMap10.6.1

サンプルデータ

このような横書きの漢字を用意しました。

f:id:sanvarie:20190721140509p:plain

回転させてみる

私は最初は「回転させたらいいのでは?」と思い、回転させてみました。結果がこれです。

f:id:sanvarie:20190721140546p:plain

これでは漢字の向きがおかしくなってしまいますので、だめですね。

手順

まず、上記のアノテーションを元の角度に戻してから、対象のアノテーションの属性を開きます。

f:id:sanvarie:20190721140751p:plain

右下のシンボルボタンを押下します。

f:id:sanvarie:20190721140711p:plain

CJK方向文字にチェックを入れてOKボタンを押下します。

f:id:sanvarie:20190721140820p:plain

注意

文字のフォントが「Arial」とかだと「CJK方向文字」が表示されないので、ご注意ください。おそらく漢字で使われるフォントのみが対象になっていると思われます。

f:id:sanvarie:20190721140902p:plain

属性ウインドウで適用ボタンを押下してください。

f:id:sanvarie:20190721141016p:plain

再度回転させるとこのように漢字が縦書きになりました。

f:id:sanvarie:20190721141144p:plain

属性ウインドウでこのように複数のアノテーションを選択して一括での設定も行うことができます。

f:id:sanvarie:20190721141528p:plain

簡単ですが、本日は以上です。今後は ArcMap や ArcGIS Pro の小ネタとかも色々紹介できればと思います。

Python で 作成した QR コードを読み込んで Googleマップにとんでみる

さて、本日は Python で QR コードを作成してみようと思います。ただ、単純に QR コードを作成してもつまらないので、作成した QR コードで Googleマップにとべるようにしてみようと思います。

使用するライブラリ

qrcode という Python の QR コード画像生成ライブラリを使います。pip でインストールしてください。

pip install qrcode[pil]

pypi.org

QR コードに埋め込む緯度経度

緯度: 35.678601
経度: 139.740286

ここがどこかといいますと永田町駅ですね。

作成する QR コード

GoogleマップへのリンクURLを格納する QR コード を作成します。上記の緯度経度をパラメータにした URL は以下のような形になります。この URL を QR コードに埋め込みます。

https://www.google.com/maps/search/?api=1&query=35.678601,139.740286

手順

今回は以下のような流れで進めてみようと思います。

  1. QRコードの作成(Python)
  2. 作成したQRコードをスマートフォンで読込
  3. Googleマップが指定した緯度経度で起動することを確認

実行環境

Windows10
Python3.6.5

サンプルコード

緯度経度を埋め込んだ QR コード作成のサンプルです。

# coding: utf-8
import qrcode

file_name = r"D:\python\qr.png" # QRコードの作成先

lat = "35.678601"  # 緯度
lon = "139.740286" # 経度

qr = "https://www.google.com/maps/search/?api=1&query=%s" \
         % (lat + "," + lon) # QRコードに埋め込む情報

img = qrcode.make(qr) # 画像作成
img.save(file_name)   # 保存

すごく簡単にできました。

作成したQRコードの画像を開くとこのようになっています。 f:id:sanvarie:20190720110800p:plain

作成したQRコードをスマートフォンで読込むとGoogleマップが出てくるのでタップします。 f:id:sanvarie:20190720111837j:plain

このように指定した緯度経度でGoogleマップを起動することに成功しました。 f:id:sanvarie:20190720111902p:plain

少し拡大させてみました。ピンが置かれている場所は間違いなく永田町ということがわかりますね。 f:id:sanvarie:20190720131025p:plain

ズームとかも指定できるみたいなので、細かい設定などをしたい方はGoogleMapへのリンクURL作成方法を調べた - Qiitaを読んでみてください。

この仕組みを利用すればマップをクリックした箇所をQR コード化してその場所をGoogleマップで確認なんてこともできるかと思います。今度はこれをもう少し発展させたものを作ってみたいですね。

Python3では SimpleHTTPServer ではなく http.server を使うべし

本日はちょっとローカルサーバーをたてたくて、あれっとなった時のお話です。

簡単にローカルサーバーをたてるならやっぱり SimpleHTTPServer かなと思い、

python -m SimpleHTTPServer 8080

を実行。しかし、

No module named SimpleHTTPServer

とでて、あれっ?となり調べてみると、Python2にはあった SimpleHTTPServer という標準ライブラリのモジュールが、Python3では http.server というモジュールに統合されていることがわかりました。

なので、Python3 では

python -m SimpleHTTPServer [ポート番号]

ではなく

python -m http.server [ポート番号]

としなければなりません。お気を付けください。

C# の WebRequest を使って標高API を使ってみる

さて、本日は C# のWebRequest を使って標高API を使ってみようと思います。最近はまっている標高APIですが、以下エントリーでは C# で作った画面から標高APIを呼び出している Python スクリプトを実行して、実行結果を画面に表示しました。今回はそれを C# オンリーで標高APIを使ってみたいと思います。

www.gis-py.com

今回実装するもの

簡単な画面を作りました。処理は以下のような流れです。

  • 作成した画面で緯度経度を入力し実行
  • 標高APIで標高値を取得し、それを標高のテキストボックスに表示

f:id:sanvarie:20190719232535p:plain

インストール

以下をNuget でインストールしてください。

  • System.Net.Http
  • Newtonsoft.Json

環境

Windows10(64bit)
Visual Studio2017
.NET Framework4.7.2

サンプルコード

実行ボタンの処理を記述します。

private async void BtnExecute_Click(object sender, RoutedEventArgs e)
{
    // パラメータ作成
    var parameters = new Dictionary<string, string>()
    {
        { "lon", LonText.Text },
        { "lat", LatText.Text },
        { "outtype", "JSON" },
    };

    // URL作成
    var url = $"http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?{await new FormUrlEncodedContent(parameters).ReadAsStringAsync()}";

    // 標高APIにリクエスト投げる
    WebRequest request = WebRequest.Create(url);

    using (Stream response_stream = request.GetResponse().GetResponseStream())
    {
        using (StreamReader reader = new StreamReader(response_stream))
        {
            // 標高取得
            var jObject = JObject.Parse(reader.ReadToEnd());
            ElevationText.Text = jObject.GetValue("elevation").ToString();
        }
    }
}

実行

このように入力し、実行を押します。
f:id:sanvarie:20190719232749p:plain

実行後、標高APIから取得した標高が表示されます。
f:id:sanvarie:20190719232801p:plain

この緯度経度の場所がどこか気になる方は以下エントリーを読んでみてください。

www.gis-py.com

簡単ですが、本日は以上です。

ArcGIS Pro SDK で開発を行うための重要な情報源

さて、本日はArcGIS Pro SDK について書いてみようと思います。

ArcGIS Pro SDK とは

ArcGIS Pro SDK とは ArcGIS Pro のアドイン開発、構成拡張をコンセプトにしたソフトウェア開発キットです。ArcGIS Pro SDK では、.NET Framework が提供する TAP(Task-based Asynchronous Pattern) による非同期プログラミング、統合言語クエリ (LINQ)、Windows Presentation Foundation (WPF)、MVVM などの最新の .NET 機能と Pro の API を使用してアドインが開発できます。

ArcGIS Pro SDK でできること

ArcGIS Pro SDK を利用することで ArcGIS Pro の画面上に表示されている既存のタブメニューを変更したり、独自のタブメニューを追加したりするなどの機能拡張を行うことができます。また、アドインとして独自のウィンドウ、外部の API を利用したデータの編集、保存などが可能です。アドインは、拡張したタブ内に設置したボタンから起動することができます。

※ Pro SDK は ArcGIS Pro の機能拡張とアドインのための開発環境であり、スタンドアロン アプリケーションのような独立したアプリケーションの開発はできません。

必要なライセンス

ADS(ArcGIS Developer Subscription)の Professional 以上が必要になります。

製品詳細 | ESRIジャパン

ArcGIS Pro SDK を扱う上で壁となりうるもの

ArcGIS Pro SDK は使いこなせたら非常に便利な反面・・・

  • 日本語での情報が少ない
  • 英語でも情報が多くない(日本語よりかは多いですが)
  • 非同期処理や MVVM など、とっつきにくい技術を使用しなければなく敬遠している

と思っている方は少なくないかと思います。そう思っている方は以下をご参照ください。ArcGIS Pro SDK で開発を行う上での重要なリソースを紹介します。

ArcGIS Pro SDK 開発をするためには

情報の取得 がキーになります。以下にキーとなる3つのサイトを紹介します。

  • ArcGIS Pro SDK for Microsoft .NET is the new .NET SDK for the ArcGIS Pro Application
    米国 Esri の Github です。ここにArcGIS Pro SDK を使って開発をするための基本的な情報が載っています。「Editing」や「Geodatabase」などといったカテゴリーに分かれており、それぞれのカテゴリーのコンセプトやスニペットを確認することができます(Geodatabase を扱うにはどういうクラスを使えばいいのかの情報を得ることができる)。

  • ArcGIS Pro SDK for Microsoft .NET Framework Community Samples
    米国 Esri の Github です。130個以上のサンプルツールが公開されています。作りたいものはあるけど、実現方法がわからないという場合はまずこのサンプルを確認してみるのがいいかと思います。

  • ArcGIS Pro 2.4 API Reference Guide
    API リファレンスです。

これらの三つの主要な情報源を活用することで効率の良い開発が望めるかと思います。ぜひ一度試してみてください。

C#からPythonスクリプトを実行する方法 ~標高APIを使用して緯度経度から標高を取得する~

さて、本日は C#からPythonを実行してみようと思います。先日、国土地理院の標高APIについて書いてみたのですが、これを生かして何かできないかと思い本エントリーを書くに至りました。国土地理院の標高API興味のある方はぜひ以下エントリーを読んでみてください。

www.gis-py.com

C# から Python スクリプトを実行する方法

C#の Process を使って、Pythonのスクリプトを実行し、printした値を受け取ることができます。そして、Pythonの戻り値そのものを取得することはできません。詳細は以下サイトに載っています。

code.msdn.microsoft.com

今回実装するもの

以下のような簡単な画面を作りました。処理は以下のような流れです。

  • C# で作成した画面で緯度経度を入力し実行(Pythonスクリプトを実行)
  • Pythonスクリプト側で緯度経度を受け取り、標高APIで標高値を取得し、それをprint
  • C# 側でPythonスクリプトがprintした値(標高)を受け取り、それを標高のテキストボックスに出力

f:id:sanvarie:20190714231700p:plain

環境

Windows10(64bit)
Python3.6.5
Visual Studio2017 .NET Framework4.7.2

サンプルコード

C#

実行ボタンを押した際の処理です。Pythonに渡す引数を作って、Process()を実行するだけですね。とてもシンプルにできます。

private void ExecuteClick(object sender, EventArgs e)
{
    // Pythonインタープリタのパス
    var pythonInterpreterPath = @"python.exe";

    // Pythonスクリプトのパス
    var pythonScriptPath = @"module.py";

    // Pythonスクリプトに渡す引数
    var arguments = new List<string>
    {
        pythonScriptPath ,
        LatText.Text, // 緯度
        LonText.Text  // 経度
    };

    var process = new Process()
    {
        StartInfo = new ProcessStartInfo(pythonInterpreterPath)
        {
            UseShellExecute = false,
            RedirectStandardOutput = true,
            Arguments = string.Join(" ", arguments),
        },
    };

    process.Start();

    //python側でprintした内容を取得
    var sr = process.StandardOutput;
    var result = sr.ReadLine();

    // 標高を取得
    ElevationText.Text = result;

    process.WaitForExit();
    process.Close();
}

Python

C# から受け取った緯度経度を使用して標高を取得し、それをprintします。printした結果がC#側に渡されます。

import sys
import requests

args = sys.argv

lat = args[1]
lon = args[2]

url = "http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php" \
       "?lon=%s&lat=%s&outtype=%s" %(lon, lat, "JSON")

resp = requests.get(url, timeout=10)
data = resp.json()

print(data["elevation"])

実行

このように入力し、実行を押します。
f:id:sanvarie:20190714232909p:plain

実行後、Pythonスクリプトで取得された標高が表示されます。
f:id:sanvarie:20190714232932p:plain

すごく簡単にできました。

Pythonのreturnを受け取れないのが少しもどかしいところですが、C# から Pythonスクリプト を実行するのは全然難しくないことがわかりました。Pytonで画面を作成するのは面倒なので、Pythonで作った処理結果を画面で表示したいという場合はこのような方法をとってもいいかもしれないですね。本日は以上です。

Pythonで国土地理院の標高API を使ってみよう!

さて、本日はPythonで国土地理院の標高API を使ってみようと思います。

標高API とは

緯度経度を送るとその地点の標高を返してくれるサービス。この仕組みを利用すれば、WEBサイト上の地図でクリックした地点の標高を取得したりすることができます。こんな便利なものを提供していただけるなんて、本当にありがたいですね。

仕様

地理院地図|標高APIをご参照ください。すごく簡単に使えますね。

例えば、このようなリクエストを投げると
http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=140.08531&lat=36.103543&outtype=JSON

このような結果が返ってきます。
f:id:sanvarie:20190713193538p:plain

「elevation」が標高ですね。

「hsrc」は標高データのデータソースみたいです。今回はこの値は無視します。

実行環境

Windows10(64bit)
Python3.6.5
Jupyter Notebook

使用する緯度経度

緯度: 35.678601
経度: 139.740286

ここがどこかといいますと永田町駅ですね。

f:id:sanvarie:20190713194234p:plain

サンプルコード

永田町駅の標高を取得するサンプルです。

import requests

lat = 35.678601  # 緯度
lon = 139.740286 # 経度

url = "http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php" \
       "?lon=%s&lat=%s&outtype=%s" %(lon, lat, "JSON")

resp = requests.get(url, timeout=10)
data = resp.json()

print(data["elevation"])


ものすごく簡単にできました。結果は29.2m ですね。
f:id:sanvarie:20190713194753p:plain

取得結果が正しいか地理院地図を使用して確かめます。
f:id:sanvarie:20190713195814p:plain

29.2m としっかり表示されていますね。素晴らしい!
f:id:sanvarie:20190713195859p:plain

簡単に使用できてこんな有益な情報が取得できるなんて本当にうれしい限りです。ぜひこれを利用して何か便利なものを作ってみたいですね。