Related Plugins and Tags

QGIS Planet

Faster maps with progressive WMS

The good old OGC WMS has many advantages compared to tiled maps:

  • Continious zoom levels
  • Support for different projections
  • Combination of multiple layers in one request
  • Higher resolutions for printing
  • Better labelling
  • No maintenance needed when updating data

Well known disadvantages are scalability issues for high-traffic sites and a slower response time for complex maps.

The second point can be significantly improved by using a technique known from the progressive JPEG format. Before loading a map with full resolution, a map image with a lower resolution is requested from the server. This results in a better response time, because rendering and transmitting of the low resolution image is significantly faster. The biggest effect on rendering time is in combination with raster layers, but also for vector layers the improvement can be substantial.

High resolution:

Low resolution:

The technique can be easily applied to any WMS using this basic OpenLayers implementation.

There is much room for improvements. The low resolution layer could be tiled, limited to certain zoom levels or having a larger extend for smoother panning.

QGISCloud has this optimization built into the QGIS Web-Client viewer, which helps collecting experience with a wide range of datasets.

Faster maps with progressive WMS

The good old OGC WMS has many advantages compared to tiled maps:

  • Continious zoom levels
  • Support for different projections
  • Combination of multiple layers in one request
  • Higher resolutions for printing
  • Better labelling
  • No maintenance needed when updating data

Well known disadvantages are scalability issues for high-traffic sites and a slower response time for complex maps.

The second point can be significantly improved by using a technique known from the progressive JPEG format. Before loading a map with full resolution, a map image with a lower resolution is requested from the server. This results in a better response time, because rendering and transmitting of the low resolution image is significantly faster. The biggest effect on rendering time is in combination with raster layers, but also for vector layers the improvement can be substantial.

High resolution:

Low resolution:

The technique can be easily applied to any WMS using this basic OpenLayers implementation.

There is much room for improvements. The low resolution layer could be tiled, limited to certain zoom levels or having a larger extend for smoother panning.

QGISCloud has this optimization built into the QGIS Web-Client viewer, which helps collecting experience with a wide range of datasets.

Serving multiple WFS-T with TinyOWS

Our favorite WFS-T server complement of UMN Mapserver is TinyOWS. We like the simplicity of it so much, that we packaged it for Ubuntu and added it to OSGeoLive. Installation is easy:

sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update
sudo apt-get install tinyows

The simplicity is a little bit too much, when it comes to serve multiple WFS-T on the same server. There is only one configuration file, but we want a configuration for each service. There are solutions for that, but I never saw a documentation of the most elegant solution we found. It uses Apache rewrite capabilities to set the TINYOWS_CONFIG_FILE environment variable according to the called URL:

# URL rewriting
RewriteEngine On

# Forbid direct access
RewriteRule ^/cgi-bin/.*$ - [F]

# Rewrite /xxx to /cgi-bin/tinyows with TINYOWS_CONFIG_FILE=/etc/tinyows/xxx.xml
RewriteRule ^/(.+)$ /cgi-bin/tinyows [QSA,PT,L,E=TINYOWS_CONFIG_FILE:/etc/tinyows/$1.xml]

This configuration included in a virtual host declaration (wfs.example.com) serves your WFS-T on wfs.example.com/servicename.

installing Postgis 2.0 under Debian wheezy

We’ll be using Postgis2.0 from UbuntuGIS, which has packages for a number of recent Ubuntu releases. Since Ubuntu precise has libc6 2.14 and Debian wheezy only 2.13 we fall back on Ubuntu oneiric for packages, which also has libc6 2.13.

However Postgis 2.0 in UbuntuGIS depends on a lot of llibraries which were in squeeze but live in wheezy under a higher version. Therefore we’ll install a lot of packages from Debian squeeze. Fortunately the libraries are versioned themselves and thus can be installed along the libraries from Debian wheezy.

Let’s go. Add the Debian squeeze sources:

# SRC="deb http://ftp.ch.debian.org/debian/ wheezy main"
# echo "$SRC" >> /etc/apt/sources.list

We’ll also add the security source, in case Debian releases a security update.

# SRC="deb http://ftp.ch.debian.org/debian/ wheezy main"
# echo "$SRC" >> /etc/apt/sources.list

You may want to replace ftp.ch.debian.org by a debian mirror nearer to you.

Now add the UbuntuGIS sources:

# SRC="deb http://ppa.launchpad.net/ubuntugis/ubuntugis-unstable/ubuntu oneiric main"
# echo "$SRC" > /etc/apt/sources.list.d/ubuntugis.list

Now update and try to install postgis:

# apt-get update
# apt-get install postgresql-9.1-postgis

Create your database:

