Get TopographySurface Z at XY with Python

Good morning,
I am working on helping my team identify the height above or below the topography our man hole and hand holes are in a large model. Inside the model I have a Topography, and TopographyLink available and am attempting to utilize the TopographySurface.FindPoints(Outline) method, and have had some great results for just under half the elements, but for the life of me cannot get the other elements provide information. If I cut a section box, I see the element and the topography intersecting but its not finding a point within the Outline… I am only interested in the Z, and am not dead set on this method, just found it and thought it worked until I my team started double checking the values in depth. Codes a draft so still its a bit of a mess still.

import clr
import sys

pyPath = r"C:\Program Files (x86)\IronPython 2.7\Lib"
sys.path.append(pyPath)

import System 
import System.Collections
#Access to Revit Document
clr.AddReference("RevitServices")
import RevitServices
#To Get Doc, UI and Application Objects
from RevitServices.Persistence import DocumentManager
#Needed to make any changes in Revit
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

from Autodesk.Revit.DB.Structure import *
clr.AddReference("RevitAPIUI")
from Autodesk.Revit.UI import *
from System.Collections.Generic import List
import traceback

doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIDocument
app = DocumentManager.Instance.CurrentUIApplication.Application

activeView = doc.ActiveView

activeViewFEC = FilteredElementCollector(doc, activeView.Id).OfCategory(BuiltInCategory.OST_ElectricalEquipment).WhereElementIsNotElementType().ToElements()
FECTopo = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Topography).WhereElementIsNotElementType().FirstElement()



i=0
mTP = []
elemMaxTP = None
for aVFEC in activeViewFEC:
	elemFamName =  aVFEC.get_Parameter(BuiltInParameter.ELEM_FAMILY_PARAM).AsValueString()
	elemLocation = aVFEC.Location.Point
	zList = []
	if elemFamName.__contains__("HEC_EQ - "):
		minXYZ = aVFEC.get_BoundingBox(None).Min
		#newMin = XYZ(minXYZ.X, minXYZ.Y , (minXYZ.Z -50))
		maxXYZ = aVFEC.get_BoundingBox(None).Max 
		#newMax = XYZ(maxXYZ.X, maxXYZ.Y , (maxXYZ.Z +50))
		outline = Outline(minXYZ,maxXYZ)
		topoPoint = FECTopo.FindPoints(outline)
		
		
		for tP in (tP for tP in topoPoint if tP != ""):
			tPZ = tP.Z
			zList.Add(tPZ)
		zList.sort()
		if zList:
			elemMaxTP = elemLocation.Z - zList[0]
		else:
			elemMaxTP = elemLocation.Z - 1000
		
		oldVal = aVFEC.LookupParameter("FOOTAGE").AsValueString()
		if aVFEC.LookupParameter("FOOTAGE").AsDouble() != elemMaxTP:
			TransactionManager.Instance.EnsureInTransaction(doc)
			aVFEC.LookupParameter("user filter 1").Set("Original Value: " + oldVal)
			TransactionManager.Instance.TransactionTaskDone()	
		
		if elemMaxTP != None:
			TransactionManager.Instance.EnsureInTransaction(doc)
			aVFEC.LookupParameter("FOOTAGE").Set(elemMaxTP)
			aVFEC.LookupParameter("user filter 0").Set("Topo Validation")
			TransactionManager.Instance.TransactionTaskDone()	
		
	zList.Clear()
	i+=1	
		
		
	
OUT = i, elemLocation, zList, elemMaxTP, oldVal, minXYZ,  maxXYZ
        
				
	

It might be easier to creat a building pad from the bounding box, pull the associated topography of the pads, and get the heights between corner points of the topography. It won’t be 100% accurate, but it’ll be within the construction tolerances for sure.

A prior post which will help: Toposurface : Elevation at a given point - #8 by jacob.small

2 Likes

I will give that a shot, Thank you sir!

Ended up not being able to figure out the pad corners for some reason… so instead went this route:

1 Like