def adding_z(feature, output, attribute): feature_coord = [] # Creating a list of (X, Y, Z) coordinates for i in range(len(feature.points)): l_coord = list(feature.points[i]) l_coord.append(feature.z[i]) t_coord = tuple(l_coord) feature_coord.append(t_coord) # Surface orientation correction except for WallSurface (2) and ClosureSurface (4) # Projected to 2D and evaluated using linear time algorithm (sf.signed_area()) if attribute[0] != 2 and attribute[0] != 5 and attribute[0] != 4: coordXY = [] for i in range(len(feature_coord)): x, y = feature_coord[i][0], feature_coord[i][1] coordXY.append((x, y)) if sf.signed_area(coordXY) < 0: feature_coord.reverse() elif attribute[0] == 4: coordXY = [] for i in range(len(feature_coord)): x, y = feature_coord[i][0], feature_coord[i][1] coordXY.append((x, y)) if sf.signed_area(coordXY) >= 0: feature_coord.reverse() output.append(feature_coord)
def adding_z_multi(feature, output, attribute): # Extracting XY coordinates to check for CW/CCW rings coordinates_xy = [] for i in range(len(feature.points)): coordinates_xy.append(feature.points[i]) feature_coord_xy = [] for i in range(len(feature.parts)): if not i == (len(feature.parts) - 1): part_coord_xy = coordinates_xy[feature.parts[i]:feature.parts[i + 1]] feature_coord_xy.append(part_coord_xy) else: part_coord_xy = coordinates_xy[feature.parts[i]:] feature_coord_xy.append(part_coord_xy) # Extracting XYZ coordinates for the end product coordinates_xyz = [] for i in range(len(feature.points)): l_coord = list(feature.points[i]) l_coord.append(feature.z[i]) t_coord = tuple(l_coord) coordinates_xyz.append(t_coord) feature_coord_xyz = [] # Dividing coordinates based on polygon parts (outer ring and inner rings) for i in range(len(feature.parts)): if not i == (len(feature.parts) - 1): part_coord_xyz = coordinates_xyz[feature.parts[i]:feature.parts[i + 1]] feature_coord_xyz.append(part_coord_xyz) else: part_coord_xyz = coordinates_xyz[feature.parts[i]:] feature_coord_xyz.append(part_coord_xyz) if attribute[0] != 2 and attribute[0] != 5 and attribute[0] != 4: # Turning CW to CCW and vice versa (CCW for outer ring and CW for inner ring) # CW => sf.signed_area < 0, CCW => sf.signed_area >= 0 for i in range(len(feature_coord_xyz)): if (i == 0) and (sf.signed_area(feature_coord_xy[i]) < 0): feature_coord_xyz[i].reverse() elif (i != 0) and (sf.signed_area(feature_coord_xy[i]) >= 0): feature_coord_xyz[i].reverse() elif attribute[0] == 4: # Turning CW to CCW and vice versa (CCW for outer ring and CW for inner ring) # CW => sf.signed_area < 0, CCW => sf.signed_area >= 0 for i in range(len(feature_coord_xyz)): if (i == 0) and (sf.signed_area(feature_coord_xy[i]) >= 0): feature_coord_xyz[i].reverse() elif (i != 0) and (sf.signed_area(feature_coord_xy[i]) < 0): feature_coord_xyz[i].reverse() output.append(feature_coord_xyz)
def interiorwall_surf(floorCoordsXYZ, floorCoordsXY, height, output): interiorWallSurfaces = [] floorCoords = [] for coord in floorCoordsXY: coord_t = tuple(coord) floorCoords.append(coord_t) floorElevs = [] for coords in floorCoordsXYZ: floorElevs.append(coords[2]) floorElev = sum(floorElevs) / len(floorElevs) if sf.signed_area(floorCoordsXY) >= 0: floorCoords.reverse() for i in range(len(floorCoords) - 1): coord1 = list(floorCoords[i]) coord1.append(floorElev) coord2 = list(floorCoords[i + 1]) coord2.append(floorElev) coord3 = [coord2[0], coord2[1], floorElev + height] coord4 = [coord1[0], coord1[1], floorElev + height] surface = [ tuple(coord1), tuple(coord2), tuple(coord3), tuple(coord4), tuple(coord1) ] interiorWallSurfaces.append(surface) output['InteriorWall'] = interiorWallSurfaces
def floor_surf(floorCoordsXYZ, floorCoordsXY, output): coordinates = floorCoordsXYZ if sf.signed_area(floorCoordsXY) < 0: coordinates.reverse() output['Floor'] = coordinates
def ceiling_surf(floorCoordsXYZ, floorCoordsXY, height, output): coordinates = [] for coord in floorCoordsXYZ: l_coord = [coord[0], coord[1], coord[2] + height] t_coord = tuple(l_coord) coordinates.append(t_coord) if sf.signed_area(floorCoordsXY) >= 0: coordinates.reverse() output['Ceiling'] = coordinates
def ground_surf(roof_base, ground_surface, elevation): coordinate = [] for i in range(len(roof_base.points)): l_coord = list(roof_base.points[i]) l_coord.append(elevation) t_coord = tuple(l_coord) coordinate.append(t_coord) # GroundSurface orientation correction, GroundSurface have to be clockwise if sf.signed_area(roof_base.points) >= 0: coordinate.reverse() ground_surface.append(coordinate)
def wall_surf(roof_base, wall_surfaces, elevation): # Roof base vertex order correction to give the extruded WallSurface the correct orientation if sf.signed_area(roof_base.points) >= 0: roof_base.points.reverse() roof_base.z.reverse() for i in range(len(roof_base.points) - 1): coord1 = list(roof_base.points[i]) coord1.append(roof_base.z[i]) coord2 = list(roof_base.points[i + 1]) coord2.append(roof_base.z[i + 1]) coord3 = [coord2[0], coord2[1], elevation] coord4 = [coord1[0], coord1[1], elevation] surface = [ tuple(coord1), tuple(coord2), tuple(coord3), tuple(coord4), tuple(coord1) ] wall_surfaces.append(surface)
"""Split a shapefile""" import shapefile import utm r = shapefile.Reader("footprints_se") w = shapefile.Writer(r.shapeType) w.fields = list(r.fields) for sr in r.shapeRecords(): utmPoints = [] for p in sr.shape.points: x,y,band,zone = utm.from_latlon(p[1],p[0]) utmPoints.append([x,y]) area = abs(shapefile.signed_area(utmPoints)) if area <= 100: w._shapes.append(sr.shape) w.records.append(sr.record) w.save("footprints_185") # Verify changes r = shapefile.Reader("footprints_se") subset = shapefile.Reader("footprints_185") print r.numRecords print subset.numRecords
if i[0]==point: array.append(i[1]) array.append(i[2]) inner_polygon.append(array) break #print inner_polygon Internal_polygon.append(inner_polygon) External_polygon=PolygonFun(massPoints(Externals,True)) ##Проверка внутреннего полигона - порядок обхода точек по часовой / против #print "Start-",Internal_polygon[0] #print "internal",len(Internal_polygon) for i in Internal_polygon: print len(i) #print "Index",i.index(i) if shapefile.signed_area(i)>=0: print 111 i.reverse() else: i.reverse() PointsPolygon=[External_polygon] for i in Internal_polygon: PointsPolygon.append(i) ##Охранные зоны Restrictions_code [код зоны], Restrictions_name название охранной зоны if len(restrictions)<>0: ##Create polygon&records #Restrictions_code=[]
def shape_from_pyshp_to_shapely(pyshp_shape): """ convert pyshp object to shapely object :param pyshp_shape: pyshp (shapefile) object :return: shapely object if successful, False otherwise """ if pyshp_shape.shapeType is 5: # Polygon or multiPolygon parts_index = pyshp_shape.parts if len(parts_index) < 2: # Create a polygon with no holes record = Polygon(pyshp_shape.points) else: # Create a polygon with one or several holes seperate_parts = [] parts_index.append(len(pyshp_shape.points)) for i in range(0, len(parts_index) - 1): points = pyshp_shape.points[parts_index[i]:parts_index[i + 1]] seperate_parts.append(points) # if list(parts_index)==[0,121,130,135,140]: # debug = 1 # assuming the first part is exterior # exterior = seperate_parts[0] # assuming the first part is exterior # interiors = [seperate_parts[i] for i in range(1,len(seperate_parts))] # assuming the last part is exterior # exterior = seperate_parts[len(parts_index)-2] # interiors = [seperate_parts[i] for i in range(0,len(seperate_parts)-2)] all_polygons = [] while (len(seperate_parts) > 0): if shapefile.signed_area( seperate_parts[0] ) < 0: # the area of ring is clockwise, it's not a hole exterior = tuple(seperate_parts[0]) seperate_parts.remove(seperate_parts[0]) # find all the holes attach to the first exterior interiors = [] holes_points = [] for points in seperate_parts: if shapefile.signed_area( points ) >= 0: # the value >= 0 means the ring is counter-clockwise, then they form a hole interiors.append(tuple(points)) holes_points.append(points) # remove the parts which are holes for points in holes_points: seperate_parts.remove(points) # else: # break if len(interiors) < 1: interiors = None else: interiors = tuple(interiors) polygon = Polygon(shell=exterior, holes=interiors) all_polygons.append(polygon) else: basic.outputlogMessage( 'error, holes found in the first ring') basic.outputlogMessage("parts_index:" + str(parts_index) + '\n' + "len of seperate_parts:" + str(len(seperate_parts))) return False if len(all_polygons) > 1: record = MultiPolygon(polygons=all_polygons) else: record = all_polygons[0] else: basic.outputlogMessage( 'have not complete, other type of shape is not consider!') return False # # plot shape for checking # from matplotlib import pyplot as plt # from descartes import PolygonPatch # from math import sqrt # # from shapely.geometry import Polygon, LinearRing # # from shapely.ops import cascaded_union # BLUE = '#6699cc' # GRAY = '#999999' # # # plot these two polygons separately # fig = plt.figure(1, dpi=90) #figsize=SIZE, # ax = fig.add_subplot(111) # poly1patch = PolygonPatch(record, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2) # # poly2patch = PolygonPatch(polygon2, ec=BLUE, alpha=0.5, zorder=2) # ax.add_patch(poly1patch) # # ax.add_patch(poly2patch) # boundary = record.bounds # xrange = [boundary[0], boundary[2]] # yrange = [boundary[1], boundary[3]] # ax.set_xlim(*xrange) # # ax.set_xticks(range(*xrange) + [xrange[-1]]) # ax.set_ylim(*yrange) # # ax.set_yticks(range(*yrange) + [yrange[-1]]) # # ax.set_aspect(1) # # plt.show() return record
import shapefile import utm reader = shapefile.Reader( r"D:\Program Files\Python学习文档\samples\footprints\footprints_se.shp") writer = shapefile.Writer( r"D:\Program Files\Python学习文档\samples\footprints\footprints_split.shp", reader.shapeType) writer.fields = list(reader.fields[1:]) for shapeRecord in reader.iterShapeRecords(): utmPoints = [] for point in shapeRecord.shape.points: x, y, band, zone = utm.from_latlon(point[1], point[0]) #latitude 纬度 longitude 经度,网格 utmPoints.append([x, y]) area = abs( shapefile.signed_area(utmPoints)) #abs()绝对值函数 signed_area()计算多边形面积 if area <= 100: writer.shape(shapeRecord.shape) writer.record(*shapeRecord.record) reader.close() writer.close() print("Shapefile文件分隔完成!") ''' r=shapefile.Reader(r"D:\Program Files\Python学习文档\samples\footprints\footprints_se.shp") subset=shapefile.Reader(r"D:\Program Files\Python学习文档\samples\footprints\footprints_split.shp") r.numRecords 26447 subset.numRecords 13331 '''
gebid = properties['gebid'] dachneig = properties['dachneig'] dachorient = properties['dachorient'] # initialize some meta data points = shape.points length = len(points) edge = -1 if dachorient == -1.0: dachorient = None print('process shape:', \ 'fid=', fid, \ 'rooftype=', daf, \ 'dachorient=', dachorient, \ 'clockwise=', shapefile.signed_area(points) > 0, \ 'vertex_count=', length) # if the roof orientation and inclination are given, search for edge index if dachneig and dachorient: idx = 0 i = length - 1 # process first edge index print('processing edge=', idx) x2 = points[0][0] x1 = points[1][0] y2 = points[0][1] * -1 y1 = points[1][1] * -1 dx = x2 - x1 dy = y2 - y1
def coords2shapefile(filename, coords): """ Converts given coordinates into shapefile that can be uploaded to CaSPAr. Parameters ---------- filename: str Name of the shapefile (without any extension). Files that will be produced are: <filename>.dbf <filename>.prj <filename>.shp <filename>.shx Zip these four files to upload to CaSPAr. coords: array 2-D Array of coordinates of a single polygon. CaSPAr does not support multiple polygons. Polygon does not need to be closed. The shapefile package is checking and copies automatically the first point to the end if polygon is not closed. Example: [[-123,50], [-118,40], [-118,44], [-113,44]] # unclosed geometry [[-123,50], [-118,40], [-118,44], [-113,44],[-123,50]] # closed geometry Returns ------- None """ # make sure coords is a list of lists coords = [list(ii) for ii in coords] # ----------------------- # Check if polygon is clockwise: # Use "shapefile.signed_area()" method to determine if a ring is clockwise or counter-clockwise # Value >= 0 means the ring is counter-clockwise. # Value < 0 means the ring is clockwise # The value returned is also the area of the polygon. # ----------------------- area = shapefile.signed_area(coords) if area >= 0: coords.reverse() # transform counter-clockwise to clockwise if sys.version_info < (3, 0, 0): # ------------------------ # Create a polygon shapefile # ------------------------ # Found under: # https://code.google.com/archive/p/pyshp/ w = shapefile.Writer(shapefile.POLYGON) # an arrow-shaped polygon east of Vancouver, Seattle, and Portland w.poly([coords]) w.field('FIRST_FLD', 'C', '40') w.record('First', 'Polygon') w.save(filename) else: # ------------------------ # Create a polygon shapefile # ------------------------ # Found under: # https://code.google.com/archive/p/pyshp/ w = shapefile.Writer(target=filename) # an arrow-shaped polygon east of Vancouver, Seattle, and Portland w.poly([coords]) w.field('FIRST_FLD', 'C', '40') w.record('First', 'Polygon') w.close() # ------------------------ # Write projection information # ------------------------ # Found under: # https://code.google.com/archive/p/pyshp/wikis/CreatePRJfiles.wiki prj = open("%s.prj" % filename, "w") epsg = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]]' prj.write(epsg) prj.close() return
archive.writestr(filename, f.read()) # write dbf with open(shapefile_path + '.dbf', 'rb') as f: filename = 'osm_{}_{}.dbf'.format(iso, osm_lvl) archive.writestr(filename, f.read()) print('calculating layer area') area = 0 for feat in feats: geom = feat['geometry'] if geom['type'] == 'Polygon': exteriors = [geom['coordinates'][0]] elif geom['type'] == 'MultiPolygon': exteriors = [poly[0] for poly in geom['coordinates']] for ring in exteriors: area += abs(shapefile.signed_area(ring, fast=True)) print('area:', area) # check if layer is complete # by ensuring the area remains roughly the same as level 0 if adm_lvl == 0: area_0 = area else: if (area / area_0) < 0.95: print( 'layer is incomplete (area is less than 95%% of level 0), skipping' ) continue # add meta input args path = '{iso}.zip/osm_{iso}_{lvl}.shp'.format(iso=iso, lvl=osm_lvl)