Related Plugins and Tags

QGIS Planet

Kicking of the QGIS Hackfest : Lisbon, April 2011

The QGIS Lisbon 2011 Hackfest got underway last night with our kick off dinner. It was great to meet many new people and re-encounter those I have met on previous hackfests. It used to be that we were a purely virtual community, but thanks to our 6 monthly developer meetings that is no longer the case. There is a lot to be said for having a face-to-face meeting like this. Firstly, when you communicate via email it's often difficult to understand what drives a person and 'makes them tick'. Having met in person, its often easier to communicate with the person later and the rapport built from shared encounters makes it less difficult to understand their point of view or to make yours known.

Our hosts Vânia NevesandGiovanni Manghi are doing an awesome job on theorganisation front and everything is looking set for a smooth running hackfest.

I'm about to leave the hotel to commence with the first day of 'hacking' and already having chatted to various people I can identify the following areas of interest that people will occupy themselves with during the hackfest:

  • bug fixing (yes we really want to fix bugs!)
  • porting QGIS Core library to ARM so it can be deployed on Android / Maemo / Symbian 3 etc.
  • sprucing up our web infrastructure
  • improving our documentation

There were lots of other great ideas bubbling around the group last night and we will have some informal presentations throughout the hackfest for people to share their ideas and work. I'm really looking forward to it and will keep you posted as we go along!

Giuseppe Sucameli ready to kill bugs!

QGIS Download Status Update

In November 2010, I posted some charts showing some  QGIS download stats. Today I made some updates to these charts (click on them for full image) – enjoy!

Cumulative download counts

Cumulative download counts

Download decay chart

Download decay chart

 

 

pixelstats trackingpixel

QGIS Download Status Update

In November 2010, I posted some charts showing some  QGIS download stats. Today I made some updates to these charts (click on them for full image) - enjoy!

Cumulative download counts

Download decay chart

Fun with GeoNames

The GeoNames dataset provides a list of global placenames, their location and some additional information such as population and so on. It is published under the Creative Commons Attribution 3.0 License, which allows you to use the data for your own purposes. You can download the data by country, or the entire global dataset. In this article, I will walk you though how I downloaded the entire dataset, loaded it into PostgreSQL and added a geometry column so that I could view it in QGIS. Note that you can substitute these instructions for a specific country’s data easily.

First up, lets get the data from the geonames download page!

wget -c http://download.geonames.org/export/dump/allCountries.zip

Note the download is around 196mb so if you live in an internet backwater like I do, expect it to take a little while. If the download gets disconnected, just rerun the same command again – the ‘-c’ option tells wget to continue where it left off last time.

Once the data is downloaded, unzip it:

unzip allCountries.zip

You should now have a text file called allCountries.txt weighing in at just under 900mb. Next we can load it into PostgreSQL using a variation of this article. I highly recommend the use of schemas to partition your database into logical units. In the code listings that follow, it is assumed you have a schema called ‘world’. If you need to create it, simply do:

create schema world;

From the psql prompt. Since I am only interested in the geoname table at the moment I simply do this in my database.

create table world.geoname (
         geonameid       int,
         name            varchar(200),
         asciiname        varchar(200),
         alternatenames  varchar(8000),
         latitude        float,
         longitude       float,
         fclass  char(1),
         fcode   varchar(10),
         country varchar(2),
         cc2 varchar(60),
         admin1  varchar(20),
         admin2  varchar(80),
         admin3  varchar(20),
         admin4  varchar(20),
         population      bigint,
         elevation       int,
         gtopo30         int,
         timezone varchar(40),
         moddate         date
 );

You will notice that I extended the alternatenames field size from the original tutorial’s 4000 characters to 8000 characters in order to accommodate some longer entries that were causing my imports to fail with 4000 chars.

Next we can import the data (also from the psql prompt):

copy world.geoname (geonameid,name,asciiname,alternatenames,
latitude,longitude,fclass,fcode,country,cc2,
admin1,admin2,admin3,admin4,population,elevation,gtopo30,
timezone,moddate) from '/home/web/allCountries.txt' null as '';

Once again this is similar to the import line used by the original article I used, except I have used a full path to my allCountries.txt file. The import may take a little while depending on the speed of your computer.

When it is completed, you should have a bunch of data (~7.5 million records) in your table:

gis=# select count(*) from world.geoname ;
  count
---------
 7664712
(1 row)

It is going to be useful to have a unique id for every record – QGIS for one would like to have it, so lets add one (in addition to the geonameid field):

alter table world.geoname add column id serial not null;
CREATE UNIQUE INDEX idx_geoname_id ON world.geoname (id);

Because I know I will be using some other fields as basis for subset queries etc., I added some indexes on those too:

CREATE INDEX idx_geoname_population ON world.geoname (population);
CREATE INDEX idx_geoname_fcode ON world.geoname(fcode);

Ok thats all great, but there is no geometry column yet so we can’t view this in QGIS easily. So lets GIS enable the table! First we add a new geometry column:

alter table world.geoname add column the_geom geometry;

Now we populate the geometry column:

update world.geoname set the_geom = st_makepoint(longitude,latitude);

Next we add a constraint to ensure that the column always contains a point record or is null

alter table world.geoname add constraint enforce_geotype_the_geom
CHECK (geometrytype(the_geom) = 'POINT'::text OR the_geom IS NULL);

Finally lets index the table on the geometry field:

CREATE INDEX idx_geoname_the_geom ON world.geoname USING gist(the_geom);

Ok next we can connect to the database using QGIS and view our data! Note that you may want to filter the data or set up scale dependent visibility so that QGIS doesn’t try to render all 7.5 million points when you zoom out.

I added a query filter like this to the layer properties -> general tab -> subset:

