2

I've created a 3D multipatch bounding envelope around a bunch of other 3D features. What I now want to do (using ArcPy) is to make the created bounding box a bit larger and move it upwards, but I can't figure out how to edit multipatch features and there is no documentation on the arcpy.MultiPatch() geometry.

My main strategy so far has been to attempt updating the multipatch with an arcpy.da.UpdateCursor. The cursor consists of the following subclasses:

>>cursor
(<Multipatch object at 0x1ad1a407dd8[0x1ad1a403fa8]>,)
>>cursor[0][0]
<Array [<Point (358405.47030000016, 579663.6179000009, 177.0521000000008, #)>,     <Point (358838.05900000036, 579663.6179000009, 177.0521000000008, #)>, <Point (358405.47030000016, 580131.0997000001, 177.0521000000008, #)>, <Point   (358838.05900000036, 580131.0997000001, 177.0521000000008, #)>, <Point  (358405.47030000016, 580131.0997000001, 177.0521000000008, #)>, <Point  (358838.05900000036, 579663.6179000009, 177.0521000000008, #)>, <Point (358405.47030000016, 579663.6179000009, 531.4100000000035, #)>, ...[way more points]... <Point (358405.47030000016, 579663.6179000009, 531.4100000000035, #)>]>
cursor[0][0][0]
<Point (358405.47030000016, 579663.6179000009, 177.0521000000008, #)>

I have tried to update these, but overwriting the point or array values does nothing since (I think) they're tuples. I also started an editor session, made my changes, updated the rows and ended the session but that also didn't work.

My other approach was to simply copy the points inside the multipatch, change their values (e.g. adding 10m to Z) and construct a new multipatch:

<Array [<Point (358405.47030000016, 579663.6179000009, 176.5, #)>, <Point (358838.05900000036, 579663.6179000009, 176.5, #)>, <Point (358405.47030000016, 580131.0997000001, 176.5, #)>, <Point (358838.05900000036, 580131.0997000001, 176.5, #)>, <Point (358405.47030000016, 580131.0997000001, 176.5, #)>, <Point (358838.05900000036, 579663.6179000009, 176.5, #)>, <Point (358405.47030000016, 579663.6179000009, 536.4100000000035, #)>, <Point (358405.47030000016, 580131.0997000001, 536.4100000000035, #)>, <Point (358838.05900000036, 579663.6179000009, 536.4100000000035, #)>,

So I put the new points in a new array, call arcpy.Multipatch(my new array), but get a runtime error:

>>arcpy.Multipatch(newAr)
Runtime error 
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "s:\ssd applications\arcgis  pro\Resources\arcpy\arcpy\arcobjects\mixins.py", line 224, in __init__
*gp_fixargs(args, True))
File "s:\ssd applications\arcgis pro\Resources\arcpy\arcpy\geoprocessing\_base.py", line 506, in <lambda>
return lambda *args: val(*gp_fixargs(args, True))
RuntimeError: Object: CreateObject cannot create geometry from inputs

I can make a Polyline out of it with the same argument (which results in a useless 2D line), so my array isn't messed. arcpy.Multipatch(cursor[0][0]) also doesn't work.

So with a multipatch that seems locked down an a arcpy.MultiPatch that doesn't accept my array as input, I don't know what I'm doing wrong or what other tools I have left to use.

Here's my current code. bb is the multipatch layer:

with arcpy.da.UpdateCursor(bb,'SHAPE@',explode_to_points = True) as cur:
    for row in cur:
        point = row[0][0]       #Point inside array
        #If the Z value is lower than 200, lower that Z value by 10
        if point.Z <= 200.0: 
            newz = point.Z - 10
            #Create a new point with the same X,Y and new Z
            newpoint = arcpy.Point()
            newpoint.X = point.X
            newpoint.Y = point.Y
            newpoint.Z = newz   
            #This next line doesn't do anything; error, PointGeom obj does not support item assignment
            row[0][0] = arcpy.PointGeometry(newpoint)
            #Same error:
            row[0][0] = newpoint
            #This does not update the Z at all:
            row[0][0].Z = newz
            cur.updateRow(row)
del cur,row
  • Instead of providing just a line or two of code here and there, to help us see at a glance what you are trying to do and where you are stuck, would you be able to provide a single code snippet, please? – PolyGeo Dec 10 '16 at 22:31
  • 1
    Can you read the multipatch JSON? Might be able to construct new geometry object from that. – Paul Dec 10 '16 at 22:31
  • PolyGeo: Good idea. I'll edit the post. Paul: Multipatch is not a supported feature type for the Feature to JSON function, so I don't know how to get a JSON out of it. I can read the point objects and copy them into a new point array, but I don't know how to turn that point array into a multipatch geometry object. – veen Dec 11 '16 at 8:05
  • @veen, what about geometry.JSON? – Paul Dec 11 '16 at 18:05
  • Runtime error Traceback (most recent call last): File "<string>", line 6, in <module> AttributeError: 'Multipatch' object has no attribute 'json' .... It seems like Esri is a bit behind on fully implementing multipatches, sadly. – veen Dec 11 '16 at 18:37
1

If you just want to change the Z-value you can use the Adjust 3D Z toolbox function. It also works for Multipatches.

https://pro.arcgis.com/en/pro-app/tool-reference/data-management/adjust-3d-z.htm

1

As per the comment by @veen:

Relevant response from the Esri devs on multipatch editing capabilities in scripts: 'Thanks for the comment. We definitely want to expose all aspects of Esri 3D capability through scripting and SDKs. This is something that’s on the roadmap and I’ll take a look with the teams at where it is in the priorities.'

It sounds like @veen's requirement is relying on ArcPy to be enhanced before it can provide a solution.

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.