示例#1
0
def getAreaOfGML(poly, height=True):
    """Function which reads <gml:Polygon> and returns its area.
    The function also accounts for the interior and checks for the validity of the polygon."""
    exteriorarea = 0.0
    interiorarea = 0.0
    #-- Decompose the exterior and interior boundary
    e, i = markup3dmodule.polydecomposer(poly)
    #-- Extract points in the <gml:LinearRing> of <gml:exterior>
    epoints =  markup3dmodule.GMLpoints(e[0])
    if isPolyValid(epoints):
        if height:
            exteriorarea += get3DArea(epoints)
        else:
            exteriorarea += get2DArea(epoints)
    for idx, iring in enumerate(i):
        #-- Extract points in the <gml:LinearRing> of <gml:interior>
        ipoints = markup3dmodule.GMLpoints(iring)
        if isPolyValid(ipoints):
            if height:
                interiorarea += get3DArea(ipoints)
            else:
                interiorarea += get2DArea(ipoints)
    #-- Account for the interior
    area = exteriorarea - interiorarea
    #-- Area in dimensionless units (coordinate units)
    return area
示例#2
0
def extract_polys(polys, label, vertices_all, faces_all):
    """
    extract polygons and their semantic information from GML and output to dictionaries
    @ param polys: list of Element. Returned by markup3dmodule.polygonFinder() function.
    @ param label: which label should we give to the polygon? e.g. "All", "WallSurface", etc
    @ param vertices_all: place to store vertices
    @ paramfaces_all : place to store faces
    """
    for poly in polys:
        #-- Decompose the polygon into exterior and interior
        e, i = markup3dmodule.polydecomposer(poly)

        #-- Points forming the exterior LinearRing
        epoints = markup3dmodule.GMLpoints(e[0])

        #-- Clean recurring points, including the last one
        # last_ep = epoints[-1]
        epoints_clean = list(remove_reccuring(epoints))
        # epoints_clean.append(last_ep)

        #-- Check the exterior polygon
        # valid = polygon3dmodule.isPolyValid(epoints_clean, True)
        valid = True
        if valid:
            vertices_all.extend(
                epoints_clean)  # do not add the final points to obj
            faces_all[label].append(epoints_clean)
        else:
            pass

    return vertices_all, faces_all
示例#3
0
def getAreaOfGML(poly, height=True):
    """Function which reads <gml:Polygon> and returns its area.
    The function also accounts for the interior and checks for the validity of the polygon."""
    exteriorarea = 0.0
    interiorarea = 0.0
    #-- Decompose the exterior and interior boundary
    e, i = markup3dmodule.polydecomposer(poly)
    #-- Extract points in the <gml:LinearRing> of <gml:exterior>
    epoints =  markup3dmodule.GMLpoints(e[0])
    if isPolyValid(epoints):
        if height:
            exteriorarea += get3DArea(epoints)
        else:
            exteriorarea += get2DArea(epoints)
    for idx, iring in enumerate(i):
        #-- Extract points in the <gml:LinearRing> of <gml:interior>
        ipoints = markup3dmodule.GMLpoints(iring)
        if isPolyValid(ipoints):
            if height:
                interiorarea += get3DArea(ipoints)
            else:
                interiorarea += get2DArea(ipoints)
    #-- Account for the interior
    area = exteriorarea - interiorarea
    #-- Area in dimensionless units (coordinate units)
    return area
