Page 1 of 1 (10 posts)

  • talks about »
  • c++

Tags

Last update:
Sat Nov 16 18:15:11 2019

A Django site.

QGIS Planet

(Fr) Oslandia recrute : développeur(se) C++ et Python

Sorry, this entry is only available in French.

QGIS speaks a lot of languages

QGIS is a real cosmopolitan. Born in Alaska sixteen years ago, it has spread all over the world since. Thanks to its open source mentality, it finds not only in economically strong countries big usergroups. No question, that beside all the developers, there is a bunch of brave translators giving everything to make and keep QGIS multilingual. It’s translated in over forty languages – even to Mandarin Chinese and Esperanto. Not only the application, but also its plugins.
And since the feature-loaded long term release 3.4.0 even the QGS-Projects themselves.  Thanks to the friendly support of QGIS Usergroup Switzerland and the QGEP Project.

How it comes

Plugins are often shipped with pre-configured project files. To provide them in the users individual language, you’ve been required to translate the project manually in the properties and store it separately. When you needed to change something, you have been coerced to update every single file. This is a big effort and fault-prone. So there appeared the idea to have translation files for each required language, and when the user opens the only one project, it will be translated to his specific language. And that’s, what this new functionality does.

How it’s done

Like QGIS and the plugins, the projects are translated with the Qt translation process. Means, it makes the translation according to a Qt Compiled Translation Source File (.qm file). When the user opens a project, QGIS checks for a .qm file laying in the same folder like the .qgs file, having the same name like the .qgs file and having the language-code as postfix of the users language (the language configured in the QGIS settings).
So when the user opens a project named “citybees.qgs” that is originally in English, but his QGIS language is German, it checks for a file named “citybees_de.qm”. The project’s layer names, field-aliases, container names and much more will be translated to German and the project will be automatically stored as “citybees_de.qgs”. So the user has his German project version and can use and edit it like he wishes. Super easy.

Start from the beginning

Swiss people love honey and so they are diligent beekeepers. So, let’s assume you want to provide a project about beekeeping in cities to your Swiss customers. Because in Switzerland people talk four different languages, you need to have the project multilingual in German, French and Italian. We skip Romansh, not because it’s less important or in the Romansh speaking parts are no cities, but because QGIS does not support Romansh (if you’ll propose this one day, you will have my vote).
Anyway. Let’s see what you have to do, to deliver the projects with the .qm file for German, French or Italian.

1. Create the project

You create your project about beekeeping and store it as “citybees.qgs”. You don’t have to care about languages at the moment. You name everything in your language. Assumed it’s English, you name the layers “apiary” and “area” and the fields “fid”, “bee-species”, “beekeeper” and so on.
On changes you will edit always this project and no translated projects.

2. Generate Ts File

In the project properties in the section General there is the part to generate a translation source file. First, you select the source language, to have this information in programs you’ll edit the file (like Qt Linguist or Transifex) afterwards. Per default the language of your QGIS is selected here.

When pressing Generate TS File you will find in your projects folder the new file “citybees.ts”.
But wait a minute, why are we generating a .ts file when we need a .qm file?
The .ts file is the translation source file and it’s the uncompiled .qm file. The .qm file contains compact binary format code Qt can make the translation of programs with, but you and your brave translator cannot read it. So you create a .ts file looking like this:

<!DOCTYPE TS>
<TS sourcelanguage="en_US">
 <context>
  <name>project:layers:apiary__offline__1f89f4fd_49da_4eb9_90b3_1f7b5e82840c</name>
  <message>
   <source>apiary</source>
   <translation type="unfinished"/>
  </message>
 </context>
 <context>
  <name>project:layers:apiary__offline__1f89f4fd_49da_4eb9_90b3_1f7b5e82840c:fieldaliases</name>
  <message>
   <source>fid</source>
   <translation type="unfinished"/>
  </message>
 </context>
 <context>
  <name>project:layers:apiary__offline__1f89f4fd_49da_4eb9_90b3_1f7b5e82840c:fieldaliases</name>
  <message>
   <source>bee_species</source>
   <translation type="unfinished"/>
  </message>
 </context>
 <context>
  <name>project:layers:apiary__offline__1f89f4fd_49da_4eb9_90b3_1f7b5e82840c:fieldaliases</name>
  <message>
   <source>beekeeper</source>
   <translation type="unfinished"/>
  </message>
 </context>
[...]

You see it’s simple XML code that contains mainly untranslated text in the <source> element and empty space for the translated text in the <translation> element.
You could enter your translations directly in this file using the text editor and then build the .qm file with the command lrelease, but it’s preferable to use tools like Qt Linguist orweb-based services like Transifex or Weblate.

3. Translate your File in Qt Linguist

You open Qt Linguist an you select the target language of the .qm file you want to build in the end. Let’s choose German.
The file opens and you see a list of entries described by the Context. The context is, where the strings are located in the QGIS project.

The string “beekeeper” stays in the context project:layers:apiary_1f7b5e82839c:fieldaliases and this means it’s a field or alias of the layer apiary_1f7b5e82839c in the project.
The translation is done simply over the graphical interface. To confirm your translation you can set the check mark.

4. Finally build your .qm file

You compile the translation – means build a .qm file – by simply select Release as… in the Qt Linguist and store it as “citybees_de.qm”.

And now your customer will be able to open your project in German 🙂

What’s translated