"population" >= 10000 AND fcode != 'PPLA' and fcode != 'PCLI' AND fcode != 'ADM1'

You should experiment and read the geonames documentation in order to define a filter that is useful for your purposes.

Geonames layer loaded in QGIS

Geonames layer loaded in QGIS

The Geonames dataset is a wonderful asset to the GIS community, particularly to those of us who value Free Software and Free Data.

 

Update 6 Aprl 2011:

I encountered one issue with the above procedure: the SRID for the imported points is -1 when loaded instead of 4326. This cause problems e.g. in mapserver you get an error like this:

 

ERROR:  Operation on two geometries with different SRIDs

To fix the issue I ran the following update query to assign all points a proper SRID:

update world.geoname set the_geom = ST_SETSRID(the_geom,4326);

Note that it takes quite a while to run.  When it completes, you can verify that the points are all in the correct CRS by running this little query:

gis=# select distinct ST_SRID(the_geom) from world.geoname;

Which should produce something like this:

 st_srid
---------
 4326
(1 row)

For good measure, I also added the geoname table to my geometry columns table:

insert into geometry_columns (f_table_catalog,f_table_schema,f_table_name,f_geometry_column,
coord_dimension,srid,type) values ('','world','geoname','the_geom',2,4326,'POINT');

Lastly I also gave select permissions to my readonly user (which I use when publishing in a web environment):

grant usage on schema world to readonly;
grant select on world to readonly;

I have also fixed the formatting of some of the SQL snippets above for those who struggled to read it within the width of this page.

 

 

pixelstats trackingpixel

Fun with GeoNames

The GeoNames dataset provides a list of global placenames, their location and some additional information such as population and so on. It is published under the Creative Commons Attribution 3.0 License, which allows you to use the data for your own purposes. You can download the data by country, or the entire global dataset. In this article, I will walk you though how I downloaded the entire dataset, loaded it into PostgreSQL and added a geometry column so that I could view it in QGIS. Note that you can substitute these instructions for a specific country's data easily.

First up, lets get the data from the geonames download page!

wget -c http://download.geonames.org/export/dump/allCountries.zip

Note the download is around 196mb so if you live in an internet backwater like I do, expect it to take a little while. If the download gets disconnected, just rerun the same command again - the '-c' option tells wget to continue where it left off last time.

Once the data is downloaded, unzip it:

unzip allCountries.zip

You should now have a text file called allCountries.txt weighing in at just under 900mb. Next we can load it into PostgreSQL using a variation of this article. I highly recommend the use of schemas to partition your database into logical units. In the code listings that follow, it is assumed you have a schema called 'world'. If you need to create it, simply do:

create schema world;

From the psql prompt. Since I am only interested in the geoname table at the moment I simply do this in my database.

create table world.geoname (
         geonameid       int,
         name            varchar(200),
         asciiname        varchar(200),
         alternatenames  varchar(8000),
         latitude        float,
         longitude       float,
         fclass  char(1),
         fcode   varchar(10),
         country varchar(2),
         cc2 varchar(60),
         admin1  varchar(20),
         admin2  varchar(80),
         admin3  varchar(20),
         admin4  varchar(20),
         population      bigint,
         elevation       int,
         gtopo30         int,
         timezone varchar(40),
         moddate         date
 );

You will notice that I extended the alternatenames field size from the original tutorial's 4000 characters to 8000 characters in order to accommodate some longer entries that were causing my imports to fail with 4000 chars.

Next we can import the data (also from the psql prompt):

copy world.geoname (geonameid,name,asciiname,alternatenames,
latitude,longitude,fclass,fcode,country,cc2,
admin1,admin2,admin3,admin4,population,elevation,gtopo30,
timezone,moddate) from '/home/web/allCountries.txt' null as '';

Once again this is similar to the import line used by the original article I used, except I have used a full path to my allCountries.txt file. The import may take a little while depending on the speed of your computer.

When it is completed, you should have a bunch of data (~7.5 million records) in your table:

gis=# select count(*) from world.geoname ;
  count
---------
 7664712
(1 row)

It is going to be useful to have a unique id for every record - QGIS for one would like to have it, so lets add one (in addition to the geonameid field):

alter table world.geoname add column id serial not null;
CREATE UNIQUE INDEX idx_geoname_id ON world.geoname (id);

Because I know I will be using some other fields as basis for subset queries etc., I added some indexes on those too:

CREATE INDEX idx_geoname_population ON world.geoname (population);
CREATE INDEX idx_geoname_fcode ON world.geoname(fcode);

Ok thats all great, but there is no geometry column yet so we can't view this in QGIS easily. So lets GIS enable the table! First we add a new geometry column:

alter table world.geoname add column the_geom geometry;

Now we populate the geometry column:

update world.geoname set the_geom = st_makepoint(longitude,latitude);

Next we add a constraint to ensure that the column always contains a point record or is null

alter table world.geoname add constraint enforce_geotype_the_geom
CHECK (geometrytype(the_geom) = 'POINT'::text OR the_geom IS NULL);

Finally lets index the table on the geometry field:

CREATE INDEX idx_geoname_the_geom ON world.geoname USING gist(the_geom);

Ok next we can connect to the database using QGIS and view our data! Note that you may want to filter the data or set up scale dependent visibility so that QGIS doesn't try to render all 7.5 million points when you zoom out.

I added a query filter like this to the layer properties -> general tab -> subset:

"population" >= 10000 AND fcode != 'PPLA' and fcode != 'PCLI' AND fcode != 'ADM1'

You should experiment and read the geonames documentation in order to define a filter that is useful for your purposes.

Geonames layer loaded in QGIS

The Geonames dataset is a wonderful asset to the GIS community, particularly to those of us who value Free Software and Free Data.

Update 6 Aprl 2011:

