前提・実現したいこと
Leafletを用いて、マップ上にマーカーを設置し、マーカーをクリック、ダブルクリックした時に別々の処理を行いたいです。
今回の場合は、
シングルクリックイベントでは、マーカーのポップアップコメントを
ダブルクリックイベントでは、クリックした座標のアラートを表示したいと考えています。
発生している問題・エラーメッセージ
ダブルクリックの場合、シングルクリックイベント2回、ダブルクリックイベント1回が呼び出される状態です。
該当のソースコード
javascript
1let mymap = null; 2let spotListLayer = null; 3function init() { 4 mymap = L.map('mapid').setView([35.015299, 135.677990], 19); 5 L.tileLayer( 6 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 7 attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a>', 8 maxZoom: 19, 9 minZoom: 19, 10 } 11 ).addTo(mymap); 12 mymap.createPane("pane620").style.zIndex = 620; 13} 14onEachSpotFeature = function onEachFeature(feature, layer) { 15 layer.on('click', function(e) { 16 console.log('single'); 17 var popLocation= e.latlng; 18 var popup = L.popup() 19 .setLatLng(popLocation) 20 .setContent('Hello') 21 .openOn(mymap); 22 }); 23 layer.on('dblclick', function(e) { 24 //ダブルクリック位置経緯度取得 25 const lat = e.latlng.lat; 26 const lng = e.latlng.lng; 27 //経緯度表示 28 alert('lat: ' + lat + ', lng: ' + lng); 29 }) 30} 31$(function() { 32 // 全体の初期化処理 33 init(); 34 getSpotList(912); 35}); 36function showSpotListLayer(geojson) { 37 if (spotListLayer != null) { 38 mymap.removeLayer(spotListLayer); 39 } 40 // マーカを生成する. 41 spotListLayer = L.geoJSON(geojson, { 42 onEachFeature:onEachSpotFeature, 43 pointToLayer: function( feature, latlng ) { 44 switch (feature.properties.spot.state) { 45 case 1: return L.marker( latlng, { riseOnHover: true }); 46 case 0: return L.marker( latlng, { riseOnHover: true }); 47 } 48 } 49 }).addTo(mymap); 50 // マップレイヤにspotListLayerを追加する. 51 spotListLayer.addTo(mymap); 52} 53function getSpotList(node_id) { 54 $.ajax({ 55 url: 'spot/', 56 method: 'GET', 57 data: { 58 'node_id': node_id, 59 }, 60 timeout: 10000, 61 dataType: "json", 62 }).done(function(response) { 63 let geojson = response; 64 showSpotListLayer(geojson); 65// console.log(geojson); 66 }).fail(function(response) { 67 window.alert('getSpotList() : レスポンス失敗'); 68 }); 69}
python
1views.py 2スポットの緯度経度、id、0,1の状態を取得しています。 3from django.shortcuts import render 4from django.http import HttpResponse 5from django.views.generic import View 6 7from .models import Node, LinkNode, Visited, Spot, Spot_State, Spot_Mesh 8from .models import Mesh, Mesh_State, Link_Mesh 9from .view_models import SpotMapper 10 11import json 12class SpotView(View): 13 def get(self, request, *args, **kwargs): 14 """ 15 スポットリストの取得 16 """ 17 # リクエストの取得 18 visited_node_id = request.GET.get('node_id') 19 #実験 20 #クリックしたノードをstart_node_idとするLinkNodeオブジェクトの取得 21 adjacent_node_list = LinkNode.objects.filter(start_node_id= visited_node_id) 22 node_list = []#クリックしたノードに隣接するノードが訪問済みであるノードのリスト 23 remove_list = []#リンク格納用リスト 24 link_meshes = []#初期ロード以外専用 25 spot_mesh_list = []#初期ロード専用 26 link_id = 0 27 for adjacent_node in adjacent_node_list: 28 #クリックしたノードの隣接ノード取得 29 node_id = adjacent_node.end_node_id 30 #クリックしたノードの隣接ノードの内、訪問済みのノードのリストを取得 31 lists = Visited.objects.filter(node_id=node_id, state=1) 32 for list in lists: 33 node_list.append(list) 34 #開始地点やクリックしたノードが終点の場合は、省く 35 if(len(node_list) > 0): 36 #クリックしたノードがstart_node_idかつ直前のノードが訪問済みであるノードがend_node_idであるLinkNodeオブジェクトの取得 37 remove_lists = LinkNode.objects.filter(start_node_id= visited_node_id, end_node_id = node_list[0].node_id) 38 for remove in remove_lists: 39 remove_list.append(remove) 40 #link_idの取得、マイナスの場合は反転 41 link_id = remove_list[0].link_id 42 if(remove_list[0].link_id < 0): 43 link_id = remove_list[0].link_id * -1 44 print('link_id = ' + str(link_id)) 45 #初期ロードのみ、link_idは0 46 if(link_id > 0): 47 #Link_Meshオブジェクト(リンクと共有するメッシュ)の取得 48 links_meshes_lists = Link_Mesh.objects.filter(link_id = link_id) 49 for links_meshes in links_meshes_lists: 50 link_meshes.append(links_meshes) 51 print(link_meshes[-1].mesh_id) 52 spot_mesh = Spot_Mesh.objects.filter(mesh_id = link_meshes[-1].mesh_id) 53 for spot in spot_mesh: 54 spot_mesh_list.append(spot) 55 #取得したスポットidの状態を0にする 56 Spot_State(spot_id = spot_mesh_list[-1].spot_id, state = 0 ).save() 57 if(link_id == 0): 58 #初期ロードの時のみ、ノードーメッシュースポットの順でスポットの状態を変更 59 # オブジェクトの取得 60 #ノードidからメッシュidの取得 61 node_mesh = Node_Mesh.objects.filter(node_id = visited_node_id) 62 node_mesh_list = [] 63 spot_mesh_list = [] 64 for mesh in node_mesh: 65 node_mesh_list.append(mesh) 66 #メッシュidからスポットidの取得 67 spot_mesh = Spot_Mesh.objects.filter(mesh_id = node_mesh_list[-1].mesh_id) 68 for spot in spot_mesh: 69 spot_mesh_list.append(spot) 70 #取得したスポットidの状態を0にする 71 Spot_State(spot_id = spot_mesh_list[-1].spot_id, state = 0 ).save() 72 spots_list = Spot_State.objects.all() 73 # レスポンスの生成 74 features = [SpotMapper(spot).as_dict() for spot in spots_list] 75 response = { 76 'type': 'FeatureCollection', 77 'crs': { 78 'type': 'name', 79 'properties': { 80 'name': 'EPSG:4326', 81 }, 82 }, 83 'features': features, 84 } 85 response_json = json.dumps(response) 86 87 # レスポンスの返却 88 return HttpResponse(response_json, content_type='application/json') 89spot_view = SpotView.as_view()
python
1view_models.py 2class SpotMapper: 3 """スポットマッパー""" 4 5 def __init__(self, obj): 6 self.obj = obj 7 8 def as_dict(self): 9 spot = self.obj 10 #0ならtrue、それ以外はfalseに変換 11 """ 12 def str2bool(v): 13 return v.lower() in ("0") 14 """ 15 return { 16 'type': 'Feature', 17 'properties': { 18 'spot': { 19 'spot_id': spot.spot.spot_id, 20 'name': spot.spot.name, 21 'state': spot.state, 22 }, 23 }, 24 'geometry': { 25 'type': 'Point', 26 'coordinates': [spot.spot.latlng.x, spot.spot.latlng.y], 27 }, 28 }
spotsテーブル 列 | 型 | 照合順序 | Null 値を許容 | デフォルト ---------+-----------------------+----------+---------------+------------ spot_id | integer | | not null | name | character varying(50) | | not null | latlng | geometry(Point,4326) | | not null | spot_id | name | latlng ---------+----------------------------------------------------+---------------------------------------------------- 1 | Ranzan | 0101000020E61000001E53776597F5604090381A76CE814140 spots_stateテーブル 列 | 型 | 照合順序 | Null 値を許容 | デフォルト ---------+---------+----------+---------------+------------ spot_id | integer | | not null | state | integer | | | spot_id | state ---------+------- 1 | 1
試したこと
クリック数をカウントする変数を置いて(mymap.clicked = 0;のように)、onEachFeatureオプションの関数内にて、カウント数をクリックに応じて変更し、カウント数が1であればシングル、2であればダブルのクリックイベントを処理するようにしたのですが、
onEachFeatureオプションは、クリックするたびに呼び出されるのではないため、変数を上手く扱うことができませんでした。
※自分の記述方法が間違っているかもしれません。
補足情報(FW/ツールのバージョンなど)
python3.8
Leaflet1.7.1
Django3.0.8
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。