Most of the needed parameters like layer names and fields are translated. There could be still some strings in your use case that are not like for example action titles or labels. But the solution is designed, that it’s extendable for more project parameters (see the next chapter). So don’t worry if you will find parameters that cannot be translated yet. They possibly will be in the future.

Translatable strings:

  • layer names
  • layer group names
  • form attributes like tab titles and group box titles
  • relation names
  • field names and aliases
  • value relations

With field names and aliases it has a special behavior: while we should not translate the field names itself because they can be used as identification, the aliases are translated only. In case there is no alias in the original project, the translation of the field name would be written as an alias in the translated project. The field name stays the same. So you can just generate and translate without the fear of overwriting field names.

Content translation

There is a possibility to have a translation of the content as well. In particular using the value relation widget.
Let’s assume, you want to have the values in the field bee_species translated as well. Means the following bee species should be German:
– European dark bee
– Carniolan honey bee
– Buckfast bee

You can solve this by using the value relation widget. Means you create a non geometrical layer “beespecies” and enter the following values:

nomenclatura name_en name_de name_fr name_it
Apis mellifera mellifera European dark bee Dunkle Europäische Biene abeille noire ape nera
Apis mellifera carnica Carniolan honey bee Kärntner Biene abeille carniolienne ape carnica
Apis mellifera Buckfast bee Buckfastbiene abeille Buckfast ape Buckfast

And configure the field bee_species of apiary as value relation widget:

And now comes the magic:

When you create the .ts file it includes not only the field name bee_species but also the referenced value name_en:

 <context>
  <name>project:layers:apiary__offline__1f89f4fd_49da_4eb9_90b3_1f7b5e82840c:fields:bee_species:valuerelationvalue</name>
  <message>
   <source>name_en</source>
   <translation type="unfinished"/>
  </message>
 </context>

When you now “translate” the name_en to name_de the field is referenced to the German values of the entry:

Getting technical

Let’s have a quick look into the source code, shall we?

Generate Ts File

When you press the Generate Ts File button in the project properties, in the background happens the following:
First QGIS scans for the translatable strings in the currently loaded project and collects everything in a QgsTranslationContext object. This object contains the filename of the .ts file and all the collected translatable strings.
The strings are collected by firing a signal called requestForTranslatableObjects delivering the QgsTranslationContext. Every object that contains translatable strings connects a slot registering the strings in the received QgsTranslationContext:

