Ejemplo n.º 1
0
def daebldglist2gmlbuildings(daebldg_shelllist, citygml_writer):
    bldg_cnt = 0
    for building in daebldg_shelllist:
        bldg_lod = "lod1"
        bldg_name = "building" + str(bldg_cnt)
        bldg_str_abv_grd = "30"
        bfacelist = py3dmodel.fetch.topo_explorer(building, "face")
        footprint, roof = get_footprint_roof(building)
        bldg_geometry_list = gml3dmodel.write_gml_srf_member(bfacelist)
        heightpt1 = py3dmodel.calculate.face_midpt(footprint)
        heightpt2 = py3dmodel.calculate.face_midpt(roof)
        height = py3dmodel.calculate.distance_between_2_pts(
            heightpt1, heightpt2)
        bldg_height = height
        citygml_writer.add_building(bldg_lod,
                                    bldg_name,
                                    bldg_geometry_list,
                                    height=str(bldg_height),
                                    stry_abv_grd=str(bldg_str_abv_grd))

        bldg_cnt += 1
Ejemplo n.º 2
0
def building_2d_to_3d(citygml_writer, zone_shp_path, district_shp_path,
                      tin_occface_list, height_col, nfloor_col):
    """
    This script extrudes buildings from the shapefile and creates intermediate floors.

    :param citygml_writer: the cityGML object to which the buildings are gonna be created.
    :param district_shp_path: path to the shapefile to be extruded of the district
    :param tin_occface_list: the faces of the terrain, to be used to put the buildings on top.
    :param height_col:
    :param nfloor_col:
    :return:
    """
    # read district shapefile and names of buildings of the zone of analysis
    district_building_records = gdf.from_file(district_shp_path).set_index(
        'Name')
    district_building_names = district_building_records.index.values
    zone_building_names = gdf.from_file(zone_shp_path)['Name'].values

    #make shell out of tin_occface_list and create OCC object
    terrain_shell = construct.sew_faces(tin_occface_list)[0]
    terrain_intersection_curves = IntCurvesFace_ShapeIntersector()
    terrain_intersection_curves.Load(terrain_shell, 1e-6)
    bsolid_list = []

    #create the buildings in 3D
    for name in district_building_names:
        height = float(district_building_records.loc[name, height_col])
        nfloors = int(district_building_records.loc[name, nfloor_col])

        # Make floors only for the buildings of the zone of interest
        # for the rest just consider one high floor.
        # simplify geometry tol =1 for buildings of interest, tol = 5 for surroundings
        if name in zone_building_names:
            range_floors = range(nfloors + 1)
            floor_to_floor_height = height / nfloors
            geometry = district_building_records.ix[name].geometry.simplify(
                1, preserve_topology=True)
        else:
            range_floors = [0, 1]
            floor_to_floor_height = height
            geometry = district_building_records.ix[name].geometry.simplify(
                5, preserve_topology=True)

        point_list_2D = list(geometry.exterior.coords)
        point_list_3D = [(a, b, 0)
                         for (a, b) in point_list_2D]  # add 0 elevation

        #creating floor surface in pythonocc
        face = construct.make_polygon(point_list_3D)
        #get the midpt of the face
        face_midpt = calculate.face_midpt(face)

        #project the face_midpt to the terrain and get the elevation
        inter_pt, inter_face = calc_intersection(terrain_intersection_curves,
                                                 face_midpt, (0, 0, 1))

        loc_pt = (inter_pt.X(), inter_pt.Y(), inter_pt.Z())
        #reconstruct the footprint with the elevation
        face = fetch.topo2topotype(modify.move(face_midpt, loc_pt, face))

        moved_face_list = []
        for floor_counter in range_floors:
            dist2mve = floor_counter * floor_to_floor_height
            #get midpt of face
            orig_pt = calculate.face_midpt(face)
            #move the pt 1 level up
            dest_pt = modify.move_pt(orig_pt, (0, 0, 1), dist2mve)
            moved_face = modify.move(orig_pt, dest_pt, face)
            moved_face_list.append(moved_face)

        #loft all the faces and form a solid
        vertical_shell = construct.make_loft(moved_face_list)
        vertical_face_list = fetch.topo_explorer(vertical_shell, "face")
        roof = moved_face_list[-1]
        footprint = moved_face_list[0]
        all_faces = []
        all_faces.append(footprint)
        all_faces.extend(vertical_face_list)
        all_faces.append(roof)
        bldg_shell_list = construct.sew_faces(all_faces)

        # make sure all the normals are correct (they are pointing out)
        if bldg_shell_list:
            bldg_solid = construct.make_solid(bldg_shell_list[0])
            bldg_solid = modify.fix_close_solid(bldg_solid)
            bsolid_list.append(bldg_solid)
            occface_list = fetch.topo_explorer(bldg_solid, "face")
            geometry_list = gml3dmodel.write_gml_srf_member(occface_list)
            citygml_writer.add_building("lod1", name, geometry_list)

    return bsolid_list
