将具有不同几何类型的sf文件合并,然后在r

问题描述

我已经更新了这个问题。我已经解决了将点,线和面组合到同一个sf文件中的原始问题。我只是将所有点和线变成了多边形(请参见下面的代码)。但是,现在我仍然无法使缓冲区正常工作,因此问题仍然存在:

我有一个数据集,其中包含美国芝加哥及其周边地区不同物种的种群。一些种群很大,因此用几个点表示(几个纬度/经度坐标=多边形)。其他的则很小,因此可以简单地用一个点(1个经/纬度坐标)表示。最后,有些又长又窄,因此用两个点(2个纬度/经度坐标)表示。请注意,一个种群可能与多个物种相关联(尽管我的示例数据集仅包括一个具有不同种群的物种)。

我想分析每种物种的种群,但在此之前,我需要确保它们符合我对单独种群的定义。如果一个种群与相同物种的其他任何种群之间至少相距50米,我将它们定义为独立的种群。因此,我想编写一个脚本,遍历我的数据集,按物种对种群进行分组,然后确定给定物种的种群(点,线和面)是否在其他种群的50米范围内。这是我的缩写数据集(完整的数据集包含大约300种和60万行数据)。

      data <- data.frame (species = c("species_2","species_2","species_2"),pop_id = c(3,3,4,5,6,2),coordinate_type = c("decimal degrees","decimal degrees","decimal degrees"),coordinate_system = c("wgs84","wgs84","wgs84"),sptaial_object_type = c("Point","Point","polygon","Linestring","Point"),POINT_X = c(-87.64021,-88.13841,-87.64021,-88.13898,-88.13902,-88.13900,-88.13895,-88.18663,-88.18659,-88.13994,-88.14022,-88.14000,-88.13978,-87.64021),POINT_Y = c(41.07428,41.34244,41.07428,41.33813,41.33821,41.33824,41.33820,41.36329,41.36348,41.33817,41.33833,41.33858,41.07428))
                
  
                

