QGIS Planet Tags
EN | PT
Now and then I get too many map symbols (points) in the same place, and I thought how nice it would be if we could drag n’ drop them around without messing with their geometries position, just like we do with labels. That thought gave me an idea for a cool hack.
Choose your point layer and start by creating two new fields called symbX and symbY (Type: Decimal number; Size: 20; Precision: 5). Now go the layer properties and in the Style tab edit your symbol. For each level of your symbol select “map units” as the offset units, and set the following expression in the offset data define properties option:
CASE WHEN symbX IS NOT NULL AND symbY IS NOT NULL THEN tostring($x - symbX) + ',' + tostring($y - symbY) ELSE '0,0' END
Be aware that, if your coordinates have negative values, you need to adapt the code. E.g., If you have negative values in X you should use “tostring(symbX -$x)” instead.
Now, temporarly label your layer with a small convenient text (I used a centered ‘+’ (plus sign) with a white buffer) and set its coordinates to data defined using the symbX and symbY Fields.
From this point on, when you use the move label tool, not only the label position change but also the actual symbol! Pretty cool, isn’t it?
Notice that the features geometries are not changed during the process. Also, remember that in this case you can also add leading lines to connect the symbols to the original position of the points.
The Oceancolor Data Downloader is a new plugin for QGIS from the Mapping and Geographic Information Centre of the British Antarctic Survey that downloads Oceancolor and Sea Surface Temperature data from NASA’s Oceancolor website. The plugin currently downloads three datasets:
The data accessed includes daily, 8 day, monthly and yearly composites, all of which can be saved to disk while downloading. Future plans for the plugin include additional access to other datasets such as ocean Net Primary Production, selection by bounding box, the ability to save in other formats, a progress bar etc.
I used the plugin to download global Sea Surface Temperatures for the 13th Jan 2015. I then used shapefiles from Natural Earth to create a simple basemap. I finally chose the IBCAO Polar Stereographic projection (EPSG: 3996) to create a map centred on the North Pole.
If you use the plugin to produce published research, please cite:
EN | PT
I had the need to add columns with the coordinates of polygons centroids. I came up with the following expressions to calculate X e Y, respectively:
xmin(centroid($geometry)) ymin(centroid($geometry))
The expression seems quite simple, but it toke me some time before I realize that, not having a x(geometry) and y(geometry) functions, I could use the xmin() and ymin() to get the coordinates of the polygons centroids. Since this wasn’t the first time I had to use this expressions, this post will work as a reminder for the future.
A very handy plugin for QGIS I use day to day is go2streetview by Enrico Ferreguti. The plugin adds an icon to the tool bar in QGIS and when selected I can click a road or street on a base map and a window will open that displays the Google Street or a Bing Maps Bird’s Eye view of the location. The camera’s direction and location is highlighted by a blue marker. I use the plugin when tracing boundaries of parks, open spaces and foot paths from aerial imagery. If the imagery is blurred or the view is obscured by trees, I click a point on a nearby street to see the location up close. The plugin works wherever Google Street view and Bing Birds Eye has coverage.
For example, in the screen-shot below notice there is a footpath leading to a bus shelter that’s not mapped by OpenStreetMap. I know where it is now, I will add it to my map.
EN | PT
Recently I had the need to add labels to features with very close geometries, resulting in their collision.
Using data-defined override for label’s position (I have used layer to labeled layer plugin to set this really fast) and the QGIS tool to move labels, it was quite easy to relocate them to better places. However, in same cases, it was difficult to understand to which geometry they belonged.
I needed some kind of leading lines to connect, whenever necessary, label and feature. I knew another great plugin called “Easy Custom Labeling“, by Regis Haubourg, that did what I needed, but it would create a memory duplicate of the original layer, wish meant that any edition on the original layer wouldn’t be updated in the labels.
Since the data were stored in a PostgreSQL/Postgis database, I have decided to create a query that would return a layer with leading lines. I used the following query in DB manager:
SELECT gid, label, ST_Makeline(St_setSRID(ST_PointOnSurface(geom),27493), St_setSRID(St_Point(x_label::numeric, y_label::numeric),27493)) FROM epvu.sgev WHERE x_label IS NOT NULL AND y_label IS NOT NULL AND NOT ST_Within(ST_Makeline(St_setSRID(ST_PointOnSurface(geom),27493), St_setSRID(St_Point(x_label::numeric, y_label::numeric),27493)),geom))
This query creates a line by using the feature centroid as starting point and the label coordinate as end point. The last condition on the WHERE statement assures that the lines are only created for labels outside the feature.
With the resulting layer loaded in my project, all I need is to move my labels and save the edition (and press refresh) to show a nice leading line.
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.
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.
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.
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
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();
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:
Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package MFC Security Update
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à!