Code Monkey home page Code Monkey logo

rasterbender's Introduction

rasterbender rasterbender rasterbender RasterBender rasterbender rasterbender rasterbender

RasterBender is an EXPERIMENTAL QGIS Python plugin allowing to distort raster layers using pairs of points. This allows to match data that has complex non-uniform and non-linear deformations (historical maps, hand drawn sketches...).

This plugin is not much tested and you should be very careful when using it.

rasterbender

How to use

Launch RasterBender from the plugins menu or from the plugin toolbar.

RasterBender works a bit like the georeferencer : you have to create pairs of points, the first one being the original location, and the second one being the target location.

To do so, RasterBender uses plain Linestring layers. Each pair is defined by the starting point and ending point of a Line in this layer. You can either use one of your own Linestring layers, or use the create pairs layers button from the RasterBender window.

You can also create a constraint layers, which will constrain the triangulation created by the plugin. This can be useful if you have some artifact generated by unwanted triangles. The constraints are line that should go from one starting point to another. Use the preview to see if the triangulation is affected as expected.

If you use RasterBender's layers, I recommend installing the "Save memory layer" plugin which will allow to save your work.

Once the layer to bend and the pairs layer are chosen, simply hit "run", wait a while (it can be quite long), and a new raster will be saved at the target path.

How does the bending work

The first points of all pairs will be triangulated, and this triangulation will be mapped on the last points of all pairs. The raster layer will then be deformed by matching the triangulation.

The "buffer" parameters sets a buffer around the triangulation, so that the transformation ends more smoothely on the edges. Hold the "preview" button to see the size of the buffer.

Using this method will INDUCE DEFORMATIONS. You should ONLY use it if your data is already deformed, and not to accomplish CRS transformations nor linear/affine transformations.

The constraints layer

The constraint layers allow to prevent triangles edges from passing through certain lines, so that those lines remain linear. A typical example is if you are distorting maps containing buildings : you may want the edges of the buildings to be preserved.

