2016-12-12 8 views
2

私が作業しているリーフレットのシャイニーアプリでポリゴンを選択したり選択解除したりするときに、多少のポリゴンスタイルの変更に問題があります。私の現在のアプリでは、ポリゴンをクリックすると、そのポリゴンが別の色で強調表示されます。理想的には、ユーザーが複数のポリゴンを選択して強調表示できるようにしたいと考えています。また、強調表示された1つのポリゴンを再度クリックして選択解除することもできます。リーフレット/シャイニーで複数のポリゴンを選択/選択解除するときにスタイルを変更

複数のポリゴンを選択し、同じグループIDに「選択済み」を与えてから、ポリゴンを再度クリックしたときにそのグループ全体を選択解除することをお勧めします。例:/再現可能なコード例:

library(raster) 
library(shiny) 
library(leaflet) 

#load shapefile 
rwa <- getData("GADM", country = "RWA", level = 1) 

shinyApp(
    ui = fluidPage(
    leafletOutput("map") 
), 

    server <- function(input, output, session){ 

    #initial map output 
    output$map <- renderLeaflet({ 
     leaflet() %>% 
     addTiles() %>% 
     addPolygons(data = rwa, 
        fillColor = "white", 
        fillOpacity = 1, 
        color = "black", 
        stroke = T, 
        weight = 1, 
        layerId = [email protected]$OBJECTID, 
        group = "regions") 
    }) #END RENDER LEAFLET 

    observeEvent(input$map_shape_click, { 

     #create object for clicked polygon 
     click <- input$map_shape_click 

     #define leaflet proxy for second regional level map 
     proxy <- leafletProxy("map") 

     #subset regions shapefile by the clicked on polygons 
     selectedReg <-rwa[[email protected]$OBJECTID == click$id,] 


     #map clicked on polygons 
     proxy %>% addPolygons(data = selectedReg, 
          fillColor = "red", 
          fillOpacity = 1, 
          weight = 1, 
          color = "black", 
          stroke = T, 
          group = "selected", 
          # layerId = "selected") 
          layerId = [email protected]$OBJECTID) 


     #remove polygon group that are clicked twice 
     if(click$group == "selected"){ 
     proxy %>% 
      clearGroup(group = "selected") 
     } #END CONDITIONAL 

    }) #END OBSERVE EVENT 

    }) #END SHINYAPP 

上記の例では、クリックされたすべてのポリゴンが赤くなります。以前に選択された赤いポリゴンが再びクリックされると、すべての赤いポリゴンがマップから消去され、最初の白いポリゴンレンダリングが残されます。

私は一度に一つのポリゴンでレイヤーレイヤー "選択"(上記のコードでコメントアウト)を使用して作業しているときに、希望の選択/選択解除エフェクトを実行できますが、同時に複数のポリゴンを強調表示することができます。

私は任意のすべての提案にオープンしています!

答えて

2

答えはlayerIdsにあります。私はこれらがどのようにポリゴンに適用され、形状を取り除くのか理解していませんでした。これが重要です。これは最も洗練されたソリューションではないかもしれませんが、それは仕事を完了させます!

ルワンダの初期地図レンダリングではlayerId[email protected]$NAME_1で、地域名です。 label[email protected]$NAME_1と設定されています。したがって、下の画像では、左端のポリゴンは、NAME_1の列にあるIburengerazubaというラベルが付けられています。 このレイヤーIDは、この最初のマップレンダリングでのクリックイベントに対して、click$idを設定します。したがって、このポリゴンはIburengerazubaとラベルされているように、そのclick$idもIburengerazubaとして設定されます。 As stated in the Leaflet Shiny documentation、複数のポリゴンがある場合は、ベクトル化された引数である必要があります。 1つのポリゴン(この例では一度に1つの領域のみ)を選択したり選択解除する必要がある場合は、layerId = "selected"のようにlayerId文字列を使用することができます。

enter image description here

次はあなたの形状クリックためobserveEventです。 Thanks to the help of user @John Paul、地図上に作成されたすべてのクリックイベント(この場合はクリックID)を保存する方法を理解しました。私はそれらを無効ベクトルに保存してから、そのクリックIDでシェイプファイルをサブセット化しました。コードはかなり徹底的にコメントされているので、うまくいけば、この同じ解決策を探している人は、何が起こっているのかを正確に把握することができます。

最後のコードビット(if...elseの条件文に格納されています)はおそらく最も混乱します。最初にコードのelse部分を見てみましょう。 (注:初めてのクリックではifの条件を満たす方法がないため、最初の地図クリックでこのイベントがトリガーされます)。白いポリゴンがクリックされた場合は、addPolygons()呼び出しがトリガーされ、クリックされたポリゴンが地図に追加されます別のスタイリング(この場合は赤です)を使用します。 これは、全く異なるポリゴンをleafletProxyオブジェクトの上にプロットしています!

enter image description here

