def test_transformer_from_pipeline__wkt_json(method_name): assert (Transformer.from_pipeline( getattr( Transformer.from_pipeline( "urn:ogc:def:coordinateOperation:EPSG::1671"), method_name, )()).description == "RGF93 to WGS 84 (1)")
def run_pipeline(self, xx, yy, zz, incrs, region_name): """ MLLW to NAVD88 """ req_hcrs_epsg = 26919 req_vcrs_epsg = 'mllw' out_vcrs_epsg = 5703 # parse the provided CRS cmpd_incrs = CompoundCRS.from_wkt(incrs.to_wkt()) if len(cmpd_incrs.sub_crs_list) == 2: inhcrs, invcrs = cmpd_incrs.sub_crs_list assert inhcrs.to_epsg() == req_hcrs_epsg assert invcrs.to_epsg() == req_vcrs_epsg elif not cmpd_incrs.is_vertical: assert incrs.to_epsg() == req_hcrs_epsg # build the output crs comp_crs = CompoundCRS( name="NAD83 UTM19 + NAVD88", components=[f"EPSG:{req_hcrs_epsg}", f"EPSG:{out_vcrs_epsg}"]) # get the transform at the sparse points transformer = Transformer.from_pipeline(f'proj=pipeline \ step inv proj=utm zone=19 \ step inv proj=vgridshift grids={self.config.grid_files[f"{region_name}/mllw.gtx"]} \ step proj=vgridshift grids={self.config.grid_files[f"{region_name}/tss.gtx"]} \ step proj=utm zone=19') result = transformer.transform(xx=xx, yy=yy, zz=zz) self.config.logger.debug('Applying pipeline: {}'.format(transformer)) return result, comp_crs
def test_transform_empty_array_xyzt(empty_array): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_array_equal( transformer.transform(empty_array, empty_array, empty_array, empty_array), (empty_array, empty_array, empty_array, empty_array), )
def test_equivalent_pipeline(): transformer = Transformer.from_pipeline( "+proj=pipeline +step +proj=longlat +ellps=WGS84 +step " "+proj=unitconvert +xy_in=rad +xy_out=deg") assert not transformer._transformer.skip_equivalent assert not transformer._transformer.projections_equivalent assert not transformer._transformer.projections_exact_same
def test_4d_itransform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( list( transformer.itransform([(3513638.19380, 778956.45250, 5248216.46900, 2008.75)])), [(3513638.1999428216, 778956.4532640711, 5248216.453456361, 2008.75)], )
def test_3d_time_itransform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( list( transformer.itransform([(3513638.19380, 778956.45250, 2008.75)], time_3rd=True)), [(3513638.1999428216, 778956.4532640711, 2008.75)], )
def test_4d_transform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( transformer.transform( xx=3513638.19380, yy=778956.45250, zz=5248216.46900, tt=2008.75 ), (3513638.1999428216, 778956.4532640711, 5248216.453456361, 2008.75), )
def test_equivalent_pipeline(): transformer = Transformer.from_pipeline( "+proj=pipeline +step +proj=longlat +ellps=WGS84 +step " "+proj=unitconvert +xy_in=rad +xy_out=deg" ) assert not transformer._transformer.skip_equivalent assert not transformer._transformer.projections_equivalent assert not transformer._transformer.projections_exact_same
def test_4d_transform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( transformer.transform( xx=3513638.19380, yy=778956.45250, zz=5248216.46900, tt=2008.75 ), (3513638.1999428216, 778956.4532640711, 5248216.453456361, 2008.75), )
def test_3d_time_itransform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( list( transformer.itransform( [(3513638.19380, 778956.45250, 2008.75)], time_3rd=True ) ), [(3513638.1999428216, 778956.4532640711, 2008.75)], )
def test_4d_itransform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( list( transformer.itransform( [(3513638.19380, 778956.45250, 5248216.46900, 2008.75)] ) ), [(3513638.1999428216, 778956.4532640711, 5248216.453456361, 2008.75)], )
def test_transformer_multithread__pipeline(): # https://github.com/pyproj4/pyproj/issues/782 trans = Transformer.from_pipeline( "+proj=pipeline +step +inv +proj=cart +ellps=WGS84 " "+step +proj=unitconvert +xy_in=rad +xy_out=deg") def transform(num): return trans.transform(-2704026.010, -4253051.810, 3895878.820) with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: for result in executor.map(transform, range(10)): pass
def test_4d_transform__inverse(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( transformer.transform( xx=3513638.1999428216, yy=778956.4532640711, zz=5248216.453456361, tt=2008.75, direction=TransformDirection.INVERSE, ), (3513638.19380, 778956.45250, 5248216.46900, 2008.75), )
def test_transform_pipeline_radians(): trans = Transformer.from_pipeline( "+proj=pipeline +step +inv +proj=cart +ellps=WGS84 " "+step +proj=unitconvert +xy_in=rad +xy_out=deg") assert_almost_equal( trans.transform(-2704026.010, -4253051.810, 3895878.820, radians=True), (-2.137113493845668, 0.6613203738996222, -20.531156923621893), ) assert_almost_equal( trans.transform( -2.137113493845668, 0.6613203738996222, -20.531156923621893, radians=True, direction=TransformDirection.INVERSE, ), (-2704026.010, -4253051.810, 3895878.820), )
def __init__(self, exist_proj=None, exist_lng0=None, exist_with_zone=False, target_proj=None, target_lng0=None, target_with_zone=False, transformer=None): """ :param exist_proj: function 获取原有坐标坐标系 epsg 代码的回调函数(Epsg类方法) :param exist_lng0: float 输入坐标点的中央经线经度值,不指定此值,将根据输入的值自动计算。 当输入坐标为投影坐标并且不带分度带带号时,必须指定此值! :param exist_with_zone: Boolean 输入坐标是否带有分度带的带号 :param target_proj: function 获取目标坐标坐标系 epsg 代码的回调函数(Epsg类方法) :param target_lng0: float 输出坐标点的中央经线经度值,不指定此值,将根据输入的值自动计算。 注意!!! 保险起见,在转换经度跨度不大的批量转换时建议均指定此值,因为在批量计算中,由于点集可能位于分度带 的中央经线周围,中央经线的自动计算是严格按照分度带的规定计算的,在输出投影坐标不加带号的情况下, 转换后的坐标可能分不清位于哪个分度带内,导致转换后坐标点使用麻烦(某些点可能会偏移一个分度带, 还需找出这些点重新指定分度带,再解算回去),因此为了统一,建议在一次批量转换过程中指定中央经线 并记录此值。 :param target_with_zone: Boolean 输出坐标是否带有分度带的带号 :param transformer: obj pyproj.transformer.Transformer 自定义的转换器。 当此参数赋值时,前面所有的参数将不起作用,因为前面所有参数是用来创建转换器用的 """ self.exist_proj = exist_proj self.exist_with_zone = exist_with_zone self.exist_lng0 = exist_lng0 self.target_proj = target_proj self.target_with_zone = target_with_zone self.target_lng0 = target_lng0 self._transformer = transformer if exist_proj is None and transformer is None: self.transformer = Transformer.from_pipeline( 'proj=noop ellps=GRS80') # 保存已经存在的转换器 self.transformers = {}
def make_model_tsr_crs(m, w, raw_world=False, return_raw_params=False, return_pyproj=False, **kwargs): """ Generate a CRS for a model that will be convertible to UTM via GIS software :param m: Model Coordinates (list of tuples of x,y) or numpy array [model, m] [corresponding to w] :param w: World Coordinates (list of tuples of lat,long) or numpy array [wgs84 lat/long decimal] [corresponding to m] :param raw_world: whether to use the given world coordinates as raw (x,y) coordinates and perform no transformations on them :param return_raw_params: whether to return ((tx, ty), (sx, sy), theta/rz) as 3rd output :param return_pyproj: whether the resulting transformer should be a pyproj transformer or our own. :return: transformer, target_crs, (and optionally) ((tx, ty), (sx, sy), theta/rz) :rtype: (Transformer, CRS)|(Transformer, CRS, tuple[tuple[float, float], tuple[float, float], float]) """ w = np.asarray(w) if not raw_world: # convert lat/lon to UTM coordinates zone, hemisphere, letter = get_utm_zone(*np.average( w, axis=0)) # zone from average of given coordinates target_crs = CRS.from_epsg(get_wgs84_utm_epsg_code( zone, hemisphere)) # target CRS target_prj = Proj(target_crs) w_utm = np.stack(target_prj(w[:, 1], w[:, 0]), axis=-1) # convert lat/long to UTM else: target_crs = None w_utm = w if 'sx' in kwargs and 'sy' in kwargs and 'theta' in kwargs: m = np.asarray(m) sx = kwargs['sx'] sy = kwargs['sy'] rz = kwargs['theta'] # calculate transformation for model coordinates to UTM coordinates xfm_2d = TransformTSR2D.from_point_tsr(m, w_utm, sx, sy, rz) else: # calculate transformation for model coordinates to UTM coordinates xfm_2d = TransformTSR2D.from_points(m, w_utm) # support for 'nudging' translation by kwargs xfm_2d.nudge(tx=kwargs.pop('nx', 0.0), ty=kwargs.pop('ny', 0.0)) # get final forward transformation details from Transform2D [partially done for backwards compatibility...] (tx, ty), (sx, sy), rz = xfm_2d.tsr if return_pyproj: # TODO: ideally we could make a proj definition that would perform the transformation and appropriate projection in 1 definition...? # TODO: this projection should actually be a 2D Helmert projection?? Affine *should* work fine thought, right?? pipeline_str = """ +proj=pipeline +step +proj=affine +xoff=%.6f +yoff=%.6f +s11=%.6f +s12=%.6f +s21=%.6f +s22=%.6f """ % (tx, ty, sx * np.cos(rz), -np.sin(rz), np.sin(rz), sy * np.cos(rz)) target_xfm = Transformer.from_pipeline(pipeline_str) else: target_xfm = xfm_2d if return_raw_params: return target_xfm, target_crs, ((tx, ty), (sx, sy), rz) return target_xfm, target_crs
def test_pipeline_itransform(pipeline_str): trans = Transformer.from_pipeline(pipeline_str) assert_almost_equal( list(trans.itransform([(50, 25, 0)])), [(3717892.6072086394, 4430811.87152035, 2679074.4628772778)], )
def test_pipeline_transform(pipeline_str): trans = Transformer.from_pipeline(pipeline_str) assert_almost_equal( trans.transform(50, 25, 0), (3717892.6072086394, 4430811.87152035, 2679074.4628772778), )
def test_from_pipeline__non_transform_input(): with pytest.raises(ProjError, match="Input is not a transformation"): Transformer.from_pipeline("epsg:4326")
def test_ll2ij(): transformer = Transformer.from_pipeline(proj_string) # Seattle assert ll2ij(transformer, 123.30661, 19.624062, -122.33, 47.61) == (-3568, 3435) # Washington DC assert ll2ij(transformer, 123.30661, 19.624062, -77.01, 38.91) == (-4097, 5162)
def test_2d_with_time_transform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( transformer.transform(xx=3513638.19380, yy=778956.45250, tt=2008.75), (3513638.1999428216, 778956.4532640711, 2008.75), )
def test_transformer_from_pipeline__input_types(input_string): assert Transformer.from_pipeline( input_string).description == "RGF93 to WGS 84 (1)"
def test_2d_with_time_transform(): transformer = Transformer.from_pipeline("+init=ITRF2008:ITRF2000") assert_almost_equal( transformer.transform(xx=3513638.19380, yy=778956.45250, tt=2008.75), (3513638.1999428216, 778956.4532640711, 2008.75), )
def test_pipeline_radian_transform_warning(): trans = Transformer.from_pipeline( "+proj=pipeline +ellps=GRS80 +step +proj=cart") with pytest.warns(UserWarning): trans.transform(0.1, 0.1, 0, radians=True)
def test_transformer_group__area_of_interest__invalid(): with pytest.raises(ProjError): TransformerGroup(4326, 2964, area_of_interest=(-136.46, 49.0, -60.72, 83.17)) def test_transformer_equals(): assert (TransformerGroup(28356, 7856).transformers[0] == TransformerGroup( 28356, 7856).transformers[0]) @pytest.mark.parametrize( "comparison", [ Transformer.from_pipeline( "+proj=pipeline +ellps=GRS80 +step +proj=cart"), 22 ], ) def test_transformer_not_equals(comparison): assert Transformer.from_crs(28356, 7856) != comparison @pytest.mark.parametrize( "pipeline_str", [ "+proj=pipeline +ellps=GRS80 +step +proj=cart", "+proj=pipeline +step +proj=unitconvert +xy_in=deg " "+xy_out=rad +ellps=GRS80 +step +proj=cart", ], ) def test_pipeline_transform(pipeline_str):