Using a csv file's data to create a set of roads

   1335   1   0
User Avatar
Member
12 posts
Joined: June 2024
Offline
Not sure I'm approaching this in the right way, I'm using Apprentice and have never used Houdini before this week. I'm finding some things quite intuitive, and others absolutely hideously difficult.

Here's what I'm trying to achieve. I've exported some road data from QGIS, which is in the form of road "segments" (sometimes an entire length of road from start to finish, sometimes just a portion of the road). I want to use this data to create a single (or multiple individual) mesh/geometry object for this road network that fits with my exported DEM data.

This is what I've got so far


An example of the pertinent data is here (other fields in the csv exist and some have potential for later use.
"LINESTRING Z (421333.716 465914.083 272.2,421338 465914 272.2,421363 465915 272.4,421371 465915 272.4,421435 465925 272.8,421464 465929 273,421482.398 465931.243 273.1,421504.054 465929.861 273,421694 465913 271.8,421729 465910 271.2,421760 465906 269.9,421929.519 465861.351 263.8,422000.214 465841.341 261.9,422137 465803 264.7)"
The number of coordinates in the row can vary between 2 and many. I've got a Table Import node set to look at the file, and then assign the values to attributes. Next I have a python node which has the following code in
import hou
import re

# Get the current node and geometry
node = hou.pwd()
geo = node.geometry()

# Define the origin for coordinate adjustment
origin_x = 424898.693
origin_y = 467956.814

# Function to parse and adjust LINESTRING data
def parse_linestring(linestring):
    # Define regex pattern to extract the LINESTRING data
    linestring_pattern = re.compile(r'LINESTRING Z \((.*?)\)')
    match = linestring_pattern.search(linestring)
    
    if match:
        points_str = match.group(1)
        # Split points into x, y, z coordinates
        points = points_str.split(',')
        adjusted_points = []
        
        for point in points:
            x, y, z = map(float, point.split())
            # Adjust coordinates based on the origin
            adjusted_x = x - origin_x
            adjusted_y = y - origin_y
            adjusted_points.append((adjusted_x, adjusted_y, 200))
        
        return adjusted_points
    return []
# Get a list of all point attributes
point_attribs = geo.pointAttribs()


# Iterate over each point in the geometry
for point in geo.points():
    
    # Extract the LINESTRING data from the first column (assuming it's stored as an attribute)
    linestring = point.attribValue("WKT")
    # Extract and parse the LINESTRING data
    points = parse_linestring(linestring)
    
    # Create a new curve in Houdini if points are found
    if points:

        #
        curve = geo.createNURBSCurve(len(points),is_closed=False, order=2)
        # Create an empty list of point indices for the curve
        i = 0        
        for x, y, z in points:
            #print(z)
            curve.vertices()[i].point().setPosition((x, y, z))
            curve.vertices()[i].point().setAttribValue("roadName", point.attribValue("roadName"))
            curve.vertices()[i].point().setAttribValue("roadClassificationNumber", point.attribValue("roadClassificationNumber"))
            curve.vertices()[i].point().setAttribValue("minimumWidth", point.attribValue("minimumWidth"))
            curve.vertices()[i].point().setAttribValue("averageWidth", point.attribValue("averageWidth"))
            curve.vertices()[i].point().setAttribValue("formOfWay", point.attribValue("formOfWay"))
            i = i + 1
Image Not Found


This is creating points and geometry, I can see that things are where they should be. (I am creating them all at 200 rather than the Z component from the file because I was trying to see if I could get a simple mesh to extrude using polyexpand2d node. This is later on though.)

I then fuse to make sure that the various points actually are not being duplicated and that the junctions are fully formed. (When I look at this with the point number and primitive number in the scene though I can see that the number of primitives corresponds to the original number of rows in the csv. I'd like where possible to merge the individually named roads together to reduce the count, and to make visualisation of what's going on easier. I've tried various methods of fuse/merge inside foreach groups, and nothing has merged primitives together at all.)

I'm then looking at the geometry spreadsheet and I notice that point 0 is still in the original csv format, and not one of the points created by my python so I use some VEX to delete it in the wrangle node ( Why is that?)

To cut a long story short, I tried using Sweep with a flattened cube to create a roadbed, which didn't work very well, even with vector UP assignment there were still stretches which refused to orient correctly. I've also tried the polyexpand2d route, that fails to cook. If I reduce the number of roads to just 1 then it will work, but clearly that's not really very helpful at all. What is the best way to approach this? Should I be trying to create 1 road at a time? I've watched countless YT videos and read lots of posts, but I've not really found a usecase that seems similar to mine yet to figure out what is the best approach.

Attachments:
node structure.png (22.2 KB)

User Avatar
Member
392 posts
Joined: Aug. 2018
Offline
If you could upload a simplified version of your HIP file plus a very small sample of your data you might have a better chance of someone helping.
  • Quick Links