这是我成功完成的事情:

    ######################
    ##                  ##
    ## LOAD PACKAGES    ##
    ##                  ##
    ######################
    
    # Load required packages
    library(data.table)
    library(geosphere)
    library(sp)
    library(rgdal)
    library(sf)
    library(dplyr)   


    ##################################
    ##   TURN POINTS INTO polyGONS  ##
    ##################################

    #Duplicate all rows that contain points to get 4 new dataframes with only the points
    data_points_1 <- subset(data_1,data_1$sptaial_object_type=="Point") #Save only the rows that are points
    data_points_2 <- subset(data_1,data_1$sptaial_object_type=="Point") #Save only the rows that are points
    data_points_3 <- subset(data_1,data_1$sptaial_object_type=="Point") #Save only the rows that are points
    data_points_4 <- subset(data_1,data_1$sptaial_object_type=="Point") #Save only the rows that are points

    #Increase all POINT_Y in data_points_2 and all POINT_X in data_points_3 by 0.001
    data_points_2$POINT_Y <- data_points_2$POINT_Y + 0.001
    data_points_3$POINT_X <- data_points_2$POINT_X + 0.001

    #Rbind the points dataframes back together and change Point attribute to polygon
    data_points_final <- rbind(data_points_1,data_points_2,data_points_3,data_points_4)
    data_points_final$sptaial_object_type <- "polygon"
    head(data_points_final) #Now every point has been turned into a polygon with 2 slightly offset,#new points and two original points (starting and ending vertices of the polgyon)

    #################################
    ##   TURN LInes INTO polyGONS  ##
    #################################

    #For every subpop that has a line add one more point by taking any of the existing points and adding to the x AND the y coordinate
    data_linestring_1 <- subset(data_1,data_1$sptaial_object_type=="Linestring") #Save only the rows that are linestrings
    data_linestring_2 <- data_linestring_1 %>%  distinct(species,pop_id,.keep_all = T)  #Save only rows with unique combos of species and pop_id 
    data_linestring_3 <- data_linestring_1 %>%  distinct(species,.keep_all = T)  #Save only rows with unique combos of species and pop_id 

    #Increase all POINT_Y and all POINT_X in data_linestring_2 by  0.001
    data_linestring_2$POINT_Y <- data_linestring_2$POINT_Y + 0.001
    data_linestring_2$POINT_X <- data_linestring_2$POINT_X + 0.001

    #Rbind the points dataframes back together and change Point attribute to polygon
    data_linestring_final <- rbind(data_linestring_1,data_linestring_2,data_linestring_3)
    data_linestring_final$sptaial_object_type <- "polygon"

    #Check that each linestring has Now been turned into a polygon with 3 points
    head(data_linestring_final) #Now every line has been turned into 
    #a polygon with 2 slightly offset,new points and two original points (starting and ending vertices of the polygon)

    #################################################################################        ############
    ##       RECOMBINE POINTS LInes AND polyGONS INTO ONE DATAFRAME                                    ##
    #################################################################################        ############

    #extract only the polygons from the original dataframe 
    data_polygons_final <- subset(data_1,data_1$sptaial_object_type=="polygon") #Save only the rows that are points

    #Combine polygons,lines and points
    data_all_polygons <- rbind(data_points_final,data_linestring_final,data_polygons_final )



    ################THIS PART NEEDS TO BE TURNED INTO A FOR LOOP LATER FOR ALL SPECIES################
    unique_species <- unique(data_all_polygons$species)
    #for (i in 1:length(unique_species)) {   
    i=1 #assign 1 to i since for loop isn't working yet

    data_all_polygons_2 <- data_all_polygons[data_all_polygons$species %in% unique_species[i],] #pull out columns for species i

    #Now convert dataframe to spatial object and assign coordinate system (3528 = Illinois East from https://spatialreference.org/ref/epsg/3528/)
    data_all_polygons_3 <- st_as_sf(data_all_polygons_2,coords = c("POINT_X","POINT_Y"),crs = 3528)


    #Turn all coordinates into spatial polygons (from  https://gis.stackexchange.com/questions/332427/converting-points-to-polygons-by-group)
    data_all_polygons_4 = st_sf( aggregate( data_all_polygons_3$geometry,list(data_all_polygons_3$species_full.subpop_id),function(g){st_cast(st_combine(g),"polyGON")} )) 


    #Create 50 meter buffer around all subpopulations and get overlaps between subpops
    data_all_polygons_50m_buffer <- st_buffer(data_all_polygons_4,50)#Create 50 meter buffer around all subpopulations

    intersection_output <-as.data.frame(st_intersection(x=data_all_polygons_50m_buffer,y=data_all_polygons_50m_buffer) %>% #Get any intersections between all subpopulations mutate(n_overlaps = lengths(st_within(geometry,data_all_polygons_50m_buffer)))) #add intersections to new column in dataframe 

    #Clean output table to leave only unique overlaps
    intersection_output_final <- as.data.frame(intersection_output %>% dplyr::filter(n_overlaps >'0') %>% #remove any columns that show zero overlaps
    filter(Group.1 != Group.1.1) %>% #remove any columns that show 1 overlap as this is the overlap of one subpop with itself
    group_by(grp = paste(pmax(Group.1,Group.1.1),pmin(Group.1,sep = "_")) %>% slice(1) %>%  ungroup() %>%  select(-grp)) #remove any reversed duplicate rows (mirror duplicates)

这一切都运行顺利,但是缓冲区中出了点问题-输出表为我提供了缓冲区之间的许多交集,但是将子种群的坐标(根据我的输出,在50米之内)插入Google地图,这表明大多数交叉点位于相距许多英里的人口之间。因此,我的缓冲区无法正常工作,因为我只希望相距50m或更小的Pops之间的交叉点。我认为这与投影有关,但是在网上搜索了几周后,我找不到它了。我将数据集分配为crs = 3528,因为这是我在网上找到的。我还尝试了许多其他方法包括仅使用wgs84。我从数据中唯一了解到的是它与wgs84相关联,并且坐标在芝加哥地区为纬度/经度。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)