void registerTranslatableObjects( QgsTranslationContext *translationContext )
{
  const QList<QgsLayerTreeLayer *> layers = mRootGroup->findLayers();
  for ( const QgsLayerTreeLayer *layer : layers )
  {
    translationContext->registerTranslation( QStringLiteral( "project:layers:%1" ).arg( layer->layerId() ), layer->name() );
[...]

This will be a growing list of strings as new features are added and missing bits are discovered.

Translate by QTranslator

The translation is made using the QTranslator. It’s loaded with the .qm file on reading the project and on loading of every single translatable string, it’s called to translate:

QString layername = mTranslator->translate( QStringLiteral( "project:layers:%1" ).arg( node.namedItem( QStringLiteral( "id" ) ).toElement().text() ), node.namedItem( QStringLiteral( "layername" ) ).toElement().text(), disambiguation, n );

That’s it

I hope you liked reading and if you have questions or inputs, feel free to add a comment.
Enjoy this cosmopolitious feature! 🙂

QGIS 3 compiling on Windows

As the Oslandia team work exclusively on GNU/Linux, the exercise of compiling QGIS 3 on Windows 8 is not an everyday’s task :). So we decided to share our experience, we bet that will help some of you.

Cygwin

The first step is to download Cygwin and to install it in the directory C:\cygwin (instead of the default C:\cygwin64). During the installation, select the lynx package:

 

Once installed, you have to click on the Cygwin64 Terminal icon newly created on your desktop:

Then, we’re able to install dependencies and download some other installers:

[pastacode lang=”bash” manual=”%24%20cd%20%2Fcygdrive%2Fc%2FUsers%2Fhenri%2FDownloads%0A%24%20lynx%20-source%20rawgit.com%2Ftranscode-open%2Fapt-cyg%2Fmaster%2Fapt-cyg%20%3E%20apt-cyg%0A%24%20install%20apt-cyg%20%2Fbin%0A%24%20apt-cyg%20install%20wget%20git%20flex%20bison%0A%24%20wget%20http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2FD%2F2%2F3%2FD23F4D0F-BA2D-4600-8725-6CCECEA05196%2Fvs_community_ENU.exe%0A%24%20chmod%20u%2Bx%20vs_community_ENU.exe%0A%24%20wget%20https%3A%2F%2Fcmake.org%2Ffiles%2Fv3.7%2Fcmake-3.7.2-win64-x64.msi%0A%24%20wget%20http%3A%2F%2Fdownload.osgeo.org%2Fosgeo4w%2Fosgeo4w-setup-x86_64.exe%0A%24%20chmod%20u%2Bx%20osgeo4w-setup-x86_64.exe” message=”” highlight=”” provider=”manual”/]

CMake

The next step is to install CMake. To do that, double clic on the file cmake-3.7.2-win64-x64.msi previously downloaded with wget. You should choose the next options during the installation:

 

Visual Studio

Then, we have to install Visual Studio and C++ tools. Double click on the vs_community_ENU.exe file and select the Custom installation. On the next page, you have to select Visual C++ chekbox:

 

 

OSGeo4W

In order to compile QGIS, some dependencies provided by the OSGeo4W installer are required. Double click on osgeo4w-setup-x86_64.exe and select the Advanced Install mode. Then, select the next packages:

  •  expat
  • fcgi
  • gdal
  • grass
  • gsl-devel
  • iconv
  • libzip-devel
  • libspatialindex-devel
  • pyqt5
  • python3-devel
  • python3-qscintilla
  • python3-nose2
  • python3-future
  • python3-pyyaml
  • python3-mock
  • python3-six
  • qca-qt5-devel
  • qca-qt5-libs
  • qscintilla-qt5
  • qt5-devel
  • qt5-libs-debug
  • qtwebkit-qt5-devel
  • qtwebkit-qt5-libs-debug
  • qwt-devel-qt5
  • sip-qt5
  • spatialite
  • oci
  • qtkeychain

QGIS

To start this last step, we have to create a file C:\OSGeo4W\OSGeo4W-dev.bat containing something like:

[pastacode lang=”bash” manual=”%40echo%20off%20%0Aset%20OSGEO4W_ROOT%3DC%3A%5COSGeo4W64%0Acall%20%22%25OSGEO4W_ROOT%25%5Cbin%5Co4w_env.bat%22%20%0Acall%20%22%25OSGEO4W_ROOT%25%5Cbin%5Cqt5_env.bat%22%20%0Acall%20%22%25OSGEO4W_ROOT%25%5Cbin%5Cpy3_env.bat%22%20%0Aset%20VS140COMNTOOLS%3D%25PROGRAMFILES(x86)%25%5CMicrosoft%20Visual%20Studio%2014.0%5CCommon7%5CTools%5C%20%0Acall%20%22%25PROGRAMFILES(x86)%25%5CMicrosoft%20Visual%20Studio%2014.0%5CVC%5Cvcvarsall.bat%22%20amd64%20%0Aset%20INCLUDE%3D%25INCLUDE%25%3B%25PROGRAMFILES(x86)%25%5CMicrosoft%20SDKs%5CWindows%5Cv7.1A%5Cinclude%20%0Aset%20LIB%3D%25LIB%25%3B%25PROGRAMFILES(x86)%25%5CMicrosoft%20SDKs%5CWindows%5Cv7.1A%5Clib%20%0Apath%20%25PATH%25%3B%25PROGRAMFILES%25%5CCMake%5Cbin%3Bc%3A%5Ccygwin%5Cbin%20%0A%40set%20GRASS_PREFIX%3D%22%25OSGEO4W_ROOT%25%5Capps%5Cgrass%5Cgrass-7.2.1%20%0A%40set%20INCLUDE%3D%25INCLUDE%25%3B%25OSGEO4W_ROOT%25%5Cinclude%20%0A%40set%20LIB%3D%25LIB%25%3B%25OSGEO4W_ROOT%25%5Clib%3B%25OSGEO4W_ROOT%25%5Clib%20%0A%0A%40cmd%20″ message=”” highlight=”” provider=”manual”/]

According to your environment, some variables should probably be adapted. Then in the Cygwin terminal:

[pastacode lang=”bash” manual=”%24%20cd%20C%3A%5C%0A%24%20git%20clone%20git%3A%2F%2Fgithub.com%2Fqgis%2FQGIS.git%0A%24%20.%2FOSGeo4W-dev.bat%0A%3E%20cd%20QGIS%2Fms-windows%2Fosgeo4w” message=”” highlight=”” provider=”manual”/]

In this directory, you have to edit the file package-nightly.cmd to replace:

[pastacode lang=”bash” manual=”cmake%20-G%20Ninja%20%5E” message=”” highlight=”” provider=”manual”/]

by:

[pastacode lang=”bash” manual=”cmake%20-G%20%22Visual%20Studio%2014%202015%20Win64%22%20%5E” message=”” highlight=”” provider=”manual”/]

Moreover, we had to update the environment variable SETUAPI_LIBRARY according to the current position of the Windows Kits file SetupAPI.Lib:

[pastacode lang=”bash” manual=”set%20SETUPAPI_LIBRARY%3DC%3A%5CProgram%20Files%20(x86)%5CWindows%20Kits%5C8.1%5CLib%5Cwinv6.3%5Cum%5Cx64%5CSetupAPI.Lib” message=”” highlight=”” provider=”manual”/]

And finally, we just have to compile with the next command:

[pastacode lang=”markup” manual=”%3E%20package-nightly.cmd%202.99.0%201%20qgis-dev%20x86_64″ message=”” highlight=”” provider=”manual”/]

Victory!

And see you soon for the generation of OSGEO4W packages 😉

Source

https://github.com/qgis/QGIS/blob/ab859c9bdf8a529df9805ff54e7250921a74d877/doc/msvc.t2t

 

 

QGIS 3 compiling on Windows

As the Oslandia team work exclusively on GNU/Linux, the exercise of compiling QGIS 3 on Windows 8 is not an everyday’s task :). So we decided to share our experience, we bet that will help some of you.

Cygwin

The first step is to download Cygwin and to install it in the directory C:\cygwin (instead of the default C:\cygwin64). During the installation, select the lynx package:

 

Once installed, you have to click on the Cygwin64 Terminal icon newly created on your desktop:

Then, we’re able to install dependencies and download some other installers:

