1

如果你有一个多线串:

multiline <- MULTILINESTRING ((12.573769564824442 55.67932019039465, 12.573664593749626 55.67929917900955, 12.572916898811318 55.679149506755245, 12.5722100725459 55.679011254788364, 12.572044628054563 55.678978898110536))

有没有一种聪明的方法可以把它分成等长的 X 行?

lines_of_equal_length <- cool_function(multiline)

或者您是否必须从零开始编写这样的函数,例如通过计算线的长度,然后将长度除以 X,然后沿着线运行并每隔 y 米切割一次?

4

1 回答 1

1

我找到了一篇不错的博客文章,详细介绍了它,Segmentation of spatial lines。基本上你将你的多线串转换成空间线,然后在博客中描述了很多很好的函数来发挥作用。

转换为空间线:

library(rgeos)
spatialLines <- readWKT(multiline)

功能一:创建线段

CreateSegment <- function(coords, from, to) {
    distance <- 0
    coordsOut <- c()
    biggerThanFrom <- F
    for (i in 1:(nrow(coords) - 1)) {
        d <- sqrt((coords[i, 1] - coords[i + 1, 1])^2 + (coords[i, 2] - coords[i + 
            1, 2])^2)
        distance <- distance + d
        if (!biggerThanFrom && (distance > from)) {
            w <- 1 - (distance - from)/d
            x <- coords[i, 1] + w * (coords[i + 1, 1] - coords[i, 1])
            y <- coords[i, 2] + w * (coords[i + 1, 2] - coords[i, 2])
            coordsOut <- rbind(coordsOut, c(x, y))
            biggerThanFrom <- T
        }
        if (biggerThanFrom) {
            if (distance > to) {
                w <- 1 - (distance - to)/d
                x <- coords[i, 1] + w * (coords[i + 1, 1] - coords[i, 1])
                y <- coords[i, 2] + w * (coords[i + 1, 2] - coords[i, 2])
                coordsOut <- rbind(coordsOut, c(x, y))
                break
            }
            coordsOut <- rbind(coordsOut, c(coords[i + 1, 1], coords[i + 1, 
                2]))
        }
    }
    return(coordsOut)
}

功能 2:创建线段

CreateSegments <- function(coords, length = 0, n.parts = 0) {
    stopifnot((length > 0 || n.parts > 0))
    # calculate total length line
    total_length <- 0
    for (i in 1:(nrow(coords) - 1)) {
        d <- sqrt((coords[i, 1] - coords[i + 1, 1])^2 + (coords[i, 2] - coords[i + 
            1, 2])^2)
        total_length <- total_length + d
    }

    # calculate stationing of segments
    if (length > 0) {
        stationing <- c(seq(from = 0, to = total_length, by = length), total_length)
    } else {
        stationing <- c(seq(from = 0, to = total_length, length.out = n.parts), 
            total_length)
    }

    # calculate segments and store the in list
    newlines <- list()
    for (i in 1:(length(stationing) - 1)) {
        newlines[[i]] <- CreateSegment(coords, stationing[i], stationing[i + 
            1])
    }
    return(newlines)
}

功能3:合并到最后一条线段

MergeLast <- function(lst) {
    l <- length(lst)
    lst[[l - 1]] <- rbind(lst[[l - 1]], lst[[l]])
    lst <- lst[1:(l - 1)]
    return(lst)
}

功能4:将它们放在一起,可以将空间线切割成n-1线或一定长度的线

SegmentSpatialLines <- function(sl, length = 0, n.parts = 0, merge.last = FALSE) {
    stopifnot((length > 0 || n.parts > 0))
    id <- 0
    newlines <- list()
    sl <- as(sl, "SpatialLines")
    for (lines in sl@lines) {
        for (line in lines@Lines) {
            crds <- line@coords
            # create segments
            segments <- CreateSegments(coords = crds, length, n.parts)
            if (merge.last && length(segments) > 1) {
                # in case there is only one segment, merging would result into error
                segments <- MergeLast(segments)
            }
            # transform segments to lineslist for SpatialLines object
            for (segment in segments) {
                newlines <- c(newlines, Lines(list(Line(unlist(segment))), ID = as.character(id)))
                id <- id + 1
            }
        }
    }
    return(SpatialLines(newlines))
}

同样,所有功劳归于函数的创建者:Creator

于 2017-11-15T09:22:23.483 回答