Home > Software engineering >  assign stick name to point in r sf
assign stick name to point in r sf

Time:02-03

I have three shapefiles, two are polylines and one is a point file. I am trying to assign the stick name of one file to the marker based on closest distance, however if the other polyline is between the two, i don't want to assign the stick value. See below image for a better understanding. example

Example data

points<-structure(list(HCPV__M = c(0.162004378, 0.226535736, 0.211458087, 
0.185156191, 0.185477992), SAND = c("A", "A", "A", "A", "A"), 
    RprFWoS = c(0.809258274, 0.48688902, 0.612390206, 0.772188963, 
    0.766851016), ROW_ID = c(20786L, 21164L, 21166L, 21543L, 
    21545L), bufferd = c(84L, 104L, 105L, 124L, 125L), geometry = structure(list(
        structure(c(156726.858085809, 2268031.5369828), class = c("XY", 
        "POINT", "sfg")), structure(c(156916.30782334, 2268042.94664473
        ), class = c("XY", "POINT", "sfg")), structure(c(156905.361863645, 
        2268225.09390341), class = c("XY", "POINT", "sfg")), 
        structure(c(157106.067661262, 2268054.37425309), class = c("XY", 
        "POINT", "sfg")), structure(c(157095.123521099, 2268236.52162291
        ), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
    "sfc"), precision = 0, bbox = structure(c(xmin = 156726.858085809, 
    ymin = 2268031.5369828, xmax = 157106.067661262, ymax = 2268236.52162291
    ), class = "bbox"), crs = structure(list(input = NA_character_, 
        wkt = NA_character_), class = "crs"), n_empty = 0L), 
    bufferid = 1:5), row.names = c(NA, 5L), class = c("sf", "tbl_df", 
"tbl", "data.frame"), sf_column = "geometry", agr = structure(c(HCPV__M = NA_integer_, 
SAND = NA_integer_, RprFWoS = NA_integer_, ROW_ID = NA_integer_, 
bufferd = NA_integer_, bufferid = NA_integer_), levels = c("constant", 
"aggregate", "identity"), class = "factor"))

##blue and green line sticks
sticks<-structure(list(OBJECTI = c(276, 306), PARENT_ = c("2U-15", "2W-05"
), SAND = c("A", "A"), fll_lng = c(1367.40152118798, 1442.74224067384
), geometry = structure(list(structure(c(156967.0539, 157006.7762, 
156980.3527, 156916.1701, 156785.8416, 2268966.7538, 2268419.012, 
2267871.2701, 2267780.608, 2267689.9459), dim = c(5L, 2L), class = c("XY", 
"LINESTRING", "sfg")), structure(c(157418.9385, 157410.2798, 
157384.6876, 157354.7615, 157331.3318, 157287.8668, 157257.1019, 
157249.3726, 157259.4366, 157270.0297, 2267660.9641, 2267618.8044, 
2267580.878, 2267609.7367, 2267672.8495, 2267873.7395, 2268078.8629, 
2268424.712, 2268639.9229, 2268910.4318), dim = c(10L, 2L), class = c("XY", 
"LINESTRING", "sfg"))), class = c("sfc_LINESTRING", "sfc"), precision = 0, bbox = structure(c(xmin = 156785.8416, 
ymin = 2267580.878, xmax = 157418.9385, ymax = 2268966.7538), class = "bbox"), crs = structure(list(
    input = NA_character_, wkt = NA_character_), class = "crs"), n_empty = 0L)), row.names = 1:2, sf_column = "geometry", agr = structure(c(OBJECTI = NA_integer_, 
PARENT_ = NA_integer_, SAND = NA_integer_, fll_lng = NA_integer_
), levels = c("constant", "aggregate", "identity"), class = "factor"), class = c("sf", 
"tbl_df", "tbl", "data.frame"))

###fault network

fault_network<-structure(list(FID = 0, geometry = structure(list(structure(list(
    structure(c(156810.024209955, 156810.060697552, 156810.079046282, 
    156810.079201361, 156806.444070142, 156885.163267909, 156931.52994574, 
    156932.297154144, 156932.304697859, 156940.44669786, 156940.466873182, 
    156951.835273182, 156951.873077278, 156967.582377276, 156967.630320938, 
    156987.511120939, 156987.54030165, 157009.574001649, 157009.597233361, 
    157033.195433362, 157033.261512764, 157060.804012764, 157060.851904448, 
    157090.877006476, 157115.60135255, 157131.323124129, 157138.414003061, 
    157135.375960797, 157126.32142518, 157126.298536579, 157126.292339323, 
    157126.302850397, 157126.330040991, 157126.373836578, 157126.434117117, 
    157126.510717383, 157126.603427421, 157126.711993118, 157126.836116904, 
    157126.975458563, 157127.129636171, 157127.298227136, 157127.480769364, 
    157127.676762517, 157127.885669394, 157128.106917393, 157128.339900091, 
    157128.583978898, 157128.83848481, 157129.102720244, 157129.37596095, 
    157129.657457995, 157129.946439813, 157130.242114326, 157130.54367111, 
    157130.850283621, 157131.161111453, 157131.475302649, 157131.475954896, 
    157131.47829809, 157131.794991445, 157132.113318966, 157132.43240814, 
    157132.751384365, 157133.069373349, 157133.385503508, 157133.69890835, 
    157134.008728854, 157134.314115824, 157134.614232216, 157134.90825543, 
    157135.195379571, 157135.47481765, 157135.745803748, 157136.00759511, 
    157136.259474184, 157136.500750588, 157136.730762999, 157136.94888097, 
    157137.154506654, 157137.347076445, 157137.526062524, 157137.690974301, 
    157137.841359766, 157137.976806721, 157138.096943917, 157138.201442065, 
    157138.290014743, 157138.36241918, 157138.418456921, 157138.457974369, 
    157147.53247437, 157147.558705079, 157150.613105077, 157150.614768518, 
    157150.599797921, 157143.465697922, 157143.439726112, 157143.401667395, 
    157127.589167395, 157127.536147824, 157127.469944466, 157102.630344465, 
    157102.536395551, 157072.48488283, 157045.000864564, 157021.445178971, 
    156999.438032853, 156979.597852061, 156963.93175165, 156952.591081196, 
    156944.461586561, 156937.929146272, 156937.925225103, 156930.511325104, 
    156930.487628526, 156919.134628526, 156919.066190762, 156900.584990762, 
    156900.518069809, 156877.111507604, 156854.425206646, 156834.095620318, 
    156834.078427899, 156812.472527898, 156812.467161651, 156790.517967414, 
    156773.822756829, 156757.744705552, 156757.682460273, 156757.603918421, 
    156757.509295269, 156757.398850168, 156757.272885833, 156757.131747517, 
    156756.975822062, 156756.80553684, 156756.62135858, 156756.423792093, 
    156756.213378882, 156755.990695664, 156755.756352785, 156755.510992549, 
    156755.255287457, 156754.989938364, 156754.715672559, 156754.433241769, 
    156754.1434201, 156753.847001918, 156753.544799667, 156753.237641645, 
    156752.926369732, 156752.611837086, 156752.294905801, 156751.976444544, 
    156751.657326179, 156751.338425366, 156751.020616174, 156750.704769677, 
    156750.391751569, 156750.082419794, 156749.77762219, 156749.47819417, 
    156749.184956427, 156748.898712688, 156748.620247512, 156748.350324136, 
    156748.089682385, 156747.839036646, 156747.599073906, 156747.370451873, 
    156747.153797171, 156746.949703623, 156746.758730623, 156746.581401603, 
    156746.418202602, 156746.269580925, 156746.135943926, 156746.017657887, 
    156745.915047015, 156745.828392554, 156745.757932012, 156745.703858512, 
    156745.666320264, 156745.645420155, 156745.641215469, 156745.653717731, 
    156745.682892673, 156745.728660332, 156761.804560332, 156761.806501864, 
    156778.531101864, 156778.596838348, 156800.580631986, 156822.175018599, 
    156842.511980948, 156842.545013341, 156865.253913342, 156865.264430547, 
    156888.63895026, 156907.048134866, 156918.360737381, 156925.763090918, 
    156930.669259378, 156930.561827929, 156930.251000239, 156929.936809152, 
    156929.620115845, 156929.301788351, 156928.982699185, 156928.663722947, 
    156928.34573393, 156928.029603719, 156927.716198804, 156927.406378208, 
    156927.100991127, 156926.800874605, 156926.506851241, 156926.219726933, 
    156925.940288668, 156925.669302368, 156925.407510787, 156925.155631477, 
    156924.914354822, 156924.684342145, 156924.466223895, 156924.260597917, 
    156924.06802782, 156874.474527821, 156874.290577311, 156874.121540273, 
    156873.967907177, 156873.830123797, 156873.70858992, 156873.603658182, 
    156873.515633048, 156873.444769929, 156794.346769928, 156794.292870719, 
    156794.256813592, 156794.238705066, 156794.23859864, 156797.878148857, 
    156796.574790047, 156796.539466995, 156796.520792719, 156796.518818404, 
    156796.533549462, 156796.564945516, 156796.612920512, 156796.677342953, 
    156796.758036261, 156796.854779263, 156796.967306793, 156797.095310419, 
    156797.238439294, 156797.396301111, 156797.568463181, 156797.75445362, 
    156797.953762642, 156798.165843955, 156798.390116257, 156798.625964835, 
    156798.872743244, 156799.129775081, 156799.39635584, 156799.671754841, 
    156799.955217236, 156800.245966073, 156800.54320443, 156800.846117598, 
    156801.153875311, 156801.465634029, 156801.780539242, 156802.097727816, 
    156802.41633036, 156802.735473607, 156803.054282806, 156803.371884125, 
    156803.687407039, 156803.999986723, 156804.308766417, 156804.612899778, 
    156804.911553198, 156805.203908087, 156805.489163122, 156805.766536438, 
    156806.035267775, 156806.294620558, 156806.543883919, 156806.782374646, 
    156807.009439051, 156807.224454767, 156807.42683245, 156807.616017398, 
    156807.791491067, 156807.952772497, 156808.099419626, 156808.231030505, 
    156808.347244398, 156808.447742769, 156808.532250161, 156808.600534944, 
    156808.652409955, 156810.024209955, 2268231.49616076, 2268231.16507166, 
    2268230.83248384, 2268230.49939029, 2268095.18812376, 2267687.14843899, 
    2267622.41459747, 2267633.8580803, 2267633.95823192, 2267731.33553192, 
    2267731.53662043, 2267828.61622043, 2267828.88651619, 2267925.40291619, 
    2267925.66202587, 2268021.48212587, 2268021.61526823, 2268117.03416823, 
    2268117.13114976, 2268212.20314976, 2268212.44754632, 2268306.51604632, 
    2268306.67185928, 2268399.89976863, 2268494.13779165, 2268590.02088181, 
    2268686.78457759, 2268783.66772944, 2268875.80369603, 2268876.12202357, 
    2268876.44111275, 2268876.76008897, 2268877.07807793, 2268877.39420806, 
    2268877.70761285, 2268878.0174333, 2268878.3228202, 2268878.62293651, 
    2268878.91695963, 2268879.20408366, 2268879.48352163, 2268879.7545076, 
    2268880.01629882, 2268880.26817775, 2268880.50945399, 2268880.73946624, 
    2268880.95758403, 2268881.16320953, 2268881.35577913, 2268881.53476501, 
    2268881.69967658, 2268881.85006183, 2268881.98550857, 2268882.10564554, 
    2268882.21014346, 2268882.29871591, 2268882.37112011, 2268882.42715761, 
    2268882.427239, 2268882.42765692, 2268882.46717437, 2268882.49006321, 
    2268882.49626071, 2268882.48574988, 2268882.45855952, 2268882.41476417, 
    2268882.35448387, 2268882.27788384, 2268882.18517403, 2268882.07660856, 
    2268881.952485, 2268881.81314356, 2268881.65896616, 2268881.4903754, 
    2268881.30783337, 2268881.11184041, 2268880.90293371, 2268880.68168589, 
    2268880.44870336, 2268880.20462471, 2268879.95011894, 2268879.68588364, 
    2268879.41264306, 2268879.13114613, 2268878.84216441, 2268878.54648999, 
    2268878.24493328, 2268877.93832084, 2268877.62749306, 2268877.31330191, 
    2268876.99660855, 2268784.65820855, 2268784.25306283, 2268686.84806283, 
    2268686.529597, 2268686.21147889, 2268588.85767889, 2268588.58652989, 
    2268588.3168118, 2268491.8814118, 2268491.59971214, 2268491.32081631, 
    2268396.64281631, 2268396.32104072, 2268303.01112619, 2268209.14246416, 
    2268114.24184526, 2268018.93793921, 2267923.31371264, 2267827.06221371, 
    2267730.21865597, 2267632.99221256, 2267535.55452591, 2267535.49973742, 
    2267438.07543742, 2267437.82984863, 2267340.76114863, 2267340.31797954, 
    2267244.22497954, 2267243.91949633, 2267148.81258517, 2267053.63189975, 
    2266957.93949411, 2266957.86111019, 2266862.36321018, 2266862.33970744, 
    2266767.07642087, 2266670.94414733, 2266577.34507036, 2266577.03205329, 
    2266576.72272281, 2266576.41792677, 2266576.11850057, 2266575.82526491, 
    2266575.53902351, 2266575.26056091, 2266574.99064035, 2266574.73000164, 
    2266574.47935917, 2266574.23939991, 2266574.01078155, 2266573.79413073, 
    2266573.59004123, 2266573.39907246, 2266573.22174783, 2266573.05855336, 
    2266572.90993635, 2266572.77630414, 2266572.658023, 2266572.55541713, 
    2266572.46876774, 2266572.39831235, 2266572.34424405, 2266572.30671104, 
    2266572.28581619, 2266572.28161678, 2266572.29412431, 2266572.32330451, 
    2266572.36907739, 2266572.43131749, 2266572.50985423, 2266572.60447235, 
    2266572.7149125, 2266572.84087199, 2266572.98200557, 2266573.13792642, 
    2266573.30820718, 2266573.49238113, 2266573.68994348, 2266573.90035272, 
    2266574.12303216, 2266574.35737146, 2266574.60272832, 2266574.85843026, 
    2266575.12377642, 2266575.39803953, 2266575.68046786, 2266575.97028732, 
    2266576.26670355, 2266576.5689041, 2266576.87606069, 2266577.18733144, 
    2266577.50186319, 2266577.81879386, 2266578.13725477, 2266578.45637306, 
    2266578.77527408, 2266579.09308376, 2266579.40893101, 2266673.01403101, 
    2266673.0252729, 2266769.3268729, 2266769.65249256, 2266865.06594648, 
    2266960.51295741, 2267056.23961185, 2267056.38618604, 2267151.66178604, 
    2267151.70520512, 2267246.68181952, 2267342.40069418, 2267439.12379443, 
    2267536.39767717, 2267609.57682151, 2267609.5457871, 2267609.47338229, 
    2267609.41734418, 2267609.37782635, 2267609.35493712, 2267609.34873924, 
    2267609.35924969, 2267609.38643966, 2267609.43023463, 2267609.49051456, 
    2267609.56711422, 2267609.65982366, 2267609.76838877, 2267609.89251198, 
    2267610.03185307, 2267610.18603013, 2267610.35462057, 2267610.53716228, 
    2267610.73315494, 2267610.94206135, 2267611.1633089, 2267611.39629117, 
    2267611.64036957, 2267611.89487511, 2267681.13377511, 2267681.40578149, 
    2267681.68729836, 2267681.97750886, 2267682.27557095, 2267682.58061977, 
    2267682.8917702, 2267683.20811944, 2267683.52874958, 2268093.53194958, 
    2268093.85887034, 2268094.18823668, 2268094.51907559, 2268094.85040971, 
    2268230.32616553, 2268239.77413924, 2268240.09132782, 2268240.40993036, 
    2268240.72907361, 2268241.04788281, 2268241.36548412, 2268241.68100704, 
    2268241.99358672, 2268242.30236642, 2268242.60649978, 2268242.9051532, 
    2268243.19750809, 2268243.48276312, 2268243.76013644, 2268244.02886777, 
    2268244.28822056, 2268244.53748392, 2268244.77597464, 2268245.00303905, 
    2268245.21805477, 2268245.42043245, 2268245.6096174, 2268245.78509107, 
    2268245.9463725, 2268246.09301963, 2268246.2246305, 2268246.3408444, 
    2268246.44134277, 2268246.52585016, 2268246.59413494, 2268246.64600995, 
    2268246.68133301, 2268246.70000728, 2268246.7019816, 2268246.68725054, 
    2268246.65585448, 2268246.60787949, 2268246.54345705, 2268246.46276374, 
    2268246.36602074, 2268246.25349321, 2268246.12548958, 2268245.98236071, 
    2268245.82449889, 2268245.65233682, 2268245.46634638, 2268245.26703736, 
    2268245.05495605, 2268244.83068374, 2268244.59483517, 2268244.34805676, 
    2268244.09102492, 2268243.82444416, 2268243.54904516, 2268243.26558276, 
    2268242.97483393, 2268242.67759557, 2268242.3746824, 2268242.06692469, 
    2268241.75516597, 2268241.44026076, 2268231.49616076), dim = c(305L, 
    2L))), class = c("XY", "POLYGON", "sfg"))), n_empty = 0L, crs = structure(list(
    input = NA_character_, wkt = NA_character_), class = "crs"), class = c("sfc_POLYGON", 
"sfc"), precision = 0, bbox = structure(c(xmin = 156745.641215469, 
ymin = 2266572.28161678, xmax = 157150.614768518, ymax = 2268882.49626071
), class = "bbox"))), row.names = 1L, sf_column = "geometry", agr = structure(c(FID = NA_integer_), class = "factor", levels = c("constant", 
"aggregate", "identity")), class = c("sf", "tbl_df", "tbl", "data.frame"
))

here is my code so far but can't seem to figure out how to remove/assign points to the blue line that are further away from the green line becuase the red line is between the given marker and the green line as seen in the example.


sticks<-sticks%>%filter(PARENT_ %in% c("2U-15","2W-05"))





sfc_as_cols <- function(x, geometry, names = c("x", "y")) {
  if (missing(geometry)) {
    geometry <- sf::st_geometry(x)
  } else {
    geometry <- rlang::eval_tidy(enquo(geometry), x)
  }
  stopifnot(inherits(x, "sf") &&
              inherits(geometry, "sfc_POINT"))
  ret <- sf::st_coordinates(geometry)
  ret <- tibble::as_tibble(ret)
  stopifnot(length(names) == ncol(ret))
  x <- x[, !names(x) %in% names]
  ret <- setNames(ret, names)
  dplyr::bind_cols(x, ret)
}


points<- points%>% mutate(bufferid = row_number())



distance_ft=500

buf <- st_buffer(points, distance_ft/3.2808399)

faults <- st_difference(buf,fault_network) %>% st_cast("MULTIPOLYGON") %>% st_cast("POLYGON")
faults <- faults %>% mutate(rowid = row_number())

result=data.frame()

fault_filter_function <- function(i) {
  faults_filter <- faults %>% filter(i == bufferid)
  points_filter <- points %>% filter(i == bufferid)
  result_it <- st_intersection(faults_filter, points_filter)
  result <<-rbind(result,result_it)
}

lapply(points$bufferid,fault_filter_function)



fault_filter <- st_intersection(faults, points)
faults <- faults%>%filter(rowid %in% c(result$rowid))

assignment <- st_intersection(sticks, faults) 

ggplot(assignment) geom_sf(data=faults,fill='blue') geom_sf() geom_sf(data=sticks,color='red')

CodePudding user response:

This is an interesting problem. If I read it correctly you are evaluating many points to two stick lines, considering two aspects:

  • distance
  • crossing of fault line.

For each point you want to find the shortest distance that does not cross the fault line. If distances to both sticks cross the fault line no stick is identified for the point in question.

Distances of points to line can be found via sf::st_nearest_points(); it will return a linestring.

To determine two lines crossing we can use sf::st_crosses(); it can be coaxed to return a boolean vector by using sparse = FALSE setting.

To bind it all together I propose the following code; it assumes that row_id is an unique identifier of a point and parent is unique identifier of a stick; if this is not the case you will need to adjust accordingly (you will need unique ids for both entities).

candidates <- data.frame() # initiate empty result set

# iterate over sticks - either two or "many"
for (working_stick in sticks$PARENT_) {
  
  # calculate point to stick distnaces as linestrings
  stick_candidate <- st_nearest_points(points, filter(sticks, PARENT_ == working_stick)) %>% 
    st_as_sf()
  
  # populate point id's
  stick_candidate$row_id <- points$ROW_ID
  
  # populate stick id's 
  stick_candidate$parent <- working_stick
  
  # bind results
  candidates <- rbind(candidates, stick_candidate)
  
}

# mark candidates crossing fault line
candidates$legal <- !st_crosses(candidates, fault_network, sparse = F)[, 1]

# calculate length
candidates$length <- st_length(candidates)

# find shortest distance for legal candidates
candidates %>% 
  st_drop_geometry() %>% # spatial dimension is no longer required
  filter(legal) %>% 
  group_by(row_id) %>% 
  slice_head(n = 1)

# A tibble: 4 × 4
# Groups:   row_id [4]
#   row_id parent legal length
#    <int> <chr>  <lgl>  <dbl>
# 1  21164 2U-15  TRUE    72.2
# 2  21166 2U-15  TRUE    92.0
# 3  21543 2W-05  TRUE   153. 
# 4  21545 2W-05  TRUE   158. 

You will note that even though you started with five points you are getting only four results; this is due to the fact that for the point number 20786 the closest distance to both sticks crosses the fault line.

  •  Tags:  
  • rsf
  • Related