Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

conversion from pv.mesh to gv.mesh? #1338

Open
k-a-mendoza opened this issue Feb 14, 2025 · 6 comments
Open

conversion from pv.mesh to gv.mesh? #1338

k-a-mendoza opened this issue Feb 14, 2025 · 6 comments
Assignees
Labels
new: documentation Highlight a new community raised "documentation" issue type: documentation Auto-labelled for doc/* and docs/* branches

Comments

@k-a-mendoza
Copy link

📚 Documentation

How does one add a mesh made in normal pyvista to a geovista plotter?

for example, I have a draped 2D line id like to place over a pv sphere. Its already in x,y lat lon coords, but it also has a z coord.

@k-a-mendoza k-a-mendoza added new: documentation Highlight a new community raised "documentation" issue type: documentation Auto-labelled for doc/* and docs/* branches labels Feb 14, 2025
Copy link

welcome bot commented Feb 14, 2025

📢 Nice one! Your first issue! Thanks for telling us how to improve geovista 📢

@k-a-mendoza
Copy link
Author

For those who want a quick and dirty way to do it and assuming your mesh is formatted as points = [lon, lat, elevation (km)], this is what I'm doing:

def convert_latlondepth_to_unit_circle(mesh: pv.DataSet):
    """converts a lat, lon, depth mesh to a unit circle"""
    # Get the min and max values of the mesh
    earth_radius = 6371.0
    lon = np.deg2rad(mesh.points[:,0])
    lat = np.deg2rad(mesh.points[:,1])
    elevation = 1 + (mesh.points[:,2] / earth_radius)
    # Convert spherical coordinates to cartesian coordinates
    x = elevation * np.cos(lat) * np.cos(lon)
    y = elevation * np.cos(lat) * np.sin(lon) 
    z = elevation * np.sin(lat)

    mesh.points = np.column_stack([x, y, z])
    return mesh

@bjlittle
Copy link
Owner

bjlittle commented Feb 15, 2025

Hey @k-a-mendoza,

Great to hear from you 😄

I'm guessing that you have a workflow where you create the pyvista.DataSet instance already and you then want to cast it to another pyvista data structure e.g., pyvista.PolyData, but the points are serialized as lons, lats and elevation.

Perhaps you could try using the convenience of the geovista.common.to_cartesian function ...

e.g., something along the lines of:

from geovista.common import to_cartesian

def convert_latlondepth_to_unit_circle(mesh: pv.DataSet) -> pv.DataSet:
    radius = 6371.0
    zscale = 1 / radius
    lons = mesh.points[:, 0]
    lats = mesh.points[:, 1]
    elevation = mesh.points[:, 2]    

    mesh.points = to_cartesian(lons, lats, zlevel=elevation, zscale=zscale, stacked=True)

    return mesh

Or perhaps the geovista.bridge.Transform.from_points method might be closer to what you need?

from geovsta.bridge import Transform

lons = mesh.points[:, 0]
lats = mesh.points[:, 1]
elevation = mesh.points[0, 2]
zscale = 1 / 6371.0

mesh = Transform.from_points(lons, lats, zlevel=elevation, zscale=zscale)

The above will return a pyvista.PolyData point-cloud.

Does your pyvista.DataSet have any form of connectivity?

Let me know if this helps 👍

@bjlittle bjlittle self-assigned this Feb 15, 2025
@k-a-mendoza
Copy link
Author

@bjlittle that helps a lot! Although, it might be worth putting some functionality in the future to change the points directly without having to initially extract them and feed them in the right args and kwargs.

I have a few datasets actually; some point clouds as well as a logically-rectilinear mesh (although in the future I may add some unstructured meshes). The meshes usually come as a custom AEQD projection, so my process for adding them involves 1st using proj to convert them to latlons, then a cartesian conversion to get them into xyz format.

@bjlittle
Copy link
Owner

bjlittle commented Feb 15, 2025

@k-a-mendoza Great, glad to help 🎉

However, I agree, my suggestions above are far from ideal. It's the first time I've seen lon/lat/elevation spatial data serialized directly within the points of a pyvista.DataSet.

My main focus up until now has been to mature the capability within the geovista.bridge as the main entry-point for users to create meshes from their various geospatial data.

Would it be possible to share with me some of your source datasets? How are they encoded? In NetCDF, GRIB or some other file format? Do you have example code of how you do this in a GH gist or repo? So that I can get a fuller understanding of what you're doing.

I'd be keen to make your workflow in geovista slicker and more natural, if possible 👍

@k-a-mendoza
Copy link
Author

yeah I could share a few. I'm currently working on a pyvista use-case of the Frontier Observatory For Geothermal Energy (FORGE)'s Magnetotelluric data model, which is a deformed logically-rectilinear 3D FEM model representation of a scalar (electric conductivity) field. The data files are of a custom format used by a small group of researchers, but I created my own simple data loader based on pandas that works well enough.

More popular and workable for examples could be the various global seismic, electric, and density models hosted by IRIS Earth Model Consortium . These are typically logically-rectilinear, uniform or near uniform grids in lat-lon, depth (z) coordinates, with several variables stored in some netcdf-like file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new: documentation Highlight a new community raised "documentation" issue type: documentation Auto-labelled for doc/* and docs/* branches
Projects
None yet
Development

No branches or pull requests

2 participants