I encountered one issue with the above procedure: the SRID for the imported points is -1 when loaded instead of 4326. This cause problems e.g. in mapserver you get an error like this:

ERROR:  Operation on two geometries with different SRIDs

To fix the issue I ran the following update query to assign all points a proper SRID:

update world.geoname set the_geom = ST_SETSRID(the_geom,4326);

Note that it takes quite a while to run.  When it completes, you can verify that the points are all in the correct CRS by running this little query:

gis=# select distinct ST_SRID(the_geom) from world.geoname;

Which should produce something like this:

 st_srid
---------
 4326
(1 row)

For good measure, I also added the geoname table to my geometry columns table:

insert into geometry_columns (f_table_catalog,f_table_schema,f_table_name,f_geometry_column,
coord_dimension,srid,type) values ('','world','geoname','the_geom',2,4326,'POINT');

Lastly I also gave select permissions to my readonly user (which I use when publishing in a web environment):

grant usage on schema world to readonly;
grant select on world to readonly;

I have also fixed the formatting of some of the SQL snippets above for those who struggled to read it within the width of this page.

Interactive label placement in QGIS 1.7

One of the nice new features coming in QGIS 1.7 is the ability to use data driven labelling interactively. I made a little video to illustrate below. This work was carried out by Marco Hugentobler of Sourcepole.

Oh, and just for Andreas, here is the same video as a webm file :-)

pixelstats trackingpixel

Interactive label placement in QGIS 1.7

One of the nice new features coming in QGIS 1.7 is the ability to use data driven labelling interactively. I made a little video to illustrate below. This work was carried out by Marco Hugentobler of Sourcepole.

Oh, and just for Andreas, here is the same video as a webm file :-)

Introducing the QGIS roadgraph plugin

One of the nice new features coming in QGIS 1.7 is the ability to do a routing analysis across a road network. This new plugin was written by Sergey Yakushev. The little screencast that follows gives a quick demonstration of its usage.

pixelstats trackingpixel

Introducing the QGIS roadgraph plugin

One of the nice new features coming in QGIS 1.7 is the ability to do a routing analysis across a road network. This new plugin was written by Sergey Yakushev. The little screencast that follows gives a quick demonstration of its usage.

On the fly raster reprojection comes to QGIS

I haven’t had much time for updating my blog lately but I thought I would just post a quick note to mention the awesome work that is taking place in QGIS. We are a few scant days from entering feature freeze in the run up to the 1.7 release, and the project has been a hive of activity in the last few weeks. There are lots of new features coming in 1.7, but also a lot of spit and polish. We have a roadmap that will take us to a 2.0 release later this year and it will be another huge milestone in our project. I’m not going to mention a bunch of new features today – we’ll save that for the release announcement. But I did want to mention that on the fly raster reprojection support was added to QGIS ‘trunk’ today by Radim Blazek.

I’ve been testing his work for the last week or two and it is fast and seamless. It’s a bit hard to show it in a static image, but here are two screenies that try to do just that.

In the first image here we see my raster layer is in Lambert Conic Conformal projection.

Raster layer: Native CRS - Lambert Conic Conformal

Raster layer: Native CRS - Lambert Conic Conformal

Next, here is a picture of my project properties. You can see on the fly reprojection is enabled, and that it is set to Google Mercator.

Project : CRS Google Mercator

Project : CRS Google Mercator

The roads layer you see overlaid is Open Street Map data also in Google Mercator. Before the addition of Radims raster improvements, you would have needed to set the project CRS to Lambert Conic Conformal (to match the raster) if you wanted to overlay the two. Now QGIS is reprojecting the raster from Lambert Conic Conformal to Google Mercator.

QGIS 1.7 should be out within the next month, and I hope you enjoy using it as much as we have been!

pixelstats trackingpixel

On the fly raster reprojection comes to QGIS

I haven't had much time for updating my blog lately but I thought I would just post a quick note to mention the awesome work that is taking place in QGIS. We are a few scant days from entering feature freeze in the run up to the 1.7 release, and the project has been a hive of activity in the last few weeks. There are lots of new features coming in 1.7, but also a lot of spit and polish. We have a roadmap that will take us to a 2.0 release later this year and it will be another huge milestone in our project. I'm not going to mention a bunch of new features today - we'll save that for the release announcement. But I did want to mention that on the fly raster reprojection support was added to QGIS 'trunk' today by Radim Blazek.

I've been testing his work for the last week or two and it is fast and seamless. It's a bit hard to show it in a static image, but here are two screenies that try to do just that.

In the first image here we see my raster layer is in Lambert Conic Conformal projection.

Raster layer: Native CRS - Lambert Conic Conformal

Next, here is a picture of my project properties. You can see on the fly reprojection is enabled, and that it is set to Google Mercator.

Project : CRS Google Mercator

The roads layer you see overlaid is Open Street Map data also in Google Mercator. Before the addition of Radims raster improvements, you would have needed to set the project CRS to Lambert Conic Conformal (to match the raster) if you wanted to overlay the two. Now QGIS is reprojecting the raster from Lambert Conic Conformal to Google Mercator.

QGIS 1.7 should be out within the next month, and I hope you enjoy using it as much as we have been!

Speeding up QGIS compilation times with ccache

I haven’t used ccache for some time, but recently I bought  a little netbook. On a netbook environment, any optimisation you can make to the compilation process will have real benifit since QGIS takes a looooong time to compile without it. Back at my desktop computer I decided to set up ccache too and do a simple benchmark of how much faster compilation is when ccache is enabled.

But perhaps I am getting ahead of myself. What is ccache? Its a piece of software that caches compiled C++ object code. When a compilation task occurs for a piece of unchanged code that is in the cache, ccache will simply return the precompiled object file instead of compiling the sources from scratch.