Ejemplo n.º 3
0
def convert_ptshpfile(field_name_list, shapeRecs, citygml):
    name_index = field_name_list.index("name") - 1
    station_index = field_name_list.index("station") - 1
    highway_index = field_name_list.index("highway") - 1
    trpst_bldg_list = []
    for rec in shapeRecs:
        poly_attribs = rec.record
        highway = poly_attribs[highway_index]
        highway.strip()
        station = poly_attribs[station_index]
        station.strip()
        name = poly_attribs[name_index]
        name.strip()

        if highway == "bus_stop":
            if name.isspace():
                name = "bus_stop" + str(uuid.uuid1())
            generic_attrib_dict = {"highway": highway}
            #transform to the location of the bus stop
            bus_stop_box = py3dmodel.construct.make_box(5, 2, 3)
            shp_pts = rec.shape.points
            for pt in shp_pts:
                pt3d = shp2citygml.pypt2d_2_3d(pt, 0.0)
                stopbox = shp2citygml.create_transit_stop_geometry(
                    bus_stop_box, pt3d)
                face_list = py3dmodel.fetch.faces_frm_solid(stopbox)
                #get the surfaces from the solid
                geometry_list = gml3dmodel.write_gml_srf_member(face_list)

            citygml.add_cityfurniture("lod1",
                                      name,
                                      geometry_list,
                                      furn_class="1000",
                                      function="1110",
                                      generic_attrib_dict=generic_attrib_dict)

        if not station.isspace():
            if name.isspace():
                name = station + str(uuid.uuid1())
            generic_attrib_dict = {"station": station}
            #create a bus stop geometry based on the point
            station_height = 8
            station_storey = 2
            storey_blw_grd = 0

            #transform to the location of the bus stop
            transit_station_box = py3dmodel.construct.make_box(5, 20, 3)
            shp_pts = rec.shape.points
            for pt in shp_pts:
                pt3d = shp2citygml.pypt2d_2_3d(pt, 0.0)
                stationbox = shp2citygml.create_transit_stop_geometry(
                    transit_station_box, pt3d)
                face_list = py3dmodel.fetch.faces_frm_solid(stationbox)
                #get the surfaces from the solid
                geometry_list = gml3dmodel.write_gml_srf_member(face_list)

            trpst_bldg_list.append(name)
            citygml.add_building("lod1",
                                 name,
                                 geometry_list,
                                 bldg_class="1170",
                                 function="2480",
                                 usage="2480",
                                 rooftype="1000",
                                 height=str(station_height),
                                 stry_abv_grd=str(station_storey),
                                 stry_blw_grd=str(storey_blw_grd),
                                 generic_attrib_dict=generic_attrib_dict)

    return trpst_bldg_list
