質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

2回答

3546閲覧

Xamarin.Forms.Mapsで大量のPinを表示する方法

randr

総合スコア202

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

0クリップ

投稿2016/09/18 12:05

編集2016/09/18 13:03
  • 前提・環境

Xamarin.Forms.Mapsを使用して地図を表示しています。
その地図にDBから取得したデータ(List<T>)をPinで位置を表示します。
以下は、抜粋かつ簡略化したコードです。

C#

1public class MyData 2{ 3 public string Name 4 { 5 get; set; 6 } 7 public Position PosData 8 { 9 get; set; 10 } 11} 12 13button.Clicked += (sender, e) => 14{ 15 List<MapData> datas = ≪データ取得≫; 16 foreach(data in datas) 17 { 18 //mapはXamarin.Forms.Maps 19 map.Pins.Add(new Pin { Label = data.Name, Position = data.PosData}); 20 } 21};
  • 困っていること

今の状態で問題なく表示はできるのですが、データ数が多いとボタンクリック後すべて終わらないと描画がされなく、操作不能状態です。

  • やりたいこと

以前iPhoneの何かの地図で、検索したら該当箇所にPinが刺さっていくのを見ました。
pinが刺さる動作は順に刺さっていくイメージで、その間マップの操作は可能でした。
現状Androidであれば、ProgressDialogを表示してごまかしているのですが、できたら上記と同じようなことを実現したいと思っています。
勉強不足のためか、非同期でコントロールにアクセスするのができませんでした。
map.Pins.AddするたびにDoEvents()のような描画通知ができたりするのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

大量のPinを Xamarin.Forms.Maps で扱う件

「大量」の定義にもよりますが、Xamarin.Forms.Maps は、沢山の Pin を登録して使うのに向いていません。これは Xamarin.Forms.Maps がラップしている Google Map Android API や Apple Map などにも言えることだと予想します。

画面に可視できる程度の数(〜100)くらいしか想定されていないと予想します。

ちなみに、拙作の Xamarin.Forms.GoogleMaps も同じくで、大量のPinを登録されることは想定していません。

操作不能状態

1000件程度になってくると表示に時間がかかっているようで、画面上ユーザが固まってるように感じる状態ができてしまいます。

「1000件のデータをループして地図に追加する」という処理を、全てUIスレッドで行うと、その間UIは固まります。

それを回避するには、可能な限り処理をワーカースレッド(非同期)で行う必要がありますが、画面のコントロールへのアクセスはUIスレッドで行うというルールがあるので、「ピンの追加だけはUIスレッドで行う」必要があります。

正しく動くとは思えないですが、概念的には以下のようなコードになると思います。

Task.Run(() => { // 非同期(ワーカースレッド) for (int i = 0; i < data; i++) { var pin = data[i]; Device.BeginInvokeOnMainThread(() => { // 同期(UIスレッド) map.Pins.Add(pin); }); } });

たぶん、1件ずつ BeginInvokeOnMainThread するのはムダで、 BeginInvokeOnMainThread で数十件まとめて(UIレスポンスが落ちない程度に) Pin.Add するのだと思います(違ってるかも)。

投稿2016/09/19 07:05

amay077

総合スコア1075

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

randr

2016/09/20 21:42

確かに大量に表示すると動きがスムーズではないですね。 非同期で処理して、数を制限することでレスポンスをよくしようと思います。 ありがとうございました。 googlemapsのことで別途質問がありますので、また宜しくお願い致します。
guest

0

こんにちは。田淵@エクセルソフトです。

データ取得に時間が掛かるとして、とりあえず動かすだけなら async/await 使って

csharp

1button.Clicked += async (sender, e) => 2{ 3 List<MapData> datas = await ≪データ取得≫; 4 foreach(data in datas) 5 { 6 //mapはXamarin.Forms.Maps 7 map.Pins.Add(new Pin { Label = data.Name, Position = data.PosData}); 8 } 9};

で良いのではないでしょうか?

私もちゃんと理解出来ていないのですが、async/await については

async/awaitと同時実行制御 | ++C++; // 未確認飛行 C ブログ

をご参照いただくと良いかと思います。

投稿2016/09/18 15:22

ytabuchi

総合スコア335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

randr

2016/09/18 20:55

説明が不十分でした。 データ取得処理はHttpClientを使用して非同期で取得しています。 そのため、記載頂いたようなコードとなっております。 取得したデータ(datas)が100件程度であれば、ストレスなく表示されるのですが、 1000件程度になってくると表示に時間がかかっているようで、 画面上ユーザが固まってるように感じる状態ができてしまいます。 1000件も対象があるときは、地図を拡大してもらうよう促せば済むのですが、できたら pinをAddしているときでもマップが動かる、もしくはpinが一つずつ刺さっていく様子が見えればと考えています。
ytabuchi

2016/09/19 04:22 編集

HttpClientをどこでインスタンス化してどれくらい使いまわすか?メモリが大丈夫か?など考えるところは多いですが、forearch の中で一個ずつ取得して都度Pinを指していけば順々にPinが刺さるように出来ますよね。Button.Click で async してるので。 ただ、そのあたりは Xamarin ではなく、設計の話になるような気がします。例えばボタンクリック時ではなく、それより前にデータを取っておけば待ち時間なく指せるはずですし。 また、Xamarin.Forms.Maps の iOS の Map で Pin を指す動作自体が重いという問題かもしれないですが、その場合は Xamarin.iOS で同じ動作を作って試してみるのが良いですね。 MapKit に拘る必要がなければ、@amay077 さんの Xamarin.Forms.GoogleMaps https://github.com/amay077/Xamarin.Forms.GoogleMaps を試してみるのも良いかもですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問