[pastacode lang=”bash” manual=”%24%20cd%20%2Fcygdrive%2Fc%2FUsers%2Fhenri%2FDownloads%0A%24%20lynx%20-source%20rawgit.com%2Ftranscode-open%2Fapt-cyg%2Fmaster%2Fapt-cyg%20%3E%20apt-cyg%0A%24%20install%20apt-cyg%20%2Fbin%0A%24%20apt-cyg%20install%20wget%20git%20flex%20bison%0A%24%20wget%20http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2FD%2F2%2F3%2FD23F4D0F-BA2D-4600-8725-6CCECEA05196%2Fvs_community_ENU.exe%0A%24%20chmod%20u%2Bx%20vs_community_ENU.exe%0A%24%20wget%20https%3A%2F%2Fcmake.org%2Ffiles%2Fv3.7%2Fcmake-3.7.2-win64-x64.msi%0A%24%20wget%20http%3A%2F%2Fdownload.osgeo.org%2Fosgeo4w%2Fosgeo4w-setup-x86_64.exe%0A%24%20chmod%20u%2Bx%20osgeo4w-setup-x86_64.exe” message=”” highlight=”” provider=”manual”/]

CMake

The next step is to install CMake. To do that, double clic on the file cmake-3.7.2-win64-x64.msi previously downloaded with wget. You should choose the next options during the installation:

 

Visual Studio

Then, we have to install Visual Studio and C++ tools. Double click on the vs_community_ENU.exe file and select the Custom installation. On the next page, you have to select Visual C++ chekbox:

 

 

OSGeo4W

In order to compile QGIS, some dependencies provided by the OSGeo4W installer are required. Double click on osgeo4w-setup-x86_64.exe and select the Advanced Install mode. Then, select the next packages:

  •  expat
  • fcgi
  • gdal
  • grass
  • gsl-devel
  • iconv
  • libzip-devel
  • libspatialindex-devel
  • pyqt5
  • python3-devel
  • python3-qscintilla
  • python3-nose2
  • python3-future
  • python3-pyyaml
  • python3-mock
  • python3-six
  • qca-qt5-devel
  • qca-qt5-libs
  • qscintilla-qt5
  • qt5-devel
  • qt5-libs-debug
  • qtwebkit-qt5-devel
  • qtwebkit-qt5-libs-debug
  • qwt-devel-qt5
  • sip-qt5
  • spatialite
  • oci
  • qtkeychain

QGIS

To start this last step, we have to create a file C:\OSGeo4W\OSGeo4W-dev.bat containing something like:

[pastacode lang=”bash” manual=”%40echo%20off%20%0Aset%20OSGEO4W_ROOT%3DC%3A%5COSGeo4W64%0Acall%20%22%25OSGEO4W_ROOT%25%5Cbin%5Co4w_env.bat%22%20%0Acall%20%22%25OSGEO4W_ROOT%25%5Cbin%5Cqt5_env.bat%22%20%0Acall%20%22%25OSGEO4W_ROOT%25%5Cbin%5Cpy3_env.bat%22%20%0Aset%20VS140COMNTOOLS%3D%25PROGRAMFILES(x86)%25%5CMicrosoft%20Visual%20Studio%2014.0%5CCommon7%5CTools%5C%20%0Acall%20%22%25PROGRAMFILES(x86)%25%5CMicrosoft%20Visual%20Studio%2014.0%5CVC%5Cvcvarsall.bat%22%20amd64%20%0Aset%20INCLUDE%3D%25INCLUDE%25%3B%25PROGRAMFILES(x86)%25%5CMicrosoft%20SDKs%5CWindows%5Cv7.1A%5Cinclude%20%0Aset%20LIB%3D%25LIB%25%3B%25PROGRAMFILES(x86)%25%5CMicrosoft%20SDKs%5CWindows%5Cv7.1A%5Clib%20%0Apath%20%25PATH%25%3B%25PROGRAMFILES%25%5CCMake%5Cbin%3Bc%3A%5Ccygwin%5Cbin%20%0A%40set%20GRASS_PREFIX%3D%22%25OSGEO4W_ROOT%25%5Capps%5Cgrass%5Cgrass-7.2.1%20%0A%40set%20INCLUDE%3D%25INCLUDE%25%3B%25OSGEO4W_ROOT%25%5Cinclude%20%0A%40set%20LIB%3D%25LIB%25%3B%25OSGEO4W_ROOT%25%5Clib%3B%25OSGEO4W_ROOT%25%5Clib%20%0A%0A%40cmd%20″ message=”” highlight=”” provider=”manual”/]

According to your environment, some variables should probably be adapted. Then in the Cygwin terminal:

[pastacode lang=”bash” manual=”%24%20cd%20C%3A%5C%0A%24%20git%20clone%20git%3A%2F%2Fgithub.com%2Fqgis%2FQGIS.git%0A%24%20.%2FOSGeo4W-dev.bat%0A%3E%20cd%20QGIS%2Fms-windows%2Fosgeo4w” message=”” highlight=”” provider=”manual”/]

In this directory, you have to edit the file package-nightly.cmd to replace:

[pastacode lang=”bash” manual=”cmake%20-G%20Ninja%20%5E” message=”” highlight=”” provider=”manual”/]

by:

[pastacode lang=”bash” manual=”cmake%20-G%20%22Visual%20Studio%2014%202015%20Win64%22%20%5E” message=”” highlight=”” provider=”manual”/]

Moreover, we had to update the environment variable SETUAPI_LIBRARY according to the current position of the Windows Kits file SetupAPI.Lib:

