Comments (14)
ok, my problem was initially with the wrong clip of the DEM and secondly with not doing an inplace=True
on the texture_map_to_plane
from pyvista-support.
Hi @craigmillernz, I'm glad to see that you figured this out on your own! To be thorough, I thought I'd add a bit more details on texture mapping for a GeoTIFF on a topography surface - also, I do this ALOT so I have plenty of examples.
As you found out, it's necessary to have texture coordinates ("texture mapping") matching the proper extents of the mesh/surface you'd like to drape the texture (GeoTIFF) on.
I commonly do this by using the spatial reference of the GeoTIFF itself, as this allows you to preserve the entire mesh that the texture is being draped on without having to clip out the parts where you don't have imagery. Unfortunately, I don't have a good example to demo that particular case, but I do have an example where we explicitly set the texture extents onto a topography surface where the texture/GeoTIFF has a much larger extent than the topography surface.
The data files for this example are quite large (~300MB) so I have them on my Dropbox here
Here's the example:
import pyvista as pv
import numpy as np
import gdal
topo = pv.read('topo_clean.vtk')
topo
UnstructuredGrid | Information |
---|---|
N Cells | 824278 |
N Points | 413250 |
X Bounds | 3.299e+05, 3.442e+05 |
Y Bounds | 4.253e+06, 4.271e+06 |
Z Bounds | 1.494e+03, 2.723e+03 |
N Arrays | 0 |
# Load the GeoTIFF/texture
filename = 'Geologic_map_on_air_photo.tif'
def get_gcps(filename):
"""This helper function retrieves the Ground Control
Points of a GeoTIFF. Note that this requires gdal"""
get_point = lambda gcp : np.array([gcp.GCPX, gcp.GCPY, gcp.GCPZ])
# Load a raster
ds = gdal.Open(filename)
# Grab the Groung Control Points
points = np.array([get_point(gcp) for gcp in ds.GetGCPs()])
# Now Grab the three corners of their bounding box
#-- This guarantees we grab the right points
bounds = pv.PolyData(points).bounds
origin = [bounds[0], bounds[2], bounds[4]] # BOTTOM LEFT CORNER
point_u = [bounds[1], bounds[2], bounds[4]] # BOTTOM RIGHT CORNER
point_v = [bounds[0], bounds[3], bounds[4]] # TOP LEFT CORNER
return origin, point_u, point_v
# Fetch the GCPs
origin, point_u, point_v = get_gcps(filename)
# Use the GCPs to map the texture coordiantes onto the topography surface
topo.texture_map_to_plane(origin, point_u, point_v, inplace=True)
# Show GCPs in relation to topo surface with texture coordinates displayed
p = pv.Plotter()
p.add_point_labels(np.array([origin, point_u, point_v,]),
['Origin', 'Point U', 'Point V'],
point_size=5)
p.add_mesh(topo)
p.show(cpos='xy')
# Read the GeoTIFF as a vtkTexture:
texture = pv.read_texture(filename)
# Now plot the topo surface with the texture draped over it
# And make window size large for a high-res screenshot
p = pv.Plotter(window_size=np.array([1024, 768])*3)
p.add_mesh(topo, texture=texture)
p.show(cpos='xy')
Please note that you do not need to use GDAL to get the ground control points (GCPs) - all you need to know are the coordinates of the BOTTOM LEFT CORNER, BOTTOM RIGHT CORNER, and TOP LEFT CORNER of the GeoTIFF/texture to feed to the texture_map_to_plane
method to properly build the texture coordinates.
from pyvista-support.
I actually get p = pv.Plotter()
p.add_point_labels(np.array([origin, point_u, point_v,]),
['Origin', 'Point U', 'Point V'],
point_size=5, color='red')
p.add_mesh(elevation)
p.show(cpos='xy')
when trying this
TypeError Traceback (most recent call last)
in
1 # Show GCPs in relation to topo surface with texture coordinates displayed
2 p = pv.Plotter()
----> 3 p.add_point_labels(np.array([origin, point_u, point_v,]),
4 ['Origin', 'Point U', 'Point V'],
5 point_size=5, color='red')
TypeError: add_point_labels() got an unexpected keyword argument 'color'
from pyvista-support.
The API has changed since that was posted and now that argument is point_color
to be more explicit about what is getting colored because the text and the box can also have color (text_color
and shape_color
). Please see the documentation for this method
from pyvista-support.
I edited the original snippet to remove that
from pyvista-support.
Thanks!
from pyvista-support.
Ok, so what happens if you take your topography map and download the puppy texture example to it?
from pyvista-support.
@bluetyson, can you please open a new issue for that.
I'd recommend just trying it. The puppy texture would just map over the topography via the UV texture coordinates produced by texture_map_to_plane
for a playful and adorable topography surface
from pyvista-support.
Will do. Obviously not an overly serious example, but I was just wondering. e.g. I have a silly case where I have a mesozoic basement surface - and was wondering, what if I put a 'mesozoic monster' on it. However, small resolution image, large scale regional area - it would just stretch out?
from pyvista-support.
I have a mesozoic basement surface - and was wondering, what if I put a 'mesozoic monster' on it.
😂 Please share the data for this in a new issue, I'd have fun putting an example together for it
small resolution image, large scale regional area - it would just stretch out?
The image will stretch but should still look okay.
from pyvista-support.
I'm trying to map a geotif to a dummy plane so I can see something over a geotif of OSM data.
Trying to create that plane:
topo_map = pv.read_texture('geotiff.tif)
#coordinates are known
x = np.arange(403926.1008, 418211.4231, 10)
y = np.arange(5470594.0881, 5484179.9408, 10)
x, y = np.meshgrid(x, y)
#height is local height minus 100 for viewing
z=np.ones(x.shape)+323-100
dummyplane= pv.StructuredGrid(x, y, z)
p = pvqt.BackgroundPlotter()
p.add_mesh(grid, cmap="seismic", clim=[-1*per,per])
p.add_mesh(pv.PolyData(path), color='orange')
p.add_mesh(dummyplane,texture=topo_map)
#p.add_floor()
p.show()
However I'm also getting the error.
Input mesh does not have texture coordinates to support the texture.
Any way to customky set these coordinates for the mesh without using gdal and all of the other stuff?
from pyvista-support.
Nevermind.
dummyplane.texture_map_to_plane(origin=[x[0],y[0],323-100],
point_u =[x[1],y[0],323-100],
point_v=[x[0],y[1],323-100],
inplace=True)
from pyvista-support.
welp, this does not throw errors, however my texure doesn't show.
using
p.add_mesh(dummyplane)
#p.add_floor()
p.show()
Without texture sows the plane.
Do the units(mesh cellseize) and pixes of the texture need to align?
from pyvista-support.
You need to pass the texture to the add_mesh method. For further help, please open a new support ticket.
from pyvista-support.
Related Issues (20)
- create uniform mesh HOT 3
- Change the orientation of a scalar bar's title
- Applying textures on models from .obj files HOT 6
- How to create an Unstructured grid from points and faces HOT 2
- Type of data, plotting with glyphs HOT 3
- Controlling the thickness and orientation of a slice in Pyvista HOT 3
- Controlling the image position in window, without any click
- Mask/Remove Voxels in Air (small intersection with surface) HOT 3
- custom slider parameters
- running pyvista on headless machine with Centos OS HOT 1
- Seismic Horizon with Pyvista HOT 8
- Algorithm in sample function?
- Automatically updates HOT 3
- Slow interaction HOT 1
- read from text HOT 4
- Uniform Grid thresholding question HOT 8
- Take data by an input x,y,x coordinate (csv file) from vtk data file HOT 4
- Program broke when creating a mesh using pv.PolyData() HOT 4
- ATTENTION: Please move questions to PyVista's Discussions HOT 1
- plotter.enable_terrain_style not working for me HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyvista-support.