Ejemplo n.º 4
0
def convert_apolygon_origlvl(rec, landuse_index, building_index, name_index,
                             plot_ratio_index, count_shapes, citygml,
                             building_list):
    poly_attribs = rec.record
    landuse = poly_attribs[landuse_index]
    landuse.strip()
    building = poly_attribs[building_index]
    building.strip()
    name = poly_attribs[name_index]
    name.strip()
    total_build_up = 0
    constr_buildings = []
    blevel_list = []
    #print "CONDITIONS:", building, landuse
    #=======================================================================================================
    #if the polygon has no building attrib and has no landuse attribute it is a boundary
    #=======================================================================================================
    if building == "" and landuse == "":
        pypolygon_list2d = shp2citygml.get_geometry(rec)
        if pypolygon_list2d:
            pypolygon_list3d = shp2citygml.pypolygon_list2d_2_3d(
                pypolygon_list2d, 0.0)
            occface_list = py3dmodel.construct.make_occfaces_frm_pypolygons(
                pypolygon_list3d)
            occface_list2 = []
            for occface in occface_list:
                pyptlist = py3dmodel.fetch.points_frm_occface(occface)
                is_anticlockwise = py3dmodel.calculate.is_anticlockwise(
                    pyptlist, (0, 0, 1))
                if is_anticlockwise:
                    r_face = py3dmodel.modify.reverse_face(occface)
                    #nrml = py3dmodel.calculate.face_normal(r_face)
                    occface_list2.append(r_face)
                else:
                    occface_list2.append(occface)

            geometry_list = gml3dmodel.write_gml_triangle(occface_list2)

            citygml.add_tin_relief("lod1", "terrain", geometry_list)
    #=======================================================================================================
    #if the polygon has no building attrib and has a landuse attribute it is a landuse
    #=======================================================================================================
    if building == "" and landuse != "":
        #the geometry is stored in parts and points
        pypolygon_list2d = shp2citygml.get_geometry(rec)
        if pypolygon_list2d:
            pypolygon_list3d = shp2citygml.pypolygon_list2d_2_3d(
                pypolygon_list2d, 0.0)
            occface_list = py3dmodel.construct.make_occfaces_frm_pypolygons(
                pypolygon_list3d)
            geometry_list = gml3dmodel.write_gml_srf_member(occface_list)

            if name.isspace():
                name = "plot" + str(count_shapes)

            function = shp2citygml.map_osm2citygml_landuse_function(landuse)
            generic_attrib_dict = {"landuse": landuse}

            plot_ratio = poly_attribs[plot_ratio_index]
            if plot_ratio != None:
                generic_attrib_dict["plot_ratio"] = plot_ratio

            plot_area = shp2citygml.get_plot_area(rec)
            generic_attrib_dict["plot_area"] = plot_area

            citygml.add_landuse("lod1",
                                name,
                                geometry_list,
                                function=function,
                                generic_attrib_dict=generic_attrib_dict)

            #=======================================================================================================
            #find the buildings that belong to this plot
            #=======================================================================================================
            buildings_on_plot_list = shp2citygml.buildings_on_plot(
                rec, building_list)
            in_construction = False
            #check if any of the buildings are under construction
            for cbuilding in buildings_on_plot_list:
                if cbuilding["building"] == "construction":
                    in_construction = True
                    constr_buildings.append(cbuilding)

            if not in_construction:
                #then separate the buildings that are parkings and usable floor area
                parking_list = []
                not_parking_list = list(buildings_on_plot_list)
                for building in buildings_on_plot_list:
                    if "amenity" in building:
                        if building["amenity"] == "parking" or building[
                                "amenity"] == "carpark":
                            parking_list.append(building)
                            not_parking_list.remove(building)

                #then measure the total building footprint on this plot
                build_footprint = 0
                for not_parking in not_parking_list:
                    bgeom_list = not_parking["geometry"]
                    for bgeom in bgeom_list:
                        build_footprint = build_footprint + py3dmodel.calculate.face_area(
                            bgeom)

                #then measure the total parking footprint on this plot
                multi_parking_footprint = 0
                for parking in parking_list:
                    bgeom_list = parking["geometry"]
                    for bgeom in bgeom_list:
                        multi_parking_footprint = multi_parking_footprint + py3dmodel.calculate.face_area(
                            bgeom)

                #base on the footprints calculate how many storeys are the buildings
                if build_footprint != 0:
                    residential_height = 3
                    commercial_height = 4

                    if plot_ratio != None:
                        total_build_up = total_build_up + (plot_area *
                                                           plot_ratio)
                        num_storeys = int(
                            round(total_build_up / build_footprint))

                        if landuse == "residential":
                            height = num_storeys * residential_height

                            if multi_parking_footprint != 0:
                                #base on the parking footprint estimate how high the multistorey carpark should be
                                total_parking_area = shp2citygml.calc_residential_parking_area(
                                    total_build_up)
                                parking_storeys = int(
                                    round(total_parking_area /
                                          multi_parking_footprint))
                                parking_storey_height = 2.5
                                parking_height = parking_storey_height * parking_storeys

                                #write the carparks as buildings
                                for parking in parking_list:
                                    if "building_l" in parking:
                                        blevel_list.append(parking)
                                        parking_storeys = parking["building_l"]
                                        parking_height = parking_storey_height * parking_storeys
                                        shp2citygml.building2citygml(
                                            parking, parking_height, citygml,
                                            landuse, parking_storeys)
                                    else:
                                        shp2citygml.building2citygml(
                                            parking,
                                            parking_height,
                                            citygml,
                                            landuse,
                                            parking_storeys,
                                        )

                        #TODO: calculate for commercial buildings in terms of parking space too
                        else:
                            height = num_storeys * commercial_height

                        for not_parking in not_parking_list:
                            if "building_l" in not_parking:
                                blevel_list.append(not_parking)
                                num_storeys = not_parking["building_l"]
                                if landuse == "residential":
                                    height = residential_height * num_storeys
                                else:
                                    height = commercial_height * num_storeys
                                shp2citygml.building2citygml(
                                    not_parking, height, citygml, landuse,
                                    num_storeys)
                            else:
                                shp2citygml.building2citygml(
                                    not_parking, height, citygml, landuse,
                                    num_storeys)

                    #================================================================================================================
                    #for those plots without plot ratio and might be educational or civic buildings
                    #================================================================================================================
                    else:
                        if landuse == "transport" or landuse == "recreation_ground" or landuse == "civic" or landuse == "place_of_worship" or landuse == "utility" or landuse == "health":
                            num_storeys = 2

                        elif landuse == "education" or landuse == "commercial":
                            num_storeys = 4

                        elif landuse == "residential":
                            num_storeys = 10

                        elif landuse == "reserve":
                            num_storeys = 1

                        else:
                            num_storeys = 1

                        for not_parking in not_parking_list:
                            if "building_l" in not_parking:
                                blevel_list.append(not_parking)
                                num_storeys = not_parking["building_l"]
                                height = commercial_height * num_storeys
                                shp2citygml.building2citygml(
                                    not_parking, height, citygml, landuse,
                                    num_storeys)
                            else:
                                height = num_storeys * commercial_height
                                shp2citygml.building2citygml(
                                    not_parking, height, citygml, landuse,
                                    num_storeys)

    return total_build_up, constr_buildings, blevel_list