Posted by & filed under QGIS.

So my previous article about fusing QGIS Desktop with web technologies generated quite a bit of interest, including some people interested to start hacking on it (always a good sign). In this article I want to show the next level of functionality we can obtain by means of a simple example. There won’t be any flashy graphics here but hopefully it will give you inspiration for other things we can do.

Here is the executive summary and a quick video to demonstrate it:

  • I replaced Metadata tab in the QGIS Raster Layer Properties with a QWebView widget
  • I created a simple web page that accepts a C++ QgsRasterLayer object and then does stuff with it
  • I implemented a Q_PROPERTY on QgsMapLayer (the base class for all map layers) that exposed the metadata property as a read-only property.
  • I created a customised BluePrint CSS template (using a narrower format than the traditional 960 grid) and deployed it in QGIS resources
  • I added a simple button  to the form and used a bit of jquery and javascript to call a slot on the QgsRasterLayer and retrieve its min and max scale properties, then update the page
More details after the break below…
The video demonstrates how the page gets rendered (I havent bothered too much with css etc yet beyond using blueprint for layout), and then the min/max scale is queried from the QgsRasterLayer object. I then change these properties on the general tab, then come back to the metadata tab and when clicking the button, you can see the javascript is hooked into a ‘live’ copy of my QgsRasterLayer object.
[advanced_iframe securitykey="da39a3ee5e6b4b0d3255bfef95601890afd80709" src="http://www.youtube.com/embed/8xBXUPrvwLQ" height="315" width="560"]