Installing ccache is simple:

sudo apt-get install ccache

After it is installed you need to enable it by doing something like:

sudo su -
ln -s /usr/bin/ccache /usr/local/bin/gcc
ln -s /usr/bin/ccache /usr/local/bin/g++
ln -s /usr/bin/ccache /usr/local/bin/cc
exit

In your QGIS build directory, you should now edit CMakeCache.txt and change the CMAKE_CXX_COMPILER:FILEPATH entry to /usr/local/bin/g++ :

CMAKE_CXX_COMPILER:FILEPATH=/usr/local/bin/g++

Then run

cmake ..

Note: After running cmake .., check your build prefix and build type, grass path etc. are still as expected – for me cmake reverted them to default values.

Now you can compile. To do a simple benchmark, open a separate terminal and type:

watch -n 20 ccache -s

The latter allows you to watch how objects are being added to your cache, and how often the cache is being used (you want it to be used a lot!). The output looks something like this:

cache directory                     /home/timlinux/.ccache
cache hit                            911
cache miss                           916
called for link                       94
compile failed                         3
not a C/C++ file                       7
files in cache                      1832
cache size                         101.5 Mbytes
max cache size                     976.6 Mbytes

Now build your project the first time from a clean state, and watch how long it takes to build:

make clean
time make install -j4

When it was built it reported a build time looking like this:

real	6m15.478s
user	18m46.230s
sys	2m33.810s

After it is build repeat the above and you should see the new build time is markedly shorter:

make clean
time make install -j4

Here is the build time with ccache doing its thing:

real	1m15.627s
user	2m28.500s
sys	0m35.380s

Conclusion: Spending a few minutes setting up ccache can save you a lot of aimless waiting around while QGIS compiles – well worth the effort!

pixelstats trackingpixel

Speeding up QGIS compilation times with ccache

I haven't used ccache for some time, but recently I bought  a little netbook. On a netbook environment, any optimisation you can make to the compilation process will have real benifit since QGIS takes a looooong time to compile without it. Back at my desktop computer I decided to set up ccache too and do a simple benchmark of how much faster compilation is when ccache is enabled.

But perhaps I am getting ahead of myself. What is ccache? Its a piece of software that caches compiled C++ object code. When a compilation task occurs for a piece of unchanged code that is in the cache, ccache will simply return the precompiled object file instead of compiling the sources from scratch.

Installing ccache is simple:

sudo apt-get install ccache

After it is installed you need to enable it by doing something like:

sudo su -
ln -s /usr/bin/ccache /usr/local/bin/gcc
ln -s /usr/bin/ccache /usr/local/bin/g++
ln -s /usr/bin/ccache /usr/local/bin/cc
exit

In your QGIS build directory, you should now edit CMakeCache.txt and change the CMAKE_CXX_COMPILER:FILEPATH entry to /usr/local/bin/g++ :

CMAKE_CXX_COMPILER:FILEPATH=/usr/local/bin/g++

Then run

cmake ..

Note: After running cmake .., check your build prefix and build type, grass path etc. are still as expected - for me cmake reverted them to default values.

Now you can compile. To do a simple benchmark, open a separate terminal and type:

watch -n 20 ccache -s

The latter allows you to watch how objects are being added to your cache, and how often the cache is being used (you want it to be used a lot!). The output looks something like this:

cache directory                     /home/timlinux/.ccache
cache hit                            911
cache miss                           916
called for link                       94
compile failed                         3
not a C/C++ file                       7
files in cache                      1832
cache size                         101.5 Mbytes
max cache size                     976.6 Mbytes

Now build your project the first time from a clean state, and watch how long it takes to build:

make clean
time make install -j4

When it was built it reported a build time looking like this:

real   6m15.478s
user    18m46.230s
sys 2m33.810s

After it is build repeat the above and you should see the new build time is markedly shorter:

make clean
time make install -j4

Here is the build time with ccache doing its thing:

real   1m15.627s
user    2m28.500s
sys 0m35.380s

Conclusion: Spending a few minutes setting up ccache can save you a lot of aimless waiting around while QGIS compiles - well worth the effort!

Help wanted: FOSS GIS and Python Geek in Africa

Are you a python programmer adept at django and other technologies in the web mapper’s toolbox? We have an exciting project on the go and are looking for someone to help us during the months of February and March 2011. You can work remotely if needed, or here in Swellendam, Western Cape, South Africa if you prefer. Please note applicants must already be available full time for these months (or a good part of them) and already up to speed with these technologies – there will be no time for ‘learning on the job’. Please send me your CV to tim [A T] linfiniti.com if you are interested.

Hope to hear from you soon!

Tim

pixelstats trackingpixel

Help wanted: FOSS GIS and Python Geek in Africa

Are you a python programmer adept at django and other technologies in the web mapper's toolbox? We have an exciting project on the go and are looking for someone to help us during the months of February and March 2011. You can work remotely if needed, or here in Swellendam, Western Cape, South Africa if you prefer. Please note applicants must already be available full time for these months (or a good part of them) and already up to speed with these technologies - there will be no time for 'learning on the job'. Please send me your CV to tim [A T] linfiniti.com if you are interested.

Hope to hear from you soon!

Tim

An interview with kCube Consulting

I have previously posted here about kCube Consulting’s donation of 6 months developer time to the QGIS project. Today I took the opportunity to interview Kumaran Narayanaswamy and SunilRaj Kiran from kCube to find out more about their plans and motivations.

Kumaran Narayanaswamy

Kumaran Narayanaswamy

SunilRaj Kiran

SunilRaj Kiran

TS: Welcome Kumaran and SunilRaj to this interview. Could we start by asking each of you to give us a brief introduction to yourselves?

