HtmlAgilityPack, выбирающий childNodes не как ожидалось

Это долго, но вот как сделать сетку границы. Вы можете повторно использовать этот код без существенных изменений на разных картах, обновляя только те значения, которые вы определили для минимума, максимума и интервалов для широты и долготы.

require(ggplot2)
require(maps)

world <- map_data("world2") #get map data

Сначала определите ваш минимум, максимум и интервал сетки для широты и долготы. Эти числа будут использоваться для создания кадра данных для прямоугольников сетки границ и для создания разрывов и ограничений осей на вашем графике.

min.lat <- -40
max.lat <- 40
interval.lat <- 20
min.long <- 0
max.long <- 90
interval.long <- 30

Затем создайте два кадра данных, содержащих координаты для прямоугольников, которые будут формировать вашу сетку, один кадр данных для черных прямоугольников и один для белых прямоугольников. Отдельные кадры данных для каждого цвета прямоугольника сетки создаются таким образом, что вам не нужно будет использовать scale_fill_manual() для заливки сетки границ, и, таким образом, вы сможете при желании использовать эстетику заполнения для ваших данных. Весь этот код написан для использования значений, определенных выше, а не фактических чисел, поэтому вам не нужно изменять код ниже, чтобы создать карту другой области, вам нужно будет только обновить значения, определенные выше. [1112 ]

#define a constant (scaled to map size) width for grid rectangles
#may need to adjust number to get width you prefer
grid.width <- (max.lat - min.lat)/90

is.even <- function(x) x %% 2 == 0 #function to test if number is even

#dataframe of longitude rectangles
rects.long <- data.frame(x_start = rep(seq(min.long, max.long - interval.long,
                                  by = interval.long), 2))
rects.long$x_end <- rects.long$x_start + interval.long
rects.long$y_start <- c(rep(min.lat, nrow(rects.long)/2),
                        rep(max.lat - grid.width, nrow(rects.long)/2))
rects.long$y_end <- c(rep(min.lat + grid.width, nrow(rects.long)/2),
                        rep(max.lat, nrow(rects.long)/2))

rects.long$color <- if(is.even(nrow(rects.long)/2)) { #even/odd test
  rep(c("black", "white"), nrow(rects.long)/2) #pattern for even
} else {
  rep(c(rep(c("black", "white"), (nrow(rects.long) - 2)/4),"black"), 2)} #odd

#dataframe of latitude rectangles
rects.lat <- data.frame(y_start = rep(seq(min.lat, max.lat - interval.lat,
                                           by = interval.lat), 2))
rects.lat$y_end <- rects.lat$y_start + interval.lat
rects.lat$x_start <- c(rep(min.long, nrow(rects.lat)/2),
                        rep(max.long - grid.width, nrow(rects.lat)/2))
rects.lat$x_end <- c(rep(min.long + grid.width, nrow(rects.lat)/2),
                      rep(max.long, nrow(rects.lat)/2))

rects.lat$color <- if(is.even(nrow(rects.lat)/2)) { #even/odd test
  rep(c("black", "white"), nrow(rects.lat)/2) #pattern for even
} else {
  rep(c(rep(c("black", "white"), (nrow(rects.lat) - 2)/4),"black"), 2)} #odd

#combine latitude and longitude grid
rects.grid <- rbind(rects.lat, rects.long)

#split into black dataframe and white dataframe
rects.black <- rects.grid[rects.grid$color == "black",]
rects.white <- rects.grid[rects.grid$color == "white",]

Наконец, создайте свой сюжет!

#define axis breaks to match grid
axis.breaks.x <- seq(min.long, max.long, interval.long)
axis.breaks.y <- seq(min.lat, max.lat, interval.lat)

ggplot(data = world) +
  geom_polygon(aes(x = long, y = lat, group = group),
               color = "black", fill = "gray50") +
  #set limits to your previously defined limits
  coord_fixed(1, xlim = c(min.long, max.long), ylim = c(min.lat, max.lat),
              expand = FALSE) +
  #define breaks same as grid, duplicate axes for lat/long labels on all sides
  scale_y_continuous(breaks = axis.breaks.y, sec.axis = dup_axis()) +
  scale_x_continuous(breaks = axis.breaks.x, sec.axis = dup_axis()) +
  #use geom_rect() to add border grid
  geom_rect(data = rects.white, inherit.aes = FALSE, #white grid rectangles
        aes(xmin = x_start, xmax = x_end, ymin = y_start, ymax = y_end), 
            color = "black", fill = "white") +
  geom_rect(data = rects.black, inherit.aes = FALSE, #black grid rectangles
        aes(xmin = x_start, xmax = x_end, ymin = y_start, ymax = y_end),
            color = "black", fill = "black") +
  theme_minimal() + #theme edits to make plot look like a map
  theme(axis.title = element_blank(),
        legend.position = "none")

enter image description here

Вот тест, чтобы проверить, работает ли этот код с различные пределы и интервалы:

min.lat <- -10
max.lat <- 50
interval.lat <- 10
min.long <- 60
max.long <- 150
interval.long <- 15
#run same code as above to create grid dataframes and plot

enter image description here

38
задан Sheff 13 May 2009 в 10:41
поделиться

2 ответа

Вам следует удалить префикс косой черты из "/ img [@alt]", поскольку он означает, что вы хотите начать с корня документа.

HtmlNode imageNode = linkNode.SelectSingleNode("img[@alt]");
38
ответ дан 27 November 2019 в 03:21
поделиться

Also, Watch out for Null Check. SelectNodes returns null instead of blank collection.

HtmlNodeCollection linkNodes = htmldoc.DocumentNode.SelectNodes("//a[@href]");

**if(linkNodes!=null)**
{
   foreach(HtmlNode linkNode in linkNodes)
  {
     string linkTitle = linkNode.GetAttributeValue("title", string.Empty);
     if (linkTitle == string.Empty)
     {
       **HtmlNode imageNode = linkNode.SelectSingleNode("img[@alt]");**   
     }
  }
}
10
ответ дан 27 November 2019 в 03:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: