5

I have a transect line to which I have already added the z value using the Interpolate Shape tool. I need to split this line into 100m in 3D length, which due to elevation must be different than 2D. However the split tool in 3D editor only gives me the 2D length.

Is there anyway to resolve this?

It will be great if I can do it in batch process.

2

Here a simple python snippet showing how to do it.

#!/usr/bin/python
import math
# -----------------------------------------------------------
# Python snippet to calculate a stepped vertex vector 
# -----------------------------------------------------------
# A Vertex class with the distance calculation
# -----------------------------------------------------------
class Vertex: 
    x = 0
    y = 0
    z = 0
    # Create a vertex by given x, y, z
    def __init__(self, aX, aY, aZ):
        self.x = aX
        self.y = aY
        self.z = aZ

    # Calculate the sqared euclidian distance 
    def distanceSqr(self, aVertex):
        dx = self.x-aVertex.x
        dy = self.y-aVertex.y
        dz = self.z-aVertex.z
        return (dx*dx+dy*dy+dz*dz)

    # Calculate the euclidian distance 
    def distance(self, aVertex):
        return math.sqrt(self.distanceSqr(aVertex))

# -----------------------------------------------------------
# Segment a stroke from x1,y1,z1 to x2, y2, z2
# -----------------------------------------------------------
class Segment:
    #Start vertex by default the origin 
    startVertex = Vertex(0,0,0);        

    #Start vertex by default the 1,1,1 
    endVertex   = Vertex(1,1,1);        

    # Create a Segment 
    def __init__(self, aStartVertex, aEndVertex):
        self.startVertex = aStartVertex
        self.endVertex = aEndVertex

    # Split the a semgent by a given stepSize and an offset
    # @param self Segment
    # @param offset an offset from the startVertex
    # @param stepSize the step size on the segment where you 
    #        want to splite
    # @param resulting vector 
    def split(self, offset, stepSize, result):
        # Length of the segment 
        length = self.startVertex.distance(self.endVertex)
        # if length zero ...nonsense
        if length == 0: 
            return result
        # Gradient dx, dy, dz
        dx = (self.endVertex.x - self.startVertex.x)/length
        dy = (self.endVertex.y - self.startVertex.y)/length
        dz = (self.endVertex.z - self.startVertex.z)/length
        # set stepping index zero
        index = 0
        # calculate the current pos on the stepped segment
        curLen = offset + stepSize * index
        # while the current length is smallet the the length 
        # of the segment
        while curLen < length:
            # calculate new verices and store them in the result vector
            x = self.startVertex.x + dx * curLen
            y = self.startVertex.y + dy * curLen
            z = self.startVertex.z + dz * curLen
            result.append(Vertex(x,y,z))
            # increase the stepping index
            index += 1
            # calculate the new actual length
            curLen = offset + stepSize * index
            # determing the index for the next step
        offset = curLen - length
        # return the vector and the offset for the next calculation
        return (result, offset)

# -----------------------------------------------------------
# A Vector to collect all vertices
# -----------------------------------------------------------
class VertexVector(object): 

    # Create the vector
    def __init__(self, aVertex):
        self.v = aVertex

# -----------------------------------------------------------
# List a VertexVector
# -----------------------------------------------------------
def vectorList(vector, header):
    print header
    print "  X   Y   Z   D  "
    print "-----------------"
    for ix in range(0,len(vector)):
        end = vector[ix]
        start = end
        if ix>0: start = vector[ix-1] 
        print end.x, end.y, end.z, start.distance(end)
    print "----\n"

# -----------------------------------------------------------
# Create a a splitted vector by splitting each segment and handle 
# the remaining offset and end vertex
# -----------------------------------------------------------
def vectorSteps(vector, stepSize, useLast):
    # Create the resulting vector
    result = []

    # Take an offset with default zero
    offset = 0

    # Index length of the vector
    vecLen = len(vector)
    for ix in range(1,vecLen):
        # Choose the start vertex
        start = vector[ix-1]
        # Choose the end vertex
        end   = vector[ix]
        # Create the segmet
        seg = Segment(start,end)
        # Calculate a stepped version of the segment ad get the offset
        (result, offset) = seg.split( offset, stepSize, result)
        # Append the end vertex if expected
        if ix == (vecLen-1) and useLast : 
            result.append(end)
    # return a stepped version of the vector
    return result


# ----------------------------------------------------
# Mainprogram
# ----------------------------------------------------
# Create a Transect 
transect = [];
transect.append(Vertex( 0, 0, 0))
transect.append(Vertex( 1, 1, 1))
transect.append(Vertex( 0, 0, 0))
# List the transect
vectorList(transect,"Original Transect")

# Calculate the stepped transect
segTransect = vectorSteps(transect,0.3, True);
# List the stepped transect
vectorList(segTransect,"Segmented Transect")

# ----------------------------------------------------
# EOF
# ----------------------------------------------------

And the result

huckfinn@whee:~/Tests$ ./SplitLine3D.py 
Original Transect
  X   Y   Z   D  
-----------------
0 0 0 0.0
1 1 1 1.73205080757
0 0 0 1.73205080757
----

offset  0.0679491924311
offset  0.135898384862
Segmented Transect
  X   Y   Z   D  
-----------------
0.0 0.0 0.0 0.0
0.173205080757 0.173205080757 0.173205080757 0.3
0.346410161514 0.346410161514 0.346410161514 0.3
0.519615242271 0.519615242271 0.519615242271 0.3
0.692820323028 0.692820323028 0.692820323028 0.3
0.866025403784 0.866025403784 0.866025403784 0.3
0.960769515459 0.960769515459 0.960769515459 0.164101615138 ! Correct but miss the corner 1,1,1
0.787564434702 0.787564434702 0.787564434702 0.3
0.614359353945 0.614359353945 0.614359353945 0.3
0.441154273188 0.441154273188 0.441154273188 0.3
0.267949192431 0.267949192431 0.267949192431 0.3
0.0947441116742 0.0947441116742 0.0947441116742 0.3
0 0 0 0.164101615138
----

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.