KN: Let me give a brief introduction about myself and kCube. kCube is a Startup company founded in year 2006 by myself and my college buddy (Senthil Kumar) and we specialize in providing Geospatial Services. I did my Engineering in Geoinformatics and graduated in 1999 and have been working in the industry mainly Logistics domain. I was working with Cognizant after graduation and have been executing projects for Logistics clients based out of US. I moved back to India in 2006 and started kCube along with my college buddy Senthil Kumar.

We did a market research before starting and we realized that Open Source want not being leveraged to a larger extent in India as it was being in western countires and we felt that Open Source Services is a huge market  in India kCube is not a exclusive Open Source Company but we push Open Source as our first priority.
We try to sell the benefits of Open Source to the customers and if they buy in our ideas we go ahead with the open source based solutions if the client already has a technology preference and if he wants to stick with that we go ahead and implement based on his technology preference. We started in 2006 as a 2 member team and now we have a team of 15 members. We provide Application Development,Data Management and Capacity Building Services.

SK:  I did my undergraduation B.E in the department of Geoinformatics right now im doing my masters in Geomatics. I have been doing various C++ applications and projects right from my college days. I joined Kcube as an employee last year and i have been dealing with Qgis since then. Initially started with building the source from trunk on various platforms and was analyzing all Qgis tools. resently I’m looking into the Qgis API for understanding. Also have developed simple plugins on Qgis to make sure I have understood the API properly.

TS: Kumaran, are you able to say what the split is in your business between FOSS GIS and Proprietary GIS solutions? In otherwords, how much demand is there for FOSS GIS solutions?

KN: All our Application Development Projects have been completely Open Source projects only for Data Projects some of the clients prefer to do their work using their infrastructre which is proproetary. We do lot of Classification work for which we use GRASS. Our target customers are NGO’s, Smaller Enterprises and Governement Agencies. We have been able to sell FOSS GIS easily in this segment. We also do a lot of Capacity Building Programs on various FOSS GIS products. In India we are the first to start on this segment.

TS:  Sunil, did you learn C++ and programming as part of your undergrad course or are you self taught?

SK: Although it is  a part of my curriculum, I always had a passion towards C and C++ programming.

TS: Recently kcube caused some excitement in the QGIS community when you announced that you would be donating 6 months of developer time to the QGIS project. What prompted kcube to do this?

KN: We have generated revenue through QGIS and we felt it is our time to give back to the community and make QGIS product even better. We do Capacity building programs on QGIS and we are promoting QGIS in India. We started working with QGIS from 2006 -  I think it was 0.98 version – and from then we have been closely following QGIS more as an end user.

I have been doing training [with QGIS] and the feedback that we have recieved for QGIS is overwhelming, especially [since]these are the users who are currently with proprietary GIS packages. Open Source is always a community based development and we felt that also should be part of the development community and hence this initiative.

TS: SunilRaj, you have been appointed as the developer to work on QGIS for 6 months. Can you tell us something about yourself from a QGIS perspective? Are you new to the project, have you done any coding on QGIS before? What kinds of development work do you usually do?

SK: As I have mentioned earlier , I have just started developing small QGIS plugins for understanding purposes. During my college days I have used Arc Objects to customize ArcMap. Other than this I was doing only non Gis C++ development. Now I am getting familiar with QGIS API and it is very interesting.

TS: Kumaran, what did you think of the process we followed to decide what the SunilRaj should work on? Are you happy that his time will be spent on bug fixing?

KN: As I said earlier Open Source is always a Community driven approach and we are perfectly okay with what Community has decided. At the end of the day they are going to use the product and if we deliver what they want it will be a huge success for the product. Also during the training [sessions we hold] the bugs crop in and sometimes I also feel that we need to trash these bugs first and that was the same answer which we got from the community.

TS: SunilRaj – are you happy to work on bug fixing for six months? Often people arriving on the project are more interested in working on cool new features rather then maintaining existing code. Can you see personal benifits to working on bug fixing?

SK: From my view, bug fixing is a good point to start with. Since I am a learner of QGIS API, it is good that I start with bug fixing so that I will come to know as many API functionality as possible. Once I successfully fix some of the bugs, I will get the confidence to look into new features development.

TS: As a general question: How well is FOSS GIS being adopted in India? Are there any good success stories of it being taken up in government and industry?

KN: There is a huge adoption for Open Source in general in India but for FOSS GIS there is not much of awareness. One of our first plan is to create awareness on various Open source GIS products. We are running road shows along with NRCFOSS and OSGeo India chapter NRCFOSS is the [government agency] set up by Indian government to promote FOSS at Government and Academia. I would say the movement at GIs has just got started and will take a while to get the momentum but people who are exposed to FOSS GIS get fascinated from day one and give us the feedback that these packages are [more] user friendly than proprietary.

Coming to Case studies, we have implemented couple of webGIS and desktop GIS  for NGO’s and government agencies. We have used mainly GeoServer, MapServer, OpenLayers, GeoExt, PostgreSQL/PostGIS stack for Web GIS  and for Desktop we go with QGIS Customization.

TS: Is there anything else you need to make a success of this 6 month bug fixing period – anything you would like to ask for help on from the QGIS community?

KN: As Sunil was mentioning he is overall comfortable with QGIS and its development process. To start with we have advised him to pick up bugs which are not more complicated so that he can understand the API first and gradually as he progresses he can pick up more complex bugs and resolve the same. Currently he is doing his development under ubuntu environment. If you have any other development environment suggestions you can let us know. Also currently we were trying to set up a integrated Debugging environment to debug issues for QGIS Code base. We would like to know from you on how the core team does the debugging? Do you use any IDE based debugging or is it through message displays?