示例#4
0
 def solarinfo(self):        
     """Computes the area, azimuth, and tilt for each roof surface (id compulsory)."""
     place = (52.01, 4.36)
     for roofsurface in self.roofsurfaces:
         #-- Skip the openings
         if roofsurface.attrib['{%s}id' %ns_gml] in self.listOfOpenings:
             continue
         #-- Add it to the list
         listofxmlroofsurfaces.append(roofsurface)
         #-- gml:id of the polygon
         pid = roofsurface.attrib['{%s}id' %ns_gml]
         #-- Area
         area = polygon3dmodule.getAreaOfGML(roofsurface, True)
         #-- Compute the normal
         norm = polygon3dmodule.getNormal(markup3dmodule.GMLpoints(markup3dmodule.polydecomposer(roofsurface)[0][0]))
         #-- Get the azimuth and tilt from the surface normal
         az, tilt = polygon3dmodule.getAngles(norm)
         az = round(az, 3)
         #-- 360 -> 0 degrees
         if az == 360.0:
             az = 0.0
         tilt = round(tilt, 3)
         #-- Peculiar problems with the normals, with a cheap solution. Luckily very uncommon.
         if tilt == 180:
             tilt = 0.0
         if tilt >= 180:
             tilt = tilt - 180.01
         elif tilt > 90:
             tilt = tilt - 90.01
         elif tilt == 90:
             tilt = 89.9
         #-- Flat surfaces always have the azimuth zero
         if tilt == 0.0:
             az = 0.0
         #-- If the TOF file is loaded, sample the irradiance
         if loadDict:
             irradiation = irr_from_tof(tilt, az)
         #-- If the TOF file is not loaded, estimate the values
         else:
             irradiation = irr.yearly_total_irr(place, az, tilt)
         #-- Add the values
         self.roofdata[pid] = {'area' : area, 'azimuth' : az, 'tilt' : tilt, 'irradiation' : irradiation, 'total_irradiation' : irradiation*area}
         roofsurfacedata[pid] = {'area' : area, 'azimuth' : az, 'tilt' : tilt, 'irradiation' : irradiation, 'total_irradiation' : irradiation*area}
         #self.roofdata.append([self.id, pid, area, az, tilt, irradiation, irradiation*area])
     self.sumIrr = 0
     #-- Sum the values for the building
     for rs in self.roofdata:
         self.sumIrr += self.roofdata[rs]['total_irradiation']
示例#5
0
 def roofarea(self):
     """The total area of RoofSurface."""
     self.roofs = []
     self.roofsurfaces = []
     roofarea = 0.0
     openings = 0.0
     for child in self.xml.getiterator():
         if child.tag == '{%s}RoofSurface' %ns_bldg:
             self.roofs.append(child)
             openings += oparea(child)
     for surface in self.roofs:
         for w in surface.findall('.//{%s}Polygon' %ns_gml):
             self.roofsurfaces.append(w)
     for roofsurface in self.roofsurfaces:
         roofarea += polygon3dmodule.getAreaOfGML(roofsurface, True)
         #-- Compute the normal
         norm = polygon3dmodule.getNormal(markup3dmodule.GMLpoints(markup3dmodule.polydecomposer(roofsurface)[0][0]))
         polygon3dmodule.getAngles(norm)
     return roofarea - openings
示例#6
0
 def roofarea(self):
     """The total area of RoofSurface."""
     self.roofs = []
     self.roofsurfaces = []
     roofarea = 0.0
     openings = 0.0
     for child in self.xml.getiterator():
         if child.tag == '{%s}RoofSurface' % ns_bldg:
             self.roofs.append(child)
             openings += oparea(child)
     for surface in self.roofs:
         for w in surface.findall('.//{%s}Polygon' % ns_gml):
             self.roofsurfaces.append(w)
     for roofsurface in self.roofsurfaces:
         roofarea += polygon3dmodule.getAreaOfGML(roofsurface, True)
         #-- Compute the normal
         norm = polygon3dmodule.getNormal(
             markup3dmodule.GMLpoints(
                 markup3dmodule.polydecomposer(roofsurface)[0][0]))
         polygon3dmodule.getAngles(norm)
     return roofarea - openings