You can browse the changes I pushed to my fork of QGIS today so see how I implemented all of this. It was a few minutes work (if you disregard the formatting tweaking I did to the metadata to make it more blueprint friendly). If anyone would like to start pitching in, it would be really nice to have some designers start tweaking the content we deliver in these QWebViews to make them look gob-smackingly beautiful! Next on  my todo list is to make the providers return their metadata as json and then we can properly separate the content from the mark up (and use the metadata in other interesting contexts too).

  • martin

    Hi Tim – interesting stuff!

    Your post makes me think about the impact that would be brought by web technologies. I am trying to put together a list of pros/cons… maybe someone has further points to add?

    The advantages:
    – reuse of the existing JS code
    – attract devs from JS community

    The disadvantages:
    – devs need a good knowledge of JS and its frameworks (dojo? ext? jQuery? YUI?)
    – more bloat: need to ship and parse thousands lines of JS code in order to show (interactive) pages
    – no way to create bindings for seamless interaction (like PyQGIS) with c++/python code
    – more complicated access to content in QWebView outside JS code

    It is clear that in some cases the hybrid approach will be useful, but we should also refrain from moving everything to HTML/JS including porting map canvas to OpenLayers :-)

    Other interesting stuff worth investigating include QML (modern, animated UI) and/or usage of Python directly in QGIS application (simple integration, lots of modules).

    • http://linfiniti.com Tim Sutton

      Hi

      Thanks for the comments Martin. Yes it’s still not clear in my mind what all the valid use cases are yet for this. There are a couple of no-brainers for me:

      – anywhere where we are using QTextEdit to display html. Since the text edit implements a subset of CSS/HTML it makes sense to me that we use webviews rather and take advantage of HTML/CSS in these spaces.
      – places where we want extra functionality without adding new compile time dependencies. Flot being a case in point – if we can completely replace Qwt its one less dependency we have to worry about.
      – places where no equivalent libraries exist in Qt and we don’t want to (or dont have the skills to) re-invent the wheel to provide them – the http://mbostock.github.com/ library being a good example.

      I’ll address a couple of your points below:

      “- more bloat: need to ship and parse thousands lines of JS code in order to show (interactive) pages”

      I would argue that the bloat introduced by these frameworks is minimal. Compared to for example the amount of extra stuff we need to ship to support e.g. GRASS or python bindings, the javascript dependencies are very small and well contained. The html/css/js stuff is also very cleanly laid out under resources/js resources/css and resources/html so its easy for a person to discover an entry point into changing things.

      “- devs need a good knowledge of JS and its frameworks (dojo? ext? jQuery? YUI?)”

      You point about devs needing a good knowledge of JS frameworks I actually see as an advantage in that we open up development of parts of the core application to a huge range of developers who normally wouldn’t have touched the core for fear of C++. Also the interfaces between the C++ api and any JS implementation can be kept really clean. For example I plan to switch the QgsMapLayer::metadata function to return JSON rather than (bad atm) html. That means the developer (who will typically be myopic from a design point of view) can just build a JSON structure and the person actually building the metadata report can just inject data from that json document into a template. JQuery and other frameworks also provide templating systems which Qt lacks providing yet another level of clean data abstraction. My suggestion would be that we settle on one framework. I am personally a fan of jQuery and so that would be my suggestion unless someone has a compelling reason why another is better.

      “- no way to create bindings for seamless interaction (like PyQGIS) with c++/python code”

      I believe we can do this with QtScript. Also you can pass any C++ QObject into the jscript space and use it there. So if we create bindings to enable the js client to create geometries etc, we should fairly easily be able to allow users to do things like instantiate a provider, add a geometry etc. Also the use of Qt’s properties system allows for a clean way for uses accessors and mutators from within the Javascript context.

      “- more complicated access to content in QWebView outside JS code”

      I don’t have a strong feeling as to whether this is true or not. If you want to reach in directly to the web view and grab stuff then yes you are probably right. However since you can pass any QObject into the web view and let the view change it’s state (as my vid in this post illustrates) it is probably just a matter of adjusting the approach you take to moving content between the web view and the core app.

      “It is clear that in some cases the hybrid approach will be useful, but we should also refrain from moving everything to HTML/JS including porting map canvas to OpenLayers ”

      OpenLayers would probably do a poor job of editing my large datasets. But I definately think that having html based widgets overlaid on the canvas (as mapcanvas items) opens up a world of possibilities.

      “Other interesting stuff worth investigating include QML (modern, animated UI) and/or usage of Python directly in QGIS application (simple integration, lots of modules).”

      Yes this (QML) is definately one area that I am keen to investigate and see what benifits it can offer us both on the mobile port and on the desktop.

      Thanks for the comments!

      Regards

      Tim

      • martin

        Agreed about the usage of QWebView for instances where we use QTextEdit for showing rich text and for functionality not provided by Qt or other libraries.

        Regarding Qwt actually it may be good to keep it as it fits into Qt ecosystem. What are the main objections against using it? I have only very limited experience using it, so I may be missing something. The default appearance of the graphs is a bit dull, but that can be easily modified to use antialiasing and thicker lines to get a bit more modern look.

        (In general it would be good to have a common graph plotting framework in QGIS, so that the graphs look consistently – whether being from qgis itself or from a plugin.)

        Regarding attraction of JS developers afraid of C++: this may not necessarily work because often you need to fiddle also with C++ world – to pass some more stuff from C++ to JS or vice versa (to propagate some events/changes to C++ backend). An important question is what capabilities would attract new people to come and contribute. This applies also to Python: if we implemented some parts of QGIS application in python, would that bring more contributors? Probably not, because you still need to dive into compiling QGIS from source etc.

        Regarding the bloat: I was merely referring to the overhead needed to parse everytime a lot of javascript code in order to show a graph / do something else. Maybe it’s not that bad, anyway it would be interesting to know the time required for initialization of such javascript libraries.

        Integration with c++/python: yes it is possible to pass QObject instances to JS, but there are various classes in QGIS that are not derived from QObject – e.g. QgsFeature, QgsGeometry – and for performance reasons they should not be QObject children. Such classes would need some special wrappers – maybe a utility class that would handle serialization between JSON and class instance.

        Showing some web content directly in map canvas sounds good. There is already QGraphicsWebView class for that (from qt 4.6). Maybe a question will be how to handle mouse/keyboard events: currently they are always passed to the active map tool.

        I do not mean that the usage of web technologies in QGIS is a bad idea. My point is that we should clearly define their scope within QGIS. Use them just for showing some read-only content? Use them in some dialogs as interactive elements? Allow JS scripting/plugins?

  • drew

    Tim, can this be applied to the identify results window? (I’m assuming there is no reason why it can’t).

    I can see potential (for my work) for linking assets to multiple attachments (photos, documents etc) in a different way to eVis and other plugins. I like the way they do this in web apps. For example web apps that link photos to assets often do it with a nice javascript image slideshow like the ones here http://valums.com/javascript-image-galleries/ – How ever typically in GIS apps that I have used they return a link to the image and you then have to download it or view it in MS Paint or view it in the GIS app in some obsure pop up.

    I think as we move forward everything is getting more web focused. I think if QGIS can leverage this web functionality then you are on a winner.