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

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

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

Leafletは、Web上で地図を作成するためのJavaScriptライブラリ。人気のあるJavaScript地図ライブラリのうちの一つでオープンソースです。軽量でインタラクティブな地図を手軽に表示することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1439閲覧

Leaflet および Leaflet.draw プラグインを用いた複数コントローラによるイベントを識別したい

SlBA2rwDEK

総合スコア13

Leaflet

Leafletは、Web上で地図を作成するためのJavaScriptライブラリ。人気のあるJavaScript地図ライブラリのうちの一つでオープンソースです。軽量でインタラクティブな地図を手軽に表示することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/07/18 09:31

編集2019/07/18 09:35

前提・実現したいこと

Leaflet とそのプラグイン Leaflet.draw を利用した地図アプリを作成しています。
https://leafletjs.com/index.html
https://github.com/Leaflet/Leaflet.draw

実現したいことは、複数のコントローラーを用いて作成した図形を、それぞれのコントローラーに紐づけた featureGroup に登録し管理したいと考えています。

詳細

下記に図を示します。
イメージ説明
図には左上、右上にコントローラーが表示されています。
そしてそれぞれのコントローラーで描いた図形を下記のように管理したいと考えています。
・左上のコントローラーで描いた図形は featureGroup1 で管理
・右上のコントローラーで描いた図形は featureGroup2 で管理

解決できない問題