# sudo su
# su - postgres
$ psql postgres
postgres=# CREATE DATABASE your_db OWNER your_preferred_user:

Now add the postgis features to that database:

$ psql -d your_db -f /usr/share/postgresql/9.1/contrib/postgis-2.0/
$ psql -d your_db -f /usr/share/postgresql/9.1/contrib/postgis-2.0/spatial_ref_sys.sql

That should be it. Let’s hope it works.

A final warning: you are mixing multiple distributions here. This can lead to problems. Due to version conflicts upgrading packages can become very difficult.

Tomáš Pospíšek tpo_hp@sourcepole.ch

Howto shrink a remote root ext3 filesystem on Debian wheezy

This howto describes how to resize a root ext3 filesystem on a remote Debian wheezy server.

This howto is not an original work but only an update of an older howto by Stefan @ https://thunked.org/. This version is specifically adapted to a server running Debian wheezy.

DISCLAIMER:

THERE IS A DECENT CHANCE THAT IF YOU FUCK THIS UP YOUR
REMOTE SYSTEM SIMPLY WONT BOOT AT ALL.  I URGE YOU TO TEST
THIS LOCALLY BEFORE USING THIS METHOD ON A PRODUCTION
SYSTEM. ESPECIALLY IF YOUR SYSTEM IS NOT DEBIAN WHEEZY,
SINCE THAT'S THE ONLY ONE I HAVE TESTED.

THE QUICK WAY:

If you don't want to read the whole thing you can only
execute the commands I run and probably skip the
explanations.

I’ve only done this on Debian Wheezy. If you’re using another distro the initrd layout and init scripts may be a bit different. However, I suspect it looks very similar on almost every distro out there. On Debian my root partition is an ext3 partition.

The general idea is pretty simple: you can’t shrink a mounted partition and it’s impossible to unmount or replace your root partition in a live system, so we have to resize the partition before it is mounted. What we’ll do to accomplish this is change the initrd image to make the init scripts resize the root partition before mounting it. This is by far the most flexible and easy method to resize your root partition I could think of. Most suggestions I found on google required you to create separate OS on a new root partition and boot into that, but I did not have any space to create a new root partition on my remote machine.

Unpacking the initrd image is fairly straight forward:

$ mkdir ~/initrd; cd ~/initrd
$ gunzip -c /boot/initrd.img-3.2.0-3-amd64 | cpio -i --make-directories
62631 blocks
$ ls -l
total 40
drwxr-xr-x 2 root root 4096 Sep 11 20:23 bin
drwxr-xr-x 3 root root 4096 Sep 11 20:23 conf
drwxr-xr-x 6 root root 4096 Sep 11 20:23 etc
-rwxr-xr-x 1 root root 6797 Sep 11 20:23 init
drwxr-xr-x 7 root root 4096 Sep 11 20:23 lib
drwxr-xr-x 2 root root 4096 Sep 11 20:23 lib64
drwxr-xr-x 2 root root 4096 Sep 11 20:23 run
drwxr-xr-x 2 root root 4096 Sep 11 20:23 sbin
drwxr-xr-x 6 root root 4096 Sep 11 20:23 scripts

First, we have to copy all the programs we need to resize our partition onto the initial ram disk. For my ext3 file system I need e2fsck and resize2fs. The programs are depending on a few libraries, so you’ll need to copy those to the new initrd image too. Libraries can also depend on other libraries, make sure you recursively check dependencies until you don’t have any missing dependencies anymore.

$ ldd /sbin/e2fsck
    linux-vdso.so.1 =>  (0x00007fff3594c000)
    libext2fs.so.2 => /lib/x86_64-linux-gnu/libext2fs.so.2 (0x00007f7cdddd5000)
    libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f7cddbd1000)
    libblkid.so.1 => /lib/x86_64-linux-gnu/libblkid.so.1 (0x00007f7cdd9a9000)
    libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f7cdd7a4000)
    libe2p.so.2 => /lib/x86_64-linux-gnu/libe2p.so.2 (0x00007f7cdd59c000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7cdd214000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7cdcff8000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f7cde01e000)
$ ldd /sbin/resize2fs
    linux-vdso.so.1 =>  (0x00007fffa216a000)
    libe2p.so.2 => /lib/x86_64-linux-gnu/libe2p.so.2 (0x00007fa01f7a2000)
    libext2fs.so.2 => /lib/x86_64-linux-gnu/libext2fs.so.2 (0x00007fa01f55f000)
    libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007fa01f35a000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa01efd3000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa01edb7000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fa01f9b0000)

We only copy the libraries that are not yet present in the initramfs. Fortunately in our case there are no recursive dependencies of those libraries.