TS:  Qt4 Creator is probably a good option for you – personally I am using command line tools – vim, gdb etc. which allow also interactive debugging, variable inspection, backtracing etcwith qt-creator you can do the same but in a point and click way. Ubuntu linux makes a very good development platform – in fact almost all QGIS developers are working on linux as far as I know as the development tools are great.

KN:  We would certainly need the help of developer community to make this a success as and when we hit road blocks we to get the required help
TS:  Many thanks to both of you for agreeing to this interview – on behalf of the QGIS community, we would like to thank you both for the awesome contribution you are making to the project. I would like to do a follow up interview at the end of this six month period so that we can reflect on how things went.

KN:  Its our pleasure Tim to be part of this great QGIS team who have been doing an outstanding job. We will send you monthly reports on how bugs are progressing which you can also share with the community.

pixelstats trackingpixel

An interview with kCube Consulting

I have previously posted here about kCube Consulting's donation of 6 months developer time to the QGIS project. Today I took the opportunity to interview Kumaran Narayanaswamy and SunilRaj Kiran from kCube to find out more about their plans and motivations.

Kumaran Narayanaswamy

SunilRaj Kiran

TS: Welcome Kumaran and SunilRaj to this interview. Could we start by asking each of you to give us a brief introduction to yourselves?

KN: Let me give a brief introduction about myself and kCube. kCube is a Startup company founded in year 2006 by myself and my college buddy (Senthil Kumar) and we specialize in providing Geospatial Services. I did my Engineering in Geoinformatics and graduated in 1999 and have been working in the industry mainly Logistics domain. I was working with Cognizant after graduation and have been executing projects for Logistics clients based out of US. I moved back to India in 2006 and started kCube along with my college buddy Senthil Kumar.

We did a market research before starting and we realized that Open Source want not being leveraged to a larger extent in India as it was being in western countires and we felt that Open Source Services is a huge market  in India kCube is not a exclusive Open Source Company but we push Open Source as our first priority.

We try to sell the benefits of Open Source to the customers and if they buy in our ideas we go ahead with the open source based solutions if the client already has a technology preference and if he wants to stick with that we go ahead and implement based on his technology preference. We started in 2006 as a 2 member team and now we have a team of 15 members. We provide Application Development,Data Management and Capacity Building Services.

SK:  I did my undergraduation B.E in the department of Geoinformatics right now im doing my masters in Geomatics. I have been doing various C++ applications and projects right from my college days. I joined Kcube as an employee last year and i have been dealing with Qgis since then. Initially started with building the source from trunk on various platforms and was analyzing all Qgis tools. resently I'm looking into the Qgis API for understanding. Also have developed simple plugins on Qgis to make sure I have understood the API properly.

TS: Kumaran, are you able to say what the split is in your business between FOSS GIS and Proprietary GIS solutions? In otherwords, how much demand is there for FOSS GIS solutions?

KN: All our Application Development Projects have been completely Open Source projects only for Data Projects some of the clients prefer to do their work using their infrastructre which is proproetary. We do lot of Classification work for which we use GRASS. Our target customers are NGO's, Smaller Enterprises and Governement Agencies. We have been able to sell FOSS GIS easily in this segment. We also do a lot of Capacity Building Programs on various FOSS GIS products. In India we are the first to start on this segment.

TS:  Sunil, did you learn C++ and programming as part of your undergrad course or are you self taught?

SK: Although it is  a part of my curriculum, I always had a passion towards C and C++ programming.

TS: Recently kcube caused some excitement in the QGIS community when you announced that you would be donating 6 months of developer time to the QGIS project. What prompted kcube to do this?

KN: We have generated revenue through QGIS and we felt it is our time to give back to the community and make QGIS product even better. We do Capacity building programs on QGIS and we are promoting QGIS in India. We started working with QGIS from 2006 -  I think it was 0.98 version - and from then we have been closely following QGIS more as an end user.

I have been doing training [with QGIS] and the feedback that we have recieved for QGIS is overwhelming, especially [since]these are the users who are currently with proprietary GIS packages. Open Source is always a community based development and we felt that also should be part of the development community and hence this initiative.

TS: SunilRaj, you have been appointed as the developer to work on QGIS for 6 months. Can you tell us something about yourself from a QGIS perspective? Are you new to the project, have you done any coding on QGIS before? What kinds of development work do you usually do?

SK: As I have mentioned earlier , I have just started developing small QGIS plugins for understanding purposes. During my college days I have used Arc Objects to customize ArcMap. Other than this I was doing only non Gis C++ development. Now I am getting familiar with QGIS API and it is very interesting.

TS: Kumaran, what did you think of the process we followed to decide what the SunilRaj should work on? Are you happy that his time will be spent on bug fixing?

KN: As I said earlier Open Source is always a Community driven approach and we are perfectly okay with what Community has decided. At the end of the day they are going to use the product and if we deliver what they want it will be a huge success for the product. Also during the training [sessions we hold] the bugs crop in and sometimes I also feel that we need to trash these bugs first and that was the same answer which we got from the community.

TS: SunilRaj - are you happy to work on bug fixing for six months? Often people arriving on the project are more interested in working on cool new features rather then maintaining existing code. Can you see personal benifits to working on bug fixing?

SK: From my view, bug fixing is a good point to start with. Since I am a learner of QGIS API, it is good that I start with bug fixing so that I will come to know as many API functionality as possible. Once I successfully fix some of the bugs, I will get the confidence to look into new features development.

TS: As a general question: How well is FOSS GIS being adopted in India? Are there any good success stories of it being taken up in government and industry?

KN: There is a huge adoption for Open Source in general in India but for FOSS GIS there is not much of awareness. One of our first plan is to create awareness on various Open source GIS products. We are running road shows along with NRCFOSS and OSGeo India chapter NRCFOSS is the [government agency] set up by Indian government to promote FOSS at Government and Academia. I would say the movement at GIs has just got started and will take a while to get the momentum but people who are exposed to FOSS GIS get fascinated from day one and give us the feedback that these packages are [more] user friendly than proprietary.

