def test_rotation_angle(): assert Affine.identity().rotation_angle == 0.0 assert Affine.scale(2).rotation_angle == 0.0 assert Affine.scale(2, 1).rotation_angle == 0.0 assert Affine.translation(32, -47).rotation_angle == pytest.approx(0.0) assert Affine.rotation(30).rotation_angle == pytest.approx(30) assert Affine.rotation(-150).rotation_angle == pytest.approx(-150)
def test_is_conformal(self): assert Affine.identity().is_conformal assert Affine.scale(2.5, 6.1).is_conformal assert Affine.translation(4, -1).is_conformal assert Affine.rotation(90).is_conformal assert Affine.rotation(-26).is_conformal assert not Affine.shear(4, -1).is_conformal
def test_is_rectilinear(self): assert Affine.identity().is_rectilinear assert Affine.scale(2.5, 6.1).is_rectilinear assert Affine.translation(4, -1).is_rectilinear assert Affine.rotation(90).is_rectilinear assert not Affine.shear(4, -1).is_rectilinear assert not Affine.rotation(-26).is_rectilinear
def test_inverse(self): seq_almost_equal(~Affine.identity(), Affine.identity()) seq_almost_equal( ~Affine.translation(2, -3), Affine.translation(-2, 3)) seq_almost_equal( ~Affine.rotation(-33.3), Affine.rotation(33.3)) t = Affine(1, 2, 3, 4, 5, 6) seq_almost_equal(~t * t, Affine.identity())
def test_rotation_matrix_pivot(): """A rotation matrix with pivot has expected elements""" rot = Affine.rotation(90.0, pivot=(1.0, 1.0)) exp = (Affine.translation(1.0, 1.0) * Affine.rotation(90.0) * Affine.translation(-1.0, -1.0)) for r, e in zip(rot, exp): assert round(r, 15) == round(e, 15)
def test_rotation_constructor_with_pivot(self): assert_equal(tuple(Affine.rotation(60)), tuple(Affine.rotation(60, pivot=(0,0)))) rot = Affine.rotation(27, pivot=(2,-4)) r = math.radians(27) s, c = math.sin(r), math.cos(r) assert_equal(tuple(rot), (c,s,2 - 2*c - 4*s, -s,c,-4 - 2*s + 4*c, 0,0,1)) assert_equal(tuple(Affine.rotation(0, (-3, 2))), tuple(Affine.identity()))
def test_eccentricity_complex(): assert \ (Affine.scale(2, 3) * Affine.rotation(77)).eccentricity == \ pytest.approx(math.sqrt(5) / 3) assert \ (Affine.rotation(77) * Affine.scale(2, 3)).eccentricity == \ pytest.approx(math.sqrt(5) / 3) assert \ (Affine.translation(32, -47) * Affine.rotation(77) * Affine.scale(2, 3)).eccentricity == \ pytest.approx(math.sqrt(5) / 3)
def test_rotation_constructor(self): rot = Affine.rotation(60) assert isinstance(rot, Affine) r = math.radians(60) s, c = math.sin(r), math.cos(r) assert_equal(tuple(rot), (c, -s, 0, s, c, 0, 0, 0, 1)) rot = Affine.rotation(337) r = math.radians(337) s, c = math.sin(r), math.cos(r) seq_almost_equal(tuple(rot), (c, -s, 0, s, c, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(0)), tuple(Affine.identity()))
def test_rotation_constructor_with_pivot(self): assert_equal(tuple(Affine.rotation(60)), tuple(Affine.rotation(60, pivot=(0, 0)))) rot = Affine.rotation(27, pivot=(2, -4)) r = math.radians(27) s, c = math.sin(r), math.cos(r) assert_equal( tuple(rot), (c, -s, 2 - 2 * c - 4 * s, s, c, -4 - 2 * s + 4 * c, 0, 0, 1)) assert_equal(tuple(Affine.rotation(0, (-3, 2))), tuple(Affine.identity()))
def test_rotation_constructor(self): rot = Affine.rotation(60) assert isinstance(rot, Affine) r = math.radians(60) s, c = math.sin(r), math.cos(r) assert_equal(tuple(rot), (c,s,0, -s,c,0, 0,0,1)) rot = Affine.rotation(337) r = math.radians(337) s, c = math.sin(r), math.cos(r) seq_almost_equal(tuple(rot), (c,s,0, -s,c,0, 0,0,1)) assert_equal(tuple(Affine.rotation(0)), tuple(Affine.identity()))
def test_rotation_constructor_quadrants(self): assert_equal(tuple(Affine.rotation(0)), (1,0,0, 0,1,0, 0,0,1)) assert_equal(tuple(Affine.rotation(90)), (0,1,0, -1,0,0, 0,0,1)) assert_equal(tuple(Affine.rotation(180)), (-1,0,0, 0,-1,0, 0,0,1)) assert_equal(tuple(Affine.rotation(-180)), (-1,0,0, 0,-1,0, 0,0,1)) assert_equal(tuple(Affine.rotation(270)), (0,-1,0, 1,0,0, 0,0,1)) assert_equal(tuple(Affine.rotation(-90)), (0,-1,0, 1,0,0, 0,0,1)) assert_equal(tuple(Affine.rotation(360)), (1,0,0, 0,1,0, 0,0,1)) assert_equal(tuple(Affine.rotation(450)), (0,1,0, -1,0,0, 0,0,1)) assert_equal(tuple(Affine.rotation(-450)), (0,-1,0, 1,0,0, 0,0,1))
def get_modelgrid_transform(grid_json_file, shift_to_cell_centers=False): """Create an affine.Affine that describes the model grid from a json file. The affine package comes with rasterio as a dependency or can be installed separately. Parameters ---------- grid_json_file : str Model grid json file produced by modflow-setup shift_to_cell_centers : bool By default, transform reflects the upper left corner of the first cell in the model, and any conversions of x, y coordinates to pixels will be relative to upper left corners. If shift_to_cell_centers=True, x,y points will be referenced to the nearest cell centers. """ with open(grid_json_file) as f: cfg = json.load(f) for dx in 'delr', 'delc': if not np.isscalar(cfg[dx]): cfg[dx] = cfg[dx][0] xul = cfg['xul'] yul = cfg['yul'] if shift_to_cell_centers: xul += 0.5 * cfg['delr'] yul -= 0.5 * cfg['delc'] transform = Affine(cfg['delr'], 0., xul, 0., -cfg['delc'], yul) * \ Affine.rotation(-cfg['angrot']) return transform
def test_move(fps1px): fps = fps1px with buzz.Env(warnings=False, allow_complex_footprint=True): # Test the `warnings` deprecation assert fpeq( fps.B, fps.A.move(fps.B.tl), fps.B.move(fps.B.tl), fps.C.move(fps.B.tl), fps.A.move(fps.B.tl, fps.B.tr), fps.B.move(fps.B.tl, fps.B.tr), fps.C.move(fps.B.tl, fps.B.tr), fps.A.move(fps.B.tl, fps.B.tr, fps.B.br), fps.B.move(fps.B.tl, fps.B.tr, fps.B.br), fps.C.move(fps.B.tl, fps.B.tr, fps.B.br), ) aff = ( Affine.translation(*fps.A.bl) * Affine.rotation(45) * Affine.scale(2**0.5, 2**0.5 * -2) ) assert fpeq( buzz.Footprint(gt=aff.to_gdal(), rsize=(1, 1)), fps.A.move(fps.A.bl, fps.A.tr, fps.I.tr), fps.B.move(fps.A.bl, fps.A.tr, fps.I.tr), fps.C.move(fps.A.bl, fps.A.tr, fps.I.tr), ) with pytest.raises(ValueError, match='angle'): fps.C.move(fps.A.bl, fps.A.tr, fps.I.c)
def trans_xy(self, point): p = point * Affine.translation(*self.offset) p *= Affine.rotation(self.rotation) p *= Affine.translation(*self.origin) p *= Affine.scale(self.scale) return p
def test_geometry_window_rotated_boundless(): """Get the right boundless window for a rotated dataset""" sqrt2 = math.sqrt(2.0) dataset = mock.MagicMock() dataset.transform = (Affine.rotation(-45.0) * Affine.translation(-sqrt2, sqrt2) * Affine.scale(sqrt2 / 2.0, -sqrt2 / 2.0)) dataset.height = 4.0 dataset.width = 4.0 geometry = { "type": "Polygon", "coordinates": [[ (-2.0, -2.0), (-2.0, 2.0), (2.0, 2.0), (2.0, -2.0), (-2.0, -2.0), ]], } win = geometry_window(dataset, [geometry, geometry], boundless=True) assert win.col_off == pytest.approx(-2.0) assert win.row_off == pytest.approx(-2.0) assert win.width == pytest.approx(2.0 * dataset.width) assert win.height == pytest.approx(2.0 * dataset.height)
def test_init_edge_cases(fps): # rotation aff = Affine.translation(42, 21) * Affine.rotation(12) * Affine.scale(0.1, -0.1) with buzz.Env(allow_complex_footprint=True): buzz.Footprint(gt=aff.to_gdal(), rsize=[1, 1]) # missing parameters with pytest.raises(ValueError): buzz.Footprint(tl=fps.A.tl, size=fps.A.size) with pytest.raises(ValueError): buzz.Footprint(rsize=fps.A.rsize, size=fps.A.size) with pytest.raises(ValueError): buzz.Footprint(rsize=fps.A.rsize, tl=fps.A.tl) with pytest.raises(ValueError): buzz.Footprint(rsize=fps.A.rsize) # shapes with pytest.raises(ValueError, match='shape'): buzz.Footprint(rsize=[], tl=fps.A.tl, size=fps.A.size) with pytest.raises(ValueError, match='shape'): buzz.Footprint(rsize=fps.A.rsize, tl=[], size=fps.A.size) with pytest.raises(ValueError, match='shape'): buzz.Footprint(rsize=fps.A.rsize, tl=fps.A.tl, size=[]) with pytest.raises(ValueError, match='shape'): buzz.Footprint(rsize=fps.A.rsize, gt=[]) # finitude with pytest.raises(ValueError): buzz.Footprint(rsize=[-1] * 2, tl=fps.A.tl, size=fps.A.size) with pytest.raises(ValueError): buzz.Footprint(rsize=fps.A.rsize, tl=[np.inf] * 2, size=fps.A.size) with pytest.raises(ValueError): buzz.Footprint(rsize=fps.A.rsize, tl=fps.A.tl, size=[np.inf] * 2) with pytest.raises(ValueError): buzz.Footprint(rsize=fps.A.rsize, gt=[np.inf] * 6)
def test_roundtrip(): point = (12, 5) trans = Affine.translation(3, 4) rot37 = Affine.rotation(37.) point_prime = (trans * rot37) * point roundtrip_point = ~(trans * rot37) * point_prime seq_almost_equal(point, roundtrip_point)
def test_full_stack_dataset_xysel(self, d, translate, scale, shear, rotate, samp): dataset = create3d_dataset(dims=d) xlines_, ilines_ = np.meshgrid(dataset.xline, dataset.iline) ix_pairs = np.dstack([ilines_, xlines_]) tr = Affine.translation(*translate) sc = Affine.scale(scale) sh = Affine.shear(*shear) rt = Affine.rotation(rotate) trsfm = lambda x: tr * sc * sh * rt * x ix_pairs = np.apply_along_axis(trsfm, 1, ix_pairs.reshape( -1, 2)).reshape(ix_pairs.shape) dataset["cdp_x"] = (DimensionKeyField.cdp_3d, ix_pairs[:, :, 0]) dataset["cdp_y"] = (DimensionKeyField.cdp_3d, ix_pairs[:, :, 1]) dataset["data"] = (DimensionKeyField.threed_twt, np.random.rand(*d)) test_points = np.dstack([ np.random.random(samp) * (d[0] - 0.1) + 0.1, np.random.random(samp) * (d[1] - 0.1) + 0.1, ])[0] # make sure at least one point is in the box test_points[0, :] = d[0] / 2, d[1] / 2 xys = np.apply_along_axis(trsfm, 1, test_points) res = dataset.seis.xysel(xys[:, 0], xys[:, 1], method="linear") assert isinstance(res, xr.Dataset) res = dataset.seis.xysel(xys[:, 0], xys[:, 1], method="nearest") assert isinstance(res, xr.Dataset)
def test_average_slope(): _lines = [ geometry.LineString(coordinates=[(0, 5), (10, 5)]), geometry.LineString(coordinates=[(5, 0), (5, 10)]), geometry.LineString(coordinates=[(0, 0), (10, 10)]), geometry.LineString(coordinates=[(0, 0), (0, 10), (10, 10)]), geometry.LineString(coordinates=[(0, 0), (5, 5), (5, 0), (0, 0)]), ] lines = geopandas.GeoDataFrame(geometry=_lines) expected = pandas.Series([ 1.000000, 0.000000, 0.707107, 0.500000, 0.000000, ]) * 100 hill = numpy.mgrid[:11, :11][1] trans = Affine.translation(0, 10) * Affine.rotation(0) * Affine.scale( 1, -1) result = algo.average_slope(lines, hill, trans) pdtest.assert_series_equal(result, expected)
def test_rotation_constructor_quadrants(self): assert_equal(tuple(Affine.rotation(0)), (1, 0, 0, 0, 1, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(90)), (0, -1, 0, 1, 0, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(180)), (-1, 0, 0, 0, -1, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(-180)), (-1, 0, 0, 0, -1, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(270)), (0, 1, 0, -1, 0, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(-90)), (0, 1, 0, -1, 0, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(360)), (1, 0, 0, 0, 1, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(450)), (0, -1, 0, 1, 0, 0, 0, 0, 1)) assert_equal(tuple(Affine.rotation(-450)), (0, 1, 0, -1, 0, 0, 0, 0, 1))
def transform_point(self, point, transform): p = point * Affine.translation(xoff=transform.offset[0], yoff=transform.offset[1]) p *= Affine.rotation(transform.rotation) p *= Affine.translation(xoff=transform.origin[0], yoff=transform.origin[1]) p *= Affine.scale(transform.scale) return p
def test_associative(): point = (12, 5) trans = Affine.translation(-10., -5.) rot90 = Affine.rotation(90.) result1 = rot90 * (trans * point) result2 = (rot90 * trans) * point seq_almost_equal(result1, (0., 2.)) seq_almost_equal(result1, result2)
def test_determinant(self): assert Affine.identity().determinant == 1 assert Affine.scale(2).determinant == 4 assert Affine.scale(0).determinant == 0 assert Affine.scale(5, 1).determinant == 5 assert Affine.scale(-1, 1).determinant == -1 assert Affine.scale(-1, 0).determinant == 0 assert Affine.rotation(77).determinant == pytest.approx(1) assert Affine.translation(32, -47).determinant == pytest.approx(1)
def test_determinant(self): assert_equal(Affine.identity().determinant, 1) assert_equal(Affine.scale(2).determinant, 4) assert_equal(Affine.scale(0).determinant, 0) assert_equal(Affine.scale(5, 1).determinant, 5) assert_equal(Affine.scale(-1, 1).determinant, -1) assert_equal(Affine.scale(-1, 0).determinant, 0) assert_almost_equal(Affine.rotation(77).determinant, 1) assert_almost_equal(Affine.translation(32, -47).determinant, 1)
def test_eccentricity(): assert Affine.identity().eccentricity == 0.0 assert Affine.scale(2).eccentricity == 0.0 #assert_equal(Affine.scale(0).eccentricity, ?) assert Affine.scale(2, 1).eccentricity == pytest.approx(math.sqrt(3) / 2) assert Affine.scale(2, 3).eccentricity == pytest.approx(math.sqrt(5) / 3) assert Affine.scale(1, 0).eccentricity == 1.0 assert Affine.rotation(77).eccentricity == pytest.approx(0.0) assert Affine.translation(32, -47).eccentricity == pytest.approx(0.0) assert Affine.scale(-1, 1).eccentricity == pytest.approx(0.0)
def drift(data, gridx, gridy, degree=3, plot=False, threed=True, anisotropy_ang=None): # Get drift function from sklearn.linear_model import Ridge from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline from affine import Affine # Make grid and setup data X = data[:, 0:2] z = data[:, 2] xv, yv = np.meshgrid(gridx, gridy) # Set up coordinates for prediction coord1, coord2 = xv.ravel(), yv.ravel() coord = np.vstack((coord1, coord2)).transpose() if anisotropy_ang: print('Method not ready yet') pass print('Rotating data and grid {} degrees CCW'.format(anisotropy_ang)) aff = Affine.rotation(anisotropy_ang) # Rotate data X_rot = [np.round(aff * a, 2) for a in X] X = np.asarray(X_rot) # Rotate grid coords grid = [np.round(aff * a, 2) for a in coord] coord = np.asarray(grid) # Do we need to rotate for the functional drift in UK? # Set up interpolation model model = make_pipeline(PolynomialFeatures(degree), Ridge()) model.fit(X, z) if plot: z_plot = model.predict(coord).reshape(np.shape(xv)) resid = model.predict(X) - z extent = (gridx.min(), gridx.max(), gridy.min(), gridy.max()) fig = plt.figure() if threed: ax = fig.add_subplot(111, projection='3d') ax.plot_surface(xv, yv, z_plot, cmap='gist_earth') ax.scatter(data[:, 0], data[:, 1], data[:, 2], c=resid) else: ax = fig.add_subplot(111) ax.contourf(xv, yv, z_plot, cmap='gist_earth') ax.scatter(data[:, 0], data[:, 1], data[:, 2], c=resid) # Try using model in drift terms as drift function return lambda x, y: model.predict(np.vstack((x, y)).T)
def test_is_degenerate(self): assert not Affine.identity().is_degenerate assert not Affine.translation(2, -1).is_degenerate assert not Affine.shear(0, -22.5).is_degenerate assert not Affine.rotation(88.7).is_degenerate assert not Affine.scale(0.5).is_degenerate assert Affine.scale(0).is_degenerate assert Affine.scale(-10, 0).is_degenerate assert Affine.scale(0, 300).is_degenerate assert Affine.scale(0).is_degenerate assert Affine.scale(0).is_degenerate
def test_itransform(self): pts = [(4, 1), (-1, 0), (3, 2)] r = Affine.scale(-2).itransform(pts) assert r is None, r assert pts == [(-8, -2), (2, 0), (-6, -4)] A = Affine.rotation(33) pts = [(4, 1), (-1, 0), (3, 2)] pts_expect = [A*pt for pt in pts] r = A.itransform(pts) assert r is None assert pts == pts_expect
def test_itransform(self): pts = [(4, 1), (-1, 0), (3, 2)] r = Affine.scale(-2).itransform(pts) assert r is None, r assert pts == [(-8, -2), (2, 0), (-6, -4)] A = Affine.rotation(33) pts = [(4, 1), (-1, 0), (3, 2)] pts_expect = [A * pt for pt in pts] r = A.itransform(pts) assert r is None assert pts == pts_expect
def transformPoint(angleB, massA_x, massA_y, massB_x, massB_y): ''' transform the origin of the space so that the mass center of animalB is the origin of the new space ''' Affine.identity() x = massA_x - massB_x y = massA_y - massB_y rotation = Affine.rotation(90- math.degrees( angleB ) ) * ( x , y ) return rotation[0], rotation[1]
def test_from_bounds_rotation(): """Get correct window when transform is rotated""" sqrt2 = math.sqrt(2.0) # An 8 unit square rotated cw 45 degrees around (0, 0). height = 4 width = 4 transform = (Affine.rotation(-45.0) * Affine.translation(-sqrt2, sqrt2) * Affine.scale(sqrt2 / 2.0, -sqrt2 / 2.0)) win = from_bounds(-2.0, -2.0, 2.0, 2.0, transform=transform) assert win.col_off == pytest.approx(-2.0) assert win.row_off == pytest.approx(-2.0) assert win.width == pytest.approx(2.0 * width) assert win.height == pytest.approx(2.0 * height)
def test_rotation_matrix(): """A rotation matrix has expected elements | cos(a) -sin(a) | | sin(a) cos(a) | """ rot = Affine.rotation(90.0) assert round(rot.a, 15) == round(math.cos(math.pi/2.0), 15) assert round(rot.b, 15) == round(-math.sin(math.pi/2.0), 15) assert rot.c == 0.0 assert round(rot.d, 15) == round(math.sin(math.pi/2.0), 15) assert round(rot.e, 15) == round(math.cos(math.pi/2.0), 15) assert rot.f == 0.0
def rotate(gbox: GeoBox, deg: float) -> GeoBox: """ Rotate GeoBox around the center. It's as if you stick a needle through the center of the GeoBox footprint and rotate it counter clock wise by supplied number of degrees. Note that from pixel point of view image rotates the other way. If you have source image with an arrow pointing right, and you rotate GeoBox 90 degree, in that view arrow should point down (this is assuming usual case of inverted y-axis) """ h, w = gbox.shape c0 = gbox.transform * (w * 0.5, h * 0.5) A = Affine.rotation(deg, c0) * gbox.transform return GeoBox(w, h, A, gbox.crs)
def D_Hplus1(self, x, y, dunits='km', doseunits='Sv'): """Returns dose rate at x, y at 1 hour after burst. This value includes dose rate from all activity that WILL be deposited at that location, not just that that has arrived by H+1 hr.""" rx, ry = self.translation * (convert_units( x, dunits, 'mi'), convert_units( y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270) f_x = self.yld * 2e6 * self.phi(rx) * self.g(rx) * self.ff s_y = np.sqrt(self.s_02 + ((8 * abs(rx + 2 * self.s_x) * self.s_02) / self.L) + (2 * (self.s_x * self.T_c * self.s_h * self.shear)**2 / self.L_2) + (((rx + 2 * self.s_x) * self.L_0 * self.T_c * self.s_h * self.shear)**2 / self.L**4)) a_2 = 1 / (1 + ((0.001 * self.H_c * self.wind) / self.s_0) * (1 - norm.cdf(2 * x / self.wind))) f_y = np.exp(-0.5 * (ry / (a_2 * s_y))**2) / (2.5066282746310002 * s_y) return convert_units(f_x * f_y, 'Roentgen', doseunits)
def test_rotation_angle(): """A positive angle rotates a vector counter clockwise (1.0, 0.0): | | | | 0---------* Affine.rotation(45.0) * (1.0, 0.0) == (0.707..., 0.707...) | | * | | 0---------- """ x, y = Affine.rotation(45.0) * (1.0, 0.0) assert round(x, 14) == round(math.sqrt(2.0) / 2.0, 14) assert round(y, 14) == round(math.sqrt(2.0) / 2.0, 14)
def test_average_slope(): _lines = [ geometry.LineString(coordinates=[(0, 5), (10, 5)]), geometry.LineString(coordinates=[(5, 0), (5, 10)]), geometry.LineString(coordinates=[(0, 0), (10, 10)]), geometry.LineString(coordinates=[(0, 0), (0, 10), (10, 10)]), geometry.LineString(coordinates=[(0, 0), (5, 5), (5, 0), (0, 0)]), ] lines = geopandas.GeoDataFrame(geometry=_lines) expected = pandas.Series([ 1.000000, 0.000000, 0.707107, 0.500000, 0.000000, ]) * 100 hill = numpy.mgrid[:11, :11][1] trans = Affine.translation(0, 10) * Affine.rotation(0) * Affine.scale(1, -1) result = algo.average_slope(lines, hill, trans) pdtest.assert_series_equal(result, expected)
def main(): args = docopt(__doc__, version=VERSION) logparams = {} if args['--debug']: logparams.update(level=logging.DEBUG) elif args['--info']: logparams.update(level=logging.INFO) else: logparams.update(level=logging.CRITICAL) if args['--logfile'] != '': logparams.update(filename=args['--logfile']) logging.basicConfig(**logparams) logger = logging.getLogger('extract_patches') logger.debug('input \n {}'.format(args)) assert isinstance(logger, logging.Logger) shapefiles = collect_filenames(args['-i']) if len(shapefiles) == 0: logger.error('No matching shapefiles for inoput `{}`'.format(args['-i'])) return raster = args['-r'] try: size = [int(x) for x in args['--size'].split(',')] patch_width, patch_height = size logger.debug("Set patch size to {} x {}".format(patch_width, patch_height)) except: logger.error("Unable to parse option '--size'") return try: scale = float(args['--scale']) assert scale > 0 logger.debug("Set scale to {}".format(scale)) except: logger.error("Unable to parse option '--scale'") return silent = args['--noprogress'] output_folder = args['--odir'] try: if not os.path.isdir(output_folder): os.makedirs(output_folder) logger.debug("Created output folder '{}'".format(output_folder)) else: logger.debug("Found existing output folder '{}'".format(output_folder)) except: logger.error("Unable to find or create output directory `{}`".format(output_folder)) return if args['--ojpg']: fmt = '.jpg' else: # args['--otif'] (default) fmt = '.tif' logger.debug("Output format set to {}".format(fmt)) clip = args['--vclip'] is not None if clip: clipmin, clipmax = [float(x) for x in args['--vclip'].split(',')] logger.debug("Clipping output to [{}, {}]".format(clipmin, clipmax)) else: clipmin, clipmax = 0, 1 logger.debug("Not clipping output -- assuming range of value is [{},{}]".format(clipmin, clipmax)) stretch = args['--vstretch'] is not None if stretch: stretchmin, stretchmax = [float(x) for x in args['--vstretch'].split(',')] logger.debug("Output value range will be stretched to [{},{}]".format(stretchmin, stretchmax)) else: logger.debug("Output values will not be stretched") if args['--csv']: csv_file_name = args['--csv'] if os.path.isfile(csv_file_name): logger.error("CSV File already exists; please remove or rename it first.") logger.debug("Writing to CSV File '{}'".format(csv_file_name)) return else: csv_file_name = None logger.debug("No CSV output") # Estimate number of shape features count = 0 if not silent: pbar = ProgressBar(len(shapefiles), ['Counting Features:', Percentage(), ' ', Bar(), ' ', ETA()]) pbar.start() for i, s in enumerate(shapefiles): vector = ogr.Open(s) layer = vector.GetLayer() count += layer.GetFeatureCount() if not silent: pbar.update(i) if not silent: pbar.finish() logger.debug("Counted {} features in {} shapefiles".format(count, len(shapefiles))) # Write header for CSV file if csv_file_name is not None: with open(os.path.join(output_folder, csv_file_name), 'w') as csvf: csvf.write('gx, gy, r1, r2, theta, patch_width, patch_height, image_namei\n') with rasterio.open(raster) as rf: assert isinstance(rf, RasterReader) srs = SpatialReference(str(rf.crs_wkt)) affine = rf.affine geo_to_pixels = ~affine logging.debug("Output CRS will be '''{}'''".format(srs.ExportToPrettyWkt())) if not silent: pbar = ProgressBar(count, ['Exporting Patches:', Percentage(), ' ', Bar(), ' ', ETA()]) pbar.start() for sf in shapefiles: logger.info("Processing input '{}'".format(sf)) vector = ogr.Open(sf) assert isinstance(vector, ogr.DataSource) layer = vector.GetLayer() assert isinstance(layer, ogr.Layer) if not srs.IsSame(layer.GetSpatialRef()): logger.warning("Coordinate system mismatch (its ok, I will reproject)") for f in layer: if not silent: pbar.update(pbar.currval + 1) geom = f.GetGeometryRef() assert isinstance(geom, ogr.Geometry) geom = geom.TransformTo(srs) points = geom.GetPoints() source = points[0] target = points[-1] sx, sy = geo_to_pixels * source tx, ty = geo_to_pixels * target if len(points) == 2: cx, cy = (sx + tx) / 2, (sy + ty) / 2 else: cx, cy = geo_to_pixels * points[1] dx, dy = (tx - sx), (ty - sy) theta = degrees(atan2(dy, dx)) # In PIXELS, CCW from +x. Not necessarily CCW from E (or CW from N) r1 = hypot(tx - cx, ty - cy) r2 = hypot(cx - sx, cy - sy) r1, r2 = max(r1, r2), min(r1, r2) # For 3 points, we assume two radii. Else these are duplicates. gx, gy = affine * (cx, cy) # Geographic coordinates (e.g. lat lon) of the center. # We read a square slightly larger than the scaled version of our patch, so that # we can safely rotate the raster without missing pixels in the corners. box_radius = hypot(patch_width, patch_height) / (2.0 * scale) x0, x1 = int(floor(cx - box_radius)), int(ceil(cx + box_radius)) y0, y1 = int(floor(cy - box_radius)), int(ceil(cy + box_radius)) # save patch... kwargs = rf.meta patch_affine = (affine * Affine.translation(cx, cy) * Affine.rotation(angle=-theta) * Affine.translation(-patch_width / 2., -patch_height / 2.)) if fmt == '.tif': kwargs.update( driver='GTiff', compress='lzw', dtype=numpy.float32 ) elif fmt == '.jpg': kwargs.update( driver='JPEG', quality=90, dtype=numpy.uint8 ) kwargs.update( transform=patch_affine, width=patch_width, height=patch_height ) box_radius *= scale name = hashlib.md5(str(patch_affine) + raster).hexdigest() image_name = os.path.join(output_folder, name + fmt) if csv_file_name is not None: with open(os.path.join(output_folder, csv_file_name), 'a+') as csvf: fields = gx, gy, r1, r2, theta, patch_width, patch_height, image_name csvf.write(','.join([str(_) for _ in fields]) + '\n') with rasterio.open(image_name, 'w', **kwargs) as pf: assert isinstance(pf, RasterUpdater) for band in range(rf.count): patch = rf.read(band + 1, window=((y0, y1), (x0, x1)), boundless=True, ) patch = patch.astype(numpy.float32) patch_rotated = rotate(patch, theta, reshape=False) patch_scaled = zoom(patch_rotated, scale) i0 = int(round(box_radius - patch_height / 2.)) i1 = i0 + patch_height j0 = int(round(box_radius - patch_width / 2.)) j1 = j0 + patch_width patch_cropped = patch_scaled[i0:i1, j0:j1] if clip: patch_cropped = numpy.clip(patch_cropped, clipmin, clipmax) if stretch: patch_cropped = (patch_cropped - clipmin) / (clipmax - clipmin) patch_cropped = patch_cropped * (stretchmax - stretchmin) + stretchmin if fmt == '.jpg': # JPEG does not support floating point output. All we can do is 8 bit # (python has not 12bit array type) patch_cropped = img_as_ubyte(patch_cropped.clip(-1, 1)) pf.write(patch_cropped, band + 1) if not silent: pbar.finish() logger.debug("Finished.")
def im_proc(flag=False): #Init GUI app = QApplication([]) flist = str(QFileDialog.getExistingDirectory(None,"Select img folder")) + "/" fname = QDir(flist) limg = fname.entryList(["*.jpg","*.png"], QDir.Files, QDir.Name) lann = fname.entryList(["*.pts"], QDir.Files, QDir.Name) if not os.path.exists(flist + "Processed"): os.mkdir(flist + "Processed") clist = str(QFileDialog.getExistingDirectory(None,"Select proc folder")) + "/" cname = QDir(clist) #Processing for i in range(len(limg)): if flag: print("Read img " + str(limg[i])) print("Read point " + str(i)) #Read image img = cv2.imread(flist+str(limg[i])) (h,w) = img.shape[:2] #Read .csv file lines = open(flist + lann[i]).read().split("\n") lines = lines [3:71] raw = np.array(np.fromstring(lines[0], sep=" ")) for x in lines[1:]: try: x1 = np.fromstring(x, sep=" ") raw = np.vstack((raw,x1)) except: pass #raw = raw.astype(int) _x = [] _y = [] for x in range(68): _x.append(raw[x][0]) _y.append(raw[x][1]) # if flag: # imgview(img, raw, "ORIGINAL") #Rotate picture to balance #31 #35 point angle = getAngle(_y[31], _x[31], _y[35], _x[35]) if flag: print("Rotate: " + str(angle)) M = cv2.getRotationMatrix2D((w/2,h/2), angle, 1.0) img = cv2.warpAffine(img, M, (w,h)) # if angle > 180.0: # continue #Update pts for x in range(68): pts = af.rotation(-angle,pivot=(w/2,h/2)) * (_x[x],_y[x]) raw[x][0] = pts[0] raw[x][1] = pts[1] _x[x] = raw[x][0] _y[x] = raw[x][1] # if flag: # imgview(img, raw, "ROTATE") #Face bounding box min_x, max_x = min(_x),max(_x) min_y, max_y = min(_y),max(_y) if (min_x-10 <= 0 or min_y-10 <= 0 or max_x >= img.shape[1] or max_y >= img.shape[0]): continue #Cropping and resize image img = img[min_y-10:max_y+10, min_x-10:max_x+10] ratio = 100.0 / img.shape[1] dim = (100, int(img.shape[0]*ratio)) img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA) #Save img cv2.imwrite(clist + str(limg[i]), img) #Update pts for x in range(68): _x[x] -= (min_x - 10) _x[x] *= ratio _y[x] -= (min_y - 10) _y[x] *= ratio raw[x][0] = _x[x] raw[x][1] = _y[x] if flag: imgview(img, raw, "CROPPED") #Write pts cimg = cname.entryList(["*.jpg","*.png"], QDir.Files, QDir.Name) with open(clist + str(cimg[-1])[:-4] + ".pts",'w') as fout: data = "version: 1\nn_points: 68\n{\n" for x in range(68): data += str(raw[x][0]) data += " " data += str(raw[x][1]) data += "\n" data += "}" fout.write(data) fout.close() print("DONE")
def draw_symbol(lib_file, part_num, pin_data, sort_type, fuzzy_match): '''Add a symbol for a part to the library.''' # Start the part definition with the header. lib_file.write( START_DEF.format(name=part_num, ref=REF_PREFIX, pin_name_offset=PIN_NAME_OFFSET, show_pin_number=SHOW_PIN_NUMBER and 'Y' or 'N', show_pin_name=SHOW_PIN_NAME and 'Y' or 'N', num_units=len(pin_data))) # Determine if there are pins across the top of the symbol. # If so, right-justify the reference and part number so they don't # run into the top pins. If not, stick with left-justification. horiz_just = 'L' horiz_offset = PIN_LENGTH for unit in list(pin_data.values()): if 'top' in list(unit.keys()): horiz_just = 'R' horiz_offset = PIN_LENGTH - 50 break # Create the field that stores the part reference. lib_file.write(REF_FIELD.format(ref_prefix=REF_PREFIX, x=XO + horiz_offset, y=YO + REF_Y_OFFSET, horiz_just=horiz_just, ref_size=REF_SIZE)) # Create the field that stores the part number. lib_file.write(PART_FIELD.format(part_num=part_num, x=XO + horiz_offset, y=YO + PART_NUM_Y_OFFSET, horiz_just=horiz_just, ref_size=PART_NUM_SIZE)) # Start the section of the part definition that holds the part's units. lib_file.write(START_DRAW) # Get a reference to the sort-key generation routine. key_func = getattr(THIS_MODULE, '{}_key'.format(sort_type)) # Now create the units that make up the part. Unit numbers go from 1 # up to the number of units in the part. The units are sorted by their # names before assigning unit numbers. for unit_num, unit in enumerate([p[1] for p in sorted(pin_data.items())], 1): # The indices of the X and Y coordinates in a list of point coords. X = 0 Y = 1 # Initialize data structures that store info for each side of a schematic symbol unit. all_sides = ['left', 'right', 'top', 'bottom'] bbox = {side: [(XO, YO), (XO, YO)] for side in all_sides} box_pt = { side: [XO + PIN_LENGTH, YO + PIN_SPACING] for side in all_sides } anchor_pt = { side: [XO + PIN_LENGTH, YO + PIN_SPACING] for side in all_sides } transform = {} # Annotate the pins for each side of the symbol and determine the bounding box # and various points for each side. for side, side_pins in list(unit.items()): annotate_pins(list(side_pins.items())) bbox[side] = pins_bbox(list(side_pins.items())) # # C B-------A # | | # ------| name1 | # | | # ------| name2 | # # A = anchor point = upper-right corner of bounding box. # B = box point = upper-left corner of bounding box + pin length. # C = upper-left corner of bounding box. anchor_pt[side] = [max(bbox[side][0][X], bbox[side][1][X]), max(bbox[side][0][Y], bbox[side][1][Y])] box_pt[side] = [ min(bbox[side][0][X], bbox[side][1][X]) + PIN_LENGTH, max(bbox[side][0][Y], bbox[side][1][Y]) ] # AL = left-side anchor point. # AB = bottom-side anchor point. # AR = right-side anchor point. # AT = top-side anchor-point. # +-------------+ # | | # | TOP | # | | # +------AL------------AT # | | # | | +---------+ # | | | | # | L | | | # | E | | R | # | F | | I | # | T | | G | # | | | H | # | | | T | # | | | | # +------AB-------+ AR--------+ # | BOTTOM | # +--------+ # # This is the width and height of the box in the middle of the pins on each side. box_width = max(abs(bbox['top'][0][Y] - bbox['top'][1][Y]), abs(bbox['bottom'][0][Y] - bbox['bottom'][1][Y])) box_height = max(abs(bbox['left'][0][Y] - bbox['left'][1][Y]), abs(bbox['left'][0][Y] - bbox['right'][1][Y])) for side in all_sides: # Each side of pins starts off with the orientation of a left-hand side of pins. # Transformation matrix starts by rotating the side of pins. transform[side] = Affine.rotation(ROTATION[side]) # Now rotate the anchor point to see where it goes. rot_anchor_pt = transform[side] * anchor_pt[side] # Translate the rotated anchor point to coincide with the AL anchor point. translate_x = anchor_pt['left'][X] - rot_anchor_pt[X] translate_y = anchor_pt['left'][Y] - rot_anchor_pt[Y] # Make additional translation to bring the AL point to the correct position. if side == 'right': # Translate AL to AR. translate_x += box_width translate_y -= box_height elif side == 'bottom': # Translate AL to AB translate_y -= box_height elif side == 'top': # Translate AL to AT translate_x += box_width # Create the complete transformation matrix = rotation followed by translation. transform[side] = Affine.translation(translate_x, translate_y) * transform[side] # Also translate the point on each side that defines the box around the symbol. box_pt[side] = transform[side] * box_pt[side] # Draw the transformed pins for each side of the symbol. for side, side_pins in list(unit.items()): # Sort the pins names for the desired order: row-wise, numeric, alphabetical. sorted_side_pins = sorted(list(side_pins.items()), key=key_func) # Draw the transformed pins for this side of the symbol. draw_pins(lib_file, unit_num, sorted_side_pins, transform[side], fuzzy_match) # Create the box around the unit's pins. lib_file.write(BOX.format(x0=int(box_pt['left'][X]), y0=int(box_pt['top'][Y]), x1=int(box_pt['right'][X]), y1=int(box_pt['bottom'][Y]), unit_num=unit_num, line_width=BOX_LINE_WIDTH, fill=FILLS[FILL])) # Close the section that holds the part's units. lib_file.write(END_DRAW) # Close the part definition. lib_file.write(END_DEF)
def test_mul_vector(self): seq_almost_equal(Affine.rotation(45.) * (1., 1.), (math.sqrt(2.), 0.))
def test_rotation_contructor_wrong_arg_types(self): with pytest.raises(TypeError): Affine.rotation(1, 1)
def test_transform_precision(): t = Affine.rotation(45.0) assert t.precision == EPSILON t.precision = 1e-10 assert t.precision == 1e-10 assert Affine.rotation(0.0).precision == EPSILON
def D_Hplus1(self, x, y, dunits='km', doseunits='Sv'): """Returns dose rate at x, y at 1 hour after burst. This value includes dose rate from all activity that WILL be deposited at that location, not just that that has arrived by H+1 hr.""" rx, ry = self.translation * (convert_units(x, dunits, 'mi'), convert_units(y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270) f_x = self.yld * 2e6 * self.phi(rx) * self.g(rx) * self.ff s_y = np.sqrt(self.s_02 + ((8 * abs(rx + 2 * self.s_x) * self.s_02) / self.L) + (2 * (self.s_x * self.T_c * self.s_h * self.shear)**2 / self.L_2) + (((rx + 2 * self.s_x) * self.L_0 * self.T_c * self.s_h * self.shear)**2 / self.L**4)) a_2 = 1 / (1 + ((0.001 * self.H_c * self.wind) / self.s_0) * (1 - norm.cdf(2 * x / self.wind))) f_y = np.exp(-0.5 * (ry / (a_2 * s_y))**2) / (2.5066282746310002 * s_y) return convert_units(f_x * f_y, 'Roentgen', doseunits)
def dose(self, x, y, dunits='km', doseunits='Sv'): """Estimate of total "Equivalent Residual Dose" (ERD) at location x, y from time of fallout arrival to 30 days, including a 90% recovery factor. """ rx, _ = self.translation * (convert_units(x, dunits, 'mi'), convert_units(y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270) t_a = self.fallouttoa(rx) # To obtain a measure of dose to humans, "Biological Dose" was defined as the # product of the DH+1 and a conversion factor, called Bio. Bio is an # empirical function depending on fallout arrival time and length of # exposure. Ten percent of the dose received is assumed irreparable and # ninety percent is assumed reparable with a thirty day time constant. This # was solved numerically and plotted as Dose vs. Time. Bio was then estimated # as Bio = (t / 19)**0.33, so that the dose at some time after activity # arrival is defined as Dose = DH+1 * Bio. Further refinements in the model # resulted in a second order approximation for Bio used here: bio = np.exp(-(0.287 + 0.52 * np.log(t_a / 31.6) + 0.04475 * np.log((t_a / 31.6)**2))) return self.D_Hplus1(x, y, dunits=dunits, doseunits=doseunits) * bio
def base_affine(rotation): return Affine.translation(5, 15) * Affine.rotation(rotation) * Affine.scale(3, -3)
def test_mul_transform(self): t = Affine.rotation(5) * Affine.rotation(29) assert isinstance(t, Affine) seq_almost_equal(t, Affine.rotation(34)) t = Affine.scale(3, 5) * Affine.scale(2) seq_almost_equal(t, Affine.scale(6, 10))
def test_rotation_contructor_wrong_arg_types(self): Affine.rotation(1, 1)