[pastacode lang=”bash” manual=”set%20SETUPAPI_LIBRARY%3DC%3A%5CProgram%20Files%20(x86)%5CWindows%20Kits%5C8.1%5CLib%5Cwinv6.3%5Cum%5Cx64%5CSetupAPI.Lib” message=”” highlight=”” provider=”manual”/]

And finally, we just have to compile with the next command:

[pastacode lang=”markup” manual=”%3E%20package-nightly.cmd%202.99.0%201%20qgis-dev%20x86_64″ message=”” highlight=”” provider=”manual”/]

Victory!

And see you soon for the generation of OSGEO4W packages 😉

Source

https://github.com/qgis/QGIS/blob/ab859c9bdf8a529df9805ff54e7250921a74d877/doc/msvc.t2t

 

 

Auxiliary Storage support in QGIS 3

For those who know how powerful QGIS can be using data defined widgets and expressions almost anywhere in styling and labeling settings, it remains today quite complex to store custom data.

For instance, moving a simple label using the label toolbar is not straightforward, that wonderful toolbar remains desperately greyed-out for manual labeling tweaks

…unless you do the following:

  • Set your vector layer editable (yes, it’s not possible with readonly data)
  • Add two columns in your data
  • Link the X property position to a column and the Y position to another

 

the Move Label map tool becomes available and ready to be used (while your layer is editable). Then, if you move a label, the underlying data is modified to store the position. But what happened if you want to fully use the Change Label map tool (color, size, style, and so on)?

 

Well… You just have to add a new column for each property you want to manage. No need to tell you that it’s not very convenient to use or even impossible when your data administrator has set your data in readonly mode…

A plugin, made some years ago named EasyCustomLabeling was made to address that issue. But it kept being full of caveats, like a dependency to another plugin (Memory layer saver) for persistence, or a full copy of the layer to label inside a memory layer which indeed led to loose synchronisation with the source layer.

Two years ago, the French Agence de l’eau Adour Garonne (a water basin agency) and the Ministry in charge of Ecology asked Oslandia to think out QGIS Enhancement proposals to port that plugin into QGIS core, among a few other things like labeling connectors or curved labels enhancements.

Those QEPs were accepted and we could work on the real implementation, so here we are, Auxiliary storage has now landed in master!

How

The aim of auxiliary storage is to propose a more integrated solution to manage these data defined properties :

  • Easy to use (one click)
  • Transparent for the user (map tools always available by default when labeling is activated)
  • Do not update the underlying data (it should work even when the layer is not editable)
  • Keep in sync with the datasource (as much as possible)
  • Store this data along or inside the project file

As said above, thanks to the Auxiliary Storage mechanism, map tools like Move Label, Rotate Label or Change Label are available by default. Then, when the user select the map tool to move a label and click for the first time on the map, a simple question is asked allowing to select a primary key :

Primary key choice dialog – (YES, you NEED a primary key for any data management)

From that moment on, a hidden table is transparently created to store all data defined values (positions, rotations, …) and joined to the original layer thanks to the primary key previously selected. When you move a label, the corresponding property is automatically created in the auxiliary layer. This way, the original data is not modified but only the joined auxiliary layer!

A new tab has been added in vector layer properties to manage the Auxiliary Storage mechanism. You can retrieve, clean up, export or create new properties from there :

Where the auxiliary data is really saved between projects?

We end up in using a light SQLite database which, by default, is just 8 Ko! When you save your project with the usual extension .qgs, the SQLite database is saved at the same location but with a different extension : .qgd.

Two thoughts with that choice: 

  • “Hey, I would like to store geometries, why no spatialite instead? “

Good point. We tried that at start in fact. But spatialite database initializing process using QGIS spatialite provider was found too long, really long. And a raw spatialite table weight about 4 Mo, because of the huge spatial reference system table, the numerous spatial functions and metadata tables. We chose to fall back onto using sqlite through OGR provider and it proved to be fast and stable enough. If some day, we achieve in merging spatialite provider and GDAL-OGR spatialite provider, with options to only create necessary SRS and functions, that would open news possibilities, like storing spatial auxiliary data.

  • “Does that mean that when you want to move/share a QGIS project, you have to manually manage these 2 files to keep them in the same location?!”

True, and dangerous isn’t it? Users often forgot auxiliary files with EasyCustomLabeling plugin.  Hence, we created a new format allowing to zip several files : .qgz.  Using that format, the SQLite database project.qgd and the regular project.qgs file will be embedded in a single project.zip file. WIN!!

Changing the project file format so that it can embed, data, fonts, svg was a long standing feature. So now we have a format available for self hosted QGIS project. Plugins like offline editing, Qconsolidate and other similar that aim at making it easy to export a portable GIS database could take profit of that new storage container.

Now, some work remains to add labeling connectors capabilities,  allow user to draw labeling paths by hand. If you’re interested in making this happen, please contact us!

 

 

More information

A full video showing auxiliary storage capabilities:

 

QEP: https://github.com/qgis/QGIS-Enhancement-Proposals/issues/27

PR New Zip format: https://github.com/qgis/QGIS/pull/4845

PR Editable Joined layers: https://github.com/qgis/QGIS/pull/4913

PR Auxiliary Storage: https://github.com/qgis/QGIS/pull/5086

Auxiliary Storage support in QGIS 3

For those who know how powerful QGIS can be using data defined widgets and expressions almost anywhere in styling and labeling settings, it remains today quite complex to store custom data.

For instance, moving a simple label using the label toolbar is not straightforward, that wonderful toolbar remains desperately greyed-out for manual labeling tweaks