$ for i in libext2fs.so.2.4 libcom_err.so.2.1 libe2p.so.2.3; do \
     cp -i /lib/x86_64-linux-gnu/$i lib/x86_64-linux-gnu/; \
  done
$ cd lib/x86_64-linux-gnu/
$ ln -s libcom_err.so.2.1 libcom_err.so.2
$ ln -s libext2fs.so.2.4 libext2fs.so.2
$ ln -s libe2p.so.2.3 libe2p.so.2
$ cd ~/initrd/

$ cp /sbin/e2fsck ~/initrd/bin/
$ cp /sbin/resize2fs ~/initrd/bin/

Next, we need to edit the init script. Debian uses busybox in its initrd image so the init script will be interpreted by a bourne shell. If you look through the init script file you’ll find the moment where the script mounts the root file system:

$ cat scripts/local
...
    # FIXME This has no error checking
    # Mount root
    if [ "${FSTYPE}" != "unknown" ]; then
            mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
    else
            mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
    fi
...

Simply add in the commands to resize the file system right before the the file system is mounted. Resize2fs in Debian does not want to resize the file system before it is forcefully checked. It may be wise to add the -p or -y flag to e2fsck. -y will answer yes to all questions, this could prevent a hung system but may cause more damage to your files or filesystem. The -p flag will only automatically answer yes to safe operations. resize2fs takes two parameters, the first is the block device that has the ext2 or ext3 file system and the second is the new size you want to give it. By default the size is in blocks, but you can append a unit to change that. ‘K’ for kilobytes, ‘M’ for megabytes, ‘G’ for gigabytes and ‘T’ for terabytes. If you don’t specify a size, it will enlarge the file system to the total size of the partition or logical volume. After adding the commands the init script will look something like this:

    #RESIZEROOTFS MODIFIED!!! DONT RUN MORE THAN ONCE
    _log_msg "Starting e2fsck"
    /bin/e2fsck -p -f -C 0 /dev/sda4 || true
    _log_msg "Starting resize2fs"
    /bin/resize2fs /dev/sda4 100G || true

    # FIXME This has no error checking
    # Mount root
    if [ "${FSTYPE}" != "unknown" ]; then
            mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
    else
            mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
    fi

If you have access to the system’s console, you might want to add a “-C 0” to e2fsck’s parameters. That will show you the progress of the fscheck.

There’s one last thing we have to do before re-packing the initrd image. e2fsck and resize2fs will fail if there is no /etc/mtab file available so we’ll have to make sure /etc/mtab exists.

$ touch ~/initrd/etc/mtab
$ cd ~/initrd/
$ find ./ | cpio -H newc -o > /tmp/initrd.cpio
64097 blocks
$ gzip -c /tmp/initrd.cpio > /boot/initrd-resize.img

And lastly, we need to add a new default boot option in grub. In Debian grub’s configuration file is constructed from various bits under /etc/grub.d. The resulting total configuration file is put under /boot/grub/grub.cfg. Open up the grub.cfg file in your favorite text editor and look for the default entry. It’s usually the first one, but may vary. Add a copy of the original entry to /etc/grub.d/40_custom and change the initrd image to the one we just created.

$ cat /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

menuentry 'resize' --class debian --class gnu-linux --class gnu --class os {
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='(hd0,gpt1)'
        search --no-floppy --fs-uuid --set=root 0aa8bc27-17e3-4ae2-a9cf-497ab444970b
        echo    'Loading Linux 3.2.0-3-amd64 ...'
        linux   /vmlinuz-3.2.0-3-amd64 root=UUID=660f79dc-c152-4e15-ad61-7075b42de609 ro  quiet
        echo    'Loading initial ramdisk ...'
        initrd  /initrd-resize.img
}

Now make sure that it’s this entry that will be booted into by default. Set GRUB_DEFAULT in /etc/default/grub to the name of the entry you’ve just created:

$ cat /etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'

#GRUB_DEFAULT=0
GRUB_DEFAULT="resize"
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
...

Finally, you can reboot the system. When it comes back online (if it comes back grin) your file system will be resized. Be aware that e2fsck and resizefs take a long time on big disks. On my system the two took 2 hours for a 1.5T filesystem. Thus don’t prematurely reboot your system if it doesn’t come up again quickly.

Don’t forget to remove the new grub entry, so your file system doesn’t get resized every time you boot.

Original howto at https://thunked.org/general/howto-shrink-a-remote-root-ext3-filesystem-t96.html

Original howto Written by Stefan @ https://thunked.org/

This version for Debian wheezy by Tomáš Pospíšek

Microsoft blocking emails to you

It’s now a month, that we can’t send email to any Microsoft owned mail domain - for example to hotmail.com or to live.com.