Coming to Case studies, we have implemented couple of webGIS and desktop GIS  for NGO's and government agencies. We have used mainly GeoServer, MapServer, OpenLayers, GeoExt, PostgreSQL/PostGIS stack for Web GIS  and for Desktop we go with QGIS Customization.

TS: Is there anything else you need to make a success of this 6 month bug fixing period - anything you would like to ask for help on from the QGIS community?

KN: As Sunil was mentioning he is overall comfortable with QGIS and its development process. To start with we have advised him to pick up bugs which are not more complicated so that he can understand the API first and gradually as he progresses he can pick up more complex bugs and resolve the same. Currently he is doing his development under ubuntu environment. If you have any other development environment suggestions you can let us know. Also currently we were trying to set up a integrated Debugging environment to debug issues for QGIS Code base. We would like to know from you on how the core team does the debugging? Do you use any IDE based debugging or is it through message displays?

TS:  Qt4 Creator is probably a good option for you - personally I am using command line tools - vim, gdb etc. which allow also interactive debugging, variable inspection, backtracing etcwith qt-creator you can do the same but in a point and click way. Ubuntu linux makes a very good development platform - in fact almost all QGIS developers are working on linux as far as I know as the development tools are great.

KN:  We would certainly need the help of developer community to make this a success as and when we hit road blocks we to get the required help

TS:  Many thanks to both of you for agreeing to this interview - on behalf of the QGIS community, we would like to thank you both for the awesome contribution you are making to the project. I would like to do a follow up interview at the end of this six month period so that we can reflect on how things went.

KN:  Its our pleasure Tim to be part of this great QGIS team who have been doing an outstanding job. We will send you monthly reports on how bugs are progressing which you can also share with the community.

Bending django flatpages to your will

I’ve been working on a web site for a client that uses django flatpages. Flatpages is a built in component that allows users to create static content within the admin interface and publish it to the web front end. Think of it as a basic content management system component for django. Out of the box django’s flatpages have some limitations though – you cannot easily dictate a sort order or heirachy for the pages. Let me demonstrate…

The old way:

Typically one might show a list of your flatpages on your website you would do something like this

{% load flatpages %} {# Custom tag defined in lib/templatetags/ #}
{% get_flatpages as flatpages %}
<ul>
{% for page in flatpages %}
 <li><a href="{{ page.url }}">{{ page.title }}</a></li>
{% endfor %}
</ul>

Which might generate some html rendered out like this:

Basic flat page listing

Basic flat page listing

Extending the FlatPages model:

We can use model inheritance to add a couple of fields to the flatpages model as explained here. To do that I simply add something like this to my models.py:

from django.db import models
from django.contrib.flatpages.models import FlatPage
class ExtendedFlatPage(FlatPage):
 show_after = models.ForeignKey('ExtendedFlatPage', \
   null=True, blank=True, default=None, \
   related_name="flatpage_predecessor", \
   help_text="Page that this one should appear after (if any)")
 child_of = models.ForeignKey('ExtendedFlatPage', \
   null=True, blank=True, default=None, \
   related_name="flatpage_parent", \
   help_text="Page that shis one should appear under (if any)")

So my new model adds two fields to the flatpages model that will allow me to define ordering and heirachy. The show_after field means that when I create a new flatpage, I can specify which other page the new page should be shown after. The child_of field can be used to state that the new page being added is a child of another page. A quick run of

python manage.py syncdb

Will go ahead and create the new table for your extended flat pages model. If we want to migrate existing flatpages into the new model, you can run a little query from the postgres command prompt like this:

insert into localsite_extendedflatpage (flatpage_ptr_id)
  select (id) from django_flatpage;

Where localsite_extendedflatpage is the table that was generated for your model (its name will vary depending on the name of your django app).

Registering the model in the admin interface:

To allow the user to administer the extended flat pages, you need to register your custom flatpages model with the admin interface and deregister the existing one (in admin.py):

from django.contrib import admin
from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
from django.contrib.flatpages.models import FlatPage

from models import ExtendedFlatPage

class ExtendedFlatPageForm(FlatpageForm):
 class Meta:
   model = ExtendedFlatPage
class ExtendedFlatPageAdmin(FlatPageAdmin):
 form = ExtendedFlatPageForm
 fieldsets = (
 (None, {'fields': ('url', 'title', 'content', \
         'sites', 'show_after', 'child_of' )}),
 )
admin.site.unregister(FlatPage)
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin)

After restarting your web server, you should now see the ExtendedFlatPages model listed in your admin interface, and it should show you our two custom fields which we use to define order and heirachy.

Admin interface for our customised flatpages model

Admin interface for our customised flatpages model

Creating a custom template tag:

The next step in our journey is to create a custom templatetag that will render our listing of flatpages according to their heirachy and order. I added this to <myapp>/templatetags/local_tags.py :

from django import template
from localsite.models import ExtendedFlatPage
register = template.Library()
@register.simple_tag
def show_ordered_flatpages():
 flatPages = ExtendedFlatPage.objects.filter(child_of__isnull=True).order_by('-show_after')
 myString = ""
 for myPage in flatPages:
   myString += get_ul_for_page( myPage )
 return myString

def get_ul_for_page( thePage ):
 flatPages = ExtendedFlatPage.objects.filter(child_of=thePage).order_by('show_after')
 if len(flatPages) < 1:
   return """<li><a href="%s">%s</a></li>""" % ( thePage.url, thePage.title )
 else:
  myString = """<li><a href="%s">%s</a>""" % ( thePage.url, thePage.title )
  myString += "<ul>\n"
  for myPage in flatPages:
    myString += get_ul_for_page( myPage ) #recursion
  myString += "</ul>\n"
  myString += "</li>\n"
  return myString