To use the constraints layer, create lines that join the starting point of at least two pairs. Preview the result to see the effect. Note that you must enable snapping for the constraints to work (constraints must pass exactly through the pairs' starting points).

Feedback / Bugs / Contribute / Known limitations

Please report bugs and ideas and see known limitations on the issue tracker : https://github.com/olivierdalang/RasterBender/issues

When reporting bugs, run the plugin with the debug checkbox and copy all QGIS's log.

Or send me some feedback at : [email protected]

RasterBender is in its early stages of developpement, and is not much tested. Please be very careful and report any unexpected behaviour.

Version history

  • 2014-11-17 - Version 0.0 : intial release
  • 2014-11-18 - Version 0.0.1 : add style button
  • 2016-04-27 - Version 0.0.2 : the deformation is interpolated
  • 2016-05-07 - Version 0.0.3 : the transformation now uses GDAL
  • 2016-05-18 - Version 0.0.4 : bugfix with older versions of GDAL, added debug checkbox
  • 2016-05-19 - Version 0.0.5 : works with non-georeferenced rasters again
  • 2016-05-19 - Version 0.0.6 : fix a windows 7 specific issue

Sponsors

Many thanks to Geodeticca for sponsoring the developpement of the versions 0.0.2 through 0.0.6 of this plugin. http://www.geodeticca.sk

How it works (internally)

Here's how it works :

Preparing the mesh

  1. Get a triangular mesh by doing a Delaunay triangulation of all original input points (starting points of the lines in the Raster Bender layer)
  2. Adapt this mesh on the ending points of the lines
  3. Get the convex hull of the points, offset it by some factor to have a smooth transition on the borders.

Doing the transformation

  1. Copy the initial raster on the destination raster file
  2. Use gdal_translate to take an extract of the intial raster corresponding to each initial triangle's bounding box (uses -srcwin) and reproject it with an affine transformation to match it to the target triangle (uses three -gcp arguments)
  3. Use gdalwarp to collect all those extracts onto the destination raster files, cropped by the destination triangle (uses -cutline and -cblend arguments)

rasterbender's People

Contributors

olivierdalang avatar

Stargazers

 avatar Thomas Gratier avatar Nobusuke IWASAKI avatar Florian Bender avatar

Watchers

James Cloos avatar  avatar tumasgiu avatar  avatar

rasterbender's Issues

qgis 3.4 crashes when running Vector Bbender

I have a building with many rooms in a geojson format. The coordinates are in meters, starting at 0,0. I defined 7 lines between the 7 angles of my building and the 7 angles of this same building on the OSM layer.

Using Vector Bender makes qgis instantly crash. Here are the logs in the console:

QGIS died on signal 11[New LWP 669]
[New LWP 670]
[New LWP 671]
[New LWP 672]
[New LWP 675]
[New LWP 676]
[New LWP 683]
[New LWP 686]
[New LWP 687]
[New LWP 688]
[New LWP 689]
[New LWP 690]
[New LWP 691]
[New LWP 692]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f1de59e56c2 in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
[Current thread is 1 (Thread 0x7f1dea543a00 (LWP 667))]
#0  0x00007f1de59e56c2 in waitpid () at /lib/x86_64-linux-gnu/libc.so.6
#1  0x0000563aecf28d9e in  ()
#2  0x00007f1de593ff20 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007f1d5143c8b8 in qh_initstatistics () at /usr/lib/python3/dist-packages/matplotlib/_qhull.cpython-36m-x86_64-linux-gnu.so
#4  0x00007f1d51413f42 in qh_initqhull_start () at /usr/lib/python3/dist-packages/matplotlib/_qhull.cpython-36m-x86_64-linux-gnu.so
#5  0x00007f1d5143d204 in qh_new_qhull () at /usr/lib/python3/dist-packages/matplotlib/_qhull.cpython-36m-x86_64-linux-gnu.so
#6  0x00007f1d514067b7 in  () at /usr/lib/python3/dist-packages/matplotlib/_qhull.cpython-36m-x86_64-linux-gnu.so
#7  0x00007f1d9e086eab in _PyCFunction_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#8  0x00007f1d9e15b393 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#9  0x00007f1d9e126b70 in _PyEval_EvalFrameDefault () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#10 0x00007f1d9e15abab in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#11 0x00007f1d9e15aec1 in _PyFunction_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#12 0x00007f1d9e174ec1 in _PyObject_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#13 0x00007f1d9e175a9d in _PyObject_Call_Prepend () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#14 0x00007f1d9e175b08 in PyObject_Call () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#15 0x00007f1d9dff7159 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#16 0x00007f1d9e061342 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#17 0x00007f1d9e174e19 in _PyObject_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#18 0x00007f1d9e15b058 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#19 0x00007f1d9e126b70 in _PyEval_EvalFrameDefault () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#20 0x00007f1d9e159953 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#21 0x00007f1d9e15afb3 in _PyFunction_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#22 0x00007f1d9e174ec1 in _PyObject_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#23 0x00007f1d9e175a9d in _PyObject_Call_Prepend () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#24 0x00007f1d9e175b08 in PyObject_Call () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#25 0x00007f1d9dff7159 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#26 0x00007f1d9e061342 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#27 0x00007f1d9e174e19 in _PyObject_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#28 0x00007f1d9e15b058 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#29 0x00007f1d9e126b70 in _PyEval_EvalFrameDefault () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#30 0x00007f1d9e159953 in  () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#31 0x00007f1d9e15afb3 in _PyFunction_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#32 0x00007f1d9e174ec1 in _PyObject_FastCallDict () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#33 0x00007f1d9e175a9d in _PyObject_Call_Prepend () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#34 0x00007f1d9e175b08 in PyObject_Call () at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
#35 0x00007f1d9da58c30 in  () at /usr/lib/python3/dist-packages/PyQt5/QtCore.cpython-36m-x86_64-linux-gnu.so
#36 0x00007f1d9da59108 in  () at /usr/lib/python3/dist-packages/PyQt5/QtCore.cpython-36m-x86_64-linux-gnu.so
#37 0x00007f1d9da59390 in  () at /usr/lib/python3/dist-packages/PyQt5/QtCore.cpython-36m-x86_64-linux-gnu.so
#38 0x00007f1d9da59d07 in  () at /usr/lib/python3/dist-packages/PyQt5/QtCore.cpython-36m-x86_64-linux-gnu.so
#39 0x00007f1de654c679 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#40 0x00007f1de738cb82 in QAbstractButton::clicked(bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#41 0x00007f1de738cd9a in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#42 0x00007f1de738e17a in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#43 0x00007f1de738e36d in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#44 0x00007f1d9cd3b9a3 in  () at /usr/lib/python3/dist-packages/PyQt5/QtWidgets.cpython-36m-x86_64-linux-gnu.so
#45 0x00007f1de72da038 in QWidget::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#46 0x00007f1d9cd3cf93 in  () at /usr/lib/python3/dist-packages/PyQt5/QtWidgets.cpython-36m-x86_64-linux-gnu.so
#47 0x00007f1de729b82c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#48 0x00007f1de72a364f in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#49 0x00007f1de8031f3b in QgsApplication::notify(QObject*, QEvent*) () at /usr/lib/libqgis_core.so.3.4.6
#50 0x00007f1de651d9a8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#51 0x00007f1de72a2622 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#52 0x00007f1de72f514b in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#53 0x00007f1de72f77ba in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#54 0x00007f1de729b82c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#55 0x00007f1de72a30f4 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#56 0x00007f1de8031f3b in QgsApplication::notify(QObject*, QEvent*) () at /usr/lib/libqgis_core.so.3.4.6
#57 0x00007f1de651d9a8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#58 0x00007f1de6adf523 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#59 0x00007f1de6ae0ff5 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#60 0x00007f1de6ab82eb in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#61 0x00007f1dc34b81c0 in  () at /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#62 0x00007f1dda42a317 in g_main_context_dispatch () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#63 0x00007f1dda42a550 in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#64 0x00007f1dda42a5dc in g_main_context_iteration () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#65 0x00007f1de65768ef in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#66 0x00007f1de651b9ea in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#67 0x00007f1de6524a84 in QCoreApplication::exec() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#68 0x0000563aecf253a0 in  ()
#69 0x00007f1de5922b97 in __libc_start_main () at /lib/x86_64-linux-gnu/libc.so.6
#70 0x0000563aecf287aa in _start ()
gdb returned 0

Crashes QGIS win32 on exit - with no operation

Hi,

I figured out that Raster Bender is responsible for QGIS crash on exit under Win32.

This is the same issue as with GarminCustomMap plugin. It does the same thing.

Please see http://hub.qgis.org/issues/11891
and
http://hub.qgis.org/issues/11901

  1. start QGIS master or QGIS 2.61
  2. close QGIS
  3. mini-dump is generated.

This appeared recently and probably related to latest GDAL.
The bug appeared after latest GDAL upgrade about a week ago.

Both master and latest stable versions are affected.

Thank you very much
Mikhail

Problems with ungeoreferenced rasters

When using the tool on ungeoreferenced rasters, we get :

# COMMAND   : create the temporaray file 1 out of 15
gdal_translate -gcp -15.3191260258 -275.129273038 -16.3821342344 -277.195409227 -gcp 2.27286324786 -257.501923077 25.3888888889 -243.166666667 -gcp 2.32287078623 -282.405719023 1.32797839544 -284.499949598 -srcwin 0 0 4.32287078623 -255.501923077 C:/Users/Olivier/Desktop/trestrb.tif C:/Users/Olivier/AppData/Local/Temp/qt_temp.Rp9880
# ERROR     : create the temporaray file 1 out of 15
Input file size is 260, 260
Error: -srcwin 0 0 4 -255 has negative width and/or height.

Raster bender issues

Hi,

Raster Bender is a great tool, doing exactly what I need. However I come across couple of issues:

  1. Constrains layer doesn't seem to work properly - I am not able to use constrains layer, to get rid of unwanted triangles. The layer is either doing nothing, or modifying triangles in unexpected and unpredictable way

  2. 1 pixel shift along the edge of the transformed area - all my transformations end up with a one pixel shift along the outer edge of the transformation area (no matter what the buffer is)

  3. There is some sort of noise introduced into the image in the buffer area, resulting in the reduced quality of the raster. (please see the attached rasters)

after_buffer5m
before

Problems noticed when working with a DEM

Hi, great plugin, thanks.
It doesn't look like there isn't any active development, but I think it is worth filing these issues in case anyone decides to work on it in the future.

I've been abusing the plugin, using it to deform a DEM.

I imagine this means I am deforming it a lot further than people usually would when rubbersheeting, which may make it easier to notice any problems - I guess it would be worth testing extreme deformations even with a normal image.

Here are the problems:

  • With large inward deformations you will notice that part of the original image still shows up at the edge, duplicating part of what you correctly see in the deformed image. When I test with an aerial that I haven't clipped, this problem seems to be fixed or worked around by using a buffer, but that doesn't solve it with the DEM (which has null values around the edge), or with an aerial that I have clipped so that it has null values around the edge. I believe in these cases the plugin should erase the original values in that area, replacing them with null values.

  • When working with a DEM the plugin creates some pixels around the outside with extremely low values. I'm not sure if this is cause by the null values around the outside, or by some sort of extrapolation. It doesn't seem that anything like this occurs when working with an aerial; maybe it only works properly with RGB images or something.

  • The plugin also creates some pixels along the triangulation lines with extremely low values. Again, it isn't obvious if there is a similar problem with an aerial.

  • It looks like the triangulation algorithm could be improved; it creates some edges crossing over each other. Try using the attached pairs layer to see.

example files.zip

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.