Microsoft is blocking us. We can actually communicate with their first level support staff responsible for the mail servers, however they will neither tell us why we are blocked, nor what we have to do to get unblocked, nor when the block would get lifted.

They propose a whole laundry list of things for us to do - registering with them and constantly maintaining and monitoring our status at some service of theirs. We’d certainly spend half a week to implement those measures and then spend ongoing time to maintain them. But none of that is guaranteed to be of any help.

So if you need to email us then please do not use any of your hotmail accounts for the communication - we unfortunately can not reach you any more.

And it seems we’re not the only ones receiving that treatment by Microsoft.

Microsoft blocking emails to you

It’s now a month, that we can’t send email to any Microsoft owned mail domain - for example to hotmail.com or to live.com.

Microsoft is blocking us. We can actually communicate with their first level support staff responsible for the mail servers, however they will neither tell us why we are blocked, nor what we have to do to get unblocked, nor when the block would get lifted.

They propose a whole laundry list of things for us to do - registering with them and constantly maintaining and monitoring our status at some service of theirs. We’d certainly spend half a week to implement those measures and then spend ongoing time to maintain them. But none of that is guaranteed to be of any help.

So if you need to email us then please do not use any of your hotmail accounts for the communication - we unfortunately can not reach you any more.

And it seems we’re not the only ones receiving that treatment by Microsoft.

per user X11 options

One would expect that considered the complexity of gdm there would be a way to have per user X11 options. So no, there isn’t one. At least not after the great rewrite after V2.22.

However good old Unix paradigms can help us (this is all under Debian, other Unices will allow a similar trick):

$ vim /usr/local/bin/X

Add something similar like this:

#!/bin/sh
#
# start X with different options depending on user

# check if the parent gdm process that started us contains
# "--username le_gamer" in its commandline
#
if ps -p $PPID -o args= | grep -q 'username le_gamer';
then
  exec /etc/X11/X.orig $* -config /etc/X11/xorg.conf.le_gamer
else
  exec /etc/X11/X.orig $*
fi

We check whether gdm is starting us and using the parameter “–username le_gamer”. If it is, then we’re using a different config file for X.

Of course you’ll need to adapt all this, unless you are using Debian or Ubuntu. You need to adapt the path to the X Server, to the config files etc.

Why did I do that? The problem is that Intel’s X server in Ubuntu Lucid Lynx 10.04 is really unstable with DRI on a Intel GM965/GL960 graphics card.

So unless I’m playing 3D games which are a lot faster with DRI, I don’t want to enable DRI (more over, “NoDRI” is pulling less power out of my battery). So my normal config contains this:

$ cat /etc/X11/xorg.conf
[...]
Section "Device"
        Identifier      "Configured Video Device"
        Option          "NoDRI"
EndSection

So now, the only thing you need to do is replace your “normal” X Server with the new “adaptable” one:

$ sudo mv /etc/X11/X /etc/X11/X.orig
$ ln -s /usr/local/bin/X /etc/X11/X

That’s it,

Tomáš Pospíšek

per user X11 options

One would expect that considered the complexity of gdm there would be a way to have per user X11 options. So no, there isn’t one. At least not after the great rewrite after V2.22.

However good old Unix paradigms can help us (this is all under Debian, other Unices will allow a similar trick):

$ vim /usr/local/bin/X

Add something similar like this:

#!/bin/sh
#
# start X with different options depending on user

# check if the parent gdm process that started us contains
# "--username le_gamer" in its commandline
#
if ps -p $PPID -o args= | grep -q 'username le_gamer';
then
  exec /etc/X11/X.orig $* -config /etc/X11/xorg.conf.le_gamer
else
  exec /etc/X11/X.orig $*
fi

We check whether gdm is starting us and using the parameter “–username le_gamer”. If it is, then we’re using a different config file for X.

Of course you’ll need to adapt all this, unless you are using Debian or Ubuntu. You need to adapt the path to the X Server, to the config files etc.

Why did I do that? The problem is that Intel’s X server in Ubuntu Lucid Lynx 10.04 is really unstable with DRI on a Intel GM965/GL960 graphics card.

So unless I’m playing 3D games which are a lot faster with DRI, I don’t want to enable DRI (more over, “NoDRI” is pulling less power out of my battery). So my normal config contains this:

$ cat /etc/X11/xorg.conf
[...]
Section "Device"
        Identifier      "Configured Video Device"
        Option          "NoDRI"
EndSection

So now, the only thing you need to do is replace your “normal” X Server with the new “adaptable” one:

$ sudo mv /etc/X11/X /etc/X11/X.orig
$ ln -s /usr/local/bin/X /etc/X11/X

That’s it,

Tomáš Pospíšek