So the template tag uses a simple recursive function to generate a heirachical nested collection of unordered lists (ul). The last thing I need to do is update my template that shows a listing of available flatpages to look something like this:

{% load local_tags %}

<div class = "flat-page-list">
   {% show_ordered_flatpages %}
</div>

The result:

After making the above changes, my contrived list of flatpages now looks like this when rendered:

Flatpages rendered using user defined order and nesting

Flatpages rendered using user defined order and nesting

A couple of gotchas:

My examples above do not check to see where the logged in user has the rights to view a page. Also my ExtendedFlatPages model needs to have some checks added to ensure that show_after and child_of fields can not be populated with a reference back to themselves (which would probably cause infinite recursion in my templatetag code).

pixelstats trackingpixel

Bending django flatpages to your will

I've been working on a web site for a client that uses django flatpages. Flatpages is a built in component that allows users to create static content within the admin interface and publish it to the web front end. Think of it as a basic content management system component for django. Out of the box django's flatpages have some limitations though - you cannot easily dictate a sort order or heirachy for the pages. Let me demonstrate...

The old way:

Typically one might show a list of your flatpages on your website you would do something like this

{% load flatpages %} {# Custom tag defined in lib/templatetags/ #}
{% get_flatpages as flatpages %}
<ul>
{% for page in flatpages %}
 <li><a href="{{ page.url }}">{{ page.title }}</a></li>
{% endfor %}
</ul>

Which might generate some html rendered out like this:

Basic flat page listing

Extending the FlatPages model:

We can use model inheritance to add a couple of fields to the flatpages model as explained here. To do that I simply add something like this to my models.py:

from django.db import models
from django.contrib.flatpages.models import FlatPage
class ExtendedFlatPage(FlatPage):
 show_after = models.ForeignKey('ExtendedFlatPage', \
   null=True, blank=True, default=None, \
   related_name="flatpage_predecessor", \
   help_text="Page that this one should appear after (if any)")
 child_of = models.ForeignKey('ExtendedFlatPage', \
   null=True, blank=True, default=None, \
   related_name="flatpage_parent", \
   help_text="Page that shis one should appear under (if any)")

So my new model adds two fields to the flatpages model that will allow me to define ordering and heirachy. The show_after field means that when I create a new flatpage, I can specify which other page the new page should be shown after. The child_of field can be used to state that the new page being added is a child of another page. A quick run of

python manage.py syncdb

Will go ahead and create the new table for your extended flat pages model. If we want to migrate existing flatpages into the new model, you can run a little query from the postgres command prompt like this:

insert into localsite_extendedflatpage (flatpage_ptr_id)
  select (id) from django_flatpage;

Where localsite_extendedflatpage is the table that was generated for your model (its name will vary depending on the name of your django app).

Registering the model in the admin interface:

To allow the user to administer the extended flat pages, you need to register your custom flatpages model with the admin interface and deregister the existing one (in admin.py):

from django.contrib import admin
from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
from django.contrib.flatpages.models import FlatPage
from models import ExtendedFlatPage

class ExtendedFlatPageForm(FlatpageForm):
 class Meta:
   model = ExtendedFlatPage
class ExtendedFlatPageAdmin(FlatPageAdmin):
 form = ExtendedFlatPageForm
 fieldsets = (
 (None, {'fields': ('url', 'title', 'content', \
         'sites', 'show_after', 'child_of' )}),
 )
admin.site.unregister(FlatPage)
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin)

After restarting your web server, you should now see the ExtendedFlatPages model listed in your admin interface, and it should show you our two custom fields which we use to define order and heirachy.

Admin interface for our customised flatpages model

Creating a custom template tag:

The next step in our journey is to create a custom templatetag that will render our listing of flatpages according to their heirachy and order. I added this to <myapp>/templatetags/local_tags.py :

from django import template
from localsite.models import ExtendedFlatPage
register = template.Library()
@register.simple_tag
def show_ordered_flatpages():
 flatPages = ExtendedFlatPage.objects.filter(child_of__isnull=True).order_by('-show_after')
 myString = ""
 for myPage in flatPages:
   myString += get_ul_for_page( myPage )
 return myString

def get_ul_for_page( thePage ):
 flatPages = ExtendedFlatPage.objects.filter(child_of=thePage).order_by('show_after')
 if len(flatPages) < 1:
   return """<li><a href="%s">%s</a></li>""" % ( thePage.url, thePage.title )
 else:
  myString = """<li><a href="%s">%s</a>""" % ( thePage.url, thePage.title )
  myString += "<ul>\n"
  for myPage in flatPages:
    myString += get_ul_for_page( myPage ) #recursion
  myString += "</ul>\n"
  myString += "</li>\n"
  return myString

So the template tag uses a simple recursive function to generate a heirachical nested collection of unordered lists (ul). The last thing I need to do is update my template that shows a listing of available flatpages to look something like this:

{% load local_tags %}

<div class = "flat-page-list">
   {% show_ordered_flatpages %}
</div>

The result:

After making the above changes, my contrived list of flatpages now looks like this when rendered:

Flatpages rendered using user defined order and nesting

A couple of gotchas:

My examples above do not check to see where the logged in user has the rights to view a page. Also my ExtendedFlatPages model needs to have some checks added to ensure that show_after and child_of fields can not be populated with a reference back to themselves (which would probably cause infinite recursion in my templatetag code).

Maps from memory

I came across this nice post about maps from memory – its a fun exercise and is quite revealing about how we perceive place & space.

Cuba

pixelstats trackingpixel

Back to Top

Sustaining Members