featureGroup への登録は Leaflet.draw プラグインの仕組みを用いて map.on(L.Draw.Event.CREATED, function (event) { の際に行うものと考えています。

ですが、上記のイベント発生時に 左上のコントローラーで発生したイベント なのか 右上のコントローラーで発生したイベント なのかを識別する方法がわかりません。
このため、それぞれの featureGroup で登録することができません。

そこで、これらを識別する方法についてご存知であればご教示いただきたく思います。

試したソースコードはこちらになります。
https://jsfiddle.net/fr78k4pn/

検討したこと

コントローラーのボタン押下時に、左上コントローラーか右上コントローラーかを判定し L.Draw.Event.CREATED 時に呼び出すメソッドを切り替えるようなことを考えましたが、やはりイベント発火時のコントローラーを識別しないとどうにもならないと感じております。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ツールバーのイベントに処理を追加して「今操作している方」を変数で保持させることで、どちらのコントローラーかを識別することならばできましたよ。

javascript

1 2//前半部分は割愛★ 3 4 var now_ctrl = 0; 5 6 var ControlDrawLeft = new L.Control.Draw({ 7 edit: { 8 featureGroup: featureGroup1, 9 poly: { 10 allowIntersection: false 11 } 12 }, 13 draw: { 14 polygon: { 15 allowIntersection: false, 16 showArea: true 17 } 18 } 19 }); 20 //左側のツールバーにイベントを追加 21 ControlDrawLeft._toolbars.draw.addEventListener('enable', function(){ now_ctrl = 1; }); 22 23 var ControlDrawRight = new L.Control.Draw({ 24 position: "topright", 25 edit: { 26 featureGroup: featureGroup2, 27 poly: { 28 allowIntersection: false 29 } 30 }, 31 draw: { 32 polygon: { 33 allowIntersection: false, 34 showArea: true 35 } 36 } 37 }); 38 //右側のツールバーにイベントを追加 39 ControlDrawRight._toolbars.draw.addEventListener('enable', function(){ now_ctrl = 2; }); 40 41 map.addControl(ControlDrawLeft); 42 map.addControl(ControlDrawRight); 43 44 map.on(L.Draw.Event.CREATED, function (event) { 45 var layer = event.layer; 46 if (now_ctrl == 1) { 47 featureGroup1.addLayer(layer); 48 } else if ( now_ctrl == 2) { 49 featureGroup2.addLayer(layer); 50 } 51 }); 52

leafletはあんまり使ったことがないので、もっと正攻法があるのでは?と思いましたが、少しでも参考になれば・・^^;


追記です。

回答を投稿してから気づきました・・!
多角形のツールバーは、両方同時に開けるんですね;;

上記のコードだけでは、多角形を両方開いた場合に、後から開いたコントローラー側のグループに、どちらのレイヤーも追加されてしまうので、調整が必要そうでした・・・


調整してみました。
と言っても、多角形のツールバーを開いた(多角形を書き始めた)状態のまま、他のものを開いた場合に、多角形のツールバーを強制的にcancelさせる、という方法です。
多角形のツールバーのボタン三つ目が「キャンセルボタン」ってのを前提に処理を入れたので、ツールバーそのものにカスタマイズ(出来るのかは不明ですが)した場合は、別途調整が必要だと思います。

javascript

1 2 var now_ctrl = false; 3 var ControlDrawLeft = new L.Control.Draw({ 4 edit: { 5 featureGroup: featureGroup1, 6 poly: { 7 allowIntersection: false 8 } 9 }, 10 draw: { 11 polygon: { 12 allowIntersection: false, 13 showArea: true 14 } 15 } 16 }); 17 18 ControlDrawLeft._toolbars.draw.addEventListener('enable', function(){ 19 if(now_ctrl && now_ctrl._activeMode.handler.type == 'polygon') { now_ctrl._actionButtons[2].button.click(); } 20 now_ctrl = this; now_ctrl.ctrl_num= 1; 21 }); 22 ControlDrawLeft._toolbars.draw.addEventListener('disable', function(){ now_ctrl = false; }); 23 var ControlDrawRight = new L.Control.Draw({ 24 position: "topright", 25 edit: { 26 featureGroup: featureGroup2, 27 poly: { 28 allowIntersection: false 29 } 30 }, 31 draw: { 32 polygon: { 33 allowIntersection: false, 34 showArea: true 35 } 36 } 37 }); 38 ControlDrawRight._toolbars.draw.addEventListener('enable', function(){ 39 if(now_ctrl && now_ctrl._activeMode.handler.type == 'polygon') { now_ctrl._actionButtons[2].button.click(); } 40 now_ctrl = this; now_ctrl.ctrl_num= 2; 41 }); 42 ControlDrawRight._toolbars.draw.addEventListener('disable', function(){ now_ctrl = false; }); 43 44 map.addControl(ControlDrawLeft); 45 map.addControl(ControlDrawRight); 46 47 map.on(L.Draw.Event.CREATED, function (event) { 48 var layer = event.layer; 49 if (now_ctrl.ctrl_num == 1) { 50 featureGroup1.addLayer(layer); 51 } else if ( now_ctrl.ctrl_num == 2) { 52 featureGroup2.addLayer(layer); 53 } 54 });

そもそも。ツールバーのイベントのthisから辿れば、親のコントローラーが見つけられるとおもうんですけどねぇ・・・どうにも簡単に取ったり判別したりする方法が見つかりませんでした。。。

投稿2019/07/19 03:44

編集2019/07/19 05:49
mix-peach

総合スコア1910

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

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

SlBA2rwDEK

2019/07/19 14:43

ご回答いただきありがとうございます! 求めていた振る舞いを実現することができました! ありがとうございました! ただ、教えていただいた内容をもとに leaflet のマニュアルを再確認したのですが実装の内容が理解できませんでした。。 お手数おかけしますがいくつか確認させていただけますと幸いです。 Q1. どのようにして `_toolbars.draw` がコントローラーの各ボタンに紐付いていることに気がついたのでしょうか? Q2. `_toolbars.draw` のイベントリスナとして指定している `enable / disable` はどのような契機で発火しているのでしょうか?(マニュアルには `click` や `mousedown` といった記載しかないように見受けられたのですが、どこかに記載されているでしょうか?)
mix-peach

2019/07/22 02:06

ライブラリが作成する要素(HTMLやクラス)と、それを設置するために自分が記述したものの中身を確認すると糸口がつかめることが多いです。 javasriptですので、クラスなどでボタンを制御することになります。なのでライブラリが作った要素(HTMLやクラス)の確認は大切です。 クラス名は、ライブラリ内で命名規則に則ってつけられているものが多く、ついでそれらに対してcss定義をすることが多いので、意外と「分かりやすい」クラス名が付いていたりします。 今回の場合は、まず制御したいボタンの周りの要素とそのクラスを確認してみます。 多角形や、丸、四角のボタン要素には、「leaflet-draw-draw-●●」といったクラスが振られていて、さらにその下にいる、編集と、ゴミ箱のボタンを見ると「leaflet-draw-edit-●●」とクラスがついています。上下のボタン郡は、「darw」か「edit」で判別されてそうだなーとなんとなく想像がつきます(これは、勘というか、経験則というか・・・) 次に、自分が作った「ControlDrawLeft」を見てみます。optionsとか_toolbarとかありますので、上から開いてみます。optionsには変数を定義した時に渡した設定が入っています。_toolbarを開くと、drawとedit・・・見覚えのある単語です。さらにそれぞれに見覚えのあるクラス名が紐づけられているのが分かります。制御したいのはdrawの方なので、そちらをさらに開いてみると、_eventが定義されていることが分かるので、ここらへんは使えないかな?と試行錯誤・・・ と、いう感じで上記コードに辿り着きました。。。 Q2 > enable / disableは、「丸」や「多角形」のボタンを押したときに、「cancel」や「finish」等の追加ボタンが表示されると思うのですが、それらが出る時・消える時と同じタイミングで発火しているイベントのようでした。 ちなみに、押した「丸」「多角形」のボタンには「leaflet-draw-toolbar-button-enabled」とクラスが付与され、描画が終わるか、キャンセルボタンを押すと、このクラスが削除されるので、こちらもクラス名とイベントが紐づいている模様。。 マニュアルには、このあたりの記載はないかもしれません。 Q1で掘り下げて見つけたdrawoのイベントにenableがあったので、ならば対照的なdisableもあるんじゃないかな?と思い、leaflet.draw.jsで、単語検索でイベントがあることを確認(中身を読み解くまではしていません・・!)googleさんで検索してみると、似たようなことをしている人がいるなー・・ じゃあ試してみよう。。。という感じです。 --- 具体的な回答ではなくて、すみません^^;;
SlBA2rwDEK

2019/07/22 05:21

ご回答いただきありがとうございます! 自分は動的型付け言語やフロントサイド、Javascriptを使った開発の経験が少なく、調査の進め方がわかりませんでした。。 ですが、回答いただいた内容から調べ方が見えた気がします! 大変参考になりました!貴重なご意見をいただきありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問