per user X11 options

One would expect that considered the complexity of gdm there would be a way to have per user X11 options. So no, there isn’t one. At least not after the great rewrite after V2.22.

However good old Unix paradigms can help us (this is all under Debian, other Unices will allow a similar trick):

$ vim /usr/local/bin/X

Add something similar like this:

#!/bin/sh
#
# start X with different options depending on user

# check if the parent gdm process that started us contains
# "--username le_gamer" in its commandline
#
if ps -p $PPID -o args= | grep -q 'username le_gamer';
then
  exec /etc/X11/X.orig $* -config /etc/X11/xorg.conf.le_gamer
else
  exec /etc/X11/X.orig $*
fi

We check whether gdm is starting us and using the parameter “–username le_gamer”. If it is, then we’re using a different config file for X.

Of course you’ll need to adapt all this, unless you are using Debian or Ubuntu. You need to adapt the path to the X Server, to the config files etc.

Why did I do that? The problem is that Intel’s X server in Ubuntu Lucid Lynx 10.04 is really unstable with DRI on a Intel GM965/GL960 graphics card.

So unless I’m playing 3D games which are a lot faster with DRI, I don’t want to enable DRI (more over, “NoDRI” is pulling less power out of my battery). So my normal config contains this:

$ cat /etc/X11/xorg.conf
[...]
Section "Device"
        Identifier      "Configured Video Device"
        Option          "NoDRI"
EndSection

So now, the only thing you need to do is replace your “normal” X Server with the new “adaptable” one:

$ sudo mv /etc/X11/X /etc/X11/X.orig
$ ln -s /usr/local/bin/X /etc/X11/X

That’s it,

Tomáš Pospíšek

per user X11 options

One would expect that considered the complexity of gdm there would be a way to have per user X11 options. So no, there isn’t one. At least not after the great rewrite after V2.22.

However good old Unix paradigms can help us (this is all under Debian, other Unices will allow a similar trick):

$ vim /usr/local/bin/X

Add something similar like this:

#!/bin/sh
#
# start X with different options depending on user

# check if the parent gdm process that started us contains
# "--username le_gamer" in its commandline
#
if ps -p $PPID -o args= | grep -q 'username le_gamer';
then
  exec /etc/X11/X.orig $* -config /etc/X11/xorg.conf.le_gamer
else
  exec /etc/X11/X.orig $*
fi

We check whether gdm is starting us and using the parameter “–username le_gamer”. If it is, then we’re using a different config file for X.

Of course you’ll need to adapt all this, unless you are using Debian or Ubuntu. You need to adapt the path to the X Server, to the config files etc.

Why did I do that? The problem is that Intel’s X server in Ubuntu Lucid Lynx 10.04 is really unstable with DRI on a Intel GM965/GL960 graphics card.

So unless I’m playing 3D games which are a lot faster with DRI, I don’t want to enable DRI (more over, “NoDRI” is pulling less power out of my battery). So my normal config contains this:

$ cat /etc/X11/xorg.conf
[...]
Section "Device"
        Identifier      "Configured Video Device"
        Option          "NoDRI"
EndSection

So now, the only thing you need to do is replace your “normal” X Server with the new “adaptable” one:

$ sudo mv /etc/X11/X /etc/X11/X.orig
$ ln -s /usr/local/bin/X /etc/X11/X

That’s it,

Tomáš Pospíšek

annotating third party web pages

Problem: I have a web site/page that I visit regularily which I want to annotate with my notes.

More specifically, I was regularly searching through the Homegate real estate hub looking for a new home. It goes without saying that I was again and again forgetting which objects I had already looked at, which objects were really interesting and I should check out more closely.

Therefore the need to annotate search results.

The here presented approach should be applicable for annotation of other web pages as well. It’s based on the observation, that restful web applications need to operate with asset IDs. These asset IDs can be reused to enrich the asset locally with additional data, such as notes. Thus we’re looking for those IDs in specific elements of the page and add a bit of HTML markup to those places.

Of course that aproach only works as long as the web site doesn’t heavily change its markup and doesn’t rendomly change asset IDs.

Here’s a screenshot of regular Homegate search results:

And here’s the same page after scripting it with Greasemonkey:

You’ll notice the input field with the comment in it.

The idea is simple: add an input box to each search result, where you write your comment. When the focus leaves the input box, the comment is stored to localStorage.

Starting with Greasemonkey is quite easy. There are howtos and templates to start from, such as this one.

However, regular JavaScripting and Greasemonkey JavaScripting do not work in exactly the same way:

