def load_boundary(boundary_json, reproject_to_proj4=None): if not isinstance(boundary_json, str): boundary_json = json.dumps(boundary_json) with fiona.open(io.BytesIO(boundary_json.encode('utf-8')), 'r') as src: if len(src) != 1: raise IOError("Boundary must have a single polygon (found: %s)" % len(src)) geom = src[0]['geometry'] if geom['type'] != 'Polygon': raise IOError("Boundary must have a polygon feature (found: %s)" % geom['type']) rings = geom['coordinates'] if len(rings) == 0: raise IOError("Boundary geometry has no rings") coords = rings[0] if len(coords) == 0: raise IOError("Boundary geometry has no coordinates") dimensions = len(coords[0]) if reproject_to_proj4 is not None: t = transformer(CRS.from_proj4(fiona.crs.to_string(src.crs)), CRS.from_proj4(reproject_to_proj4)) coords = [t.TransformPoint(*c)[:dimensions] for c in coords] return coords
def from_raster(cls, *, data: tp.Union[tp.List[Rasterdata], Rasterdata], domain: tp.Optional[GeoPolygon] = None) -> "Mesh": # Extract cpp objects if isinstance(data, list): if data[0].array.dtype == np.float64: rasterdata_cpp = triangulate_dem.raster_list_double() else: rasterdata_cpp = triangulate_dem.raster_list_float() proj4_str = data[0].coordinate_system for raster in data: rasterdata_cpp.add_raster(raster.to_cpp()) else: rasterdata_cpp = data.to_cpp() proj4_str = data.coordinate_system if domain: tmp = triangulate_dem.make_mesh( rasterdata_cpp, domain.to_cpp(), CRS.from_proj4(proj4_str).to_proj4()) mesh = cls(tmp) else: mesh = cls( triangulate_dem.make_mesh( rasterdata_cpp, CRS.from_proj4(proj4_str).to_proj4())) return mesh
def pandafy_h5_make_radarXY( folder='../../KNMI_24h/KNMI-data_2019-12-09_14-07-28/rad_nl25_rac_mfbs_24h/2.0/0002/2016/12/31/RAD_NL25_RAC_MFBS_24H/2017/', save_name_radar='../../pandafied_data/pandafied_h5_radar.csv'): ''' This function maps the y,x pixel coordinates of the KNMI precipitation data to boxes with a longitude latitude center and corner points. ''' radar = {} radar['latlon_center'] = [] radar['latlon_sw'] = [] radar['latlon_se'] = [] radar['latlon_ne'] = [] radar['latlon_nw'] = [] radar['radarX'] = [] radar['radarY'] = [] subfolder = "01/" onlyfiles = [ f for f in listdir(folder + subfolder) if isfile(join(folder + subfolder, f)) ] h5_files = [f for f in onlyfiles if '.h5' in f] with h5py.File(folder + subfolder + h5_files[0], 'r') as f: proj4 = str(list(f['geographic/map_projection'].attrs.items())[2][1]) proj4 = proj4[2:len(proj4) - 1] from_proj = CRS.from_proj4(proj4) to_proj = CRS.from_proj4("+proj=latlong +datum=WGS84 +R=+12756274" ) #circumference around equator transform = Transformer.from_crs(from_proj, to_proj) y_offset = 3650.0 x_offset = 0.0 img = list(f['image1/image_data']) for i in tqdm(range(len(img))): for j in range(len(img[i])): if img[i][j] < 65535: local_latlon_center = transform.transform( j + 0.5 - x_offset, -i - 0.5 - y_offset) radar['latlon_center'].append( (local_latlon_center[1], local_latlon_center[0])) local_sw = transform.transform(j - x_offset, -i - 1 - y_offset) radar['latlon_sw'].append((local_sw[1], local_sw[0])) local_se = transform.transform(j + 1 - x_offset, -i - 1 - y_offset) radar['latlon_se'].append((local_se[1], local_se[0])) local_ne = transform.transform(j + 1 - x_offset, -i - y_offset) radar['latlon_ne'].append((local_ne[1], local_ne[0])) local_nw = transform.transform(j - x_offset, -i - y_offset) radar['latlon_nw'].append((local_nw[1], local_nw[0])) radar['radarX'].append(j) radar['radarY'].append(i) radar = pd.DataFrame(radar) print(radar) radar.to_csv(save_name_radar, index=False)
def add_lon_lat(ds, PROJSTRING, x='x', y='y', chunks={}): """ add longitude and latitude as compute from the inverse projection given in PROJSTRING PARAMETERS: ----------- ds: xarray.Dataset PROJSTRING: str """ from pyproj import CRS, Transformer # create the coordinate reference system crs = CRS.from_proj4(PROJSTRING) # create the projection from lon/lat to x/y proj = Transformer.from_crs(crs.geodetic_crs, crs) # make x,y 2d arrays xx, yy = np.meshgrid(ds[x].values, ds[y].values) # compute the lon/lat lon, lat = proj.transform(xx, yy, direction='INVERSE') # add to dataset ds['lon'] = xr.DataArray(data=lon, dims=('y', 'x')) ds['lat'] = xr.DataArray(data=lat, dims=('y', 'x')) ds['lon'].attrs = dict(units='degrees_east') ds['lat'].attrs = dict(units='degrees_north') return ds
def extract(self, *, uid: str, face_id: int) -> Geometry: filename = self.path / f"{uid}.h5" if not filename.exists(): raise FileNotFoundError(f"File {filename.absolute()} not found.") with File(filename, "r") as archive: tin_grp_name = "tin" tin_group = archive[tin_grp_name] if "face_fields" not in tin_group: raise IOError("No face fields in dataset.") face_group = tin_group["face_fields"] if "cover_type" not in face_group: raise IOError("No cover type information in dataset.") if "cover_color" not in face_group: raise IOError("No face color information in dataset.") pts = tin_group["points"][:] projection = tin_group["points"].attrs["projection"] faces = tin_group["faces"][:] mesh = Mesh.from_points_and_faces(points=pts, faces=faces, proj4_str=projection) indices = [i for (i, f) in enumerate(tin_group["face_fields"]["cover_type"]) if f == face_id] if not indices: raise IOError(f"face_id {face_id} not found in dataset") base_color = tin_group["face_fields"]["cover_color"][indices[0]] mesh = mesh.extract_sub_mesh(np.asarray(indices)) geometry = Geometry(mesh=mesh, crs=CRS.from_proj4(projection), base_color=base_color) return geometry
def test_mars_tms(): """The Mars global mercator scheme should broadly align with the Earth Web Mercator CRS, despite the different planetary radius and scale. """ MARS_MERCATOR = CRS.from_proj4( "+proj=merc +R=3396190 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs" ) # same boundaries as Earth mercator mars_tms = TileMatrixSet.custom( [ -179.9999999999996, -85.05112877980656, 179.9999999999996, 85.05112877980656, ], MARS_MERCATOR, extent_crs=MARS2000_SPHERE, title="Web Mercator Mars", geographic_crs=MARS2000_SPHERE, ) pos = (35, 40, 3) mars_tile = mars_tms.tile(*pos) mercator_tms = morecantile.tms.get("WebMercatorQuad") earth_tile = mercator_tms.tile(*pos) assert mars_tile.x == earth_tile.x assert mars_tile.y == earth_tile.y assert mars_tile.z == earth_tile.z == 3
def reproject_et(inpath, outpath, new_crs):# new_crs: use 'EPSG:4326' for WGS 84 dst_crs = new_crs source_crs = CRS.from_proj4("+proj=ob_tran +o_proj=longlat +o_lon_p=-162 +o_lat_p=39.25 +lon_0=180 +to_meter=0.01745329") #CRS used by COSMO-REA6 with rio.open(inpath) as src: transform, width, height = calculate_default_transform( source_crs, dst_crs, src.width, src.height, *src.bounds) kwargs = src.meta.copy() kwargs.update({ 'crs': dst_crs, 'transform': transform, 'width': width, 'height': height }) with rio.open(outpath, 'w+', **kwargs) as dst: for i in range(1, src.count + 1): reproject( source=rio.band(src, i), destination=rio.band(dst, i), src_transform=src.transform, src_crs=src.crs, dst_transform=transform, dst_crs=dst_crs, resampling=Resampling.nearest)
def lonlat_to_utm(lon, lat, crs=None, units='m', false_northing=True): """Return x, y.""" if crs is None: proj4 = get_utm_proj4string(lon, lat, units) crs = CRS.from_proj4(proj4) crs = cast_to_crs(crs) proj = cast_to_proj(crs) # apply projection x, y = proj(lon, lat) # remove false northing units = retrieve_units_from_crs(crs) if false_northing: pass elif not hasattr(crs, 'utm_zone'): pass elif not crs.utm_zone.endwith('S'): pass elif units == 'm': y -= 10**7 elif units == 'km': y -= 10**4 else: raise ValueError('Unknown units: %s' % get_utm_units(crs)) return x, y
def test_nonearth_custom(): """Test Custom geographic_crs.""" MARS2000_SPHERE = CRS.from_proj4("+proj=longlat +R=3396190 +no_defs") MARS_MERCATOR = CRS.from_proj4( "+proj=merc +R=3396190 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs" ) mars_tms = TileMatrixSet.custom( [ -179.9999999999996, -85.05112877980656, 179.9999999999996, 85.05112877980656, ], MARS_MERCATOR, extent_crs=MARS2000_SPHERE, title="Web Mercator Mars", geographic_crs=MARS2000_SPHERE, ) @attr.s class MarsReader(COGReader): """Use custom geographic CRS.""" geographic_crs: rasterio.crs.CRS = attr.ib( init=False, default=rasterio.crs.CRS.from_proj4( "+proj=longlat +R=3396190 +no_defs"), ) with pytest.warns(None) as warnings: with MarsReader(COG_MARS, tms=mars_tms) as cog: assert cog.geographic_bounds[0] > -180 assert len(warnings) == 0 with pytest.warns(None) as warnings: with COGReader( COG_MARS, tms=mars_tms, geographic_crs=rasterio.crs.CRS.from_proj4( "+proj=longlat +R=3396190 +no_defs"), ) as cog: assert cog.geographic_bounds[0] > -180 assert len(warnings) == 0
def test_explicit_crs_from_epsg(self): with pytest.warns(FutureWarning): assert explicit_crs_from_epsg(epsg=4326) == CRS.from_epsg(4326) assert explicit_crs_from_epsg(epsg="4326") == CRS.from_epsg(4326) assert explicit_crs_from_epsg( crs={"init": "epsg:4326"}) == CRS.from_dict( {"init": "epsg:4326"}) assert explicit_crs_from_epsg( crs="+init=epsg:4326") == CRS.from_proj4("+init=epsg:4326")
def basin_avg_netcdf(netcdf_file, shp_file, mask_file): data_netcdf = Dataset(netcdf_file, 'r') # reads the netCDF file print(data_netcdf) # get all variable names print(data_netcdf.variables.keys()) temp_lat = data_netcdf.variables['lat'] # temperature variable temp_lon = data_netcdf.variables['lon'] # temperature variable for d in data_netcdf.dimensions.items(): print(d) x, y = data_netcdf.variables['x'], data_netcdf.variables['y'] x = data_netcdf.variables['x'][:] y = data_netcdf.variables['y'][:] lx = list(x) ly = list(y) print(all(ix < jx for ix, jx in zip(lx, lx[1:]))) print(all(iy > jy for iy, jy in zip(ly, ly[1:]))) lons = data_netcdf.variables['lon'][:] lats = data_netcdf.variables['lat'][:] crs_pro_str = '+proj=lcc +lat_1=25 +lat_2=60 +lat_0=42.5 +lon_0=-100 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs' crs_geo_str = '+proj=longlat +datum=WGS84 +no_defs' crs_from = CRS.from_proj4(crs_geo_str) crs_to = CRS.from_proj4(crs_pro_str) new_shps = gpd.read_file(shp_file) polygon = new_shps.at[0, 'geometry'] start = time.time() mask = create_mask(polygon, x, y, lons, lats, crs_from, crs_to) end = time.time() print('time:', '%.7f' % (end - start)) hydro_util.serialize_numpy(np.array(mask), mask_file) var_types = ['tmax'] # var_types = ['tmax', 'tmin', 'prcp', 'srad', 'vp', 'swe', 'dayl'] avgs = [] for var_type in var_types: start = time.time() avg = calc_avg(mask, data_netcdf, var_type) end = time.time() print('time:', '%.7f' % (end - start)) print('mean value:', avg) avgs.append(avg) return avgs
def transfrom_latlng_to_m(lat, lng, bounds, h, w): center = ((bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2) x = geodesic(center, (bounds[0], center[1])).m y = geodesic(center, (center[0], bounds[1])).m crs = CRS.from_proj4( "+proj=laea +lat_0=" + str(center[0]) + " +lon_0=" + str(center[1]) + " +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs") transformer = Transformer.from_crs("epsg:4326", crs) y1, x1 = transformer.transform(lat, lng) return ([(h / 2) / y * y1, (w / 2) / x * x1])
def __init__(self, fname, grid, crs): self.grid = grid self.crs = crs # grid centroilds xc = (np.arange(grid['nx']) + .5) * grid['dx'] + grid['x0'] yc = (np.arange(grid['ny']) + .5) * grid['dy'] + grid['y0'] self.x = xc self.y = yc # crs crs_wgs = CRS.from_epsg(4326) crs_model = CRS.from_proj4(crs.proj4_init) self.trns = Transformer.from_crs(crs_wgs, crs_model) # read the receptor file df = pd.read_csv(fname, delimiter=' ', names=['rdx', 'lat', 'lon']) # get x,y coords x, y = [_ * .001 for _ in self.trns.transform(df.lat, df.lon)] df['x'], df['y'] = x, y # get i,j idx = np.array([np.arange(len(xc))[np.isclose(_, xc)][0] for _ in x]) jdx = np.array([np.arange(len(yc))[np.isclose(_, yc)][0] for _ in y]) df['idx0'], df['jdx0'] = idx, jdx df['idx1'], df['jdx1'] = idx + 1, jdx + 1 # see if grid is fully covered, and if it does order nx, ny = len(self.x), len(self.y) self.nx, self.ny = nx, ny cnt_g = nx * ny cnt_d = len(df.index) self.nsta = cnt_d if cnt_g == cnt_d: # full if np.all(idx == np.tile(np.arange(nx), ny)) \ and np.all(jdx == np.repeat(np.arange(ny), nx)): self.coverage = 'full, c-order' elif np.all(idx == np.repeat(np.arange(nx), ny)) \ and np.all(jdx == np.tile(np.arange(ny), nx)): self.coverage = 'full, f-order' else: self.coverage = 'full, random' elif cnt_g > cnt_d: self.coverage = 'partial, random' else: raise ValueError('more data than grid def') print(self.coverage) #df = df.set_index('rdx', drop=False) self.df = df
def parse_srs_header(header): """ Parse a header coming from GCP or coordinate file :param header (str) line :return Proj object """ log.ODM_INFO('Parsing SRS header: %s' % header) header = header.strip() ref = header.split(' ') try: if ref[0] == 'WGS84' and ref[1] == 'UTM': datum = ref[0] utm_pole = (ref[2][len(ref[2]) - 1]).upper() utm_zone = int(ref[2][:len(ref[2]) - 1]) proj_args = { 'zone': utm_zone, 'datum': datum } proj4 = '+proj=utm +zone={zone} +datum={datum} +units=m +no_defs=True' if utm_pole == 'S': proj4 += ' +south=True' srs = CRS.from_proj4(proj4.format(**proj_args)) elif '+proj' in header: srs = CRS.from_proj4(header.strip('\'')) elif header.lower().startswith("epsg:"): srs = CRS.from_epsg(header.lower()[5:]) else: raise RuntimeError('Could not parse coordinates. Bad SRS supplied: %s' % header) except RuntimeError as e: log.ODM_ERROR('Uh oh! There seems to be a problem with your coordinates/GCP file.\n\n' 'The line: %s\n\n' 'Is not valid. Projections that are valid include:\n' ' - EPSG:*****\n' ' - WGS84 UTM **(N|S)\n' ' - Any valid proj4 string (for example, +proj=utm +zone=32 +north +ellps=WGS84 +datum=WGS84 +units=m +no_defs)\n\n' 'Modify your input and try again.' % header) raise RuntimeError(e) return srs
def transform_to_custom(lon, lat, targetproj='', epsg=True): from pyproj import CRS, Transformer if epsg: targetcrs = CRS.from_epsg(targetproj) else: targetcrs = CRS.from_proj4(targetproj) srccrs = CRS.from_epsg(4326) ctrans = Transformer.from_crs(srccrs, targetcrs, always_xy=True) return ctrans.transform(lon, lat)
def transect(src, lon_1, lon_2, lat_1, lat_2, width, dist, tifout, csvout): ds = gdal.Open(src) #print (ds.GetMetadata()) #coordinate transform proj_str = "+proj=tpeqd +lon_1={} +lat_1={} +lon_2={} +lat_2={}".format( lon_1, lat_1, lon_2, lat_2) tpeqd = CRS.from_proj4(proj_str) transformer = Transformer.from_crs(CRS.from_proj4("+proj=latlon"), tpeqd) #transfer to tpeqd coordinates point_1 = transformer.transform(lon_1, lat_1) point_2 = transformer.transform(lon_2, lat_2) print(point_1) print(point_2) #create box in tpeqd coordinates bbox = (point_1[0], -(width * 0.5), point_2[0], (width * 0.5)) #calculate number of samples num_samples = int((point_2[0] - point_1[0]) / dist) #num_samples = 100 #Warp it into dataset in tpeqd projection format = 'GTiff' profile = gdal.Warp(tifout, ds, dstSRS=proj_str, outputBounds=bbox, height=1, width=num_samples, resampleAlg='near', format=format) #Extract pixel values and write output file data = profile.GetRasterBand(1).ReadAsArray() #Write csv output with open(csvout, 'w') as f: f.write("dist,value\n") for (d, value) in enumerate(data[0, :]): f.write("{}, {}\n".format(d * dist, value)) print("saves as{}".format(csvout))
def GK2WGS84(x_y, d): """ 高斯坐标转WGS84坐标 :param x_y: 高斯坐标x,y集合 :param d: 带号 :return: 纬度,经度集合 """ format = '+proj=tmerc +lat_0=0 +lon_0=' + str( d * 3) + ' +k=1 +x_0=500000 +y_0=0 +ellps=WGS84 +units=m +no_defs' crs_GK = CRS.from_proj4(format) transformer = Transformer.from_crs(crs_GK, crs_WGS84) lat_lon = transformer.itransform(x_y) return lat_lon
def grid_info_to_yaml_dict(grid_info: dict) -> dict: area_dict = {} area_dict["description"] = "" crs = grid_info["crs"] if "crs" in grid_info else CRS.from_proj4( grid_info["proj4_str"]) proj_dict = crs_to_proj_dict(crs) area_dict["projection"] = proj_dict _add_shape(grid_info, area_dict) dx, dy = _add_resolution(grid_info, area_dict) _add_origin(grid_info, area_dict, crs, dx, dy) return area_dict
def _check_edges(edges): """ This checks that all the edges follow the right hand rule :param list edges: The list of edges to be analysed. :return: An instance of :class:`numpy.ndarray` of cardinality equal to the number of edges. Where integers are positive, the edges need to be flipped. """ # Check the input if len(edges) < 1: return None # Create a matrix of points pnts = [] for edge in edges: pnts += [[pnt.longitude, pnt.latitude, pnt.depth] for pnt in edge.points] pnts = np.array(pnts) # Project the points using Lambert Conic Conformal fmt = "+proj=lcc +lon_0={:f} +lat_1={:f} +lat_2={:f}" mla = np.mean(pnts[:, 1]) srs = CRS.from_proj4(fmt.format(np.mean(pnts[:, 0]), mla - 10, mla + 10)) p = Proj(srs) # From m to km x, y = p(pnts[:, 0], pnts[:, 1]) x = x / 1e3 # m -> km y = y / 1e3 # m -> km # Fit the plane tmp = np.vstack((x.flatten(), y.flatten(), pnts[:, 2].flatten())).T _, ppar = plane_fit(tmp) # Analyse the edges chks = [] for edge in edges: epnts = np.array([[pnt.longitude, pnt.latitude, pnt.depth] for pnt in edge.points[0:2]]) ex, ey = p(epnts[:, 0], epnts[:, 1]) ex = ex / 1e3 ey = ey / 1e3 # Check the edge direction Vs plane perpendicular edgv = np.array([np.diff(ex[0:2])[0], np.diff(ey[0:2])[0]]) chks.append(np.sign(np.cross(ppar[:2], edgv))) return np.array(chks)
def WGS84ToGK_Single(lat, lon): """ WGS84坐标转高斯坐标 :param lat: WGS84坐标纬度 :param lon: WGS84坐标经度 :return: 高斯坐标x,y """ d = int((lon + 1.5) / 3) format = '+proj=tmerc +lat_0=0 +lon_0=' + str( d * 3) + ' +k=1 +x_0=500000 +y_0=0 +ellps=WGS84 +units=m +no_defs' crs_GK = CRS.from_proj4(format) transformer = Transformer.from_crs(crs_WGS84, crs_GK) x, y = transformer.transform(lat, lon) return x, y
def GK2WGS84_Single(x, y, d): """ 高斯坐标转WGS84坐标 :param x: 高斯坐标x :param y: 高斯坐标y :param d: 带号 :return: 纬度,经度 """ format = '+proj=tmerc +lat_0=0 +lon_0=' + str( d * 3) + ' +k=1 +x_0=500000 +y_0=0 +ellps=WGS84 +units=m +no_defs' crs_GK = CRS.from_proj4(format) transformer = Transformer.from_crs(crs_GK, crs_WGS84) lat, lon = transformer.transform(x, y) return lat, lon
def GK2WebMercator_Single(x, y, d): """ 高斯坐标转Web墨卡托坐标 :param x: 高斯坐标x值 :param y: 高斯坐标y值 :param d: 带号 :return: web墨卡托坐标 """ format = '+proj=tmerc +lat_0=0 +lon_0=' + str( d * 3) + ' +k=1 +x_0=500000 +y_0=0 +ellps=WGS84 +units=m +no_defs' crs_GK = CRS.from_proj4(format) transformer = Transformer.from_crs(crs_GK, crs_WebMercator) web_x, web_y = transformer.transform(x, y) return web_x, web_y
def to_crs(self) -> CRS: return CRS.from_proj4(" ".join([ "+proj=tmerc", "+lat_0=0", f"+lon_0={self.central_meridian}", f"+k_0={self.scale_factor}", f"+x_0={self.false_easting}", f"+y_0={self.false_northing}", "+towgs84=0,0,0,0,0,0,0", "+units=m", "+vunits=m", "+ellps=WGS84", "+no_defs", "+axis=neu", ]))
def read(self, *, uid: str) -> Geometry: filename = self.path / f"{uid}.h5" if not filename.exists(): raise FileNotFoundError(f"Mesh with uid '{uid}' not found in tin archive {self.path}.") with File(filename, "r") as archive: tin_grp_name = "tin" tin_group = archive[tin_grp_name] pts = tin_group["points"][:] projection = tin_group["points"].attrs["projection"] faces = tin_group["faces"][:] mesh = Mesh.from_points_and_faces(points=pts, faces=faces, proj4_str=projection) geometry = Geometry(mesh=mesh, crs=CRS.from_proj4(projection)) if "face_fields" in tin_group and "cover_color" in tin_group["face_fields"]: geometry.colors = tin_group["face_fields"]["cover_color"][:] return geometry
def test_mars_local_tms(): """Local TMS using Mars CRS""" # A transverse mercator projection for the landing site of the Perseverance rover. SYRTIS_TM = CRS.from_proj4( "+proj=tmerc +lat_0=17 +lon_0=76.5 +k=0.9996 +x_0=0 +y_0=0 +a=3396190 +b=3376200 +units=m +no_defs" ) # 100km grid centered on 17N, 76.5E syrtis_tms = TileMatrixSet.custom( [-5e5, -5e5, 5e5, 5e5], SYRTIS_TM, title="Web Mercator Mars", geographic_crs=MARS2000_SPHERE, ) center = syrtis_tms.ul(1, 1, 1) assert round(center.x, 6) == 76.5 assert round(center.y, 6) == 17
def write_reference_lla(self, offset_x, offset_y, proj4): reference_lla = self.path("reference_lla.json") longlat = CRS.from_epsg("4326") lon, lat = location.transform2(CRS.from_proj4(proj4), longlat, offset_x, offset_y) with open(reference_lla, 'w') as f: f.write( json.dumps({ 'latitude': lat, 'longitude': lon, 'altitude': 0.0 }, indent=4)) log.ODM_INFO("Wrote reference_lla.json")
def test_azimuthal_mask_outputs_expected_polygons(self): for case in self.azimuthal_test_cases: proj4_str = case['proj4'] crs = CRS.from_proj4(proj4_str) mask = azimuthal_mask(crs) mask_wgs84 = azimuthal_mask_wgs84(crs) world_map = self.get_world_map() world_map = world_map.intersection(mask_wgs84) flight_paths = self.get_flight_paths() flight_paths = flight_paths.intersection(mask_wgs84) canvas = self.build_canvas(proj4_str) self.draw_azimuthal(canvas, crs, mask, world_map, flight_paths) self.draw_wgs84(canvas, mask_wgs84, world_map, flight_paths) canvas.close()
def test_azimuthal_mask_raises_error_for_unsupported_proj(self): unsupported_projs = [ '+proj=aeqd', '+proj=airy', '+proj=hammer', '+proj=laea', '+proj=lee_os', '+proj=mil_os', '+proj=gs48', '+proj=gs50', '+proj=alsk', '+proj=oea +m=1 +n=2', '+proj=stere +lat_0=90 +lat_ts=75', '+proj=sterea +lat_0=90', ] for unsupported_proj in unsupported_projs: crs = CRS.from_proj4(unsupported_proj) with self.assertRaises(Exception): azimuthal_mask(crs) with self.assertRaises(Exception): azimuthal_mask_wgs84(crs)
def build_epsg(self): """ Coordinates are entered as latitude/longitude without any coordinate system encoding. We assume WGS84 and provide the potential zone/hemisphere for the data. Also provide the geographic coordinate system EPSG for the given lat lon coordinates """ self.zone = [ int((np.floor((int(d) + 180) / 6) % 60) + 1) for d in self.longitude ] if np.unique(self.zone).size > 1: print( 'WARNING: Found profiles that are of differing zones: zone numbers {}' .format(self.zone)) self.hemisphere = ['S' if l < 1 else 'N' for l in self.latitude] self.src_crs = [ CRS.from_proj4('+proj=longlat +datum=WGS84'.format(zn[0], zn[1])) for zn in zip(self.zone, self.hemisphere) ] self.src_epsg = [c.to_epsg() for c in self.src_crs]
def trans_shp_coord( input_folder, input_shp_file, output_folder, output_crs_proj4_str='+proj=longlat +datum=WGS84 +no_defs'): """按照坐标系信息,转换shapefile,被转换坐标读取自shapefile,默认转换为WGS84经纬度坐标""" fp = os.path.join(input_folder, input_shp_file) data = gpd.read_file(fp) crs_proj4 = CRS(data.crs).to_proj4() crs_final = CRS.from_proj4(output_crs_proj4_str) all_columns = data.columns.values # ndarray type new_datas = [] start = time.time() for i in range(0, data.shape[0]): # data.shape[0] print("生成第 ", i, " 个流域的shapefile:") newdata = gpd.GeoDataFrame() for column in all_columns: # geodataframe读取shapefile之后几何属性名称就是geometry if column == 'geometry': # 首先转换坐标 polygon_from = data.iloc[i, :]['geometry'] polygon_to = trans_polygon(crs_proj4, crs_final, polygon_from) # 要赋值到newdata的i位置上,否则就成为geoseries了,无法导出到shapefile newdata.at[0, column] = polygon_to print(type(newdata.at[0, column])) else: newdata.at[0, column] = data.iloc[i, :][column] print("转换该流域的坐标完成!") print(newdata) # 貌似必须转到wkt才能用来创建shapefile newdata.crs = crs_final.to_wkt() print("坐标系: ", newdata.crs) write_shpfile(newdata, output_folder) new_datas.append(newdata) end = time.time() print('计算耗时:', '%.7f' % (end - start)) return new_datas