def volume_overwrap(pca_src_example, vertices, pca_tgt_example): if len(vertices) == 0: return 0 elif len(vertices) == 1: poly_input = point(pca_src_example[vertices][0]) elif len(vertices) == 2: poly_input = line(pca_src_example[vertices]) else: poly_input = poly(clockwise(pca_src_example[vertices])) if not poly_input.is_valid: poly_input = poly_input.buffer(0) if len(pca_tgt_example) == 0: return 0 elif len(pca_tgt_example) == 1: poly_tgt = point(pca_tgt_example[0]) return int(poly_input.contains(poly_tgt)) elif len(pca_tgt_example) == 2: poly_tgt = line(pca_tgt_example) if poly_tgt.length > 0: return poly_input.intersection( poly_tgt).length / poly_tgt.length * 1.0 else: return 0 else: poly_tgt = poly(clockwise(pca_tgt_example)) poly_tgt = poly_tgt.buffer(0) if poly_tgt.area > 0: return poly_input.intersection(poly_tgt).area / poly_tgt.area * 1.0 else: return 0
def plotStrip(bp, at, ps, crop): """ Plot a strip of colored polygons along a trace of GPS coordinates (deg). Extension of the strip outward from the line to either side is specified by ps.sideRange, in meters. Parameters ---------- bp.polyList: master list of polygons, all lines included bp.colorList: master list of colors for each polygon bp.lineList: master list of survey lines at.fix : float (deg), (pktCount)x2 array [longitude, latitude] coordinates of ship, rows are packets in order. at.depth : float (m), array length pktCount Water depth beneath the ship at each fix. Used with extended lead-in length of cable to estimate sensor position by layback calculation. at.leadin : float (m) at.color : float (m), array length pktCount List of numbers for each position indicating the color to plot representing IP data results. """ # Start by transforming the fix points into a local azimuthal equidistant # reference system. Units along x and y are meters. ptList = [point(tuple(row)) for row in at.fix] dfPt = gpd.GeoDataFrame({'geometry': ptList}) # Assign the WGS84 latitude-longitude Coordinate Reference System (CRS). dfPt.crs = ps.crsWGS84 # Transform to the azimuthal equidistant reference. dfPt = dfPt.to_crs(ps.crsAzEq) # Extract the transformed coordinates into an array. flatFix = sp.zeros_like(at.fix, dtype=float) for p in range(len(flatFix)): flatFix[p, :] = sp.array(dfPt.geometry[p].coords) # (m) # Track vectors between each pair of consecutive GPS fixes. vParSeg = flatFix[1:, :] - flatFix[0:-1, :] # Length of each trach vector. segLen = sp.sqrt(vParSeg[:, 0]**2 + vParSeg[:, 1]**2) # (m) # Cumulative sum along the track line. sumLen = sp.hstack((0, sp.cumsum(segLen))) # Print the total line length (m). # print('%.1f m along line.' % (sumLen[-1])) # Distance between start and endpoints. startFinDist = mm.norm(flatFix[0, :] - flatFix[-1, :]) # print('%.1f m distance from start point to finish point.' % startFinDist) # Time elapsed on the line. lineTime = (at.cpuDT[-1] - at.cpuDT[0]).total_seconds() # print('%.0f s elapsed.' % lineTime) lineSpeed = startFinDist / lineTime # (m/s) lineSpeed *= 1.94384 # (kt) # print('%.1f kt average speed' % lineSpeed) # Interpolate a laidback fix location on the track line. # Layback the extra length at the start of the line according to # the boat's heading for the first few meters twice the length of # the cable lead in. newFix = sp.zeros_like(flatFix, dtype=float) linLoc = 2 * at.leadin closeIdx = sp.argmin(abs(sumLen - linLoc)) # If the line is at least as long as twice the lead in. if sumLen[-1] > linLoc: if linLoc >= sumLen[closeIdx]: idx1 = closeIdx idx2 = closeIdx + 1 else: idx1 = closeIdx - 1 idx2 = closeIdx l1 = sumLen[idx1] l2 = sumLen[idx2] startHeadingFix = flatFix[idx1, :] + ( flatFix[idx2, :] - flatFix[idx1, :]) * (linLoc - l1) / (l2 - l1) else: # Else just use the heading of the whole line. startHeadingFix = flatFix[-1, :] startHeadingVec = mm.unit(startHeadingFix - flatFix[0, :]) for p in range(len(flatFix)): linLoc = sumLen[p] - mm.cableRange(at.leadin, at.depth[p]) if linLoc >= 0: closeIdx = sp.argmin(abs(sumLen - linLoc)) if linLoc >= sumLen[closeIdx]: idx1 = closeIdx idx2 = closeIdx + 1 else: idx1 = closeIdx - 1 idx2 = closeIdx l1 = sumLen[idx1] l2 = sumLen[idx2] if l1 != l2: newFix[p, :] = flatFix[idx1, :] + (flatFix[idx2, :] - flatFix[ idx1, :]) * (linLoc - l1) / (l2 - l1) else: # Case of interpolation between two repeated locations. newFix[p, :] = flatFix[idx1, :] else: newFix[p, :] = flatFix[0, :] + linLoc * startHeadingVec # Overwrite. flatFix = newFix # Reevaluate track vectors between each pair of consecutive GPS fixes. vParSeg = flatFix[1:, :] - flatFix[0:-1, :] # Track vectors at each point, found from points before and after. vParPt = flatFix[2:, :] - flatFix[0:-2, :] # Include segment parallels for the boundary fix points. vParPt = sp.vstack((vParSeg[0, :], vParPt, vParSeg[-1, :])) # Midpoints along the sequence of GPS fixes. midPts = (flatFix[1:, :] + flatFix[0:-1, :]) / 2 # Perpendicular vectors at each segment and fix point. # Vector lengths are set to sideRange. vPerpSeg = ps.sideRange * mm.unit(mm.perp(vParSeg)) # (m) vPerpPt = ps.sideRange * mm.unit(mm.perp(vParPt)) # (m) # If cropping, only include fix points where asked. plottedPkts = sp.array(range(len(at.pkt))) if crop and ps.plotThis != 'crop': plottedPkts = plottedPkts[at.cropLogic] lastGoodVerts = sp.zeros((4, 2)) # Polygon patches for each packet. for p in plottedPkts: # Perpendicular displacement, length sideRange, at the first midpoint. if p != 0: # Identify a trailing midpoint which is different from the # present fix location. (Not between duplicate fixes.) pPrior = p - 1 while pPrior >= 0 and all(midPts[pPrior, :] == flatFix[p, :]): pPrior -= 1 vert01 = sp.vstack((midPts[pPrior, :] - vPerpSeg[pPrior, :], midPts[pPrior, :] + vPerpSeg[pPrior, :])) else: vert01 = sp.zeros((0, 2)) # Polygon points offset from the flat fix points themselves. vert2 = flatFix[p, :] + vPerpPt[p, :] vert5 = flatFix[p, :] - vPerpPt[p, :] if p != len(flatFix) - 1: # at the second midpoint. vert34 = sp.vstack( (midPts[p, :] + vPerpSeg[p, :], midPts[p, :] - vPerpSeg[p, :])) else: vert34 = sp.zeros((0, 2)) # Polygon vertices. verts = sp.vstack((vert01, vert2, vert34, vert5)) # In the case where IP packets come in at a higher rate than the GPS # fixes are updated, consecutive packets have the same position at # times. In this case, reuse the last useable polygon. This will plot # on top of the reused position. if sp.isnan(verts).any(): verts = lastGoodVerts.copy() else: lastGoodVerts = verts.copy() # Vertices as tuples in a list. vertList = [tuple(row) for row in verts] # Append the latest polygon vertices to the list of polygons. bp.polyList.append(polygon(vertList)) bp.colorList = sp.hstack((bp.colorList, at.color[plottedPkts])) # Include each segment between the fix coordinates as its own line object. for p in plottedPkts: if p < len(flatFix) - 1: endPts = [tuple(row) for row in flatFix[p:p + 2, :]] if at.xmitFund == 8: bp.lineList.append(lineStr(endPts)) if ps.saveTxt: # Pseudocolor plots. txtName = 'ch%d_H%d_%s_%s_%d.txt' % ( ps.ch, ps.h, ps.plotThis, at.fileDateStr, at.fileNum, ) txtPath = os.path.join(ps.folderPath, 'plotData', ps.plotThis, txtName) with open(txtPath, 'w') as f: for p in range(at.pktCount): # longi (deg), lat (deg), color (?) wStr = (str(dfPt.geometry[p].x) + ',' + str(dfPt.geometry[p].y) + ',' + str(at.color[p]) + '\n') f.write(wStr)
def distance(p_x, p_y, line): # l = line([(1, 1), (-1,1)]) p = point(p_x, p_y) return p.distance(line)
def distance(p_x, p_y, line_points): # l = line([(1, 1), (-1,1)]) link_line = line(line_points) p = point(p_x, p_y) return p.distance(link_line)
def connect(separated_path, outputpath, fpnumber, fpnumberr, window_coords, wall_coords, window_polygon, new_pair): filename = separated_path + fpnumber img = cv2.imread(filename + '_merged.png') affine_m = [1, 0, 0, -1, 0, img.shape[0]] window_point = [] #change window_coords to shapley Points for i in range(len(window_coords)): window_x = window_coords[i][0] window_y = window_coords[i][1] a = point(window_x, window_y) apoint = af(a, affine_m) window_point.append( apoint) # calibrate coordinates using affine matrix # window_point = shapely points of window endpoints wall_point = [] for i in range(len(wall_coords)): wall_x = wall_coords[i][0] wall_y = wall_coords[i][1] apoint = af(point(wall_x, wall_y), affine_m) wall_point.append(apoint) wdict = dict() for i in range(len(window_polygon)): wlist = [] for j in range(len(window_point)): if window_polygon[i].contains(window_point[j]) == True: wlist.append(j) wdict[i] = wlist # ddict = window_corners in the same window polygon def vis(window_polygon, window_point, wall_point): window_polygon = gpd.GeoDataFrame(window_polygon, columns=['geometry']) window_point = gpd.GeoDataFrame(window_point, columns=['geometry']) wall_point = gpd.GeoDataFrame(wall_point, columns=['geometry']) window_polygon.to_file(outputpath + fpnumber + '_window_polys.shp') window_point.to_file(outputpath + fpnumber + '_window_corner.shp') wall_point.to_file(outputpath + fpnumber + '_wall_corner.shp') vis(window_polygon, window_point, wall_point) close = dict() # 폐합하는 부분 for i in range(len(wdict)): av = [] for j in range(len((wdict[i]))): idx = wdict[i][j] #window 코너의 인덱스 crd = window_coords[idx] #해당 인덱스의 좌표값 for k in range(len(new_pair)): #new_set = [문원래좌표, 바뀐거, 인접벽, 거리] if crd == new_pair[k][0]: #문원래 좌표랑 맞는게 있으면 crd_n = new_pair[k][1] #바뀐 좌표로 바꿔라 av.append(crd_n) close[i] = av # 인접 벽의 좌표들로 바뀐 문 좌표들을 문 인덱스별로 묶음 window_line = [] for i in range(len(close)): sng = [] for j in range(len(close[i])): ax = close[i][j][0] ay = close[i][j][1] a = point(ax, ay) apoint = af(a, affine_m) sng.append(apoint) if len(sng) > 1 and len(sng) < 9: line = string(sng) window_line.append(line) window_gj = [] # window_line을 geojson으로 저장 for i in range(len(window_line)): window_gj.append(Feature(geometry=window_line[i], properties={})) window = FeatureCollection(window_gj) with open(outputpath + fpnumber + '_window_line.geojson', 'w') as f: dump(window, f) with open(outputpath + fpnumber + '_wall.geojson') as f: wall_v = gj.load(f) wall_vecs = [ wall_v['features'][i]['geometry'] for i in range(len(wall_v['features'])) ] #geojson obj wall_vecs = [shape(wall_vecs[i]) for i in range(len(wall_vecs))] #shapely obj wall_lines = sp.ops.linemerge(wall_vecs) # wall_poly = sp.ops.polygonize(wall_lines) ksk = [] for i in range(len(window_line)): kiki = [] for j in range(len(wall_lines)): #여기 수정이 필요할듯 new_window_line = snap(window_line[i], wall_lines[j], tolerance=2) #벽 라인에 대해서 문 라인을 스냅핑 if window_line[i] == new_window_line: continue else: kiki.append(new_window_line) ksk.append(kiki) new_window_gj = [] #폐합하는 window for i in range(len(ksk)): for j in range(len(ksk[i])): new_window_gj.append(Feature(geometry=ksk[i][j], properties={})) new_window = FeatureCollection(new_window_gj) with open(outputpath + fpnumber + '_window_new_line.geojson', 'w') as f: dump(new_window, f) return window_gj
def plotStrip(at, ps, crop): """ Plot a strip of colored polygons along a trace of GPS coordinates (deg). Extension of the strip outward from the line to either side is specified by ps.sideRange, in meters. Parameters ---------- at.fix : float (deg), (pktCount)x2 array [longitude, latitude] coordinates of ship, rows are packets in order. at.depth : float (m), array length pktCount Water depth beneath the ship at each fix. Used with extended lead-in length of cable to estimate sensor position by layback calculation. at.leadin : float (m) at.color : float (m), array length pktCount List of numbers for each position indicating the color to plot representing IP data results. """ # Start by transforming the fix points into a local azimuthal equidistant # reference system. Units along x and y are meters. ptList = [point(tuple(row)) for row in at.fix] dfPt = gpd.GeoDataFrame({'geometry': ptList}) # Assign the WGS84 latitude-longitude Coordinate Reference System (CRS). dfPt.crs = ps.crsWGS84 # Transform to the azimuthal equidistant reference. dfPt = dfPt.to_crs(ps.crsAzEq) # Extract the transformed coordinates into an array. flatFix = sp.zeros_like(at.fix, dtype=float) for p in range(len(flatFix)): flatFix[p, :] = sp.array(dfPt.geometry[p].coords) # (m) # Track vectors between each pair of consecutive GPS fixes. vParSeg = flatFix[1:, :] - flatFix[0:-1, :] # Length of each trach vector. segLen = sp.sqrt(vParSeg[:, 0]**2 + vParSeg[:, 1]**2) # (m) # Cumulative sum along the track line. sumLen = sp.hstack((0, sp.cumsum(segLen))) # Interpolate a laidback fix location on the track line. # Layback the extra length at the start of the line according to # the boat's heading for the first few meters twice the length of # the cable lead in. newFix = sp.zeros_like(flatFix, dtype=float) linLoc = 2 * at.leadin closeIdx = sp.argmin(abs(sumLen - linLoc)) if linLoc >= sumLen[closeIdx]: idx1 = closeIdx idx2 = closeIdx + 1 else: idx1 = closeIdx - 1 idx2 = closeIdx l1 = sumLen[idx1] l2 = sumLen[idx2] startHeadingFix = flatFix[idx1, :] + ( flatFix[idx2, :] - flatFix[idx1, :]) * (linLoc - l1) / (l2 - l1) startHeadingVec = mm.unit(startHeadingFix - flatFix[0, :]) for p in range(len(flatFix)): linLoc = sumLen[p] - mm.cableRange(at.leadin, at.depth[p]) if linLoc >= 0: closeIdx = sp.argmin(abs(sumLen - linLoc)) if linLoc >= sumLen[closeIdx]: idx1 = closeIdx idx2 = closeIdx + 1 else: idx1 = closeIdx - 1 idx2 = closeIdx l1 = sumLen[idx1] l2 = sumLen[idx2] newFix[p, :] = flatFix[idx1, :] + (flatFix[idx2, :] - flatFix[ idx1, :]) * (linLoc - l1) / (l2 - l1) else: newFix[p, :] = flatFix[0, :] + linLoc * startHeadingVec # Overwrite. flatFix = newFix # Reevaluate track vectors between each pair of consecutive GPS fixes. vParSeg = flatFix[1:, :] - flatFix[0:-1, :] # Track vectors at each point, found from points before and after. vParPt = flatFix[2:, :] - flatFix[0:-2, :] # Include segment parallels for the boundary fix points. vParPt = sp.vstack((vParSeg[0, :], vParPt, vParSeg[-1, :])) # Midpoints along the sequence of GPS fixes. midPts = (flatFix[1:, :] + flatFix[0:-1, :]) / 2 # Perpendicular vectors at each segment and fix point. # Vector lengths are set to sideRange. vPerpSeg = ps.sideRange * mm.unit(mm.perp(vParSeg)) # (m) vPerpPt = ps.sideRange * mm.unit(mm.perp(vParPt)) # (m) # Include each segment between the fix coordinates as its own line object. lineList = [] for p in range(len(flatFix) - 1): endPts = [tuple(row) for row in flatFix[p:p + 2, :]] lineList.append(lineStr(endPts)) dfLine = gpd.GeoDataFrame({'geometry': lineList}) dfLine.crs = ps.crsAzEq polyList = [] # If cropping, only include fix points where asked. plottedPkts = sp.array(range(len(at.pkt))) if crop: plottedPkts = plottedPkts[at.cropLogic] # Polygon patches for each packet. for p in plottedPkts: # Perpendicular displacement, length sideRange, at the first midpoint. if p != 0: vert01 = sp.vstack((midPts[p - 1, :] - vPerpSeg[p - 1, :], midPts[p - 1, :] + vPerpSeg[p - 1, :])) else: vert01 = sp.zeros((0, 2)) # Polygon points offset from the flat fix points themselves. vert2 = flatFix[p, :] + vPerpPt[p, :] vert5 = flatFix[p, :] - vPerpPt[p, :] if p != len(flatFix) - 1: # at the second midpoint. vert34 = sp.vstack( (midPts[p, :] + vPerpSeg[p, :], midPts[p, :] - vPerpSeg[p, :])) else: vert34 = sp.zeros((0, 2)) # Polygon vertices. verts = sp.vstack((vert01, vert2, vert34, vert5)) # Vertices as tuples in a list. vertList = [tuple(row) for row in verts] # Append the latest polygon vertices to the list of polygons. polyList.append(polygon(vertList)) # Geopandas data frame object containing each polygon in the list, along # with colors. dfPoly = gpd.GeoDataFrame({ 'geometry': polyList, 'color': at.color[plottedPkts] }) dfPoly.crs = ps.crsAzEq # Transform back to (longi,lat), if requested. if ps.plotWGS84: dfPt = dfPt.to_crs(ps.crsWGS84) dfLine = dfLine.to_crs(ps.crsWGS84) dfPoly = dfPoly.to_crs(ps.crsWGS84) dfPoly.plot(ax=ps.ax, column='color', cmap=ps.cmap, vmin=ps.colMin, vmax=ps.colMax) if ps.showLines: dfLine.plot(ax=ps.ax, color=ps.lineCol) if ps.showPts: dfPt.plot(ax=ps.ax) # Transform back to (longi,lat). if ~ps.plotWGS84: dfPt = dfPt.to_crs(ps.crsWGS84) dfLine = dfLine.to_crs(ps.crsWGS84) dfPoly = dfPoly.to_crs(ps.crsWGS84) if ps.saveTxt: # Pseudocolor plots. txtName = 'ch%d_H%d_%s_%s_%d.txt' % ( ps.ch, ps.h, ps.plotThis, at.fileDateStr, at.fileNum, ) txtPath = os.path.join(ps.folderPath, 'plotData', ps.plotThis, txtName) with open(txtPath, 'w') as f: for p in range(at.pktCount): # longi (deg), lat (deg), color (?) wStr = (str(dfPt.geometry[p].x) + ',' + str(dfPt.geometry[p].y) + ',' + str(at.color[p]) + '\n') f.write(wStr)