One of the differences is that Greasemonkey creates a separate JavaScript environment, in which the Greasemonkey scripts are executed. That is calling Javascript contained in the page from Greasemonkey and the inverse calling Greasemonkey scripts from the page is not possible by default. This is on purpose, so that the web page can not detect and not interfere with the Greasemonkey scripts, because you want your Greasemonkey scripts to work allways on some page, whether or not that page likes it or not. Therefore no interference is possible.

Greasemonkey however provides a standard way to access the web page’s scripts, and that’s through the “unsafeWindow” object, which is a reference to the web page’s environment.

I had two mechanisms I had to make accessible using the “unsafeWindow” handle:

  • the first was accessing JQuery, which is included by default by the Homegate page. Since I needed to use JQuery functions in my Greasemonkey script, I got a reference to it via the standard Greasemonkey precedure:
    var jQuery = unsafeWindow['jQuery'];
  • the second mechanism that needed to cross the boundaries between the web page and Greasemonkey was callbacks from the web page to my Greasemonkey script. This is necessary, because I’m attaching “input” elements to each search result, which contain a note and which, “onblur”, need to call a function that saves the content of the input box. Here’s part that constructs the input element:
    jQuery("<input onclick='event.cancelBubble = true;'" +
                 " onblur='saveComment(this, immoID);'>").insertAfter(immoElement);

And this is the function that gets called back by “onblur”:

    unsafeWindow.saveComment = function(element, immoID) {
      unsafeWindow.localStorage.setItem(immoID, element.value);
    };

The next interesting thing you’ll note is usage of ‘locaStorage’. Support for the latter in browsers does not seem mature yet. One problem I’ve encountered when developing under Firefox 3.6 was that saving to ‘localStorage’ was not possible when cookies were disabled (see this report). Thus you’ll need to permanently enable cookies for Homegate in order for the script to be able to save its data.

Finally, while developing, a major problem was, that Firefox did not show me errors in the Greasemonkey scripts. Thus either the script would work or not work and fail completely silently. That made debugging a bit painful.

So now, here’s the script.

Tomáš Pospíšek

PS: This script also lives at userscripts.org

annotating third party web pages

Problem: I have a web site/page that I visit regularily which I want to annotate with my notes.

More specifically, I was regularly searching through the Homegate real estate hub looking for a new home. It goes without saying that I was again and again forgetting which objects I had already looked at, which objects were really interesting and I should check out more closely.

Therefore the need to annotate search results.

The here presented approach should be applicable for annotation of other web pages as well. It’s based on the observation, that restful web applications need to operate with asset IDs. These asset IDs can be reused to enrich the asset locally with additional data, such as notes. Thus we’re looking for those IDs in specific elements of the page and add a bit of HTML markup to those places.

Of course that aproach only works as long as the web site doesn’t heavily change its markup and doesn’t rendomly change asset IDs.

Here’s a screenshot of regular Homegate search results:

And here’s the same page after scripting it with Greasemonkey:

You’ll notice the input field with the comment in it.

The idea is simple: add an input box to each search result, where you write your comment. When the focus leaves the input box, the comment is stored to localStorage.

Starting with Greasemonkey is quite easy. There are howtos and templates to start from, such as this one.

However, regular JavaScripting and Greasemonkey JavaScripting do not work in exactly the same way:

One of the differences is that Greasemonkey creates a separate JavaScript environment, in which the Greasemonkey scripts are executed. That is calling Javascript contained in the page from Greasemonkey and the inverse calling Greasemonkey scripts from the page is not possible by default. This is on purpose, so that the web page can not detect and not interfere with the Greasemonkey scripts, because you want your Greasemonkey scripts to work allways on some page, whether or not that page likes it or not. Therefore no interference is possible.

Greasemonkey however provides a standard way to access the web page’s scripts, and that’s through the “unsafeWindow” object, which is a reference to the web page’s environment.

I had two mechanisms I had to make accessible using the “unsafeWindow” handle:

  • the first was accessing JQuery, which is included by default by the Homegate page. Since I needed to use JQuery functions in my Greasemonkey script, I got a reference to it via the standard Greasemonkey precedure:
    var jQuery = unsafeWindow['jQuery'];
  • the second mechanism that needed to cross the boundaries between the web page and Greasemonkey was callbacks from the web page to my Greasemonkey script. This is necessary, because I’m attaching “input” elements to each search result, which contain a note and which, “onblur”, need to call a function that saves the content of the input box. Here’s part that constructs the input element:
    jQuery("<input onclick='event.cancelBubble = true;'" +
                 " onblur='saveComment(this, immoID);'>").insertAfter(immoElement);

And this is the function that gets called back by “onblur”:

    unsafeWindow.saveComment = function(element, immoID) {
      unsafeWindow.localStorage.setItem(immoID, element.value);
    };

