diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..3dfe05b --- /dev/null +++ b/404.html @@ -0,0 +1,1298 @@ + + + +
+ + + + + + + + + + + + + + + + + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation.
+Examples of behaviour that contributes to creating a positive environment +include:
+Examples of unacceptable behaviour by participants include:
+Project maintainers are responsible for clarifying the standards of acceptable +behaviour and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behaviour.
+Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful.
+This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers.
+Instances of abusive, harassing, or otherwise unacceptable behaviour may be +reported by contacting the project team. All complaints will be reviewed and +investigated and will result in a response that is deemed necessary and +appropriate to the circumstances. The project team is obligated to maintain +confidentiality with regard to the reporter of an incident. Further details of +specific enforcement policies may be posted separately.
+Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership.
+This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+ + + + + + +This project is open source, so you can create a pull request(PR) after you fix issues. Get a local copy of the plugins checked out for development using the following process.
+Before uploading your PR, run test one last time to check if there are any errors. If it has no errors, commit and then push it!
+For more information on PR's steps, please see links in the Contributing section.
+Please make this project more fun and easy to scan by using emoji prefixes for your +commit messages (see GitMoji).
+Commit type | +Emoji | +
---|---|
Initial commit | +🎉 :tada: |
+
Version tag | +🔖 :bookmark: |
+
New feature | +✨ :sparkles: |
+
Bugfix | +🐛 :bug: |
+
Metadata | +📇 :card_index: |
+
Documentation | +📚 :books: |
+
Documenting source code | +💡 :bulb: |
+
Performance | +🐎 :racehorse: |
+
Cosmetic | +💄 :lipstick: |
+
Tests | +🚨 :rotating_light: |
+
Adding a test | +✅ :white_check_mark: |
+
Make a test pass | +✔️ :heavy_check_mark: |
+
General update | +⚡️ :zap: |
+
Improve format/structure | +🎨 :art: |
+
Refactor code | +🔨 :hammer: |
+
Removing code/files | +🔥 :fire: |
+
Continuous Integration | +💚 :green_heart: |
+
Security | +🔒 :lock: |
+
Upgrading dependencies | +⬆️ :arrow_up: |
+
Downgrading dependencies | +⬇️ :arrow_down: |
+
Lint | +👕 :shirt: |
+
Translation | +👽 :alien: |
+
Text | +📝 :pencil: |
+
Critical hotfix | +🚑 :ambulance: |
+
Deploying stuff | +🚀 :rocket: |
+
Fixing on MacOS | +🍎 :apple: |
+
Fixing on Linux | +🐧 :penguin: |
+
Fixing on Windows | +🏁 :checkered_flag: |
+
Work in progress | +🚧 :construction: |
+
Adding CI build system | +👷 :construction_worker: |
+
Analytics or tracking code | +📈 :chart_with_upwards_trend: |
+
Removing a dependency | +➖ :heavy_minus_sign: |
+
Adding a dependency | +➕ :heavy_plus_sign: |
+
Docker | +🐳 :whale: |
+
Configuration files | +🔧 :wrench: |
+
Package.json in JS | +📦 :package: |
+
Merging branches | +🔀 :twisted_rightwards_arrows: |
+
Bad code / need improv. | +💩 :hankey: |
+
Reverting changes | +⏪ :rewind: |
+
Breaking changes | +💥 :boom: |
+
Code review changes | +👌 :ok_hand: |
+
Accessibility | +♿️ :wheelchair: |
+
Move/rename repository | +🚚 :truck: |
+
Other | +Be creative | +
This plugin was developed by:
+Tim Sutton | +Nyall Dawson | +Jeremy Prior | +
---|---|---|
+ | + | + |
Coder and Ideas Guy | +Genius Guru of Awesomeness | +Document and Logo Guy | +
timlinux @ github | +nyalldawson @ github | +Jeremy-Prior @ github | +
Thanks to:
+We are looking for contributors, add yourself here!
+Also:
+Version 2, June 1991
+Copyright © 1989, 1991 Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed.
+The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too.
+When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things.
+To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it.
+For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights.
+We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software.
+Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations.
+Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all.
+The precise terms and conditions for copying, distribution and +modification follow.
+0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The “Program”, below, +refers to any such program or work, and a “work based on the Program” +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term “modification”.) Each licensee is addressed as “you”.
+Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does.
+1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program.
+You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee.
+2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions:
+These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it.
+Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program.
+In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License.
+3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following:
+The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable.
+If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code.
+4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance.
+5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it.
+6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License.
+7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program.
+If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances.
+It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice.
+This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License.
+8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License.
+9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns.
+Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and “any +later version”, you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation.
+10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally.
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION.
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms.
+To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the “copyright” line and a pointer to where the full notice is found.
+<one line to give the program's name and a brief idea of what it does.>
+Copyright (C) <year> <name of author>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+If the program is interactive, make it output a short notice like this +when it starts in an interactive mode:
+Gnomovision version 69, Copyright (C) year name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
+
+The hypothetical commands show w
and show c
should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than show w
and show c
; they could even be
+mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your +school, if any, to sign a “copyright disclaimer” for the program, if +necessary. Here is a sample; alter the names:
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+<signature of Ty Coon>, 1 April 1989
+Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License.
+ + + + + + +Documentation is written using mkdocs.
+You can build a copy of the documentation as a PDF file using the following steps:
+pip install mkdocs-with-pdf
+pip install mkdocs-material
+pip install qrcode
+mkdocs build --config-file mkdocs-pdf.yml
+xdg-open pdfs/QGISAnimationWorkbench.pdf
+
+
+
+
+
+
+
+ In this section, we walk you through setting up a development environment and +describe common workflows for debugging etc.
+Fork the main
branch into your personal repository. Clone it to your local
+computer. Install QGIS and the following dependencies.
Clone the repo and symlink the animation_workbench
subfolder into your profile.
+Remember to change <profile>
in the line below with the actual name of the
+profile you will be using.
git clone https://github.com/{your-personal-repo}/QGISAnimationWorkbench.git
+ln -s animation_workbench ~.local/share/QGIS/QGIS3/profiles/<profile>/python/plugins
+
+Enable the plugin in the QGIS plugin manager. You should also install the +Plugin Reloader plugin so +you can quickly deploy changes to your local session in QGIS as you are +working.
+We use the VSCode remote debugger with debugpy
in order to carry our
+debugging workflows such as setting breakpoints, inspecting the application
+state, stepping through code etc.
To start debugging, you need to put the plugin into developer mode.
+ +Next, open the QGIS Animation Workbench git checkout (as described above), and
+then active the Run and Debug
tab (1 in the image below). From the list of
+launchers, choose Python: Remote Attach
and press the green run icon (2 in
+the image below).
The animation workbench will then resume normal operation, but you will be able +to set breakpoints and inspect objects in CSCode. Please refer to VSCode +documentation for the actual nuts and bolts of using their debugging tools.
+Every time a merge is made to the main branch, a package is built automatically.
+TODO
+
+TODO
+
+
+
+
+
+
+
+ In this section of the documentation, we aim to onboard developers onto the +process of setting up a developer workstation, understanding the system +architecture, contributing back to the project and so forth. Here is a brief +overview of the content provided here:
+This is the homepage for all developer related documentation.
+Welcome to the QGIS Animation Workbench developer manual. This section of the documentation describes how to participate in the development of the application and what the various components. The manual is intended to function as a reference for the application. For narrative / workflow based tutorials, you may prefer to work through our developer guide. Here is a brief overview of the content provided here:
+Welcome to the QGIS Animation Workbench (QAW). QAW is a QGIS Plugin that will help you bring your maps to life! Let's start with a quick overview. Click on the image below to view a 14 minute walkthrough on YouTube.
+ +QGIS Animation Bench exists because we wanted to use all the awesome cartography features in QGIS and make cool, animated maps! +QGIS already includes the Temporal Manager which allows you to produce animations for time-based data. But what if you want to +make animations where you travel around the map, zooming in and out, and perhaps making features on the map wiggle and jiggle as the +animation progresses? That is what the animation workbench tries to solve...
+++ + + + + + +Supports only English currently - we may add other languages in the future if there is demand.
+
Welcome to the QGIS Animation Workbench (QAW). QAW is a QGIS Plugin that will help you bring your maps to life! Let's start with a quick overview. Click on the image below to view a 14 minute walkthrough on YouTube.
"},{"location":"#why-qgis-animation-workbench","title":"\ud83e\udd16 Why QGIS Animation Workbench?","text":"QGIS Animation Bench exists because we wanted to use all the awesome cartography features in QGIS and make cool, animated maps! QGIS already includes the Temporal Manager which allows you to produce animations for time-based data. But what if you want to make animations where you travel around the map, zooming in and out, and perhaps making features on the map wiggle and jiggle as the animation progresses? That is what the animation workbench tries to solve...
"},{"location":"#features","title":"\ud83c\udfa8 Features","text":"Supports only English currently - we may add other languages in the future if there is demand.
"},{"location":"about/code-of-conduct/","title":"Contributor Covenant Code of Conduct","text":""},{"location":"about/code-of-conduct/#our-pledge","title":"Our Pledge","text":"In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
"},{"location":"about/code-of-conduct/#our-standards","title":"Our Standards","text":"Examples of behaviour that contributes to creating a positive environment include:
Examples of unacceptable behaviour by participants include:
Project maintainers are responsible for clarifying the standards of acceptable behaviour and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behaviour.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
"},{"location":"about/code-of-conduct/#scope","title":"Scope","text":"This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
"},{"location":"about/code-of-conduct/#enforcement","title":"Enforcement","text":"Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
"},{"location":"about/code-of-conduct/#attribution","title":"Attribution","text":"This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
"},{"location":"about/contribute/","title":"Contribute","text":""},{"location":"about/contribute/#pull-request-steps","title":"\ud83d\udd27 Pull Request Steps","text":"This project is open source, so you can create a pull request(PR) after you fix issues. Get a local copy of the plugins checked out for development using the following process.
"},{"location":"about/contribute/#pull-request","title":"Pull Request","text":"Before uploading your PR, run test one last time to check if there are any errors. If it has no errors, commit and then push it!
For more information on PR's steps, please see links in the Contributing section.
"},{"location":"about/contribute/#commit-messages","title":"Commit messages","text":"Please make this project more fun and easy to scan by using emoji prefixes for your commit messages (see GitMoji).
Commit type Emoji Initial commit \ud83c\udf89:tada:
Version tag \ud83d\udd16 :bookmark:
New feature \u2728 :sparkles:
Bugfix \ud83d\udc1b :bug:
Metadata \ud83d\udcc7 :card_index:
Documentation \ud83d\udcda :books:
Documenting source code \ud83d\udca1 :bulb:
Performance \ud83d\udc0e :racehorse:
Cosmetic \ud83d\udc84 :lipstick:
Tests \ud83d\udea8 :rotating_light:
Adding a test \u2705 :white_check_mark:
Make a test pass \u2714\ufe0f :heavy_check_mark:
General update \u26a1\ufe0f :zap:
Improve format/structure \ud83c\udfa8 :art:
Refactor code \ud83d\udd28 :hammer:
Removing code/files \ud83d\udd25 :fire:
Continuous Integration \ud83d\udc9a :green_heart:
Security \ud83d\udd12 :lock:
Upgrading dependencies \u2b06\ufe0f :arrow_up:
Downgrading dependencies \u2b07\ufe0f :arrow_down:
Lint \ud83d\udc55 :shirt:
Translation \ud83d\udc7d :alien:
Text \ud83d\udcdd :pencil:
Critical hotfix \ud83d\ude91 :ambulance:
Deploying stuff \ud83d\ude80 :rocket:
Fixing on MacOS \ud83c\udf4e :apple:
Fixing on Linux \ud83d\udc27 :penguin:
Fixing on Windows \ud83c\udfc1 :checkered_flag:
Work in progress \ud83d\udea7 :construction:
Adding CI build system \ud83d\udc77 :construction_worker:
Analytics or tracking code \ud83d\udcc8 :chart_with_upwards_trend:
Removing a dependency \u2796 :heavy_minus_sign:
Adding a dependency \u2795 :heavy_plus_sign:
Docker \ud83d\udc33 :whale:
Configuration files \ud83d\udd27 :wrench:
Package.json in JS \ud83d\udce6 :package:
Merging branches \ud83d\udd00 :twisted_rightwards_arrows:
Bad code / need improv. \ud83d\udca9 :hankey:
Reverting changes \u23ea :rewind:
Breaking changes \ud83d\udca5 :boom:
Code review changes \ud83d\udc4c :ok_hand:
Accessibility \u267f\ufe0f :wheelchair:
Move/rename repository \ud83d\ude9a :truck:
Other Be creative"},{"location":"about/contribute/#contributing","title":"\ud83d\udcac Contributing","text":"This plugin was developed by:
Tim Sutton Nyall Dawson Jeremy Prior Coder and Ideas Guy Genius Guru of Awesomeness Document and Logo Guy timlinux @ github nyalldawson @ github Jeremy-Prior @ github"},{"location":"about/credits/#contributors","title":"Contributors","text":"Thanks to:
We are looking for contributors, add yourself here!
Also:
Version 2, June 1991 Copyright \u00a9 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
"},{"location":"about/license/#preamble","title":"Preamble","text":"The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
"},{"location":"about/license/#terms-and-conditions-for-copying-distribution-and-modification","title":"TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION","text":"0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The \u201cProgram\u201d, below, refers to any such program or work, and a \u201cwork based on the Program\u201d means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term \u201cmodification\u201d.) Each licensee is addressed as \u201cyou\u201d.
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and \u201cany later version\u201d, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
"},{"location":"about/license/#no-warranty","title":"NO WARRANTY","text":"11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \u201cAS IS\u201d WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
"},{"location":"about/license/#how-to-apply-these-terms-to-your-new-programs","title":"How to Apply These Terms to Your New Programs","text":"If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the \u201ccopyright\u201d line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>\nCopyright (C) <year> <name of author>\n\nThis program is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 2 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program; if not, write to the Free Software Foundation, Inc.,\n51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author\nGnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\nThis is free software, and you are welcome to redistribute it\nunder certain conditions; type `show c' for details.\n
The hypothetical commands show w
and show c
should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than show w
and show c
; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a \u201ccopyright disclaimer\u201d for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n`Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n<signature of Ty Coon>, 1 April 1989\nTy Coon, President of Vice\n
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.
"},{"location":"developer/","title":"For Developers","text":"This is the homepage for all developer related documentation.
Documentation is written using mkdocs.
"},{"location":"developer/documentation/overview/#building-documentation-pdf","title":"Building documentation PDF","text":"You can build a copy of the documentation as a PDF file using the following steps:
pip install mkdocs-with-pdf\npip install mkdocs-material\npip install qrcode\nmkdocs build --config-file mkdocs-pdf.yml\nxdg-open pdfs/QGISAnimationWorkbench.pdf \n
"},{"location":"developer/guide/","title":"Developer guide","text":"In this section of the documentation, we aim to onboard developers onto the process of setting up a developer workstation, understanding the system architecture, contributing back to the project and so forth. Here is a brief overview of the content provided here:
In this section, we walk you through setting up a development environment and describe common workflows for debugging etc.
"},{"location":"developer/guide/ide-setup/#setup","title":"Setup","text":"Fork the main
branch into your personal repository. Clone it to your local computer. Install QGIS and the following dependencies.
Clone the repo and symlink the animation_workbench
subfolder into your profile. Remember to change <profile>
in the line below with the actual name of the profile you will be using.
git clone https://github.com/{your-personal-repo}/QGISAnimationWorkbench.git\nln -s animation_workbench ~.local/share/QGIS/QGIS3/profiles/<profile>/python/plugins\n
Enable the plugin in the QGIS plugin manager. You should also install the Plugin Reloader plugin so you can quickly deploy changes to your local session in QGIS as you are working.
"},{"location":"developer/guide/ide-setup/#debugging","title":"Debugging","text":"We use the VSCode remote debugger with debugpy
in order to carry our debugging workflows such as setting breakpoints, inspecting the application state, stepping through code etc.
To start debugging, you need to put the plugin into developer mode.
Next, open the QGIS Animation Workbench git checkout (as described above), and then active the Run and Debug
tab (1 in the image below). From the list of launchers, choose Python: Remote Attach
and press the green run icon (2 in the image below).
The animation workbench will then resume normal operation, but you will be able to set breakpoints and inspect objects in CSCode. Please refer to VSCode documentation for the actual nuts and bolts of using their debugging tools.
"},{"location":"developer/guide/ide-setup/#packaging","title":"Packaging","text":"Every time a merge is made to the main branch, a package is built automatically.
TODO\n
"},{"location":"developer/guide/ide-setup/#run-test","title":"Run test","text":"TODO\n
"},{"location":"developer/manual/","title":"Developer manual","text":"Welcome to the QGIS Animation Workbench developer manual. This section of the documentation describes how to participate in the development of the application and what the various components. The manual is intended to function as a reference for the application. For narrative / workflow based tutorials, you may prefer to work through our developer guide. Here is a brief overview of the content provided here:
This is the homepage for all user related documentation.
The user content is divided into three sections:
This tutorial introduces the concept of moving a point along a line within your animated map.
1. Download and extract the Required Tutorial Zip Folder
2. Open the tutorial_1.qgz project file that is in the folder. When you first open it you you see something like this:
3. Select the premade line
layer (1
), and click on the Add Symbol Layer
(green plus symbol) button (2
) to it.
Change the new Symbol Layer
(3
) type to marker line and then style it (4
) so that it is more visible.
4. Change the Symbol Layer's
settings so that the point is only on the first vertex
(5
) and and not at equidistant intervals.
Change the offset along the line to be Percentage
(6
).
Click the Dropdown Menu
(7
) \u2794Edit...
(8
) and then add the following code snippet
-- Point Along Line Code Snippet\n (@current_hover_frame/@hover_frames) * 100\n
The snippet tells QGIS how far along the line (as a percentage of the line length) to render the point in each frame.
5. Open the Workbench and select Fixed Extent
(9
).
Click on Map Canvas Extent
(10
) and set the the Frames
to 300 (11
) (for a 10 second output at 30 frames per second).
6. Skip over the Intro
, Outro
, and Soundtrack
tabs. In the Output
tab, set the output format (12
) and resolution (13
), and set the output location's path (14
).
7. Click Run
and render your output.
After this tutorial you should have a better idea of how to make a point move along a line. An expansion to this example would be to make the moving point a dynamically changing marker (like the markers in tutorial 1). Go have fun!
"},{"location":"user/guide/#tutorial-2-basic-dynamically-changing-markers","title":"Tutorial 2: Basic Dynamically Changing Markers","text":"This tutorial aims to show you the basics of creating, and animating, a static layer to use with the Animation Workbench. There are three pre-made layers to allow the main focus of the tutorial to be on the Animation Workbench and not on QGIS as a whole.
1. Download and extract the Required Tutorial Zip Folder
2. Open the tutorial_2.qgz project file that is in the folder. \u00a0
3. Set the CRS of your project to WGS84/UTM zone 35S (EPSG: 32735).
4. In the Browser
, expand the tutorial_2.gpkg and add the three pre-made layers (VaalDam, SouthAfrica, and route) (A
) to your project.
5. In the Layers
Panel, arrange the layers in the following order: route
, VaalDam
, SouthAfrica
. Then right-click on the VaalDam
layer and Zoom to Layer(s)
(B
)
Style the three layers to your preferred style. \u00a0
6. Now create a new layer in the tutorial_2.gpkg by clicking Layer
\u2794Create Layer
\u2794 New GeoPackage Layer...
(C
).
Click on the Ellipsis
(D
), navigate to and select the tutorial_2.gpkg, and click Save
. Change the Table name to fish (E
), set the Geometry type as Point (F
), and change the CRS to match the Project CRS (G
).
Click on OK
and then click Add New Layer
on the window that pops up. \u00a0
7. Select the fish
layer and then click on Toggle Editing
\u2794Add Point Feature
(H
).
Add a few points wherever you feel they should go (Hint: This is a fish layer so adding them above the dam layer would be best). Don't worry about naming the points, just add them.
Save your changes by clicking on Save Layer Edits
just next to the Toggle Editing
button. Then stop editing the layer. \u00a0
8. Repeat steps 6. and 7. but change the Table name to bird and add the points over the land areas.
9. Select the fish
layer and then in the Layer styling
toolbar (I
) change the Symbol layer type
to Raster Image Marker
(J
).
Select the marker image by clicking the Dropdown menu
\u2794Select File...
(K
) and then choosing fish
\u2794fish_0000.png
.
Click Open
10. Change the marker's Size Unit to Meters at Scale
(L
)
and set the Width and Height to 1000. \u00a0
11. Repeat Steps 9. and 10. with the bird
layer but instead choosing bird
\u2794bird_0000.png
and setting the Width and Height to 3000.
In QGIS 3.26
, or later, the Symbol layer type
can simply be selected as Animated Marker
and Step 12. can be skipped.
12. To animate the fish
and bird
layers using the QGIS Expressions
system click the Dropdown Menu
\u2794Edit...
(M
).
For the fish
layer use the following expression:
@project_home\n || \n '/fish/fish_00'\n ||\n lpad(to_string( @frame_number % 32), 2, '0')\n ||\n '.png'\n
And for the bird
layer use:
@project_home\n ||\n '/bird/bird_00'\n || \n lpad(to_string(@frame_number % 9), 2, '0')\n || \n '.png'\n
Refer to the What is the Workbench doing? section for an explanation about what the above code snippet is doing.
13. Open the Animation Workbench (refer to the Using the Animation Workbench section if you are unsure how to open the Workbench).
In the Animation Plan
tab set:
Render Mode
to Planar
(N
),Animation Layer
to route
(O
) using the dropdown menu,Zoom Range
(P
) to 1:270000 for the Minimum and 1:135000 for the Maximum,Frame rate per second
to 9 fps (Q
),Travel duration
to 4,00 s (R
),Feature hover duration
to 2,00 s (S
)Enable both the Pan
and Zoom
easings and set them to linear.
14. Skip past the Intro
, Outro
, and Soundtrack
tabs to the Output
tab. Set the Output Format
as Animated Gif
(T
) and the Output Resolution
to 720p (1280x720)
(U
). The Output Resolution
can be set as any of the three choices but was set at 720
for this tutorial for the sake of speed. Set the output location to one you can find easily (V
)
15. Click Run
and watch what the Workbench is doing in the Progress
tab. Once the Workbench is finished running, you should end up with an output similar to this:
After this tutorial you should have a better understanding of how to create a point layer in your project and then to change the Single Symbol
markers into stationary animated markers. A key focus is the idea that you can tell versions of QGIS
before 3.26
to dynamically change markers using short code snippets. Versions of QGIS
post 3.26
allow a user to simply use the Animated Marker
feature without editing an expression.
This tutorial aims to show you how add a flying point animation to points on your map using built-in QGIS functionalities (The geometry generator line) and introduced variables from the workbench.
1. Download and extract the Required Tutorial Zip Folder
2. Open the tutorial_3.qgz project file. When you first open the project file you should be greeted with something like this:
3. Create a new point layer in a new geopackage by clicking Layer
\u2794Create Layer
\u2794 New GeoPackage Layer...
. Click on the Ellipsis
(three dots) next to the Database textbox and navigate to the folder that the tutorial_3.qgz file is located in. Type the File name \"tutorial_3\" (1
) and ensure the file will be saved as a GeoPackage
(2
) and click Save
(3
).
Change the Table name to flying_points (4
), set the Geometry type as Point (5
) and change the CRS to match the Project CRS (6
).
Click OK
(7
) \u00a0
4. Click on Toggle Editing
\u2794Add Point Feature
(8
).
And randomly add points to your map. Depending on your computer's capabilites, you can add more, or fewer, points than the example below.
Save your Layer Edits and toggle off the Editing tool. \u00a0
5. Style the points layer.
Select the flying_points
(9
) layer and in the Layer Styling
toolbar click on the Add Symbol Layer
(green plus symbol) button (10
).
Select the top Simple Marker
(11
) and change its Symbol layer type to Geometry Generator
(12
)
and then set the Geometry type to LineString / MultiLineString
(13
).
Change the line's Symbol layer type to Marker Line
(14
).
Add a second Simple marker
to the marker line so that you end up with something like this:
Style the various Simple Markers
to your preferred look.
6. Select the Geometry Generator
symbol layer (15
) and add this code to it:
wave_randomized(\n make_line(\n $geometry, geometry(@hover_feature)), \n 100, 1000, 1000, 10000, 1)\n
More information about what changing the numbers will affect can be found in the QGIS expressions editor. \u00a0
7. A few options need to be changed in the Marker Line
symbol layer (16
): The Marker placement needs to be set to On first vertex
(17
) and, the Offset along line needs to be changed to Percentage
(18
). The click the Dropdown menu
next to Offset along line and select Edit...
(19
).
In the Expression String Builder
add the following code snippet:
100 - to_int((@current_hover_frame / @hover_frames) * 100 )\n
Click OK
8. Select the first Simple Marker
symbol layer (20
) in the Marker Line
symbol layer. Scroll down to Offset and click on the Dropdown Menu
\u2794Edit..
(21
).
In the Expression String Builder
add the following code snippet:
-- Taken from https://spicyyoghurt.com/tools/easing-functions\n -- t = Time - Amount of time that has passed since the beginning of the animation. Usually starts at 0 and is slowly increased using a game loop or other update function.\n -- b = Beginning value - The starting point of the animation. Usually it's a static value, you can start at 0 for example.\n -- c = Change in value - The amount of change needed to go from starting point to end point. It's also usually a static value.\n -- d = Duration - Amount of time the animation will take. Usually a static value aswell.\n -- Sinusoidal\n -- -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n\n -- Use with the animation in static mode\n if(@hover_feature_id != $id,\n array(\n (-@hover_frames / 2) * (cos( (pi() * @frame_number / @hover_frames ) - 1)) ,\n (-@hover_frames / 2) * (sin( (pi() * @frame_number / @hover_frames ) - 1)) \n ),\n array (0,0))\n
Click OK
9. Open the Animation Workbench
(22
)
10. Set up the Animation Plan
with:
Render Mode
to Planar
(23
),Animation Layer
to flying_points
(24
) using the dropdown menu,Zoom Range
(25
) to 1:22000000 for the Minimum and 1:11000000 for the Maximum,Frame rate per second
to 9 fps (26
),Travel duration
to 2,00 s (27
),Feature hover duration
to 2,00 s (28
),Zoom Easing
as InCirc (29
)
With a decently specced computer you can up the fps and get the points to fly faster in your output. \u00a0
11. Add license-free media to the Intro
, Outro
, and Soundtrack
.
Make sure your Soundtrack
is as long as, or longer than, your final animation will be (including the Intro
, Animation
, and Outro
).
12. Set the Output Format
as Movie (MP4)
(30
) and the Output Resolution
to 1080 (1920x1080)
(31
). The Output Resolution
can be set as any of the three choices but was set at 1080
for this tutorial for the sake of speed. Set the output location (32
) to one you can easily locate.
13. Click Run
and get an output. The GIF below is the visual output of the tutorial if you followed step-by-step and set the parameters to exactly what was stated.
The link to a more complex output (with an Intro
, an Outro
, and a Soundtrack
) can be found here
After this tutorial you should have a better idea of how you can use a mixture of built-in QGIS functionalites and the workbench's introduced variables to generate interesting outputs.
"},{"location":"user/guide/#tutorial-4-spinning-globe","title":"Tutorial 4: Spinning Globe","text":"Given a global point layer and countries layer like this:
You can create a nice spinning globe effect like this:
I set up the animation workbench like this:
For the above animated GIF, I compressed it using imagemagick like this:
convert globe.gif -coalesce -resize 700x525 -fuzz 2% +dither -layers Optimize +map globe_small.gif\n
This is a handy technique if you want to generate small file size animations.
For the points I made a red marker using a quarter circle that spins around the points like this:
The rotation field expression is this:
if (@id = @hover_feature_id, \n 0-((1440 * (@current_hover_frame/@hover_frames)) % 360),\n 0)\n
This will spin around 4 times during the hover cycle.
For the ocean (AOI in the layers list), I generated a grid of 1 degree cells covering the earth. You need to do it as smaller polygons instead of one large polygon because QGIS will run into issues reprojecting a single polygon whose edges lie on the date line.
Here is how the final video came out:
"},{"location":"user/guide/tutorial1/","title":"1 Points on a Line","text":""},{"location":"user/guide/tutorial1/#tutorial-1-point-along-a-line","title":"Tutorial 1: Point Along A Line","text":"This tutorial introduces the concept of moving a point along a line within your animated map.
1. Download and extract the Required Tutorial Zip Folder
2. Open the tutorial_1.qgz project file that is in the folder. When you first open it you you see something like this:
3. Select the premade line
layer (1
), and click on the Add Symbol Layer
(green plus symbol) button (2
) to it.
Change the new Symbol Layer
(3
) type to marker line and then style it (4
) so that it is more visible.
4. Change the Symbol Layer's
settings so that the point is only on the first vertex
(5
) and and not at equidistant intervals.
Change the offset along the line to be Percentage
(6
).
Click the Dropdown Menu
(7
) \u2794Edit...
(8
) and then add the following code snippet
-- Point Along Line Code Snippet\n (@current_hover_frame/@hover_frames) * 100\n
The snippet tells QGIS how far along the line (as a percentage of the line length) to render the point in each frame.
5. Open the Workbench and select Fixed Extent
(9
).
Click on Map Canvas Extent
(10
) and set the the Frames
to 300 (11
) (for a 10 second output at 30 frames per second).
6. Skip over the Intro
, Outro
, and Soundtrack
tabs. In the Output
tab, set the output format (12
) and resolution (13
), and set the output location's path (14
).
7. Click Run
and render your output.
After this tutorial you should have a better idea of how to make a point move along a line. An expansion to this example would be to make the moving point a dynamically changing marker (like the markers in tutorial 1). Go have fun!
"},{"location":"user/guide/tutorial2/","title":"2 Dynamic Markers","text":""},{"location":"user/guide/tutorial2/#tutorial-2-basic-dynamically-changing-markers","title":"Tutorial 2: Basic Dynamically Changing Markers","text":"This tutorial aims to show you the basics of creating, and animating, a static layer to use with the Animation Workbench. There are three pre-made layers to allow the main focus of the tutorial to be on the Animation Workbench and not on QGIS as a whole.
1. Download and extract the Required Tutorial Zip Folder
2. Open the tutorial_2.qgz project file that is in the folder. \u00a0
3. Set the CRS of your project to WGS84/UTM zone 35S (EPSG: 32735).
4. In the Browser
, expand the tutorial_2.gpkg and add the three pre-made layers (VaalDam, SouthAfrica, and route) (A
) to your project.
5. In the Layers
Panel, arrange the layers in the following order: route
, VaalDam
, SouthAfrica
. Then right-click on the VaalDam
layer and Zoom to Layer(s)
(B
)
Style the three layers to your preferred style. \u00a0
6. Now create a new layer in the tutorial_2.gpkg by clicking Layer
\u2794Create Layer
\u2794 New GeoPackage Layer...
(C
).
Click on the Ellipsis
(D
), navigate to and select the tutorial_2.gpkg, and click Save
. Change the Table name to fish (E
), set the Geometry type as Point (F
), and change the CRS to match the Project CRS (G
).
Click on OK
and then click Add New Layer
on the window that pops up. \u00a0
7. Select the fish
layer and then click on Toggle Editing
\u2794Add Point Feature
(H
).
Add a few points wherever you feel they should go (Hint: This is a fish layer so adding them above the dam layer would be best). Don't worry about naming the points, just add them.
Save your changes by clicking on Save Layer Edits
just next to the Toggle Editing
button. Then stop editing the layer. \u00a0
8. Repeat steps 6. and 7. but change the Table name to bird and add the points over the land areas.
9. Select the fish
layer and then in the Layer styling
toolbar (I
) change the Symbol layer type
to Raster Image Marker
(J
).
Select the marker image by clicking the Dropdown menu
\u2794Select File...
(K
) and then choosing fish
\u2794fish_0000.png
.
Click Open
10. Change the marker's Size Unit to Meters at Scale
(L
)
and set the Width and Height to 1000. \u00a0
11. Repeat Steps 9. and 10. with the bird
layer but instead choosing bird
\u2794bird_0000.png
and setting the Width and Height to 3000.
In QGIS 3.26
, or later, the Symbol layer type
can simply be selected as Animated Marker
and Step 12. can be skipped.
12. To animate the fish
and bird
layers using the QGIS Expressions
system click the Dropdown Menu
\u2794Edit...
(M
).
For the fish
layer use the following expression:
@project_home\n || \n '/fish/fish_00'\n ||\n lpad(to_string( @frame_number % 32), 2, '0')\n ||\n '.png'\n
And for the bird
layer use:
@project_home\n ||\n '/bird/bird_00'\n || \n lpad(to_string(@frame_number % 9), 2, '0')\n || \n '.png'\n
Refer to the What is the Workbench doing? section for an explanation about what the above code snippet is doing.
13. Open the Animation Workbench (refer to the Using the Animation Workbench section if you are unsure how to open the Workbench).
In the Animation Plan
tab set:
Render Mode
to Planar
(N
),Animation Layer
to route
(O
) using the dropdown menu,Zoom Range
(P
) to 1:270000 for the Minimum and 1:135000 for the Maximum,Frame rate per second
to 9 fps (Q
),Travel duration
to 4,00 s (R
),Feature hover duration
to 2,00 s (S
)Enable both the Pan
and Zoom
easings and set them to linear.
14. Skip past the Intro
, Outro
, and Soundtrack
tabs to the Output
tab. Set the Output Format
as Animated Gif
(T
) and the Output Resolution
to 720p (1280x720)
(U
). The Output Resolution
can be set as any of the three choices but was set at 720
for this tutorial for the sake of speed. Set the output location to one you can find easily (V
)
15. Click Run
and watch what the Workbench is doing in the Progress
tab. Once the Workbench is finished running, you should end up with an output similar to this:
After this tutorial you should have a better understanding of how to create a point layer in your project and then to change the Single Symbol
markers into stationary animated markers. A key focus is the idea that you can tell versions of QGIS
before 3.26
to dynamically change markers using short code snippets. Versions of QGIS
post 3.26
allow a user to simply use the Animated Marker
feature without editing an expression.
This tutorial aims to show you how add a flying point animation to points on your map using built-in QGIS functionalities (The geometry generator line) and introduced variables from the workbench.
1. Download and extract the Required Tutorial Zip Folder
2. Open the tutorial_3.qgz project file. When you first open the project file you should be greeted with something like this:
3. Create a new point layer in a new geopackage by clicking Layer
\u2794Create Layer
\u2794 New GeoPackage Layer...
. Click on the Ellipsis
(three dots) next to the Database textbox and navigate to the folder that the tutorial_3.qgz file is located in. Type the File name \"tutorial_3\" (1
) and ensure the file will be saved as a GeoPackage
(2
) and click Save
(3
).
Change the Table name to flying_points (4
), set the Geometry type as Point (5
) and change the CRS to match the Project CRS (6
).
Click OK
(7
) \u00a0
4. Click on Toggle Editing
\u2794Add Point Feature
(8
).
And randomly add points to your map. Depending on your computer's capabilites, you can add more, or fewer, points than the example below.
Save your Layer Edits and toggle off the Editing tool. \u00a0
5. Style the points layer.
Select the flying_points
(9
) layer and in the Layer Styling
toolbar click on the Add Symbol Layer
(green plus symbol) button (10
).
Select the top Simple Marker
(11
) and change its Symbol layer type to Geometry Generator
(12
)
and then set the Geometry type to LineString / MultiLineString
(13
).
Change the line's Symbol layer type to Marker Line
(14
).
Add a second Simple marker
to the marker line so that you end up with something like this:
Style the various Simple Markers
to your preferred look.
6. Select the Geometry Generator
symbol layer (15
) and add this code to it:
wave_randomized(\n make_line(\n $geometry, geometry(@hover_feature)), \n 100, 1000, 1000, 10000, 1)\n
More information about what changing the numbers will affect can be found in the QGIS expressions editor. \u00a0
7. A few options need to be changed in the Marker Line
symbol layer (16
): The Marker placement needs to be set to On first vertex
(17
) and, the Offset along line needs to be changed to Percentage
(18
). The click the Dropdown menu
next to Offset along line and select Edit...
(19
).
In the Expression String Builder
add the following code snippet:
100 - to_int((@current_hover_frame / @hover_frames) * 100 )\n
Click OK
8. Select the first Simple Marker
symbol layer (20
) in the Marker Line
symbol layer. Scroll down to Offset and click on the Dropdown Menu
\u2794Edit..
(21
).
In the Expression String Builder
add the following code snippet:
-- Taken from https://spicyyoghurt.com/tools/easing-functions\n -- t = Time - Amount of time that has passed since the beginning of the animation. Usually starts at 0 and is slowly increased using a game loop or other update function.\n -- b = Beginning value - The starting point of the animation. Usually it's a static value, you can start at 0 for example.\n -- c = Change in value - The amount of change needed to go from starting point to end point. It's also usually a static value.\n -- d = Duration - Amount of time the animation will take. Usually a static value aswell.\n -- Sinusoidal\n -- -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n\n -- Use with the animation in static mode\n if(@hover_feature_id != $id,\n array(\n (-@hover_frames / 2) * (cos( (pi() * @frame_number / @hover_frames ) - 1)) ,\n (-@hover_frames / 2) * (sin( (pi() * @frame_number / @hover_frames ) - 1)) \n ),\n array (0,0))\n
Click OK
9. Open the Animation Workbench
(22
)
10. Set up the Animation Plan
with:
Render Mode
to Planar
(23
),Animation Layer
to flying_points
(24
) using the dropdown menu,Zoom Range
(25
) to 1:22000000 for the Minimum and 1:11000000 for the Maximum,Frame rate per second
to 9 fps (26
),Travel duration
to 2,00 s (27
),Feature hover duration
to 2,00 s (28
),Zoom Easing
as InCirc (29
)
With a decently specced computer you can up the fps and get the points to fly faster in your output. \u00a0
11. Add license-free media to the Intro
, Outro
, and Soundtrack
.
Make sure your Soundtrack
is as long as, or longer than, your final animation will be (including the Intro
, Animation
, and Outro
).
12. Set the Output Format
as Movie (MP4)
(30
) and the Output Resolution
to 1080 (1920x1080)
(31
). The Output Resolution
can be set as any of the three choices but was set at 1080
for this tutorial for the sake of speed. Set the output location (32
) to one you can easily locate.
13. Click Run
and get an output. The GIF below is the visual output of the tutorial if you followed step-by-step and set the parameters to exactly what was stated.
The link to a more complex output (with an Intro
, an Outro
, and a Soundtrack
) can be found here
After this tutorial you should have a better idea of how you can use a mixture of built-in QGIS functionalites and the workbench's introduced variables to generate interesting outputs.
"},{"location":"user/guide/tutorial4/","title":"4 Spinning Globe","text":""},{"location":"user/guide/tutorial4/#tutorial-4-spinning-globe","title":"Tutorial 4: Spinning Globe","text":"Given a global point layer and countries layer like this:
You can create a nice spinning globe effect like this:
I set up the animation workbench like this:
For the above animated GIF, I compressed it using imagemagick like this:
convert globe.gif -coalesce -resize 700x525 -fuzz 2% +dither -layers Optimize +map globe_small.gif\n
This is a handy technique if you want to generate small file size animations.
For the points I made a red marker using a quarter circle that spins around the points like this:
The rotation field expression is this:
if (@id = @hover_feature_id, \n 0-((1440 * (@current_hover_frame/@hover_frames)) % 360),\n 0)\n
This will spin around 4 times during the hover cycle.
For the ocean (AOI in the layers list), I generated a grid of 1 degree cells covering the earth. You need to do it as smaller polygons instead of one large polygon because QGIS will run into issues reprojecting a single polygon whose edges lie on the date line.
Here is how the final video came out:
"},{"location":"user/guide/tutorial5/","title":"Tutorial 5: Planar Map Animation","text":"Given a global point layer and countries layer like this:
You can create a nice planar map animation effect like this:
In planar mode, we do not pan and zoom the map from feature to feature. Rather, the map zoom stays constant and the variables for
are updated as we iterate over the features of your animation layer. In this example project I duplicated the animation point layer twice. The first (lower) copy is used to 'drive' the animation, whilst the second (upper) layer shows only the feature currently being hovered over, with animation effects applied to that feature.
I set up the animation workbench like this:
For the above animated GIF, I compressed it using imagemagick like this:
convert globe.gif -coalesce -resize 700x525 -fuzz 2% +dither -layers Optimize +map globe_small.gif\n
This is a handy technique if you want to generate small file size animations.
"},{"location":"user/guide/tutorial5/#expressions-used","title":"Expressions Used","text":""},{"location":"user/guide/tutorial5/#copyright-decoration","title":"Copyright Decoration","text":"Firstly for debugging, we use the following copyright label in View \u21d2 Decorations \u21d2 Copyright Label. You can use the checkbox in the Copyright configuration dialog to toggle this on and off. This will help you while debugging / tweaking your animations. When you are ready to render your final product, simply turn it off before rendering.
[%\n' \\nRotation:' || to_string( 0-((1440 * (@current_hover_frame/@hover_frames)) % 360)) ||\n'\\nFeature Variables:' ||\n' \\n------------------------' ||\n' \\nPrevious Feature ' || to_string(coalesce(attribute(@previous_feature, 'name'), '-')) ||\n' \\nPrevious Feature ID ' || to_string(coalesce(@previous_feature_id, '-')) ||\n' \\n' ||\n' \\nNext Feature ' || to_string(coalesce(attribute(@next_feature, 'name'), '-')) ||\n' \\nNext Feature ID ' || to_string(coalesce(@next_feature_id, '-')) ||\n' \\n' ||\n' \\nHover Feature ' || to_string(coalesce(attribute(@hover_feature, 'name'), '-')) ||\n' \\nHover Feature ID ' || to_string(coalesce(@hover_feature_id, '-')) ||\n' \\n' ||\n' \\nFrom Feature ' || to_string(coalesce(attribute(@from_feature, 'name'), '-')) ||\n' \\nFrom Feature ID ' || to_string(coalesce(@from_feature_id, '-')) ||\n' \\n' ||\n' \\nTo Feature ' || to_string(coalesce(attribute(@to_feature, 'name'), '-')) ||\n' \\nTo Feature ID ' || to_string(coalesce(@to_feature_id, '-')) ||\n' \\n' ||\n' \\nTotal Hover Frames ' || to_string(coalesce(@hover_frames, 0)) ||\n' \\nCurrent Hover Frame ' || to_string(coalesce(@current_hover_frame, 0)) ||\n' \\nTotal Travel Frames ' || to_string(coalesce(@travel_frames, 0)) ||\n' \\nCurrent Travel Frame ' || to_string(coalesce(@current_travel_frame, 0)) ||\n' \\nTotal Frame Count ' || to_string(coalesce(@total_frame_count, 0)) ||\n' \\nFrame Number ' || to_string(coalesce(@frame_number, 0)) ||\n' \\nFrame Rate ' || to_string(coalesce(@frame_rate, 0)) ||\n' \\nwith Current Animation Action: ' || @current_animation_action ||\n' \\nTo Direction ' || coalesce(format_number(degrees(azimuth( geometry(@hover_feature), geometry(@previous_feature) ) ) ), 0) || \n' \\nFrom Direction ' || coalesce(format_number(degrees( azimuth( geometry(@hover_feature), geometry(@next_feature) ) ) ), 0)%]\n
"},{"location":"user/guide/tutorial5/#symbol-rotation","title":"Symbol Rotation","text":"For the points I made a red marker using a quarter circle that spins around the points like this:
The first line of the listing from the previous section gives you a hint about how we can vary the rotation of a symbol depending on how far through the animation sequence we are. With the addition of an if
clause, we can apply this rotation only to features that are being hovered over during the planar animation.
if (\n @id = @hover_feature_id, \n 0-((1440 * (@current_hover_frame/@hover_frames)) % 360), \n 0)\n
This if
clause has the effect of excluding calculation for any feature that is not the current hover feature.
This will spin around 4 times during the hover cycle. This is because four rotations are 4 x 360 = 1440
. We calculate the percentage of completion for the current hover frame (@current_hover_frame/@hover_frames
) and then multiply our rotation product by the current completion percentage. Lastly we calculate the modulus of this (% 360
) to compute how far along we are in the current rotation. More advanced users could substitute 1440 with a project variable so that it is easy to change the number of desired rotations in a single place.
The rotating symbol layer and the other symbol layers in our animation layer are similarly hidden if the feature being rendered is not the hover_feature_id
using an expression like this:
if ( @id = @hover_feature_id, 10, 0)\n
This has the effect of setting the symbol size to 0 if it is not the feature we are focussing on.
"},{"location":"user/guide/tutorial5/#other-planar-experiments","title":"Other Planar Experiments","text":"With the basic concepts of working with planar animations covered above, you can do other interesting things.
"},{"location":"user/guide/tutorial5/#generate-a-line","title":"Generate a line","text":"In this example, we can generate a line using the Geometry Generator function in QGIS. The line will start from the previous point, extend through the current point and terminate and the next point.
if ( \n $id = @hover_feature_id,\n make_line(\n geometry(@previous_feature),\n geometry(@hover_feature),\n geometry(@next_feature)\n ),\n $geometry)\n
We wrap it in an if clause again so that the line is not rendered if the current feature being rendered is not the same as the current animation feature.
There may be some edge cases where there is no previous or next feature. This example does not try to deal with these cases but you could easily add some logic that checks if each of the three components making up the line is null or not.
"},{"location":"user/guide/tutorial5/#generate-a-curve","title":"Generate a curve","text":"We can extend the above example by creating a curve rather than a line, for a more natural looking connection between the hover feature and its previous and following feature.
if ( \n $id = @hover_feature_id,\n smooth(\n make_line(\n geometry(@previous_feature),\n geometry(@hover_feature),\n geometry(@next_feature)\n ),\n iterations:=1,\n offset:=0.2,\n min_length:=-1,\n max_angle:=180),\n $geometry)\n
If you increase the number of iterations, you can achieve a more and more smoothed out line, at the expense of processing time.
if ( \n $id = @hover_feature_id,\n smooth(\n make_line(\n geometry(@previous_feature),\n geometry(@hover_feature),\n geometry(@next_feature)\n ),\n iterations:=5,\n offset:=0.2,\n min_length:=-1,\n max_angle:=180),\n $geometry)\n
"},{"location":"user/guide/tutorial5/#subtring-the-line","title":"Subtring the Line","text":"As a much more advanced example, you can extract a substring of the smoothed line that connects the previous, current and next features. Don't get put off by the with_variable
elements - they just allow us to re-use calculations in our expression.
First, let's start with extracting the first half of the smoothed line:
if ( \n $id = @hover_feature_id,\n with_variable(\n 'smoothed_line',\n smooth(\n make_line(\n geometry(@previous_feature),\n geometry(@hover_feature),\n geometry(@next_feature)\n ),\n iterations:=5,\n offset:=0.2,\n min_length:=-1,\n max_angle:=180),\n with_variable(\n 'line_length',\n length(@smoothed_line),\n line_substring(@smoothed_line, 0, @line_length / 2 ))),\n $geometry)\n
"},{"location":"user/guide/tutorial5/#animating-the-substring","title":"Animating the substring","text":"If we follow the same approach as above, but vary the start and length of the line clip, we can create some cool line animation effects.
if ( \n $id = @hover_feature_id,\n with_variable(\n 'smoothed_line',\n smooth(\n make_line(\n geometry(@previous_feature),\n geometry(@hover_feature),\n geometry(@next_feature)\n ),\n iterations:=5,\n offset:=0.2,\n min_length:=-1,\n max_angle:=180),\n with_variable(\n 'line_length',\n length(@smoothed_line),\n line_substring(\n @smoothed_line, \n @line_length * (@current_hover_frame/@hover_frames), \n @line_length ))),\n\n $geometry)\n\n
"},{"location":"user/guide/tutorial5/#final-render","title":"Final Render","text":"There are still a few details that would need to be taken care of to reach a final solution - in particular taking care of datelines and the like. But here is a little example of what we managed to make thus far (without any debugging text).
"},{"location":"user/manual/","title":"User manual","text":"Welcome to the QGIS Animation Workbench user manual. This section of the documentation describes the application and what the various components of each dialog do. The manual is intended to function as a reference for the application. For narrative / workflow based tutorials, you may prefer to work through our user guide. Here is a brief overview of the content provided here:
As long as you can provide the proper attribution for an image you can use it in your project.
"},{"location":"user/manual/faq/#i-have-an-older-less-powerful-computer-will-it-handle-running-this-workbench","title":"I have an older, less powerful, computer, will it handle running this workbench?","text":"If you open the standard QGIS settings dialog and select the Animation Workbench options you can follow the advice with regards to lowering the number of threads allowed during rendering to help you computer cope. Rendering shorter movies or GIFs (i.e. fewer frames) will also help. Below is an example of running a job with 9000 frames at 60fps and 999 frames per feature
And the subsequent CPU load during processing:
After processing:
And here is the resulting video:
https://youtu.be/1quc3xPdJsU
"},{"location":"user/manual/faq/#i-get-an-error-when-rendering-because-of-my-intro-outro-images","title":"I get an error when rendering because of my intro / outro images","text":"Currently your filenames should not contain spaces or special characters
.(, ), [, ], {, }, <, >, /, \\, :, *, ?, |, \", &, etc.).\n
"},{"location":"user/manual/faq/#can-i-use-a-movie-as-the-intro-outro-media","title":"Can I use a movie as the intro / outro media?","text":"This is planned but not yet implemented. Tim - check.
"},{"location":"user/manual/faq/#can-i-pay-you-to-add-some-features","title":"Can I pay you to add some features?","text":"This is a fun / hobby project, currently we want other contributors who also want to have a fun experience with building this plugin and contribute in-kind efforts to the project. Both Kartoza and North-Road offer commercial development services but not for this plugin which is a intended to provide an experimental, no-pressure space for us to work on something fun for QGIS.
"},{"location":"user/manual/project_preparation/","title":"How to set up a project to work with the animation plugin","text":"1. The first step for getting an output using the Workbench is to create a QGIS Project \u00a0 Open QGIS and click on Project
\u2794 New
Next, add new layers to your project. You will want a few layers; one, or more, backing layer(s) (vector layers or XYZ Tiles), a layer for the workbench to follow, and one, or more, layer(s) of animated points. The example in this section only has one animated layer. \u00a0
To add a layer, go to Layer
\u2794 Create Layer
and then select the type of layer you want to add. The example adds a point layer to a GeoPackage to make the project more portable.
Once you have added your layers you need to add features to the layers. This is done by selecting a layer and then clicking Toggle Editing
(1
) \u2794 Add PointFeature
(2
). Then click around on your map to add as few, or as many, features as you need.
The example project has four layers: two point layers (3
) and two backing layers (4
).
A simple way to add a vector base layer is to type \"world\" into the coordinate textbox
Finally, style your layers to make your project look aesthetically pleasing. To style your layers you must select the layer you want to style and then using the Layer Styling toolbar, play around with the style of the layer until it suits you. A good practice is to have your backing layers as more muted colours and your desired features as more eye-catching colours.
You now have a QGIS Project. \u00a0
2. The next step is to choose which features you want to be animated. \u00a0
Pick the layer (or layers) that you want to have animations. Then either find, or create, the animation for the layer. Make sure you have all the correct attribution for any animations you use. Below is an example of a simple fish animation split into its frames. The frames are repeated to slow down the animation's playback speed.
If you are using QGIS 3.26
you can simply use the new animated point symbol, or if you're using an older version of QGIS 3.x
follow the instructions below.
The layer should contain a Raster Image Marker
. Once you have selected the marker you want to use click on the QGIS Expressions dropdown menu (5
) and click on Edit
(6
).
You can also make a marker move along a line relative to the frame of the animation. Use the Code Snippets Section for more in-depth help.
The example below works with the animation from earlier.
@project_home\n|| \n'/fish/fish_00'\n||\nlpad(to_string( @frame_number % 32), 2, '0')\n||\n'.png'\n
3. Configure your animation
After animating your markers it's time to configure your animation. Open the Animated Workbench and begin choosing between the different modes and options. \u00a0
Open the Workbench by clicking the Animation Workbench
(7
) icon in the Plugin Toolbar.
Configure the settings for your animation. The screenshot below is configured for the example presented in this section. The Animation Layer is selected as route
(8
) because that is the path that the output animation will fly along. The Zoom Range (9
) was selected from the Map Canvas Extent, and the Frame rate per second (fps) (10
) was set to match the number of frames of the animated markers so that they will play nicely in the output. The other settings were selected as a personal choice.
Select the Output Resolution (11
) and a location for your output by clicking on the ellipsis (three dots) or by typing in the desired file path (12
).
Refer to the Workbench User Interface section for more information about what various settings and buttons accomplish.
4. Render your animation! \u00a0 Click Run
and render your output. The output below is the output from the example.
Should work with and version of QGIS 3.x. If you have QGIS 3.26 or better you can benefit from the animated icon support (see @nyalldawson's most excellent patch #48060).
For QGIS versions below 3.26, you can animate markers by unpacking a GIF image into its constituent frames and then referencing a specific frame from the symbol data defined property for the image file. Note that to do this extraction below you need to have the Open Source ImageMagick application installed:
First extract a gif to a sequence of images:
convert cat.gif -coalesce cat_%05d.png\n
Example of how to create a dynamically changing image marker based on the current frame count:
@project_home \n||\n'/gifs/cat_000'\n|| \nlpad(to_string( @frame_number % 48 ), 2, '0')\n|| \n'.png'\n
Note that for the above, 48 is the number of frames that the GIF was composed of, and it assumes the frames are in the project directory in a subfolder called gifs
.
In this example we use a geometry generator to create a line between the origin point and the destination point:
if (@from_feature_id = $id OR @to_feature_id = $id,\n -- read this from inside to out so \n -- last tranform the geometry back to the map crs\n transform( \n -- densify the geometry so that when we transform\n -- back it makes a great circle\n densify_by_count( \n -- move the geometry into a crs that \n -- shows a great circle as a straight line\n transform( \n -- make a line from the previous pont to the next point\n make_line( \n geometry(@from_feature), \n geometry(@to_feature)\n ), \n @map_crs, 'EPSG:4326'),\n 99), \n 'EPSG:4326', @map_crs),\n None)\n
"},{"location":"user/manual/snippets/#showing-diagnostic-info-as-a-copyright-label","title":"Showing diagnostic info as a copyright label","text":"Showing diagnostic information in the QGIS copyright label:
[%\n'Feature Variables:' ||\n' \\n------------------------' ||\n' \\nPrevious Feature ' || to_string(coalesce(attribute(@previous_feature, 'name'), '-')) ||\n' \\nPrevious Feature ID ' || to_string(coalesce(@previous_feature_id, '-')) ||\n' \\n' ||\n' \\nNext Feature ' || to_string(coalesce(attribute(@next_feature, 'name'), '-')) ||\n' \\nNext Feature ID ' || to_string(coalesce(@next_feature_id, '-')) ||\n' \\n' ||\n' \\nHover Feature ' || to_string(coalesce(attribute(@hover_feature, 'name'), '-')) ||\n' \\nHover Feature ID ' || to_string(coalesce(@hover_feature_id, '-')) ||\n' \\n' ||\n' \\nFrom Feature ' || to_string(coalesce(attribute(@from_feature, 'name'), '-')) ||\n' \\nFrom Feature ID ' || to_string(coalesce(@from_feature_id, '-')) ||\n' \\n' ||\n' \\nTo Feature ' || to_string(coalesce(attribute(@to_feature, 'name'), '-')) ||\n' \\nTo Feature ID ' || to_string(coalesce(@to_feature_id, '-')) ||\n' \\n' ||\n' \\nTotal Hover Frames ' || to_string(coalesce(@hover_frames, 0)) ||\n' \\nCurrent Hover Frame ' || to_string(coalesce(@current_hover_frame, 0)) ||\n' \\nTotal Travel Frames ' || to_string(coalesce(@travel_frames, 0)) ||\n' \\nCurrent Travel Frame ' || to_string(coalesce(@current_travel_frame, 0)) ||\n' \\nTotal Frame Count ' || to_string(coalesce(@total_frame_count, 0)) ||\n' \\nFrame Number ' || to_string(coalesce(@frame_number, 0)) ||\n' \\nFrame Rate ' || to_string(coalesce(@frame_rate, 0)) ||\n' \\nwith Current Animation Action: ' || @current_animation_action ||\n' \\nTo Direction ' || coalesce(format_number(degrees(azimuth( geometry(@hover_feature), geometry(@previous_feature) ) ) ), 0) || \n' \\nFrom Direction ' || coalesce(format_number(degrees( azimuth( geometry(@hover_feature), geometry(@next_feature) ) ) ), 0)\n%]\n\n\n
Example output:
"},{"location":"user/manual/snippets/#variable-size-of-labels","title":"Variable size of labels","text":"Variably changing the size on a label as we approach it in the animation:
```40 * ((@frame_number % @hover_frames) / @hover_frames)
\n## Calculating the angle between points\n\nYou can calculate the angle between the hover point and the previous point like this:\n\n```python\ncoalesce(\n format_number(\n degrees( \n azimuth( \n geometry(@hover_feature), \n geometry(@previous_feature) \n )\n )\n ), 0)\n
"},{"location":"user/manual/snippets/#rotation","title":"Rotation","text":"You can set the angle of rotation for a symbol using this expression:
Using this technique you can also create an animation effect showing the source direction of travel and the new destination.
scale_linear (\n @current_hover_frame,\n 0,\n @hover_frames,\n degrees( \n azimuth( \n geometry(@hover_feature), \n geometry(@previous_feature) \n )\n ),\n degrees( \n azimuth( \n geometry(@hover_feature), \n geometry(@next_feature) \n )\n )\n)\n
Will produce something like this:
"},{"location":"user/manual/snippets/#flying-points-cluster","title":"Flying points cluster","text":"Here is an example where we animate all the points in a cluster that are not the hover point. We use an easing function to make the animation have an interesting circular motion.
-- Taken from https://spicyyoghurt.com/tools/easing-functions\n-- t = Time - Amount of time that has passed since the beginning of the animation. Usually starts at 0 and is slowly increased using a game loop or other update function.\n-- b = Beginning value - The starting point of the animation. Usually it's a static value, you can start at 0 for example.\n-- c = Change in value - The amount of change needed to go from starting point to end point. It's also usually a static value.\n-- d = Duration - Amount of time the animation will take. Usually a static value aswell.\n-- Sinusoidal\n-- -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n\n-- Use with the animation in static mode\nif(@hover_feature_id != $id,\narray(\n (-@hover_frames / 2) * (cos( (pi() * @frame_number / @hover_frames ) - 1)) ,\n (-@hover_frames / 2) * (sin( (pi() * @frame_number / @hover_frames ) - 1)) \n),\narray (0,0))\n\n
This function should be applied to the offset X,Y property of the symbol.
"},{"location":"user/manual/under_the_hood/","title":"What is the Workbench doing?","text":"What does the workbench do?
The workbench creates animations from QGIS by generating multiple static frames (images) and then combining those frames into an animation. The user tells QGIS how the frames should change from one to the other. In QGIS 3.26
and later the animated markers allow markers to be animated without the use of the expressions system. \u00a0
How do the animated markers work?
In the code snippet below, the user tells QGIS that as the frame count increments by one the Raster Image Marker
should change to the next image in the sequence.
py @project_home || '/fish/fish_00' || lpad(to_string( @frame_number % 32), 2, '0') || '.png'
The user specifies the path of the image (@project_home/fish/fish_00
). Then the lpad(to_string( @frame_number % 32), 2, '0')
tells QGIS to convert the frame number to a string and then modulus the number of frames by the number of animation frames (32
) (i.e. QGIS divides the number of frames by 32 and then repeats the sequence when the remainder is zero). The 2
and '0'
in the snippet tell QGIS to pad the /fish/fish_00
with two zeroes at the end. Finally the '.png'
tells QGIS the type of file to finish off the path. \u00a0
Frame Output location on Windows
For users on a Windows machine who are interested in seeing the frames before they are combined into an animation (GIF or movie) you can find them by going to \"C:\\Users\\Username\\AppData\\Local\\Temp\\animation_workbench-0000000000.png\". Bear in mind that AppData is a hidden file, so it's preferable to not make changes unless explicitly told otherwise. \u00a0
Frame Output on Linux
The frames should be in your /tmp directory.
The animation workbench exposes or modifies a number of different QGIS Expression variables that you can use to achieve different dynamic rendering effects.
"},{"location":"user/manual/variables/#common-variables","title":"Common variables","text":"These variables will always be available, regardless of the animation mode
Variable Notes frame_number Frame number within the current dwell or pan range. frame_rate Number of frames per second that the video will be rendered at. total_frame_count Total number of frames for the whole animation across all features."},{"location":"user/manual/variables/#fixed-extent-mode-variables-with-layer","title":"Fixed extent mode variables (with layer)","text":"These variables are available when in the fixed extent animation mode when a vector layer has been set
Variable Notes hover_feature The feature we are currently hovering over hover_feature_id Feature ID for the feature we a current hovering over previous_feature The previously visited feature (or NULL if there isn't one) previous_feature_id Feature ID for the previously visited feature (or NULL if there isn't one) next_feature The next feature to visit after the current one (or NULL if there isn't one) next_feature_id Feature ID for the next feature to visit after the current one (or NULL if there isn't one) current_hover_frame The frame number for the current feature (i.e. how many frames we have hovered at the current feature) hover_frames Number of frames we will hover at the current feature for current_animation_action Always \"Hovering\""},{"location":"user/manual/variables/#planarsphere-modes","title":"Planar/Sphere modes","text":"These variables are available in the Planar or Sphere mode.
Variable Notes current_animation_action Either \"Hovering\" or \"Travelling\""},{"location":"user/manual/variables/#when-hovering","title":"When hovering","text":"These variables are available in planar or sphere mode, when the animation is currently hovering over a feature
Variable Notes hover_feature The feature we are currently hovering over hover_feature_id The feature ID for the feature we are currently hovering over previous_feature The previously visited feature (or NULL if there isn't one) previous_feature_id Feature ID for the previously visited feature (or NULL if there isn't one) next_feature The next feature to visit after the current one (or NULL if there isn't one) next_feature_id Feature ID for the next feature to visit after the current one (or NULL if there isn't one) current_hover_frame The frame number for the current feature (i.e. how many frames we have hovered at the current feature) hover_frames Number of frames we will hover at the current feature for"},{"location":"user/manual/variables/#when-travelling","title":"When travelling","text":"These variables are available in planar or sphere mode, when the animation is currently travelling between two features
Variable Notes from_feature The feature we are travelling away from from_feature_id The feature ID for the feature we are travelling away from to_feature The feature we are heading toward to_feature_id The feature ID for the feature we are heading toward current_travel_frame The frame number for the current travel operation travel_frames Number of frames we will travel between the current features"},{"location":"user/manual/variables/#example-expressions","title":"Example expressions","text":"Visit the snippets section of our documentation for example expressions.
"},{"location":"user/manual/workbench_ui/","title":"The Workbench User Interface","text":""},{"location":"user/manual/workbench_ui/#animation-plan","title":"Animation Plan","text":"1
): These determine the behaviour and type of animationSphere
: The coordinate reference system (CRS) will be manipulated to create a spinning globe effect. Like Google Earth might do, but with your own data and cartography.Planar
: The coordinate reference system (CRS) will not be altered, but the camera will pan and zoom to each point. It lets you move from feature to feature on a flat map, pausing at each if you want to.Fixed extent
: The frame of reference stays the same and you can animate the symbology within that scene.
Animation Layer (2
):
Dropdown menu
: This allows you to select which map layer you want the animation to follow.Loop from final feature back to first feature
: allows for a seamlessly looping output GIF or movie(MP4).
Zoom Range (3
): The scale range that the animation should move through.
Maximum (inclusive): The scale (zoom level) used when we arrive at each point, i.e. the most \"zoomed in\".
Data defined settings (4
)
Scale
Animation Frames (5
)
6
):Can be set as a rectangular extent using the Draw on Canvas
feature.
Pan and Zoom Easings (7
)
Zoom Easing (Z): The pan easing will determine the motion characteristics of the camera on the Z axis as it flies across the scene (i.e. how the camera zooms in and out of the points)
Frame previews (8
): A preview of what each frame of the animation will look like. A user can decide which Frame
to view.
Edit the intro section of the generated movie here.
1
): Add images or moviesRemove Media (Minus sign) (2
): Remove images or movies
Duration (3
): For images, you can set a duration for each image (in seconds).
Preview Frame (4
): This shows what the media will look like.
Details: Provides details about where the media is stored on your computer.
Edit the outro section of the generated movie here.
1
): Add images or moviesRemove Media (Minus sign) (2
): Remove images or movies
Duration (3
): For images, you can set a duration for each image (in seconds).
Preview Frame (4
): This shows what the media will look like.
Details: Provides details about where the media is stored on your computer.
1
): Add sound files (.mp3 or .wav) to play during the generated movie.Remove Media (Minus sign) (2
): Remove sound files (.mp3 or .wav)
Duration (3
): The cumulative length of your soundtracks should be as long, or longer, than your movie, including the intro/outro sections. If the soundtrack is longer than the movie it will be truncated (shortened) when the movie ends.
Details: Provides details about where the media is stored on your computer.
1
): This will not erase cached images on disk and will resume processing from the last cached image.2
): For this export to work, you need to have the ImageMagick 'convert' application available on your system.3
): For this option to work, you need to have the 'ffmpeg' application on your system.4
): Allows a user to specify one of four image resolutions for the output animation. The numbers in brackets for the first three options represent the width and height of the output in pixels (i.e. width x height), and the fourth option matches the output's size to the size of the Map Canvas
on the screen.5
): This lets a user select the location where the output will be stored.1
): A preview of what each frame of the animation will look like. It changes automatically as the workbench runs.2
): This provides a detailed look at what is happening while the workbench runs.3
): A detailed list of what steps the workbench is doing (a record of processing)4
): A visual representation of the workbench's progression as a percentage.Run
: Starts the process of getting an output from the workbench. It is greyed out until a user provides a destination for the output file.Close
: Closes the workbench.Cancel
: Ends the workbench processing at whatever point it has reached when the button is pressed.Help
: Opens a link to the Animation Workbench documentation.Content needed
"},{"location":"user/quickstart/configure/","title":"Initial Configuration","text":"There is nothing really to configure! We do provide a few options in the configuration dialog, but most users should not need to change them.
You can access the QGIS Animation Workbench plugin options by opening the standard QGIS Setting dialog and clicking on the animation workbench tab.
Settings \u2794 Options
1
)Currently there are just three configuration options:
2
): This is the number of concurrent tasks that will be used to render animations. The default is 1.3
): This is a developer option that enables the developers to see an icon in the toolbar which will start the debug remote server.4
): This will add extra messages in the logging pane to help you understand what is going on during the rendering process.In this section we explain how to install the plugin.
"},{"location":"user/quickstart/install/#install-from-plugin-manager","title":"Install from plugin manager","text":"To access the QGIS Plugin Manager you simply need to select Plugins
\u27a1 Manage and Install Plugins...
(1
) in the Menu Toolbar.
Once the QGIS Plugin Manager loads, you need to navigate to the All
(2
) tab and type \"animation\" into the search bar (3
). Select QGIS Animation Workbench from the list of available plugins and then select Install Plugin
(4
).
Once the Animation Workbench is installed, you can access it by clicking on the Animation Workbench
icon (5
) in the Plugin Toolbar.
Note if you are on Ubuntu, you may need to install the Qt5 multimedia libraries.
sudo apt install PyQt5.QtMultimedia\n
"},{"location":"user/quickstart/install/#manual-install-from-github-tagged-release","title":"Manual install from GitHub (tagged release)","text":"To install, visit the Github Repository, click on the Actions
tab, and click on the Make QGIS Plugin Zip For Manual Installs
workflow (the bottom one).
Click on the most recent workflow run (the top one).
Scroll down on the on the page.
And click on animation_workbench
to download the most recent build of the plugin
Download the animation_workbench.zip
file and open it in QGIS using the plugin manager as described below.
Note if you are on Ubuntu, you may need to install the Qt5 multimedia libraries.
sudo apt install PyQt5.QtMultimedia\n
"},{"location":"user/quickstart/using/","title":"Using the Animation Workbench","text":"In this section, we describe the general workflow for using the Animation Workbench.
"},{"location":"user/quickstart/using/#process-overview","title":"Process Overview","text":"1. Create a QGIS Project \u00a0 Open QGIS and click on Project
\u2794 New
Add new layers to your project
A simple way to add a base layer is to type \"world\" (1
) into the coordinate textbox
Style the layers you've added to make your project look a bit better. Select the layer (2
) you want to style and in the Layer Styling toolbar (3
), style the layer to look appealing to you.
2. Identify features that will be animated. \u00a0
Pick the layer (or layers) that you want to animate. Then either find or create the animation for the layer. Make sure you have all the correct attribution for any animations you use. Below is an example of an animation split into its frames.
3. Use the QGIS Expressions system with the variables introduced by the Animation Workbench to define behaviours of your symbols during flight and hover modes of your animation. \u00a0
Select the layer you want to animate and open the Layer Styling toolbar.
If you are using QGIS 3.26
you can simply use the new animated point symbol, or if you're using an older version of QGIS 3.x
follow the instructions below.
The layer should be a Raster Image Marker
. Once you have selected the image you want to use click on the QGIS Expressions dropdown menu (4
) and click on Edit
(5
).
Use the Code Snippets Section for more in depth help. The example below works with the bird animation from earlier
@project_home\n ||\n '/bird/bird_00'\n || \n lpad(to_string(@frame_number % 9), 2, '0')\n || \n '.png'\n
1. Open the Animation Workbench and configure your animation, choosing between the different modes and options. \u00a0
Open the Workbench by clicking the Animation Workbench
(6
) icon in the Plugin Toolbar.
Configure the settings for your animation. The screenshot below is configured for the example presented in this section. The Animation Layer is selected as route (7
) because that is the path the animation will fly along, the Zoom Range (8
) was selected from the Map Canvas Extent, and the Frame rate per second (9
) was set to 9 to match the bird animation.
Set your desired Output Options
(10
) Select a location for your output (11
).
Refer to the Workbench User Interface Section for more information about what various settings and buttons accomplish.
2. Render your animation! \u00a0 Click Run
and render your output. The output below is the output from the example.
This tutorial introduces the concept of moving a point along a line within your animated +map.
+1. Download and extract the Required Tutorial Zip Folder +
+2. Open the tutorial_1.qgz project file that is in the folder. When you first open it you +you see something like this:
++
+3. Select the premade line
layer (1
), and click on the Add Symbol Layer
+(green plus symbol) button (2
) to it.
Change the new Symbol Layer
(3
) type to marker line and then style it (4
) so that it is more visible.
4. Change the Symbol Layer's
settings so that the point is only on the first vertex
(5
) and
+and not at equidistant intervals.
Change the offset along the line to be Percentage
(6
).
Click the Dropdown Menu
(7
) ➔Edit...
(8
) and then add the following code snippet
-- Point Along Line Code Snippet
+ (@current_hover_frame/@hover_frames) * 100
+
+
+The snippet tells QGIS how far along the line (as a percentage of the line length) to +render the point in each frame.
+5. Open the Workbench and select Fixed Extent
(9
).
Click on Map Canvas Extent
(10
) and set the the Frames
to 300 (11
) (for a 10 second
+output at 30 frames per second).
6. Skip over the Intro
, Outro
, and Soundtrack
tabs. In the Output
tab, set the output
+format (12
) and resolution (13
), and set the output location's path (14
).
7. Click Run
and render your output.
After this tutorial you should have a better idea of how to make a point move along a line. +An expansion to this example would be to make the moving point a dynamically changing +marker (like the markers in tutorial 1). Go have fun!
+This tutorial aims to show you the basics of creating, and animating, a static layer to use +with the Animation Workbench. There are three pre-made layers to allow the main focus of +the tutorial to be on the Animation Workbench and not on QGIS as a whole.
+1. Download and extract the Required Tutorial Zip Folder +
+2. Open the tutorial_2.qgz project file that is in the folder. +
+3. Set the CRS of your project to WGS84/UTM zone 35S (EPSG: 32735).
++
+4. In the Browser
, expand the tutorial_2.gpkg and add the three pre-made layers
+(VaalDam, SouthAfrica, and route) (A
) to your project.
+
+5. In the Layers
Panel, arrange the layers in the following order: route
, VaalDam
,
+SouthAfrica
. Then right-click on the VaalDam
layer and Zoom to Layer(s)
(B
)
Style the three layers to your preferred style. +
+6. Now create a new layer in the tutorial_2.gpkg by clicking Layer
➔Create Layer
➔
+New GeoPackage Layer...
(C
).
+
+Click on the Ellipsis
(D
), navigate to and select the tutorial_2.gpkg, and
+click Save
. Change the Table name to fish (E
), set the Geometry type as Point (F
), and
+change the CRS to match the Project CRS (G
).
Click on OK
and then click Add New Layer
on the window that pops up.
+
7. Select the fish
layer and then click on Toggle Editing
➔Add Point Feature
(H
).
Add a few points wherever you feel they should go (Hint: This is a fish layer so adding +them above the dam layer would be best). Don't worry about naming the points, just add +them.
+ +Save your changes by clicking on Save Layer Edits
just next to the Toggle Editing
+button. Then stop editing the layer.
+
8. Repeat steps 6. and 7. but change the Table name to bird and add the points over +the land areas.
++
+9. Select the fish
layer and then in the Layer styling
toolbar (I
) change the
+Symbol layer type
to Raster Image Marker
(J
).
Select the marker image by clicking the Dropdown menu
➔Select File...
(K
)
+and then choosing fish
➔fish_0000.png
.
Click Open
+
10. Change the marker's Size Unit to Meters at Scale
(L
)
and set the Width and Height to 1000. +
+11. Repeat Steps 9. and 10. with the bird
layer but instead choosing bird
➔bird_0000.png
+and setting the Width and Height to 3000.
+
++In
+QGIS 3.26
, or later, theSymbol layer type
can simply be selected as +Animated Marker
and Step 12. can be skipped.
12. To animate the fish
and bird
layers using the QGIS Expressions
system click the
+Dropdown Menu
➔Edit...
(M
).
For the fish
layer use the following expression:
@project_home
+ ||
+ '/fish/fish_00'
+ ||
+ lpad(to_string( @frame_number % 32), 2, '0')
+ ||
+ '.png'
+
+And for the bird
layer use:
@project_home
+ ||
+ '/bird/bird_00'
+ ||
+ lpad(to_string(@frame_number % 9), 2, '0')
+ ||
+ '.png'
+
+++Refer to the What is the Workbench doing? section for an explanation + about what the above code snippet is doing.
+
13. Open the Animation Workbench (refer to the Using the Animation Workbench section +if you are unsure how to open the Workbench).
+In the Animation Plan
tab set:
Render Mode
to Planar
(N
),Animation Layer
to route
(O
) using the dropdown menu,Zoom Range
(P
) to 1:270000 for the Minimum and 1:135000 for the Maximum,Frame rate per second
to 9 fps (Q
),Travel duration
to 4,00 s (R
),Feature hover duration
to 2,00 s (S
)Enable both the Pan
and Zoom
easings and set them to linear.
14. Skip past the Intro
, Outro
, and Soundtrack
tabs to the Output
tab. Set the
+Output Format
as Animated Gif
(T
) and the Output Resolution
to
+720p (1280x720)
(U
). The Output Resolution
can be set as any of the three
+choices but was set at 720
for this tutorial for the sake of speed. Set the output
+location to one you can find easily (V
)
+
+15. Click Run
and watch what the Workbench is doing in the Progress
tab. Once the
+Workbench is finished running, you should end up with an output similar to this:
After this tutorial you should have a better understanding of how to create a point layer
+in your project and then to change the Single Symbol
markers into stationary animated
+markers. A key focus is the idea that you can tell versions of QGIS
before 3.26
to dynamically
+change markers using short code snippets. Versions of QGIS
post 3.26
allow a user to
+simply use the Animated Marker
feature without editing an expression.
This tutorial aims to show you how add a flying point animation to points on your map using +built-in QGIS functionalities (The geometry generator line) and introduced variables from +the workbench.
+1. Download and extract the Required Tutorial Zip Folder +
+2. Open the tutorial_3.qgz project file. +When you first open the project file you should be greeted with something like this:
++
+3. Create a new point layer in a new geopackage by clicking Layer
➔Create Layer
➔
+ New GeoPackage Layer...
. Click on the Ellipsis
(three dots) next to the Database
+textbox and navigate to the folder that the tutorial_3.qgz file is located in. Type the File
+name "tutorial_3" (1
) and ensure the file will be saved as a GeoPackage
(2
) and click
+Save
(3
).
+
+Change the Table name to flying_points (4
), set the Geometry type as Point (5
) and
+change the CRS to match the Project CRS (6
).
Click OK
(7
)
+
4. Click on Toggle Editing
➔Add Point Feature
(8
).
+
+And randomly add points to your map. Depending on your computer's capabilites, you +can add more, or fewer, points than the example below.
++
+Save your Layer Edits and toggle off the Editing tool. +
+5. Style the points layer.
+Select the flying_points
(9
) layer and in the Layer Styling
toolbar click on the
+Add Symbol Layer
(green plus symbol) button (10
).
+
+Select the top Simple Marker
(11
) and change its Symbol layer type to
+Geometry Generator
(12
)
and then set the Geometry type to LineString / MultiLineString
(13
).
+
+Change the line's Symbol layer type to Marker Line
(14
).
+
+Add a second Simple marker
to the marker line so that you end up with something like
+this:
+
+Style the various Simple Markers
to your preferred look.
+
6. Select the Geometry Generator
symbol layer (15
) and add this code to it:
wave_randomized(
+ make_line(
+ $geometry, geometry(@hover_feature)),
+ 100, 1000, 1000, 10000, 1)
+
++
+++More information about what changing the numbers will affect can be found in the +QGIS expressions editor. +
+
7. A few options need to be changed in the Marker Line
symbol layer (16
): The Marker
+placement needs to be set to On first vertex
(17
) and, the Offset along line needs to be
+changed to Percentage
(18
). The click the Dropdown menu
next to Offset along line and
+select Edit...
(19
).
+
+In the Expression String Builder
add the following code snippet:
100 - to_int((@current_hover_frame / @hover_frames) * 100 )
+
++
+Click OK
+
8. Select the first Simple Marker
symbol layer (20
) in the Marker Line
symbol layer. Scroll
+down to Offset and click on the Dropdown Menu
➔Edit..
(21
).
+
+In the Expression String Builder
add the following code snippet:
-- Taken from https://spicyyoghurt.com/tools/easing-functions
+ -- t = Time - Amount of time that has passed since the beginning of the animation. Usually starts at 0 and is slowly increased using a game loop or other update function.
+ -- b = Beginning value - The starting point of the animation. Usually it's a static value, you can start at 0 for example.
+ -- c = Change in value - The amount of change needed to go from starting point to end point. It's also usually a static value.
+ -- d = Duration - Amount of time the animation will take. Usually a static value aswell.
+ -- Sinusoidal
+ -- -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
+
+ -- Use with the animation in static mode
+ if(@hover_feature_id != $id,
+ array(
+ (-@hover_frames / 2) * (cos( (pi() * @frame_number / @hover_frames ) - 1)) ,
+ (-@hover_frames / 2) * (sin( (pi() * @frame_number / @hover_frames ) - 1))
+ ),
+ array (0,0))
+
++
+Click OK
+
9. Open the Animation Workbench
(22
)
+
+10. Set up the Animation Plan
with:
Render Mode
to Planar
(23
),Animation Layer
to flying_points
(24
) using the dropdown menu,Zoom Range
(25
) to 1:22000000 for the Minimum and 1:11000000 for the
+ Maximum,Frame rate per second
to 9 fps (26
),Travel duration
to 2,00 s (27
),Feature hover duration
to 2,00 s (28
),Zoom Easing
as InCirc (29
)+
+++With a decently specced computer you can up the fps and get the points to fly +faster in your output. +
+
11. Add license-free media to the Intro
, Outro
, and Soundtrack
.
++Make sure your
+Soundtrack
is as long as, or longer than, your final animation will be +(including theIntro
,Animation
, andOutro
).
+
12. Set the Output Format
as Movie (MP4)
(30
) and the Output Resolution
to
+1080 (1920x1080)
(31
). The Output Resolution
can be set as any of the three
+choices but was set at 1080
for this tutorial for the sake of speed. Set the output
+location (32
) to one you can easily locate.
+
+13. Click Run
and get an output. The GIF below is the visual output of the tutorial if you
+followed step-by-step and set the parameters to exactly what was stated.
+
+The link to a more complex output (with an Intro
, an Outro
, and a Soundtrack
) can
+be found here
+
After this tutorial you should have a better idea of how you can use a mixture of built-in +QGIS functionalites and the workbench's introduced variables to generate interesting outputs.
+Given a global point layer and countries layer like this:
+ +You can create a nice spinning globe effect like this:
+ +I set up the animation workbench like this:
+ +For the above animated GIF, I compressed it using imagemagick like this:
+convert globe.gif -coalesce -resize 700x525 -fuzz 2% +dither -layers Optimize +map globe_small.gif
+
+This is a handy technique if you want to generate small file size animations.
+For the points I made a red marker using a quarter circle that spins around the points like this:
+ +The rotation field expression is this:
+if (@id = @hover_feature_id,
+ 0-((1440 * (@current_hover_frame/@hover_frames)) % 360),
+ 0)
+
+This will spin around 4 times during the hover cycle.
+For the ocean (AOI in the layers list), I generated a grid of 1 degree cells covering the earth. You need to do it as smaller polygons instead of one large polygon because QGIS will run into issues reprojecting a single polygon whose edges lie on the date line.
+Here is how the final video came out:
+ + + + + + + +This tutorial introduces the concept of moving a point along a line within your animated +map.
+1. Download and extract the Required Tutorial Zip Folder +
+2. Open the tutorial_1.qgz project file that is in the folder. When you first open it you +you see something like this:
++
+3. Select the premade line
layer (1
), and click on the Add Symbol Layer
+(green plus symbol) button (2
) to it.
Change the new Symbol Layer
(3
) type to marker line and then style it (4
) so that it is more visible.
4. Change the Symbol Layer's
settings so that the point is only on the first vertex
(5
) and
+and not at equidistant intervals.
Change the offset along the line to be Percentage
(6
).
Click the Dropdown Menu
(7
) ➔Edit...
(8
) and then add the following code snippet
-- Point Along Line Code Snippet
+ (@current_hover_frame/@hover_frames) * 100
+
+
+The snippet tells QGIS how far along the line (as a percentage of the line length) to +render the point in each frame.
+5. Open the Workbench and select Fixed Extent
(9
).
Click on Map Canvas Extent
(10
) and set the the Frames
to 300 (11
) (for a 10 second
+output at 30 frames per second).
6. Skip over the Intro
, Outro
, and Soundtrack
tabs. In the Output
tab, set the output
+format (12
) and resolution (13
), and set the output location's path (14
).
7. Click Run
and render your output.
After this tutorial you should have a better idea of how to make a point move along a line. +An expansion to this example would be to make the moving point a dynamically changing +marker (like the markers in tutorial 1). Go have fun!
+ + + + + + +This tutorial aims to show you the basics of creating, and animating, a static layer to use +with the Animation Workbench. There are three pre-made layers to allow the main focus of +the tutorial to be on the Animation Workbench and not on QGIS as a whole.
+1. Download and extract the Required Tutorial Zip Folder +
+2. Open the tutorial_2.qgz project file that is in the folder. +
+3. Set the CRS of your project to WGS84/UTM zone 35S (EPSG: 32735).
++
+4. In the Browser
, expand the tutorial_2.gpkg and add the three pre-made layers
+(VaalDam, SouthAfrica, and route) (A
) to your project.
+
+5. In the Layers
Panel, arrange the layers in the following order: route
, VaalDam
,
+SouthAfrica
. Then right-click on the VaalDam
layer and Zoom to Layer(s)
(B
)
Style the three layers to your preferred style. +
+6. Now create a new layer in the tutorial_2.gpkg by clicking Layer
➔Create Layer
➔
+New GeoPackage Layer...
(C
).
+
+Click on the Ellipsis
(D
), navigate to and select the tutorial_2.gpkg, and
+click Save
. Change the Table name to fish (E
), set the Geometry type as Point (F
), and
+change the CRS to match the Project CRS (G
).
Click on OK
and then click Add New Layer
on the window that pops up.
+
7. Select the fish
layer and then click on Toggle Editing
➔Add Point Feature
(H
).
Add a few points wherever you feel they should go (Hint: This is a fish layer so adding +them above the dam layer would be best). Don't worry about naming the points, just add +them.
+ +Save your changes by clicking on Save Layer Edits
just next to the Toggle Editing
+button. Then stop editing the layer.
+
8. Repeat steps 6. and 7. but change the Table name to bird and add the points over +the land areas.
++
+9. Select the fish
layer and then in the Layer styling
toolbar (I
) change the
+Symbol layer type
to Raster Image Marker
(J
).
Select the marker image by clicking the Dropdown menu
➔Select File...
(K
)
+and then choosing fish
➔fish_0000.png
.
Click Open
+
10. Change the marker's Size Unit to Meters at Scale
(L
)
and set the Width and Height to 1000. +
+11. Repeat Steps 9. and 10. with the bird
layer but instead choosing bird
➔bird_0000.png
+and setting the Width and Height to 3000.
+
++In
+QGIS 3.26
, or later, theSymbol layer type
can simply be selected as +Animated Marker
and Step 12. can be skipped.
12. To animate the fish
and bird
layers using the QGIS Expressions
system click the
+Dropdown Menu
➔Edit...
(M
).
For the fish
layer use the following expression:
@project_home
+ ||
+ '/fish/fish_00'
+ ||
+ lpad(to_string( @frame_number % 32), 2, '0')
+ ||
+ '.png'
+
+And for the bird
layer use:
@project_home
+ ||
+ '/bird/bird_00'
+ ||
+ lpad(to_string(@frame_number % 9), 2, '0')
+ ||
+ '.png'
+
+++Refer to the What is the Workbench doing? section for an explanation + about what the above code snippet is doing.
+
13. Open the Animation Workbench (refer to the Using the Animation Workbench section +if you are unsure how to open the Workbench).
+In the Animation Plan
tab set:
Render Mode
to Planar
(N
),Animation Layer
to route
(O
) using the dropdown menu,Zoom Range
(P
) to 1:270000 for the Minimum and 1:135000 for the Maximum,Frame rate per second
to 9 fps (Q
),Travel duration
to 4,00 s (R
),Feature hover duration
to 2,00 s (S
)Enable both the Pan
and Zoom
easings and set them to linear.
14. Skip past the Intro
, Outro
, and Soundtrack
tabs to the Output
tab. Set the
+Output Format
as Animated Gif
(T
) and the Output Resolution
to
+720p (1280x720)
(U
). The Output Resolution
can be set as any of the three
+choices but was set at 720
for this tutorial for the sake of speed. Set the output
+location to one you can find easily (V
)
+
+15. Click Run
and watch what the Workbench is doing in the Progress
tab. Once the
+Workbench is finished running, you should end up with an output similar to this:
After this tutorial you should have a better understanding of how to create a point layer
+in your project and then to change the Single Symbol
markers into stationary animated
+markers. A key focus is the idea that you can tell versions of QGIS
before 3.26
to dynamically
+change markers using short code snippets. Versions of QGIS
post 3.26
allow a user to
+simply use the Animated Marker
feature without editing an expression.
This tutorial aims to show you how add a flying point animation to points on your map using +built-in QGIS functionalities (The geometry generator line) and introduced variables from +the workbench.
+1. Download and extract the Required Tutorial Zip Folder +
+2. Open the tutorial_3.qgz project file. +When you first open the project file you should be greeted with something like this:
++
+3. Create a new point layer in a new geopackage by clicking Layer
➔Create Layer
➔
+ New GeoPackage Layer...
. Click on the Ellipsis
(three dots) next to the Database
+textbox and navigate to the folder that the tutorial_3.qgz file is located in. Type the File
+name "tutorial_3" (1
) and ensure the file will be saved as a GeoPackage
(2
) and click
+Save
(3
).
+
+Change the Table name to flying_points (4
), set the Geometry type as Point (5
) and
+change the CRS to match the Project CRS (6
).
Click OK
(7
)
+
4. Click on Toggle Editing
➔Add Point Feature
(8
).
+
+And randomly add points to your map. Depending on your computer's capabilites, you +can add more, or fewer, points than the example below.
++
+Save your Layer Edits and toggle off the Editing tool. +
+5. Style the points layer.
+Select the flying_points
(9
) layer and in the Layer Styling
toolbar click on the
+Add Symbol Layer
(green plus symbol) button (10
).
+
+Select the top Simple Marker
(11
) and change its Symbol layer type to
+Geometry Generator
(12
)
and then set the Geometry type to LineString / MultiLineString
(13
).
+
+Change the line's Symbol layer type to Marker Line
(14
).
+
+Add a second Simple marker
to the marker line so that you end up with something like
+this:
+
+Style the various Simple Markers
to your preferred look.
+
6. Select the Geometry Generator
symbol layer (15
) and add this code to it:
wave_randomized(
+ make_line(
+ $geometry, geometry(@hover_feature)),
+ 100, 1000, 1000, 10000, 1)
+
++
+++More information about what changing the numbers will affect can be found in the +QGIS expressions editor. +
+
7. A few options need to be changed in the Marker Line
symbol layer (16
): The Marker
+placement needs to be set to On first vertex
(17
) and, the Offset along line needs to be
+changed to Percentage
(18
). The click the Dropdown menu
next to Offset along line and
+select Edit...
(19
).
+
+In the Expression String Builder
add the following code snippet:
100 - to_int((@current_hover_frame / @hover_frames) * 100 )
+
++
+Click OK
+
8. Select the first Simple Marker
symbol layer (20
) in the Marker Line
symbol layer. Scroll
+down to Offset and click on the Dropdown Menu
➔Edit..
(21
).
+
+In the Expression String Builder
add the following code snippet:
-- Taken from https://spicyyoghurt.com/tools/easing-functions
+ -- t = Time - Amount of time that has passed since the beginning of the animation. Usually starts at 0 and is slowly increased using a game loop or other update function.
+ -- b = Beginning value - The starting point of the animation. Usually it's a static value, you can start at 0 for example.
+ -- c = Change in value - The amount of change needed to go from starting point to end point. It's also usually a static value.
+ -- d = Duration - Amount of time the animation will take. Usually a static value aswell.
+ -- Sinusoidal
+ -- -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
+
+ -- Use with the animation in static mode
+ if(@hover_feature_id != $id,
+ array(
+ (-@hover_frames / 2) * (cos( (pi() * @frame_number / @hover_frames ) - 1)) ,
+ (-@hover_frames / 2) * (sin( (pi() * @frame_number / @hover_frames ) - 1))
+ ),
+ array (0,0))
+
++
+Click OK
+
9. Open the Animation Workbench
(22
)
+
+10. Set up the Animation Plan
with:
Render Mode
to Planar
(23
),Animation Layer
to flying_points
(24
) using the dropdown menu,Zoom Range
(25
) to 1:22000000 for the Minimum and 1:11000000 for the
+ Maximum,Frame rate per second
to 9 fps (26
),Travel duration
to 2,00 s (27
),Feature hover duration
to 2,00 s (28
),Zoom Easing
as InCirc (29
)+
+++With a decently specced computer you can up the fps and get the points to fly +faster in your output. +
+
11. Add license-free media to the Intro
, Outro
, and Soundtrack
.
++Make sure your
+Soundtrack
is as long as, or longer than, your final animation will be +(including theIntro
,Animation
, andOutro
).
+
12. Set the Output Format
as Movie (MP4)
(30
) and the Output Resolution
to
+1080 (1920x1080)
(31
). The Output Resolution
can be set as any of the three
+choices but was set at 1080
for this tutorial for the sake of speed. Set the output
+location (32
) to one you can easily locate.
+
+13. Click Run
and get an output. The GIF below is the visual output of the tutorial if you
+followed step-by-step and set the parameters to exactly what was stated.
+
+The link to a more complex output (with an Intro
, an Outro
, and a Soundtrack
) can
+be found here
+
After this tutorial you should have a better idea of how you can use a mixture of built-in +QGIS functionalites and the workbench's introduced variables to generate interesting outputs.
+ + + + + + +Given a global point layer and countries layer like this:
+ +You can create a nice spinning globe effect like this:
+ +I set up the animation workbench like this:
+ +For the above animated GIF, I compressed it using imagemagick like this:
+convert globe.gif -coalesce -resize 700x525 -fuzz 2% +dither -layers Optimize +map globe_small.gif
+
+This is a handy technique if you want to generate small file size animations.
+For the points I made a red marker using a quarter circle that spins around the points like this:
+ +The rotation field expression is this:
+if (@id = @hover_feature_id,
+ 0-((1440 * (@current_hover_frame/@hover_frames)) % 360),
+ 0)
+
+This will spin around 4 times during the hover cycle.
+For the ocean (AOI in the layers list), I generated a grid of 1 degree cells covering the earth. You need to do it as smaller polygons instead of one large polygon because QGIS will run into issues reprojecting a single polygon whose edges lie on the date line.
+Here is how the final video came out:
+ + + + + + + +Given a global point layer and countries layer like this:
+ +You can create a nice planar map animation effect like this:
+ +In planar mode, we do not pan and zoom the map from feature to feature. Rather, the map zoom stays constant and the variables for
+are updated as we iterate over the features of your animation layer. In this +example project I duplicated the animation point layer twice. The first (lower) +copy is used to 'drive' the animation, whilst the second (upper) layer shows +only the feature currently being hovered over, with animation effects applied +to that feature.
+I set up the animation workbench like this:
+ +For the above animated GIF, I compressed it using imagemagick like this:
+convert globe.gif -coalesce -resize 700x525 -fuzz 2% +dither -layers Optimize +map globe_small.gif
+
+This is a handy technique if you want to generate small file size animations.
+Firstly for debugging, we use the following copyright label in View ⇒ +Decorations ⇒ Copyright Label. You can use the checkbox in the Copyright +configuration dialog to toggle this on and off. This will help you while +debugging / tweaking your animations. When you are ready to render your final +product, simply turn it off before rendering.
+[%
+' \nRotation:' || to_string( 0-((1440 * (@current_hover_frame/@hover_frames)) % 360)) ||
+'\nFeature Variables:' ||
+' \n------------------------' ||
+' \nPrevious Feature ' || to_string(coalesce(attribute(@previous_feature, 'name'), '-')) ||
+' \nPrevious Feature ID ' || to_string(coalesce(@previous_feature_id, '-')) ||
+' \n' ||
+' \nNext Feature ' || to_string(coalesce(attribute(@next_feature, 'name'), '-')) ||
+' \nNext Feature ID ' || to_string(coalesce(@next_feature_id, '-')) ||
+' \n' ||
+' \nHover Feature ' || to_string(coalesce(attribute(@hover_feature, 'name'), '-')) ||
+' \nHover Feature ID ' || to_string(coalesce(@hover_feature_id, '-')) ||
+' \n' ||
+' \nFrom Feature ' || to_string(coalesce(attribute(@from_feature, 'name'), '-')) ||
+' \nFrom Feature ID ' || to_string(coalesce(@from_feature_id, '-')) ||
+' \n' ||
+' \nTo Feature ' || to_string(coalesce(attribute(@to_feature, 'name'), '-')) ||
+' \nTo Feature ID ' || to_string(coalesce(@to_feature_id, '-')) ||
+' \n' ||
+' \nTotal Hover Frames ' || to_string(coalesce(@hover_frames, 0)) ||
+' \nCurrent Hover Frame ' || to_string(coalesce(@current_hover_frame, 0)) ||
+' \nTotal Travel Frames ' || to_string(coalesce(@travel_frames, 0)) ||
+' \nCurrent Travel Frame ' || to_string(coalesce(@current_travel_frame, 0)) ||
+' \nTotal Frame Count ' || to_string(coalesce(@total_frame_count, 0)) ||
+' \nFrame Number ' || to_string(coalesce(@frame_number, 0)) ||
+' \nFrame Rate ' || to_string(coalesce(@frame_rate, 0)) ||
+' \nwith Current Animation Action: ' || @current_animation_action ||
+' \nTo Direction ' || coalesce(format_number(degrees(azimuth( geometry(@hover_feature), geometry(@previous_feature) ) ) ), 0) ||
+' \nFrom Direction ' || coalesce(format_number(degrees( azimuth( geometry(@hover_feature), geometry(@next_feature) ) ) ), 0)%]
+
+For the points I made a red marker using a quarter circle that spins around the +points like this:
+ +The first line of the listing from the previous section gives you a hint about
+how we can vary the rotation of a symbol depending on how far through the
+animation sequence we are. With the addition of an if
clause, we can apply
+this rotation only to features that are being hovered over during the planar
+animation.
if (
+ @id = @hover_feature_id,
+ 0-((1440 * (@current_hover_frame/@hover_frames)) % 360),
+ 0)
+
+This if
clause has the effect of excluding calculation for any feature that is not the current hover feature.
This will spin around 4 times during the hover cycle. This is because four
+rotations are 4 x 360 = 1440
. We calculate the percentage of completion for
+the current hover frame (@current_hover_frame/@hover_frames
) and then
+multiply our rotation product by the current completion percentage. Lastly we
+calculate the modulus of this (% 360
) to compute how far along we are in
+the current rotation. More advanced users could substitute 1440 with a project
+variable so that it is easy to change the number of desired rotations in a
+single place.
The rotating symbol layer and the other symbol layers in our animation layer are
+similarly hidden if the feature being rendered is not the hover_feature_id
+using an expression like this:
if ( @id = @hover_feature_id, 10, 0)
+
+This has the effect of setting the symbol size to 0 if it is not the feature we +are focussing on.
+With the basic concepts of working with planar animations covered above, you can do other interesting things.
+In this example, we can generate a line using the Geometry Generator function in QGIS. The line will start from the previous point, extend through the current point and terminate and the next point.
+ +if (
+ $id = @hover_feature_id,
+ make_line(
+ geometry(@previous_feature),
+ geometry(@hover_feature),
+ geometry(@next_feature)
+ ),
+ $geometry)
+
+We wrap it in an if clause again so that the line is not rendered if the +current feature being rendered is not the same as the current animation +feature.
+There may be some edge cases where there is no previous or next feature. This +example does not try to deal with these cases but you could easily add some +logic that checks if each of the three components making up the line is null or +not.
+We can extend the above example by creating a curve rather than a line, for a +more natural looking connection between the hover feature and its previous and +following feature.
+ +if (
+ $id = @hover_feature_id,
+ smooth(
+ make_line(
+ geometry(@previous_feature),
+ geometry(@hover_feature),
+ geometry(@next_feature)
+ ),
+ iterations:=1,
+ offset:=0.2,
+ min_length:=-1,
+ max_angle:=180),
+ $geometry)
+
+If you increase the number of iterations, you can achieve a more and more +smoothed out line, at the expense of processing time.
+ +if (
+ $id = @hover_feature_id,
+ smooth(
+ make_line(
+ geometry(@previous_feature),
+ geometry(@hover_feature),
+ geometry(@next_feature)
+ ),
+ iterations:=5,
+ offset:=0.2,
+ min_length:=-1,
+ max_angle:=180),
+ $geometry)
+
+As a much more advanced example, you can extract a substring of the smoothed
+line that connects the previous, current and next features. Don't get put off
+by the with_variable
elements - they just allow us to re-use calculations
+in our expression.
First, let's start with extracting the first half of the smoothed line:
+ +if (
+ $id = @hover_feature_id,
+ with_variable(
+ 'smoothed_line',
+ smooth(
+ make_line(
+ geometry(@previous_feature),
+ geometry(@hover_feature),
+ geometry(@next_feature)
+ ),
+ iterations:=5,
+ offset:=0.2,
+ min_length:=-1,
+ max_angle:=180),
+ with_variable(
+ 'line_length',
+ length(@smoothed_line),
+ line_substring(@smoothed_line, 0, @line_length / 2 ))),
+ $geometry)
+
+If we follow the same approach as above, but vary the start and length of the +line clip, we can create some cool line animation effects.
+ +if (
+ $id = @hover_feature_id,
+ with_variable(
+ 'smoothed_line',
+ smooth(
+ make_line(
+ geometry(@previous_feature),
+ geometry(@hover_feature),
+ geometry(@next_feature)
+ ),
+ iterations:=5,
+ offset:=0.2,
+ min_length:=-1,
+ max_angle:=180),
+ with_variable(
+ 'line_length',
+ length(@smoothed_line),
+ line_substring(
+ @smoothed_line,
+ @line_length * (@current_hover_frame/@hover_frames),
+ @line_length ))),
+
+ $geometry)
+
+
+There are still a few details that would need to be taken care of to reach a +final solution - in particular taking care of datelines and the like. But here is +a little example of what we managed to make thus far (without any debugging +text).
+ + + + + + + +This is the homepage for all user related documentation.
+The user content is divided into three sections:
+As long as you can provide the proper attribution for an image you can use it in your project.
+If you open the standard QGIS settings dialog and select the Animation Workbench options +you can follow the advice with regards to lowering the number of threads allowed during +rendering to help you computer cope. Rendering shorter movies or GIFs (i.e. fewer frames) +will also help. Below is an example of running a job with 9000 frames at 60fps and 999 +frames per feature
+ +And the subsequent CPU load during processing:
+ +After processing:
+ +And here is the resulting video:
+ +Currently your filenames should not contain spaces or special characters
+.(, ), [, ], {, }, <, >, /, \, :, *, ?, |, ", &, etc.).
+
+This is planned but not yet implemented. Tim - check.
+This is a fun / hobby project, currently we want other contributors who also want to +have a fun experience with building this plugin and contribute in-kind efforts to the +project. Both Kartoza and North-Road +offer commercial development services but not for this plugin which is a intended to +provide an experimental, no-pressure space for us to work on something fun for QGIS.
+ + + + + + +Welcome to the QGIS Animation Workbench user manual. This section of the documentation describes the application and what the various components of each dialog do. The manual is intended to function as a reference for the application. For narrative / workflow based tutorials, you may prefer to work through our user guide. Here is a brief overview of the content provided here:
+1. The first step for getting an output using the Workbench is to create a QGIS Project
+
+Open QGIS and click on Project
➔ New
+
Next, add new layers to your project. You will want a few layers; one, or more, backing +layer(s) (vector layers or XYZ Tiles), a layer for the workbench to follow, and one, +or more, layer(s) of animated points. The example in this section only has one animated +layer. +
+To add a layer, go to Layer
➔ Create Layer
and then select the type of layer you
+want to add. The example adds a point layer to a GeoPackage to make the project more
+portable.
Once you have added your layers you need to add features to the layers. This is done
+by selecting a layer and then clicking Toggle Editing
(1
) ➔ Add PointFeature
(2
).
+Then click around on your map to add as few, or as many, features as you need.
The example project has four layers: two point layers (3
) and two backing layers (4
).
++A simple way to add a vector base layer is to type "world" into the coordinate +textbox
+
Finally, style your layers to make your project look aesthetically pleasing. To +style your layers you must select the layer you want to style and then using the +Layer Styling toolbar, play around with the style of the layer until it suits you. A +good practice is to have your backing layers as more muted colours and your desired +features as more eye-catching colours.
+ ++You now have a QGIS Project. +
+2. The next step is to choose which features you want to be animated. +
+Pick the layer (or layers) that you want to have animations. Then either find, or create, +the animation for the layer. Make sure you have all the correct attribution for any +animations you use. Below is an example of a simple fish animation split into its frames. +The frames are repeated to slow down the animation's playback speed.
++
+++If you are using
+QGIS 3.26
you can simply use the new animated point symbol, +or if you're using an older version ofQGIS 3.x
follow the instructions below.
The layer should contain a Raster Image Marker
. Once you have selected the marker you
+want to use click on the QGIS Expressions dropdown menu (5
) and click on Edit
(6
).
+
++You can also make a marker move along a line relative to the frame of the animation. +Use the Code Snippets Section for more in-depth help.
+
The example below works with the animation from earlier.
+ +@project_home
+||
+'/fish/fish_00'
+||
+lpad(to_string( @frame_number % 32), 2, '0')
+||
+'.png'
+
+3. Configure your animation
+After animating your markers it's time to configure your animation. Open the Animated +Workbench and begin choosing between the different modes and options. +
+Open the Workbench by clicking the Animation Workbench
(7
) icon in the Plugin Toolbar.
+
+Configure the settings for your animation. The screenshot below is configured for
+the example presented in this section. The Animation Layer is selected as route
(8
)
+because that is the path that the output animation will fly along. The Zoom Range (9
) was
+selected from the Map Canvas Extent, and the Frame rate per second (fps) (10
) was set to
+match the number of frames of the animated markers so that they will play nicely in
+the output. The other settings were selected as a personal choice.
+
+Select the Output Resolution (11
) and a location for your output by clicking on the
+ellipsis (three dots) or by typing in the desired file path (12
).
+
+++Refer to the Workbench User Interface section for more information about +what various settings and buttons accomplish.
+
4. Render your animation!
+
+Click Run
and render your output. The output below is the output from the example.
Should work with and version of QGIS 3.x. If you have QGIS 3.26 or better you can benefit from the animated icon support (see @nyalldawson's most excellent patch #48060).
+For QGIS versions below 3.26, you can animate markers by unpacking a GIF image into its constituent frames and then referencing a specific frame from the symbol data defined property for the image file. Note that to do this extraction below you need to have the Open Source ImageMagick application installed:
+First extract a gif to a sequence of images:
+convert cat.gif -coalesce cat_%05d.png
+
+Example of how to create a dynamically changing image marker based on the current frame count:
+@project_home
+||
+'/gifs/cat_000'
+||
+lpad(to_string( @frame_number % 48 ), 2, '0')
+||
+'.png'
+
+Note that for the above, 48 is the number of frames that the GIF was composed of, and it assumes the frames are in the project directory in a subfolder called gifs
.
In this example we use a geometry generator to create a line between the origin point and the destination point:
+if (@from_feature_id = $id OR @to_feature_id = $id,
+ -- read this from inside to out so
+ -- last tranform the geometry back to the map crs
+ transform(
+ -- densify the geometry so that when we transform
+ -- back it makes a great circle
+ densify_by_count(
+ -- move the geometry into a crs that
+ -- shows a great circle as a straight line
+ transform(
+ -- make a line from the previous pont to the next point
+ make_line(
+ geometry(@from_feature),
+ geometry(@to_feature)
+ ),
+ @map_crs, 'EPSG:4326'),
+ 99),
+ 'EPSG:4326', @map_crs),
+ None)
+
+
+Showing diagnostic information in the QGIS copyright label:
+[%
+'Feature Variables:' ||
+' \n------------------------' ||
+' \nPrevious Feature ' || to_string(coalesce(attribute(@previous_feature, 'name'), '-')) ||
+' \nPrevious Feature ID ' || to_string(coalesce(@previous_feature_id, '-')) ||
+' \n' ||
+' \nNext Feature ' || to_string(coalesce(attribute(@next_feature, 'name'), '-')) ||
+' \nNext Feature ID ' || to_string(coalesce(@next_feature_id, '-')) ||
+' \n' ||
+' \nHover Feature ' || to_string(coalesce(attribute(@hover_feature, 'name'), '-')) ||
+' \nHover Feature ID ' || to_string(coalesce(@hover_feature_id, '-')) ||
+' \n' ||
+' \nFrom Feature ' || to_string(coalesce(attribute(@from_feature, 'name'), '-')) ||
+' \nFrom Feature ID ' || to_string(coalesce(@from_feature_id, '-')) ||
+' \n' ||
+' \nTo Feature ' || to_string(coalesce(attribute(@to_feature, 'name'), '-')) ||
+' \nTo Feature ID ' || to_string(coalesce(@to_feature_id, '-')) ||
+' \n' ||
+' \nTotal Hover Frames ' || to_string(coalesce(@hover_frames, 0)) ||
+' \nCurrent Hover Frame ' || to_string(coalesce(@current_hover_frame, 0)) ||
+' \nTotal Travel Frames ' || to_string(coalesce(@travel_frames, 0)) ||
+' \nCurrent Travel Frame ' || to_string(coalesce(@current_travel_frame, 0)) ||
+' \nTotal Frame Count ' || to_string(coalesce(@total_frame_count, 0)) ||
+' \nFrame Number ' || to_string(coalesce(@frame_number, 0)) ||
+' \nFrame Rate ' || to_string(coalesce(@frame_rate, 0)) ||
+' \nwith Current Animation Action: ' || @current_animation_action ||
+' \nTo Direction ' || coalesce(format_number(degrees(azimuth( geometry(@hover_feature), geometry(@previous_feature) ) ) ), 0) ||
+' \nFrom Direction ' || coalesce(format_number(degrees( azimuth( geometry(@hover_feature), geometry(@next_feature) ) ) ), 0)
+%]
+
+
+
+Example output:
+ +Variably changing the size on a label as we approach it in the animation:
+```40 * ((@frame_number % @hover_frames) / @hover_frames)
+
+## Calculating the angle between points
+
+You can calculate the angle between the hover point and the previous point like this:
+
+```python
+coalesce(
+ format_number(
+ degrees(
+ azimuth(
+ geometry(@hover_feature),
+ geometry(@previous_feature)
+ )
+ )
+ ), 0)
+
+You can set the angle of rotation for a symbol using this expression:
+ + +Using this technique you can also create an animation effect showing the source +direction of travel and the new destination.
+scale_linear (
+ @current_hover_frame,
+ 0,
+ @hover_frames,
+ degrees(
+ azimuth(
+ geometry(@hover_feature),
+ geometry(@previous_feature)
+ )
+ ),
+ degrees(
+ azimuth(
+ geometry(@hover_feature),
+ geometry(@next_feature)
+ )
+ )
+)
+
+Will produce something like this:
+ +Here is an example where we animate all the points in a cluster that are not the hover point. We use an easing function to make the animation have an interesting circular motion.
+ +-- Taken from https://spicyyoghurt.com/tools/easing-functions
+-- t = Time - Amount of time that has passed since the beginning of the animation. Usually starts at 0 and is slowly increased using a game loop or other update function.
+-- b = Beginning value - The starting point of the animation. Usually it's a static value, you can start at 0 for example.
+-- c = Change in value - The amount of change needed to go from starting point to end point. It's also usually a static value.
+-- d = Duration - Amount of time the animation will take. Usually a static value aswell.
+-- Sinusoidal
+-- -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
+
+-- Use with the animation in static mode
+if(@hover_feature_id != $id,
+array(
+ (-@hover_frames / 2) * (cos( (pi() * @frame_number / @hover_frames ) - 1)) ,
+ (-@hover_frames / 2) * (sin( (pi() * @frame_number / @hover_frames ) - 1))
+),
+array (0,0))
+
+
+This function should be applied to the offset X,Y property of the symbol.
+ + + + + + + +What does the workbench do?
+The workbench creates animations from QGIS by generating multiple static frames (images)
+and then combining those frames into an animation. The user tells QGIS how the frames
+should change from one to the other. In QGIS 3.26
and later the animated markers
+allow markers to be animated without the use of the expressions system.
+
How do the animated markers work?
+In the code snippet below, the user tells QGIS that as the frame count increments by
+one the Raster Image Marker
should change to the next image in the sequence.
py
+ @project_home
+ ||
+ '/fish/fish_00'
+ ||
+ lpad(to_string( @frame_number % 32), 2, '0')
+ ||
+ '.png'
The user specifies the path of the image (@project_home/fish/fish_00
). Then the
+lpad(to_string( @frame_number % 32), 2, '0')
tells QGIS to convert the frame
+number to a string and then modulus the number of frames by the number of animation
+frames (32
) (i.e. QGIS divides the number of frames by 32 and then repeats the
+sequence when the remainder is zero). The 2
and '0'
in the snippet tell
+QGIS to pad the /fish/fish_00
with two zeroes at the end. Finally the '.png'
tells
+QGIS the type of file to finish off the path.
+
Frame Output location on Windows
+For users on a Windows machine who are interested in seeing the frames before they +are combined into an animation (GIF or movie) you can find them by going to +"C:\Users\Username\AppData\Local\Temp\animation_workbench-0000000000.png". Bear in +mind that AppData is a hidden file, so it's preferable to not make changes unless +explicitly told otherwise. +
+Frame Output on Linux
+The frames should be in your /tmp directory.
+The animation workbench exposes or modifies a number of different QGIS Expression variables that you can use to achieve different dynamic rendering effects.
+These variables will always be available, regardless of the animation mode
+Variable | +Notes | +
---|---|
frame_number | +Frame number within the current dwell or pan range. | +
frame_rate | +Number of frames per second that the video will be rendered at. | +
total_frame_count | +Total number of frames for the whole animation across all features. | +
These variables are available when in the fixed extent animation mode when a vector layer has been set
+Variable | +Notes | +
---|---|
hover_feature | +The feature we are currently hovering over | +
hover_feature_id | +Feature ID for the feature we a current hovering over | +
previous_feature | +The previously visited feature (or NULL if there isn't one) | +
previous_feature_id | +Feature ID for the previously visited feature (or NULL if there isn't one) | +
next_feature | +The next feature to visit after the current one (or NULL if there isn't one) | +
next_feature_id | +Feature ID for the next feature to visit after the current one (or NULL if there isn't one) | +
current_hover_frame | +The frame number for the current feature (i.e. how many frames we have hovered at the current feature) | +
hover_frames | +Number of frames we will hover at the current feature for | +
current_animation_action | +Always "Hovering" | +
These variables are available in the Planar or Sphere mode.
+Variable | +Notes | +
---|---|
current_animation_action | +Either "Hovering" or "Travelling" | +
These variables are available in planar or sphere mode, when the animation is currently hovering over a feature
+Variable | +Notes | +
---|---|
hover_feature | +The feature we are currently hovering over | +
hover_feature_id | +The feature ID for the feature we are currently hovering over | +
previous_feature | +The previously visited feature (or NULL if there isn't one) | +
previous_feature_id | +Feature ID for the previously visited feature (or NULL if there isn't one) | +
next_feature | +The next feature to visit after the current one (or NULL if there isn't one) | +
next_feature_id | +Feature ID for the next feature to visit after the current one (or NULL if there isn't one) | +
current_hover_frame | +The frame number for the current feature (i.e. how many frames we have hovered at the current feature) | +
hover_frames | +Number of frames we will hover at the current feature for | +
These variables are available in planar or sphere mode, when the animation is currently travelling between two features
+Variable | +Notes | +
---|---|
from_feature | +The feature we are travelling away from | +
from_feature_id | +The feature ID for the feature we are travelling away from | +
to_feature | +The feature we are heading toward | +
to_feature_id | +The feature ID for the feature we are heading toward | +
current_travel_frame | +The frame number for the current travel operation | +
travel_frames | +Number of frames we will travel between the current features | +
Visit the snippets section of our documentation for example expressions.
+ + + + + + +1
): These determine the behaviour and type of animationSphere
: The coordinate reference system (CRS) will be manipulated to create a
+ spinning globe effect. Like Google Earth might do, but with your own data and
+ cartography.Planar
: The coordinate reference system (CRS) will not be altered, but the camera
+ will pan and zoom to each point. It lets you move from feature to feature on a
+ flat map, pausing at each if you want to.Fixed extent
: The frame of reference stays the same and you can animate the
+ symbology within that scene.
Animation Layer (2
):
Dropdown menu
: This allows you to select which map layer you want the animation
+ to follow.Loop from final feature back to first feature
: allows for a seamlessly looping
+ output GIF or movie(MP4).
Zoom Range (3
): The scale range that the animation should move through.
Maximum (inclusive): The scale (zoom level) used when we arrive at each point, + i.e. the most "zoomed in".
+Data defined settings (4
)
Scale
+Animation Frames (5
)
6
):Can be set as a rectangular extent using the Draw on Canvas
feature.
Pan and Zoom Easings (7
)
Zoom Easing (Z): The pan easing will determine the motion characteristics of the + camera on the Z axis as it flies across the scene (i.e. how the camera zooms in + and out of the points)
+Frame previews (8
): A preview of what each frame of the animation will look like. A
+ user can decide which Frame
to view.
Edit the intro section of the generated movie here.
+ +1
): Add images or moviesRemove Media (Minus sign) (2
): Remove images or movies
Duration (3
): For images, you can set a duration for each image (in seconds).
Preview Frame (4
): This shows what the media will look like.
Details: Provides details about where the media is stored on your computer.
+Edit the outro section of the generated movie here.
+ +1
): Add images or moviesRemove Media (Minus sign) (2
): Remove images or movies
Duration (3
): For images, you can set a duration for each image (in seconds).
Preview Frame (4
): This shows what the media will look like.
Details: Provides details about where the media is stored on your computer.
+1
): Add sound files (.mp3 or .wav) to play during the
+ generated movie.Remove Media (Minus sign) (2
): Remove sound files (.mp3 or .wav)
Duration (3
): The cumulative length of your soundtracks should be as long, or longer,
+ than your movie, including the intro/outro sections. If the soundtrack is longer
+ than the movie it will be truncated (shortened) when the movie ends.
Details: Provides details about where the media is stored on your computer.
+1
): This will not erase cached images on disk and will resume
+ processing from the last cached image.2
): For this export to work, you need to have the ImageMagick 'convert'
+ application available on your system.3
): For this option to work, you need to have the 'ffmpeg' application
+ on your system.4
): Allows a user to specify one of four image resolutions
+ for the output animation. The numbers in brackets for the first three options represent
+ the width and height of the output in pixels (i.e. width x height), and the fourth
+ option matches the output's size to the size of the Map Canvas
on the screen.5
): This lets a user select the location where the output
+ will be stored.1
): A preview of what each frame of the animation will look like.
+ It changes automatically as the workbench runs.2
): This provides a detailed look at what is happening while the workbench
+ runs.3
): A detailed list of what steps the workbench is doing (a record of processing)4
): A visual representation of the workbench's progression as a percentage.Run
: Starts the process of getting an output from the workbench. It is greyed out
+ until a user provides a destination for the output file.Close
: Closes the workbench.Cancel
: Ends the workbench processing at whatever point it has reached when the
+ button is pressed.Help
: Opens a link to the Animation Workbench documentation.There is nothing really to configure! We do provide a few options in the +configuration dialog, but most users should not need to change them.
+You can access the QGIS Animation Workbench plugin options by opening the standard +QGIS Setting dialog and clicking on the animation workbench tab.
+++ +Settings ➔ Options
+
1
)Currently there are just three configuration options:
+2
): This is the number of concurrent tasks
+that will be used to render animations. The default is 1.3
): This is a developer option that enables the developers
+to see an icon in the toolbar which will start the debug remote server.4
): This will add extra messages in the logging pane to
+help you understand what is going on during the rendering process.Content needed
+ + + + + + +In this section we explain how to install the plugin.
+To access the QGIS Plugin Manager you simply need to select
+Plugins
➡ Manage and Install Plugins...
(1
) in the Menu Toolbar.
Once the QGIS Plugin Manager loads, you need to navigate to the All
(2
)
+tab and type "animation" into the search bar (3
). Select QGIS Animation
+Workbench from the list of available plugins and then select Install Plugin
+(4
).
Once the Animation Workbench is installed, you can access it by clicking on the
+Animation Workbench
icon (5
) in the Plugin Toolbar.
++Note if you are on Ubuntu, you may need to install the Qt5 multimedia +libraries.
+
sudo apt install PyQt5.QtMultimedia
+
+To install, visit the Github
+Repository, click on the
+Actions
tab, and click on the Make QGIS Plugin Zip For Manual Installs
+workflow (the bottom one).
Click on the most recent workflow run (the top one).
+ +Scroll down on the on the page.
+ +And click on animation_workbench
to download the most recent build of the plugin
Download the animation_workbench.zip
file and open it in QGIS using the plugin
+manager as described below.
++Note if you are on Ubuntu, you may need to install the Qt5 multimedia +libraries.
+
sudo apt install PyQt5.QtMultimedia
+
+
+
+
+
+
+
+ In this section, we describe the general workflow for using the Animation Workbench.
+1. Create a QGIS Project
+
+Open QGIS and click on Project
➔ New
+
Add new layers to your project
+ +++A simple way to add a base layer is to type "world" (
+1
) into the coordinate +textbox
Style the layers you've added to make your project look a bit better. Select the
+layer (2
) you want to style and in the Layer Styling toolbar (3
), style the layer to
+look appealing to you.
+
2. Identify features that will be animated. +
+Pick the layer (or layers) that you want to animate. Then either find or create the +animation for the layer. Make sure you have all the correct attribution for any +animations you use. Below is an example of an animation split into its frames.
+ +3. Use the QGIS Expressions system with the variables introduced by the Animation +Workbench to define behaviours of your symbols during flight and hover modes of your +animation. +
+Select the layer you want to animate and open the Layer Styling toolbar.
+++If you are using
+QGIS 3.26
you can simply use the new animated point symbol, +or if you're using an older version ofQGIS 3.x
follow the instructions below.
The layer should be a Raster Image Marker
. Once you have selected the image you
+want to use click on the QGIS Expressions dropdown menu (4
) and click on Edit
(5
).
+Use the Code Snippets Section for more in depth help. The +example below works with the bird animation from earlier
+ + @project_home
+ ||
+ '/bird/bird_00'
+ ||
+ lpad(to_string(@frame_number % 9), 2, '0')
+ ||
+ '.png'
+
+1. Open the Animation Workbench and configure your animation, choosing between the +different modes and options. +
+Open the Workbench by clicking the Animation Workbench
(6
) icon in the Plugin Toolbar.
+
+Configure the settings for your animation. The screenshot below is configured for
+the example presented in this section. The Animation Layer is selected as route (7
)
+because that is the path the animation will fly along, the Zoom Range (8
) was selected
+from the Map Canvas Extent, and the Frame rate per second (9
) was set to 9 to match
+the bird animation.
+
+Set your desired Output Options
(10
) Select a location for your output (11
).
+
+++Refer to the Workbench User Interface Section for more information about +what various settings and buttons accomplish.
+
2. Render your animation!
+
+Click Run
and render your output. The output below is the output from the example.