示例#7
0
def poly_to_obj(poly, cl, material=None):
	"""Main conversion function of one polygon to one or more faces in OBJ,
	in a specific semantic class. Supports assigning a material."""
	global local_vertices
	global vertices
	global face_output
	#-- Decompose the polygon into exterior and interior
	e, i = markup3dmodule.polydecomposer(poly)
	#-- Points forming the exterior LinearRing
	epoints = markup3dmodule.GMLpoints(e[0])
	#-- Clean recurring points, except the last one
	last_ep = epoints[-1]
	epoints_clean = list(remove_reccuring(epoints))
	epoints_clean.append(last_ep)
	# print epoints
	# print epoints_clean
	# print
	#-- LinearRing(s) forming the interior
	irings = []
	for iring in i:
		ipoints = markup3dmodule.GMLpoints(iring)
		#-- Clean them in the same manner as the exterior ring
		last_ip = ipoints[-1]
		ipoints_clean = list(remove_reccuring(ipoints))
		ipoints_clean.append(last_ip)		
		irings.append(ipoints_clean)
	#-- If the polygon validation option is enabled
	if VALIDATION:
		#-- Check the polygon
		valid = polygon3dmodule.isPolyValid(epoints_clean, True)
		if valid:
			for iring in irings:
				if not polygon3dmodule.isPolyValid(iring, False):
					valid = False
		#-- If everything is valid send them to the Delaunay triangulation
		if valid:
			if SKIPTRI:
				#-- Triangulation is skipped, polygons are converted directly to faces
				#-- The last point is removed since it's equal to the first one
				t = [epoints_clean[:-1]]
			else:
				#-- Triangulate polys
				# t = polygon3dmodule.triangulation(epoints, irings)
				try:
					t = polygon3dmodule.triangulation(epoints_clean, irings)
				except:
					t = []
			#-- Process the triangles/polygons
			for tri in t:
				#-- Face marker
				f = "f "
				#-- For each point in the triangle/polygon (face) get the index "v" or add it to the index
				for ep in range(0, len(tri)):
					v, local_vertices[cl] = get_index(tri[ep], local_vertices[cl], len(vertices[cl]))
					f += str(v) + " "
				#-- Add the material if invoked
				if material:
					face_output[cl].append("usemtl " + str(mtl(material, min_value, max_value, res)) + str("\n"))
				#-- Store all together
				face_output[cl].append(f + "\n")
		else:
			# Get the gml:id of the Polygon if it exists
			polyid = poly.xpath("@g:id", namespaces={'g' : ns_gml})
			if polyid:
				polyid = polyid[0]
				print "\t\t!! Detected an invalid polygon (%s). Skipping..." %polyid
			else:
				print "\t\t!! Detected an invalid polygon. Skipping..."
			
	else:
		#-- Do exactly the same, but without the validation
		try:
			if SKIPTRI:
				t = [epoints_clean[:-1]]
			else:
				t = polygon3dmodule.triangulation(epoints_clean, irings)
		except:
			t = []
		for tri in t:
			f = "f "
			for ep in range(0, len(tri)):
				v, local_vertices[cl] = get_index(tri[ep], local_vertices[cl], len(vertices[cl]))
				f += str(v) + " "   
			if material:
				face_output[cl].append("usemtl " + str(mtl(material, min_value, max_value, res)) + str("\n"))
			face_output[cl].append(f + "\n")
示例#8
0
 def solarinfo(self):
     """Computes the area, azimuth, and tilt for each roof surface (id compulsory)."""
     place = (52.01, 4.36)
     for roofsurface in self.roofsurfaces:
         #-- Skip the openings
         if roofsurface.attrib['{%s}id' % ns_gml] in self.listOfOpenings:
             continue
         #-- Add it to the list
         listofxmlroofsurfaces.append(roofsurface)
         #-- gml:id of the polygon
         pid = roofsurface.attrib['{%s}id' % ns_gml]
         #-- Area
         area = polygon3dmodule.getAreaOfGML(roofsurface, True)
         #-- Compute the normal
         norm = polygon3dmodule.getNormal(
             markup3dmodule.GMLpoints(
                 markup3dmodule.polydecomposer(roofsurface)[0][0]))
         #-- Get the azimuth and tilt from the surface normal
         az, tilt = polygon3dmodule.getAngles(norm)
         az = round(az, 3)
         #-- 360 -> 0 degrees
         if az == 360.0:
             az = 0.0
         tilt = round(tilt, 3)
         #-- Peculiar problems with the normals, with a cheap solution. Luckily very uncommon.
         if tilt == 180:
             tilt = 0.0
         if tilt >= 180:
             tilt = tilt - 180.01
         elif tilt > 90:
             tilt = tilt - 90.01
         elif tilt == 90:
             tilt = 89.9
         #-- Flat surfaces always have the azimuth zero
         if tilt == 0.0:
             az = 0.0
         #-- If the TOF file is loaded, sample the irradiance
         if loadDict:
             irradiation = irr_from_tof(tilt, az)
         #-- If the TOF file is not loaded, estimate the values
         else:
             irradiation = irr.yearly_total_irr(place, az, tilt)
         #-- Add the values
         self.roofdata[pid] = {
             'area': area,
             'azimuth': az,
             'tilt': tilt,
             'irradiation': irradiation,
             'total_irradiation': irradiation * area
         }
         roofsurfacedata[pid] = {
             'area': area,
             'azimuth': az,
             'tilt': tilt,
             'irradiation': irradiation,
             'total_irradiation': irradiation * area
         }
         #self.roofdata.append([self.id, pid, area, az, tilt, irradiation, irradiation*area])
     self.sumIrr = 0
     #-- Sum the values for the building
     for rs in self.roofdata:
         self.sumIrr += self.roofdata[rs]['total_irradiation']