The next interesting thing you’ll note is usage of ‘locaStorage’. Support for the latter in browsers does not seem mature yet. One problem I’ve encountered when developing under Firefox 3.6 was that saving to ‘localStorage’ was not possible when cookies were disabled (see this report). Thus you’ll need to permanently enable cookies for Homegate in order for the script to be able to save its data.

Finally, while developing, a major problem was, that Firefox did not show me errors in the Greasemonkey scripts. Thus either the script would work or not work and fail completely silently. That made debugging a bit painful.

So now, here’s the script.

Tomáš Pospíšek

PS: This script also lives at userscripts.org

annotating third party web pages

Problem: I have a web site/page that I visit regularily which I want to annotate with my notes.

More specifically, I was regularly searching through the Homegate real estate hub looking for a new home. It goes without saying that I was again and again forgetting which objects I had already looked at, which objects were really interesting and I should check out more closely.

Therefore the need to annotate search results.

The here presented approach should be applicable for annotation of other web pages as well. It’s based on the observation, that restful web applications need to operate with asset IDs. These asset IDs can be reused to enrich the asset locally with additional data, such as notes. Thus we’re looking for those IDs in specific elements of the page and add a bit of HTML markup to those places.

Of course that aproach only works as long as the web site doesn’t heavily change its markup and doesn’t rendomly change asset IDs.

Here’s a screenshot of regular Homegate search results:

And here’s the same page after scripting it with Greasemonkey:

You’ll notice the input field with the comment in it.

The idea is simple: add an input box to each search result, where you write your comment. When the focus leaves the input box, the comment is stored to localStorage.

Starting with Greasemonkey is quite easy. There are howtos and templates to start from, such as this one.

However, regular JavaScripting and Greasemonkey JavaScripting do not work in exactly the same way:

One of the differences is that Greasemonkey creates a separate JavaScript environment, in which the Greasemonkey scripts are executed. That is calling Javascript contained in the page from Greasemonkey and the inverse calling Greasemonkey scripts from the page is not possible by default. This is on purpose, so that the web page can not detect and not interfere with the Greasemonkey scripts, because you want your Greasemonkey scripts to work allways on some page, whether or not that page likes it or not. Therefore no interference is possible.

Greasemonkey however provides a standard way to access the web page’s scripts, and that’s through the “unsafeWindow” object, which is a reference to the web page’s environment.

I had two mechanisms I had to make accessible using the “unsafeWindow” handle:

  • the first was accessing JQuery, which is included by default by the Homegate page. Since I needed to use JQuery functions in my Greasemonkey script, I got a reference to it via the standard Greasemonkey precedure:
    var jQuery = unsafeWindow['jQuery'];
  • the second mechanism that needed to cross the boundaries between the web page and Greasemonkey was callbacks from the web page to my Greasemonkey script. This is necessary, because I’m attaching “input” elements to each search result, which contain a note and which, “onblur”, need to call a function that saves the content of the input box. Here’s part that constructs the input element:
    jQuery("<input onclick='event.cancelBubble = true;'" +
                 " onblur='saveComment(this, immoID);'>").insertAfter(immoElement);

And this is the function that gets called back by “onblur”:

    unsafeWindow.saveComment = function(element, immoID) {
      unsafeWindow.localStorage.setItem(immoID, element.value);
    };

The next interesting thing you’ll note is usage of ‘locaStorage’. Support for the latter in browsers does not seem mature yet. One problem I’ve encountered when developing under Firefox 3.6 was that saving to ‘localStorage’ was not possible when cookies were disabled (see this report). Thus you’ll need to permanently enable cookies for Homegate in order for the script to be able to save its data.

Finally, while developing, a major problem was, that Firefox did not show me errors in the Greasemonkey scripts. Thus either the script would work or not work and fail completely silently. That made debugging a bit painful.

So now, here’s the script.

Tomáš Pospíšek

PS: This script also lives at userscripts.org

Visually sorting images under Linux

to visually sort images under Linux doesn’t seem to be a trivial task. I duckduckgo‘ed for a long time and had a look at various image and file managing applications before finding gthumb. And even there, you first need to create a “catalog” and within the catalog a “library” which will finally allow you to manually sort your images. All of which is not documented.

Once you’ve sorted your images, you’d possibly want to export the sorting? Again, no trace of any help or documentation: gthumb catalogs are saved under $HOME/.local/share/gthumb/catalogs/foobar.catalog.

Tomáš Pospíšek

Visually sorting images under Linux

to visually sort images under Linux doesn’t seem to be a trivial task. I duckduckgo‘ed for a long time and had a look at various image and file managing applications before finding gthumb. And even there, you first need to create a “catalog” and within the catalog a “library” which will finally allow you to manually sort your images. All of which is not documented.