赤を削除するための鍵は、これらのポリゴンに初期マップのレンダリングとは異なるlayerIdを与えているポリゴンをクリックしました。上記の画像では、Iburengerazubaというラベルの付いた白いポリゴンは3とラベル付けされています。これは、コールのlayerIdCCA_1 INSTEAD OF NAME_1に設定されているためです。下層の白いマップにはNAME_1のレイヤIDがあり、そのためNAME_1のクリックIDがあります。赤いクリックされたポリゴンの上にプロットされた赤いクリックポリゴンのCCA_1レイヤIDはCCA_1のクリックIDです。

ifステートメントには、が既にclickedPolysポリゴンに存在する場合、このシェイプが削除されると記載されています。これは紛らわしいので、コードの各行を辿って真に理解するのに役立ちます。

もう一度上記の例を使用して、左端のポリゴンをクリックすると、ベクターにlayerId Iburengerazubaが追加されます。このクリックイベントは、クリックされたポリゴンを別のスタイルで描画し、layerIdが3(CCA_1列から)にプロットした2番目のマップ描画をトリガーします。赤いポリゴンが2回クリックされた場合(if(click$id %in% [email protected]$CCA_1))、選択解除としてカウントされ、そのポリゴンをマップから削除する必要があります。したがって、layerIdが3の赤い左端のポリゴンをクリックすると、clickedIds$idsベクトルはIburengerazuba3となります。 のclickedPolysポリゴンのIburengerazubaはCCA_1列の3に対応し、ifをトリガします。 removeShape(layerId = click$id)というコールは、そのクリック$ idに対応する図形を削除することを意味します。したがって、この場合には、3

CCA_1layerIdclickedPolysポリゴンがすべてのクリックIDことを覚えておいてください、NAME_1CCA_1の両方があなたのclickedIds$idsベクトルに記録されています。このベクトルは、ルワンダのシェイプファイルをサブセット化して、クリックされたすべてのポリゴンをマップします。ポリゴンをクリックすると、clickedPolysポリゴンは動的に更新されます。printを呼び出すと、これが意味をなさない場合はすべてのビットをチェックします。ダブルクリックされた図形を削除するだけでは、すべてを正確にプロットするには不十分です。clickedIds$idsベクトルから、選択解除されたlayerIds(NAME_1とCCA_1)を削除する必要があります。私は、選択されていないそれぞれのCCA_1 layerIdを対応するNAME_1の値にマッチさせ、clickedIds$idsベクトルからこれらの属性を削除して、clickedPolysポリゴンから削除しました。

Voila!これで、必要なポリゴンを選択したり選択解除したりできます。

library(raster) 
library(shiny) 
library(leaflet) 

#load shapefile 
rwa <- getData("GADM", country = "RWA", level = 1) 

shinyApp(
    ui = fluidPage(
    leafletOutput("map") 
), 

    server <- function(input, output, session){ 

    #create empty vector to hold all click ids 
    clickedIds <- reactiveValues(ids = vector()) 

    #initial map output 
    output$map <- renderLeaflet({ 
     leaflet() %>% 
     addTiles() %>% 
     addPolygons(data = rwa, 
        fillColor = "white", 
        fillOpacity = 1, 
        color = "black", 
        stroke = T, 
        weight = 1, 
        layerId = [email protected]$NAME_1, 
        group = "regions", 
        label = [email protected]$NAME_1) 
    }) #END RENDER LEAFLET 

    observeEvent(input$map_shape_click, { 

     #create object for clicked polygon 
     click <- input$map_shape_click 

     #define leaflet proxy for second regional level map 
     proxy <- leafletProxy("map") 

     #append all click ids in empty vector 
     clickedIds$ids <- c(clickedIds$ids, click$id) 

     #shapefile with all clicked polygons - original shapefile subsetted by all admin names from the click list 
     clickedPolys <- rwa[[email protected]$NAME_1 %in% clickedIds$ids, ] 

     #if the current click ID [from CCA_1] exists in the clicked polygon (if it has been clicked twice) 
     if(click$id %in% [email protected]$CCA_1){ 

     #define vector that subsets NAME that matches CCA_1 click ID 
     nameMatch <- [email protected]$NAME_1[[email protected]$CCA_1 == click$id] 

     #remove the current click$id AND its name match from the clickedPolys shapefile 
     clickedIds$ids <- clickedIds$ids[!clickedIds$ids %in% click$id] 
     clickedIds$ids <- clickedIds$ids[!clickedIds$ids %in% nameMatch] 

     #remove that highlighted polygon from the map 
     proxy %>% removeShape(layerId = click$id) 

     } else { 

     #map highlighted polygons 
     proxy %>% addPolygons(data = clickedPolys, 
           fillColor = "red", 
           fillOpacity = 1, 
           weight = 1, 
           color = "black", 
           stroke = T, 
           label = [email protected]$CCA_1, 
           layerId = [email protected]$CCA_1) 
     } #END CONDITIONAL 
    }) #END OBSERVE EVENT 
    }) #END SHINYAPP 
関連する問題