class EngineeringReviewService: def __init__(self,layers,objects,topology): self.layers,self.objects,self.topology=layers,objects,topology @staticmethod def num(r,names): for n in names: try: if r.get(n) not in (None,""): return float(r[n]) except Exception: pass return None def conduit_screening(self): out=[] for r in self.objects.collection_records("Conduits"): L=self.num(r,("Length","Len")); D=self.num(r,("Geom1","Diameter","Height")); S=self.num(r,("Slope","PipeSlope")) issues=[] if L is not None and L<=0: issues.append("non-positive length") if D is not None and D<=0: issues.append("non-positive diameter/height") if S is not None and S<0: issues.append("negative slope") if issues: out.append({"Name":r.get("Name"),"issues":issues,"Length":L,"DiameterOrHeight":D,"Slope":S}) return out def subcatchment_screening(self): try: rows=self.layers.records("Subcatchments") except Exception: rows=self.objects.collection_records("Subcatchments") out=[] for r in rows: A=self.num(r,("Area","TotalArea")); I=self.num(r,("PctImperv","PercentImpervious","%Imperv")); W=self.num(r,("Width",)); S=self.num(r,("Slope","%Slope")); O=r.get("Outlet") issues=[] if A is not None and A<=0: issues.append("non-positive area") if I is not None and not 0<=I<=100: issues.append("imperviousness outside 0–100%") if W is not None and W<=0: issues.append("non-positive width") if S is not None and S<0: issues.append("negative slope") if O in (None,""): issues.append("missing outlet") if issues: out.append({"Name":r.get("Name"),"Outlet":O,"Area":A,"PctImperv":I,"Width":W,"Slope":S,"issues":issues}) return out def model_screening_summary(self): return {"orphan_link_count":len(self.topology.orphan_links()),"isolated_node_count":len(self.topology.isolated_nodes()), "duplicate_link_pair_count":len(self.topology.duplicate_link_pairs()),"conduit_finding_count":len(self.conduit_screening()), "subcatchment_finding_count":len(self.subcatchment_screening())}