Листовка R / блестящая: отображение и смещение перекрывающихся полилиний на основе значения столбца - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь растянуть то, что я могу сделать в R, и ударился о стену, и надеюсь, что вы можете указать мне правильное направление на то, как лучше всего я смог бы выполнить sh то, что я хочу сделать. Я строю набор полилиний из файла формы, данные которого выглядят так:

placename,placetype,placebook,numbooks,row_number,placelinecoords
Main Street,street,"BOOKTDS",1,1,LINESTRING(-3.700559678237278 40.42098474661999,-3.698346475125229 40.42033268716025,-3.69731867182242 40.42003534594848,-3.697243299580215 40.42003534594848)
First Street,street,"BOOKESM",3,1,LINESTRING(-3.710546258545151 40.41308011176736,-3.710213664627304 40.41309440722183,-3.709234658336868 40.41341707524381,-3.708880606746902 40.4135232694443,-3.708711627578964 40.41372748858957)
First Street,street,"BOOKTDS",3,2,LINESTRING(-3.710546258545151 40.41308011176736,-3.710213664627304 40.41309440722183,-3.709234658336868 40.41341707524381,-3.708880606746902 40.4135232694443,-3.708711627578964 40.41372748858957)
First Street,street,"BOOKLDE",3,3,LINESTRING(-3.710546258545151 40.41308011176736,-3.710213664627304 40.41309440722183,-3.709234658336868 40.41341707524381,-3.708880606746902 40.4135232694443,-3.708711627578964 40.41372748858957)
Loughborough Street,street,"BOOKESM",2,1,LINESTRING(-3.707336328013795 40.42433623251054,-3.707014282978915 40.42429971916709,-3.706726498054129 40.42429971916709,-3.706281116622912 40.42409628731927,-3.705390353760477 40.42377288157678,-3.704602371228324 40.42316257940762,-3.70376642454204 40.42259400231908)
Loughborough Street,street,"BOOKTDS",2,2,LINESTRING(-3.707336328013795 40.42433623251054,-3.707014282978915 40.42429971916709,-3.706726498054129 40.42429971916709,-3.706281116622912 40.42409628731927,-3.705390353760477 40.42377288157678,-3.704602371228324 40.42316257940762,-3.70376642454204 40.42259400231908)
Oak Street,street,"BOOKLMI",2,1,LINESTRING(-3.700391803697817 40.41664973667679,-3.700384951675798 40.41673842198933,-3.699754565650076 40.4176044018386,-3.699549004989513 40.41782350340716)
Oak Street,street,"BOOKLBU",2,2,LINESTRING(-3.700391803697817 40.41664973667679,-3.700384951675798 40.41673842198933,-3.699754565650076 40.4176044018386,-3.699549004989513 40.41782350340716)

"placebook" - это уникальный код для книги, в которой появляется название конкретной улицы. Каждой книге я присвоил цвет и загрузку данных:

books = c("OBRAESM", "OBRAHOR", "OBRAINS", "OBRALBU", "OBRALCT", "OBRALDB","OBRALDE","OBRALMI","OBRALPI","OBRATDS")
color = c("red", "orange", "yellow", "green", "blue", "pink","gray","purple","black","white")
df = cbind.data.frame(books,color)
colnames(df) = c("books","color")

placeographypaths <- readOGR("shapefiles/places_paths.shp")
placeographypathsstreets <- subset(placeographypaths, placetype %like% "street")

Я хотел бы нарисовать эти линии на карте по книгам, каждая из которых будет иметь свой цвет. Когда для определенной строки назначено более одной книги, мне нужно сместить строки, чтобы они все были видны. Эти линии будут полностью перекрываться, и в большинстве случаев в одном и том же месте будут перекрываться только несколько линий (максимум 5, но большинство 1-3).

Таким образом, отображается «Первая улица» три линии: красная, серая и белая. Я вижу, что есть инструмент PolylineOffset, но я не могу найти примеров, которые используют значения столбцов в качестве критериев для смещения - и, кажется, это в основном относится к более сложным ситуациям, когда перекрывается только часть строки) - возможно, есть более простое решение, которое мне не хватает.

1 Ответ

1 голос
/ 08 января 2020

Я потратил некоторое время, чтобы подумать, что я мог бы сделать, так как я не знаю, как использовать PolylineOffset. Похоже, эта функция появится в листовке. Я хочу предложить альтернативу для вашей визуализации. Читая ваш вопрос, у вас будет пять типов строк. То есть каждый тип линии может представлять, сколько раз улицы появляются в вашем наборе данных. Вы сказали, что максимальное перекрытие составляет пять раз. Я думаю, что вы можете создать пять уровней в переменной группировки и создать цвета в листовке.

Сначала я обобщил вашу группировку данных по названию места. Для каждого названия места я посчитал, сколько существует точек данных (строк). Я также создал строку, содержащую названия книг. Строка устроена для всплывающих окон. Затем я создал цветовую палитру для листовки. Наконец, я нарисовал карту. Если вы хотите что-то более изумительное, я думаю, вы можете использовать пакет htmlTable, например.

library(dplyr)
library(leaflet)
library(sf)
library(viridis)

# Aggregate the data by placename. Note your data is called mysf, which is an
# sf object.