Once you’ve sorted your images, you’d possibly want to export the sorting? Again, no trace of any help or documentation: gthumb catalogs are saved under $HOME/.local/share/gthumb/catalogs/foobar.catalog.

Tomáš Pospíšek

Visually sorting images under Linux

to visually sort images under Linux doesn’t seem to be a trivial task. I duckduckgo‘ed for a long time and had a look at various image and file managing applications before finding gthumb. And even there, you first need to create a “catalog” and within the catalog a “library” which will finally allow you to manually sort your images. All of which is not documented.

Once you’ve sorted your images, you’d possibly want to export the sorting? Again, no trace of any help or documentation: gthumb catalogs are saved under $HOME/.local/share/gthumb/catalogs/foobar.catalog.

Tomáš Pospíšek

FOSSGIS 2011: SDI-Architektur mit verteilter Datenhaltung

Aggregation von OGC Diensten

Um OGC-Dienste verschiedener Anbieter (z.B. Bundesländer) zu einem zentralen Dienst zusammenzufassen, müssen neben der Kaskadierung noch einige weitere Operationen ausgeführt werden. Eine hohe Performance und Ausfallsicherheit kann mit einem Tile-Cache auf Basis der aggregierten Dienste gewährleistet werden. Dieser Vortrag zeigt die Problempunkte, die es bei bei einer solchen SDI-Architektur zu berücksichtigen gilt und stellt entsprechende Lösungen vor.

Präsentation

Ubuntu PostGIS package for PostgreSQL 9.0

A while ago I’ve compiled PostGIS 1.5.2 for PostgreSQL 9.0.

To install it on Ubuntu the following steps are required:

apt-get install python-software-properties

add-apt-repository ppa:ubuntugis/ubuntugis-unstable
add-apt-repository ppa:pitti/postgresql
add-apt-repository ppa:pi-deb/gis

apt-get update

apt-get install postgresql-9.0-postgis

A basic template database can be created with the following commands:

sudo su - postgres

createdb template_postgis
psql -q -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis-1.5/postgis.sql
psql -q -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis-1.5/spatial_ref_sys.sql
psql -q -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis_comments.sql
cat <<EOS | psql -d template_postgis
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template_postgis';
REVOKE ALL ON SCHEMA public FROM public;
GRANT USAGE ON SCHEMA public TO public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE
  ON TABLE public.geometry_columns TO PUBLIC;
GRANT SELECT, UPDATE, INSERT, DELETE
  ON TABLE public.spatial_ref_sys TO PUBLIC;
EOS

To test database creation you can do the following:

createdb --template template_postgis test_gis
psql -d test_gis -c "select postgis_lib_version();"

Ubuntu supports parallel installations of different PostgreSQL versions. So if you have already PostgreSQL 8.x installed, PostgreSQL 9.0 will probably be configured to listen on port 5433. So you have to add the option -p 5433 to each command and to specify the full path for the executables. For example:

/usr/lib/postgresql/9.0/bin/psql -p 5433 -d test_gis -c "select postgis_lib_version();"

Ubuntu PostGIS package for PostgreSQL 9.0

A while ago I’ve compiled PostGIS 1.5.2 for PostgreSQL 9.0.

To install it on Ubuntu the following steps are required:

apt-get install python-software-properties

add-apt-repository ppa:ubuntugis/ubuntugis-unstable
add-apt-repository ppa:pitti/postgresql
add-apt-repository ppa:pi-deb/gis

apt-get update

apt-get install postgresql-9.0-postgis

A basic template database can be created with the following commands:

sudo su - postgres

createdb template_postgis
psql -q -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis-1.5/postgis.sql
psql -q -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis-1.5/spatial_ref_sys.sql
psql -q -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis_comments.sql
cat <<EOS | psql -d template_postgis
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template_postgis';
REVOKE ALL ON SCHEMA public FROM public;
GRANT USAGE ON SCHEMA public TO public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE
  ON TABLE public.geometry_columns TO PUBLIC;
GRANT SELECT, UPDATE, INSERT, DELETE
  ON TABLE public.spatial_ref_sys TO PUBLIC;
EOS

To test database creation you can do the following:

createdb --template template_postgis test_gis
psql -d test_gis -c "select postgis_lib_version();"

Ubuntu supports parallel installations of different PostgreSQL versions. So if you have already PostgreSQL 8.x installed, PostgreSQL 9.0 will probably be configured to listen on port 5433. So you have to add the option -p 5433 to each command and to specify the full path for the executables. For example:

/usr/lib/postgresql/9.0/bin/psql -p 5433 -d test_gis -c "select postgis_lib_version();"

Back to Top

Sustaining Members