After saving a view with a spatial bookmark, if one later wants to get back to this exact same view, it appears that you have to have the correct height/width ratio in the view panel. Is there a way to save and reestablish that?


This might be a way, though not automatic:

When you save a view (spatial bookmark) the way you want it (the horizontal field of view as well as vertical), note the scale.

Then when you wish to come back to this exact same view, first set the view panel so it is wider than the way you want it. Click on and "zoom to" the spatial bookmark. The scale will be correct but your horizontal field will be too large. Drag the left edge of the view to the right, until the map scale (shown in a box at the bottom) begins to change. That's when you have gone too far. Drag it back to the left just until your resolution is again correct. You then have the exact same view (I think...)

  • I'd recommend then that the "scale" be made a part of the bookmark name. It's really too bad that SpatialBookmarks don't record the enclosing window geometry because I use that geometry to "frame" the area I want to print in the print composer, and then save off a spatial bookmark of the view. More often than not, I need to add a new layer that I forgot and print it out too, and if the windows geometry has changed in the meantime due to other projects, my hope for the new layer registering with the existing ones is near-zero. I typ. have to reprint all layers. Thank you very much for the sugg. – quagmire Jun 24 '20 at 23:13
  • If an interested person is listening, this would be a great plug-in: "Remember/Set my viewport." – quagmire Jun 24 '20 at 23:21
  • I have tried this--and thank you again. The idea is sound, but for the large areas my projects cover, and the small display I use, it is too coarse an approach. "Shirley," there must be programmatic solution! – quagmire Jun 25 '20 at 12:01

I present my sorry, ugly, brutish attempt at recording, at least, the 'view' parameters for later user-assisted restoration. And I have to say, it almost works.

I have QGIS set to open the Python console on startup (although I've forgotten how) and, accidentally, the script editor opens onto this, the only script I've ever written, or and possibly likely to write.

After I "save" a view with a Spatial Bookmark, I then run my script which:

  1. saves a file QGIS_<project_name,etc.>.txt in the project folder, containing all the relevant parameters for reconstructing the view.
  2. lists, as a 'help', a set of commands to be copied/pasted to the open Python console to re-create the view later. (The

In practice, after running the script, I open QGIS and the project at some later time. I open the script and, if I have not run the script on another project since, copy/paste the commands to re-create the view. (I believe it may help to have the QGIS window large but not maximized.) If otoh I have run the script on another project, I open the previously saved parameters file and copy paste the relevant parameters into the commands before executing them in the Python console. You can tell my "style" is in the vein of "monkey-see/-do."

# open Plugins->Python Console
# references for these functions...
#  https://qgis.org/pyqgis/3.2/gui/Map/QgsMapCanvas.html#qgis.gui.QgsMapCanvas.setScaleLocked
#  https://qgis.org/pyqgis/3.2/core/other/QgsRectangle.html?highlight=qgsrectangle
#  https://qgis.org/pyqgis/3.2/core/Point/QgsPointXY.html?highlight=qgspointxy
#  https://doc.qt.io/qtforpython/PySide2/QtCore/QSize.html
pn, pp

canvas = qgis.utils.iface.mapCanvas() #create shortcut to the current canvas
sl=canvas.scaleLocked() # T/F
# write these out to a file
# NB write takes a single, string, argument
f.write('   File:'+str(fne)+'\n\n')
f.write('extra spatial bookmark data nec. to\n')
f.write(' reconstruct view in QGIS in order to\n')
f.write(' assure perfect registration for new\n')
f.write(' layers.\n')
f.write('generated by a crude pygis script of my device; namely,\n')
f.write('  ./upundn_projects/_NB_QGIS/save_qgis_view_parameters.py\n')
f.write('which outputs this local file:\n')
f.write('    <PROJECT>_qgis_params_to_reconstruct_view.txt\n')
f.write('containing the parameters nec. to recreate the view layout; e.g.,\n')
f.write('  WindowSize(px): QSize('+str(ws.width())+','+str(ws.height())+')\n')
f.write('     ActualScale: '+str(sc)+'\n')
f.write('ScaleLocked(T/F): '+str(sl)+'\n')
f.write('    MagnifFactor: '+str(mf)+'\n')
f.write('     Extents(km): QgsRectangle('+str(ex.xMinimum())+','+str(ex.yMinimum())+','+str(ex.xMaximum())+','+str(ex.yMaximum())+')\n')
f.write(' CenterPoint(km): QgsPointXY('+str(cp.x())+','+str(cp.y())+')\n\n')
f.write('Before running the script, and thus saving the parameters:\n')
f.write('  Create a new shapefile layer.\n')
f.write('  Select layer and toggle Edit mode. Use Azimuth Sequence Digitizer to\n')
f.write('  Draw a framing rectangle of the desired 3:2 aspect ratio.\n')
f.write('  Move it to the desired location.\n')
f.write('  Set a large 3:2 AR window size: canvas.resize(QSize(750,500).\n')
f.write('  [Note: Window Units do Not Align with Projection Units.]\n')
f.write('  Roughly zoom to that rectangle and note the scale and magnif.\n')
f.write('  [Note: scale400k/magn100 & scale500k/magn120 are the same view.]\n')
f.write('  Adjust window edges to closely fit the rectangle.\n')
f.write('  Create a spatial bookmark.\n')
f.write('Finally, run the script to save the parameters of the view.\n\n')
# presumably there is some way to use this information to 
#  reconstruct the view with "set" type functions
f.write('To reconstruct view, reconstruct the conditions; e.g., in the console,\n')
f.write('copy/paste these commands):\n')
f.write('  canvas = qgis.utils.iface.mapCanvas() # attach to the iface\n')
f.write('  ws=QSize('+str(ws.width())+','+str(ws.height())+') # set window size\n')
f.write('  canvas.resize(ws)\n')
f.write('  sc='+str(sc)+' # set window scale factor\n')
f.write('  canvas.zoomScale(sc)\n')
f.write('  sl='+str(sl)+' # lock scale for zooming (also bool(1) but not true)\n')
f.write('  canvas.setScaleLocked(sl)\n')
f.write('  mf='+str(mf)+' # set magnification factor/zoom\n')
f.write('  canvas.setMagificationFactor(mf)\n')
f.write('  ex=QgsRectangle('+str(ex.xMinimum())+','+str(ex.yMinimum())+','+str(ex.xMaximum())+','+str(ex.yMaximum())+')\n')
f.write('  canvas.setExtent(ex) # set XY extents\n') 
f.write('  cp=QgsPointXY('+str(cp.x())+','+str(cp.y())+') # set center point\n')
f.write('  canvas.setCenter(cp)\n')
f.write('Note: setting ws and ex should result in cp and sc being set as well.\n')

print(fn+' view parameters saved')

I wrote "almost works" because it seems at times that some of the restore commands are ignored, and do not change the view. This is where a monkey s/d approach breaks down.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.