…unless you do the following:

  • Set your vector layer editable (yes, it’s not possible with readonly data)
  • Add two columns in your data
  • Link the X property position to a column and the Y position to another

 

the Move Label map tool becomes available and ready to be used (while your layer is editable). Then, if you move a label, the underlying data is modified to store the position. But what happened if you want to fully use the Change Label map tool (color, size, style, and so on)?

 

Well… You just have to add a new column for each property you want to manage. No need to tell you that it’s not very convenient to use or even impossible when your data administrator has set your data in readonly mode…

A plugin, made some years ago named EasyCustomLabeling was made to address that issue. But it kept being full of caveats, like a dependency to another plugin (Memory layer saver) for persistence, or a full copy of the layer to label inside a memory layer which indeed led to loose synchronisation with the source layer.

Two years ago, the French Agence de l’eau Adour Garonne (a water basin agency) and the Ministry in charge of Ecology asked Oslandia to think out QGIS Enhancement proposals to port that plugin into QGIS core, among a few other things like labeling connectors or curved labels enhancements.

Those QEPs were accepted and we could work on the real implementation, so here we are, Auxiliary storage has now landed in master!

How

The aim of auxiliary storage is to propose a more integrated solution to manage these data defined properties :

  • Easy to use (one click)
  • Transparent for the user (map tools always available by default when labeling is activated)
  • Do not update the underlying data (it should work even when the layer is not editable)
  • Keep in sync with the datasource (as much as possible)
  • Store this data along or inside the project file

As said above, thanks to the Auxiliary Storage mechanism, map tools like Move Label, Rotate Label or Change Label are available by default. Then, when the user select the map tool to move a label and click for the first time on the map, a simple question is asked allowing to select a primary key :

Primary key choice dialog – (YES, you NEED a primary key for any data management)

From that moment on, a hidden table is transparently created to store all data defined values (positions, rotations, …) and joined to the original layer thanks to the primary key previously selected. When you move a label, the corresponding property is automatically created in the auxiliary layer. This way, the original data is not modified but only the joined auxiliary layer!

A new tab has been added in vector layer properties to manage the Auxiliary Storage mechanism. You can retrieve, clean up, export or create new properties from there :

Where the auxiliary data is really saved between projects?

We end up in using a light SQLite database which, by default, is just 8 Ko! When you save your project with the usual extension .qgs, the SQLite database is saved at the same location but with a different extension : .qgd.

Two thoughts with that choice: 

  • “Hey, I would like to store geometries, why no spatialite instead? “

Good point. We tried that at start in fact. But spatialite database initializing process using QGIS spatialite provider was found too long, really long. And a raw spatialite table weight about 4 Mo, because of the huge spatial reference system table, the numerous spatial functions and metadata tables. We chose to fall back onto using sqlite through OGR provider and it proved to be fast and stable enough. If some day, we achieve in merging spatialite provider and GDAL-OGR spatialite provider, with options to only create necessary SRS and functions, that would open news possibilities, like storing spatial auxiliary data.

  • “Does that mean that when you want to move/share a QGIS project, you have to manually manage these 2 files to keep them in the same location?!”

True, and dangerous isn’t it? Users often forgot auxiliary files with EasyCustomLabeling plugin.  Hence, we created a new format allowing to zip several files : .qgz.  Using that format, the SQLite database project.qgd and the regular project.qgs file will be embedded in a single project.zip file. WIN!!

Changing the project file format so that it can embed, data, fonts, svg was a long standing feature. So now we have a format available for self hosted QGIS project. Plugins like offline editing, Qconsolidate and other similar that aim at making it easy to export a portable GIS database could take profit of that new storage container.

Now, some work remains to add labeling connectors capabilities,  allow user to draw labeling paths by hand. If you’re interested in making this happen, please contact us!

 

 

More information

A full video showing auxiliary storage capabilities:

 

QEP: https://github.com/qgis/QGIS-Enhancement-Proposals/issues/27

PR New Zip format: https://github.com/qgis/QGIS/pull/4845

PR Editable Joined layers: https://github.com/qgis/QGIS/pull/4913

PR Auxiliary Storage: https://github.com/qgis/QGIS/pull/5086

Increasing the stability of processing algorithms

Processing just got a new testing framework to improve the long-term stability of this important plugin. And you can help to improve it, even if you are not a software developer! This is yet another piece in our never-stopping crusade to

Passing android Intents to Qt

