GithubHelp home page GithubHelp logo

Comments (14)

craigmillernz avatar craigmillernz commented on July 18, 2024

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.

banesullivan avatar banesullivan commented on July 18, 2024

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
UnstructuredGridInformation
N Cells824278
N Points413250
X Bounds3.299e+05, 3.442e+05
Y Bounds4.253e+06, 4.271e+06
Z Bounds1.494e+03, 2.723e+03
N Arrays0
# 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')

download

# 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')

download

Screen Shot 2019-06-13 at 10 55 58 AM

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.

bluetyson avatar bluetyson commented on July 18, 2024

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.

banesullivan avatar banesullivan commented on July 18, 2024

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.

banesullivan avatar banesullivan commented on July 18, 2024

I edited the original snippet to remove that

from pyvista-support.

bluetyson avatar bluetyson commented on July 18, 2024

Thanks!

from pyvista-support.

bluetyson avatar bluetyson commented on July 18, 2024

Ok, so what happens if you take your topography map and download the puppy texture example to it?

from pyvista-support.

banesullivan avatar banesullivan commented on July 18, 2024

@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.

bluetyson avatar bluetyson commented on July 18, 2024

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.

banesullivan avatar banesullivan commented on July 18, 2024

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.

GGDRriedel avatar GGDRriedel commented on July 18, 2024

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.

GGDRriedel avatar GGDRriedel commented on July 18, 2024

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.

GGDRriedel avatar GGDRriedel commented on July 18, 2024

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.

banesullivan avatar banesullivan commented on July 18, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.