group_by(mysf, placename) %>% 
summarize(frequency = factor(n(), levels = 1:3, labels = c("1", "2", "3")),
          books = paste0("<br/>", paste0(placebook, collapse = "<br/>"))) -> mysf2

# Create categorical colors
# I am checking colors here
previewColors(colorFactor(palette = "viridis", domain = mysf2$frequency),
                          values = unique(mysf2$frequency))

# Create my own palette
mypal <- colorFactor(palette = "viridis", domain = mysf2$frequency)

# Draw a leaflet map
leaflet() %>% 
addProviderTiles("CartoDB.Positron") %>% 
addPolylines(data = mysf2, color = ~mypal(mysf2$frequency),
             popup = paste("Place: ", mysf2$placename, "<br>",
                           "Book(s): ", mysf2$books, "<br>")) %>% 
addLegend(position = "bottomright", pal = mypal, values = mysf2$frequency,
          title = "Frequency",
          opacity = 1)

enter image description here

Наконец, одна заметка. То, как вы предоставили свои данные, к сожалению, никому не поможет воспроизвести вашу ситуацию. (Я потратил довольно много времени на создание ваших данных вручную. Я бы не стал этого делать, если бы у меня не было достаточно времени. Perhapd вы бы тоже не хотели, не так ли?) Если ваши данные большие, вы можете подумать о загрузке. это где-то еще. В противном случае вы можете использовать dput(), который создает копию ваших данных. Если вы внимательно видите вопросы в R, многие пользователи предоставляют свои данные с dput(). Я настоятельно рекомендую вам использовать эту функцию, когда вы будете задавать больше вопросов в будущем.

DATA

mysf <- structure(list(placename = structure(c(3L, 1L, 1L, 1L, 2L, 2L, 
4L, 4L), .Label = c("First Street", "Loughborough Street", "Main Street", 
"Oak Street"), class = "factor"), placetype = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "placetype", class = "factor"), 
placebook = structure(c(5L, 1L, 5L, 3L, 1L, 5L, 4L, 2L), .Label = c("BOOKESM", 
"BOOKLBU", "BOOKLDE", "BOOKLMI", "BOOKTDS"), class = "factor"), 
geometry = structure(list(structure(c(-3.70055967823728, 
-3.69834647512523, -3.69731867182242, -3.69724329958022, 
40.42098474662, 40.4203326871602, 40.4200353459485, 40.4200353459485
), .Dim = c(4L, 2L), class = c("XY", "LINESTRING", "sfg")), 
    structure(c(-3.71054625854515, -3.7102136646273, -3.70923465833687, 
    -3.7088806067469, -3.70871162757896, 40.4130801117674, 
    40.4130944072218, 40.4134170752438, 40.4135232694443, 
    40.4137274885896), .Dim = c(5L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.71054625854515, 
    -3.7102136646273, -3.70923465833687, -3.7088806067469, 
    -3.70871162757896, 40.4130801117674, 40.4130944072218, 
    40.4134170752438, 40.4135232694443, 40.4137274885896), .Dim = c(5L, 
    2L), class = c("XY", "LINESTRING", "sfg")), structure(c(-3.71054625854515, 
    -3.7102136646273, -3.70923465833687, -3.7088806067469, 
    -3.70871162757896, 40.4130801117674, 40.4130944072218, 
    40.4134170752438, 40.4135232694443, 40.4137274885896), .Dim = c(5L, 
    2L), class = c("XY", "LINESTRING", "sfg")), structure(c(-3.70733632801379, 
    -3.70701428297891, -3.70672649805413, -3.70628111662291, 
    -3.70539035376048, -3.70460237122832, -3.70376642454204, 
    40.4243362325105, 40.4242997191671, 40.4242997191671, 
    40.4240962873193, 40.4237728815768, 40.4231625794076, 
    40.4225940023191), .Dim = c(7L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.70733632801379, 
    -3.70701428297891, -3.70672649805413, -3.70628111662291, 
    -3.70539035376048, -3.70460237122832, -3.70376642454204, 
    40.4243362325105, 40.4242997191671, 40.4242997191671, 
    40.4240962873193, 40.4237728815768, 40.4231625794076, 
    40.4225940023191), .Dim = c(7L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.70039180369782, 
    -3.7003849516758, -3.69975456565008, -3.69954900498951, 
    40.4166497366768, 40.4167384219893, 40.4176044018386, 
    40.4178235034072), .Dim = c(4L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.70039180369782, 
    -3.7003849516758, -3.69975456565008, -3.69954900498951, 
    40.4166497366768, 40.4167384219893, 40.4176044018386, 
    40.4178235034072), .Dim = c(4L, 2L), class = c("XY", 
    "LINESTRING", "sfg"))), class = c("sfc_LINESTRING", "sfc"
), precision = 0, bbox = structure(c(xmin = -3.71054625854515, 
ymin = 40.4130801117674, xmax = -3.69724329958022, ymax = 40.4243362325105
), class = "bbox"), crs = structure(list(epsg = 4326L, proj4string = "+proj=longlat +datum=WGS84 +no_defs"), class = "crs"), n_empty = 0L)), row.names = c(NA, 
8L), sf_column = "geometry", agr = structure(c(placename = NA_integer_, 
placetype = NA_integer_, placebook = NA_integer_), class = "factor", .Label = c("constant", 
"aggregate", "identity")), class = c("sf", "data.frame"))
...