Working on QField I had the necessity of passing values from the QtActivity.java to the Qt cpp world, here how I did it using an Intent that is sent to the QtActivity (the one you should not edit that comes with

QGIS Crowdfunding: 2.5D Rendering

2.5D rendering

Build and deploy c++ QGIS custom application on windows

After a lot of troubles, I managed to compile and deploy a QGIS c++ app on windows. This small guide will describe the steps I followed. This has been tested on win xp and windows 7, both in 32 bits.

Development environment

Your app must be built using MSVC 9.0 (2008) since QGIS in OSGeo’s package was built with it. Hence, MinGW cannot be used.

  1. Install Microsoft Visual Studio Express 2008.
  2. Install QGIS and Qt libs using OSGeo4W installer
  3. Install Qt Creator
  4. If you want a debugger,you should install CDB. This can be achieved by installing Windows SDK environment. In the installation process, only select Debugging toos for windows.

I wasn’t able to use the compiler yet, so I am not 100% sure about 4.

Now, if you want to build using Qt Creator, it must be started in a proper environment. Adapt this batch to launch Qt Creator:

ECHO Setting up QGIS DEV ENV

set PYTHONPATH=

set OSGEO4W_ROOT=C:\OSGeo4W
call "%OSGEO4W_ROOT%\bin\o4w_env.bat"

@set QMAKESPEC=win32-msvc2008
@set PATH=%OSGEO4W_ROOT%\bin;%OSGEO4W_ROOT%\apps\qgis-dev\bin;%PATH%

@set INCLUDE=%INCLUDE%;%OSGEO4W_ROOT%\include;%OSGEO4W_ROOT%\apps\qgis-dev\include
@set LIB=%LIB%;%OSGEO4W_ROOT%\lib;%OSGEO4W_ROOT%\apps\qgis-dev\lib

path %OSGEO4W_ROOT%\bin;%SYSTEMROOT%\System32;%SYSTEMROOT%;%SYSTEMROOT%\System32\wbem;C:\Progra~1\Git\bin;C:\Qt\qtcreator-3.0.1\bin;%PATH%

set VS90COMNTOOLS=C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86

start "Qt Creator" /B C:\Qt\qtcreator-3.0.1\bin\qtcreator.exe %*

Then, you need to configure a proper kit in Qt Creator.

  1. Go to Options -> Build & Run -> Compilers and check that Microsoft Visual C++ Compiler 9.0 is correctly detected.
  2. Then in Qt Versions tab, add Qt from the OSGeO installation, normally c:\OSGeo4W\bin\qmake.exe
  3. In Debuggers tab, add cdb.exe found in c:\Debugging tools for windows\ 
  4. Finally, check in Kits that it is properly configured.

Building the application

This is what looks like an application project file.

QT += core gui xml
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = hfp
TEMPLATE = app
SOURCES += YOURSOURCES
HEADERS +=YOUR HEADERS
FORMS += YOUR FORMS
RESOURCES += images/images.qrc

win32:CONFIG(Release, Debug|Release) {
 LIBS += -L"C:/OSGeo4W/lib/" -lQtCore4
 LIBS += -L"C:/OSGeo4W/lib/" -lQtGui4
 LIBS += -L"C:/OSGeo4W/lib/" -lQtXml4
 LIBS += -L"C:/OSGeo4W/apps/qgis-dev/lib/" -lqgis_core
 LIBS += -L"C:/OSGeo4W/apps/qgis-dev/lib/" -lqgis_gui
}
else:win32:CONFIG(Debug, Debug|Release) {
 PRE_TARGETDEPS += C:/OSGeo4W/lib/QtCored4.lib
 PRE_TARGETDEPS += C:/OSGeo4W/lib/QtGuid4.lib
 PRE_TARGETDEPS += C:/OSGeo4W/lib/QtXmld4.lib
 LIBS += -L"C:/OSGeo4W/lib/" -lQtCored4
 LIBS += -L"C:/OSGeo4W/lib/" -lQtGuid4
 LIBS += -L"C:/OSGeo4W/lib/" -lQtXmld4
 LIBS += -L"C:/OSGeo4W/apps/qgis-dev/lib/" -lqgis_core
 LIBS += -L"C:/OSGeo4W/apps/qgis-dev/lib/" -lqgis_gui
}
win32:{
 INCLUDEPATH += C:/OSGeo4W/include
 DEPENDPATH += C:/OSGeo4W/include
 INCLUDEPATH += C:/OSGeo4W/apps/qgis-dev/include
 DEPENDPATH += C:/OSGeo4W/apps/qgis-dev/include
 DEFINES += GUI_EXPORT=__declspec(dllimport) CORE_EXPORT=__declspec(dllimport)
}
unix {
 LIBS += -L/usr/local/lib/ -lqgis_core -lqgis_gui
 LIBS += -L/usr/local/lib/qgis/plugins/ -lgdalprovider
 INCLUDEPATH += /usr/local/include/qgis
 DEFINES += GUI_EXPORT= CORE_EXPORT=
}

Remarks

  • GUI_EXPORT and CORE_EXPORT must be set to __declspec(dllimport). I don’t know exactly what it means, but I found out reading this thread, with some hazardous tries. If you don’t set these, you won’t be able to call any variable defined as extern in QGIS (e.g. cursors).
  • Qt release libraries shall not be mixed up with debug config in your project. In other words, use release libs for release mode and debug libs for debug mode.

With this, you should be able to compile your QGIS application in Qt Creator!

You can find some coding examples on github which are a bit old but still useful to start.

Now, to get the whole potential of QGIS libs, you must initialize the QgsApplication in your main window class:

#if defined(Q_WS_WIN)
  QString pluginPath = "c:\\OSGeo4W\\apps\\qgis-dev\\plugins";
  QString prefixPath = "c:\\OSGeo4W\\apps\\qgis-dev\\";
#else
  QString pluginPath = "/usr/local/lib/qgis/plugins/";
  QString prefixPath = "/usr/local";
#endif

  QgsApplication::setPluginPath( pluginPath );
  QgsApplication::setPrefixPath( prefixPath, true);
  QgsApplication::initQgis();

Deploying on windows

Since QGIS is not to be installed on the target computer, the built app will not be able to find the path declared in previous code.
There is probably a better approach, but here is a way to solve this:
Change the path to

  QString pluginPath = "c:\\myapp\\qgis\plugins";
  QString prefixPath = "c:\\myapp\\qgis";

This means you must deploy the app to this exact location: c:\myapp. In this directory, you need to create a qgis folder in which you will copy c:\OSGeo4W\apps\qgis-dev\resources and c:\OSGeo4W\apps\qgis-dev\plugins.

Besides, this you will need to copy some DLLs to be able to run the applications. You might want to use the dependency walker to find which are needed.

The batch file hereafter creates a folder on the building machine that will contain all the needed files in my case (it might be different in your case).

rmdir c:\myapp /Q /S
mkdir c:\myapp
mkdir c:\myapp\iconengines
mkdir c:\myapp\qgis
mkdir c:\myapp\qgis\resources
mkdir c:\myapp\qgis\plugins

copy PATHTOMYAPP\build-myapp-Desktop-Release\release\myapp.exe c:\myapp\
copy c:\OSGeo4W\bin\QtCore4.dll c:\myapp\
copy c:\OSGeo4W\bin\QtGui4.dll c:\myapp\
copy c:\OSGeo4W\bin\QtXml4.dll c:\myapp\
copy c:\OSGeo4W\bin\QtNetwork4.dll c:\myapp\
copy c:\OSGeo4W\bin\QtSvg4.dll c:\myapp\
copy c:\OSGeo4W\bin\QtWebKit4.dll c:\myapp\

copy c:\OSGeo4W\bin\zlib_osgeo.dll c:\myapp\
copy c:\OSGeo4W\bin\msvcr71.dll c:\myapp\
copy c:\OSGeo4W\bin\phonon4.dll c:\myapp\
copy c:\OSGeo4W\bin\proj.dll c:\myapp\
copy c:\OSGeo4W\bin\geos_c.dll c:\myapp\
copy c:\OSGeo4W\bin\gdal110.dll c:\myapp\
copy c:\OSGeo4W\bin\ogdi_32b1.dll c:\myapp\
copy c:\OSGeo4W\bin\libexpat.dll c:\myapp\
copy c:\OSGeo4W\bin\xerces-c_3_1.dll c:\myapp\
copy c:\OSGeo4W\bin\LIBPQ.dll c:\myapp\
copy c:\OSGeo4W\bin\SSLEAY32.dll c:\myapp\
copy c:\OSGeo4W\bin\LIBEAY32.dll c:\myapp\
copy c:\OSGeo4W\bin\krb5_32.dll c:\myapp\
copy c:\OSGeo4W\bin\comerr32.dll c:\myapp\
copy c:\OSGeo4W\bin\k5sprt32.dll c:\myapp\
copy c:\OSGeo4W\bin\gssapi32.dll c:\myapp\
copy c:\OSGeo4W\bin\hdf_fw.dll c:\myapp\
copy c:\OSGeo4W\bin\mfhdf_fw.dll c:\myapp\
copy c:\OSGeo4W\bin\jpeg_osgeo.dll c:\myapp\
copy c:\OSGeo4W\bin\jpeg12_osgeo.dll c:\myapp\
copy c:\OSGeo4W\bin\netcdf.dll c:\myapp\
copy c:\OSGeo4W\bin\geotiff.dll c:\myapp\
copy c:\OSGeo4W\bin\libtiff.dll c:\myapp\
copy c:\OSGeo4W\bin\sqlite3.dll c:\myapp\
copy c:\OSGeo4W\bin\spatialite4.dll c:\myapp\
copy c:\OSGeo4W\bin\freexl.dll c:\myapp\
copy c:\OSGeo4W\bin\iconv.dll c:\myapp\
copy c:\OSGeo4W\bin\libxml2.dll c:\myapp\
copy c:\OSGeo4W\bin\LIBMYSQL.dll c:\myapp\
copy c:\OSGeo4W\bin\hdf5.dll c:\myapp\
copy c:\OSGeo4W\bin\szip.dll c:\myapp\
copy c:\OSGeo4W\bin\libcurl.dll c:\myapp\
copy c:\OSGeo4W\bin\zlib1.dll c:\myapp\
copy c:\OSGeo4W\bin\openjp2.dll c:\myapp\
copy c:\OSGeo4W\bin\spatialindex1.dll c:\myapp\
copy c:\OSGeo4W\bin\qwt5.dll c:\myapp\

copy c:\OSGeo4W\apps\qt4\plugins\iconengines\qsvgicon4.dll c:\myapp\iconengines\

copy C:\Progra~1\Git\bin\libiconv-2.dll c:\myapp\
copy C:\Progra~1\Git\bin\libintl-8.dll c:\myapp\

copy c:\OSGeo4W\apps\qgis-dev\bin\qgis_Core.dll c:\myapp\
copy c:\OSGeo4W\apps\qgis-dev\bin\qgis_gui.dll c:\myapp\
copy c:\OSGeo4W\apps\qgis-dev\bin\msvcp90.dll c:\myapp\

copy c:\windows\system32\msvcp100.dll c:\myapp\
copy c:\windows\system32\msvcr100.dll c:\myapp\

copy C:\OSGeo4W\apps\qgis-dev\resources\* c:\myapp\qgis\resources
copy C:\OSGeo4W\apps\qgis-dev\plugins\* c:\myapp\qgis\plugins

To be able to run the app, on a fresh windows XP, I had to install:

And copy the whole folder c:\myapp from the building machine to the target machine.

It seems that from Vista, the 2005 redistributable package is included. So, no need to install it.

And voilà!

  • Page 1 of 1 ( 10 posts )
  • c++

Back to Top

Sponsors