<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kukkaisvoima version 7" -->
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<channel>
<title>vmx: Python</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi</link>
<description>Blog of Volker Mische</description>
<pubDate>Mon, 03 May 2010 22:35:25 +0200</pubDate>
<lastBuildDate>Mon, 03 May 2010 22:35:25 +0200</lastBuildDate>
<generator>http://23.fi/kukkaisvoima/</generator>
<language>en</language>
<item>
<title>GeoCouch: The future is now
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future-is-now%3A2010-05-03%3Aen%2CCouchDB%2CPython%2CErlang%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future-is-now%3A2010-05-03%3Aen%2CCouchDB%2CPython%2CErlang%2Cgeo#comments</comments>
<pubDate>Mon, 03 May 2010 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<category>Erlang</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future-is-now%3A2010-05-03%3Aen%2CCouchDB%2CPython%2CErlang%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p><b>Update:</b> <em>This blog entry is outdated and kepts for historical
reasons. Please do always check for newer blog posts. The up to date
information on how to install and use GeoCouch can be found in
<a href="https://github.com/couchbase/geocouch/#readme">its README</a>.
</em></p>

<p>An idea has become reality. Exactly two years after the
<a href="http://vmx.cx/cgi-bin/blog/index.cgi/couchdb-and-geodata:2008-05-03:en,geo,CouchDB">blog post with the initial vision</a>,
a new version of GeoCouch is finished. It's a huge step forward. The first time
the dependencies were narrowed down to <a href="http://couchdb.apache.org">CouchDB</a>
itself. No <a href="http://www.python.org">Python</a>,
no <a href="http://www.gaia-gis.it/spatialite/">SpatiaLite</a> any longer, it's pure
<a href="http://www.erlang.org">Erlang</a>. GeoCouch is tightly integrated with
CouchDB, so you'll get all the nice features you love about CouchDB.</p>

<h3>Current implementation</h3>

<p>Thanks to the feedback after the FOSS4G 2009 and
<a href="http://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future:2009-12-20:en,CouchDB,Python,geo">"GeoCouch: The future" blog entry</a>"
it was clear that people prefer a simple, yet powerful and tightly integrated
approach, rather than having to many external dependencies (which was a
showstopper for quite a few people).</p>

<p>I implemented an R-tree (I call it vtree as the implementation is
subject to change a lot) from scratch. The reason why I haven't used
the <a href="http://github.com/cchandler/RTreeCouchDB">already existing R-Tree implementation available at
Github</a> is that I needed
something to learn Erlang, it doesn't contain test or examples and
that it is always a good idea to implement a data structure yourself
to understand the details/problems. My implementation is far from
being perfect but works good enough for now. The vtree is implemented
as an append-only data structure just as CouchDB's B-trees
are. Currently it doesn't support bulk insertion.</p>

<p>If you want to know details on how to create your own indexer, have a look at
my <a href="http://vmx.cx/couchdb/tutorial/indexer.html">Indexer tutorial</a>.</p>

<h3>Feature set</h3>

<p>Following the "Release early, release often" philosophy currently only points
can be inserted, the only supported query is a bounding box search. Though
other geometries should follow soon.</p>

<h3>Using GeoCouch</h3>

<p>GeoCouch is now <a href="http://github.com/vmx/couchdb/tree/geocouch">hosted
at Github</a>. Giving GeoCouch a go is easy:</p>

<pre><code>git clone http://github.com/vmx/couchdb.git
cd couchdb
./bootstrap
./configure
make dev
./utils/run
</code></pre>

<p>To try the spatial features when it's up and running is easy as well. Just add
a <code>spatial</code> property and a named function to your Design Document as you
would to for
<a href="http://wiki.apache.org/couchdb/Formatting_with_Show_and_List">show or list functions</a>:</p>

<pre><code>function(doc) {
    if (doc.loc) {
        emit(doc._id, {
            type: "Point",
            coordinates: [doc.loc[0], doc.loc[1]]
        });
    }
};
</code></pre>

<p>All you need to do is emitting <a href="http://geojson.org">GeoJSON</a> as the value
(Remember that <code>point</code> is the only supported geometry at the moment), the
key is currently ignored.</p>

<pre><code>curl -X PUT http://127.0.0.1:5984/places
curl -X PUT -d '{"spatial":{"points":"function(doc) {\n    if (doc.loc) {\n        emit(doc._id, {\n            type: \"Point\",\n            coordinates: [doc.loc[0], doc.loc[1]]\n        });\n    }};"}}' http://127.0.0.1:5984/places/_design/main
</code></pre>

<p>Before a bounding box query can return anything, you need to insert Documents
that contain a location.</p>

<pre><code>curl -X PUT -d '{"loc": [-122.270833, 37.804444]}' http://127.0.0.1:5984/places/oakland
curl -X PUT -d '{"loc": [10.898333, 48.371667]}' http://127.0.0.1:5984/places/augsburg
</code></pre>

<p>And finally you can make a bounding box request:</p>

<pre><code>curl -X GET 'http://localhost:5984/places/_design/main/_spatial/points/%5B0,0,180,90%5D'
</code></pre>

<p>This one should return only <code>augsburg</code>:</p>

<pre><code>{"query1":[{"id":"augsburg","loc":[10.898333,48.371667]}]}
</code></pre>

<h3>Next steps</h3>

<p>The development of GeoCouch was quite slow in the past, but it gets up
to speed as my diploma thesis (comparable to a master's thesis) will be
about GeoCouch. Additionally <a href="http://www.couch.io/">Couchio</a> kindly
supports the development.</p>

<p>The next steps are (in no particular order):</p>

<ul>
<li>Better R-tree (better splitting algorithm, bulk operations)</li>
<li>Supporting more geometries</li>
<li>Polygon search</li>
<li>Improving CouchDB's plugin capabilities</li>
</ul>

<h3>Thanks</h3>

<p>I'd like to thank all the people that kept me motivated over the past two
years with their tremendous feedback. Special thanks go to
<a href="http://jan.prima.de/">Jan Lehnardt</a> for getting me onto the Couch,
<a href="http://cameronshorter.blogspot.com/">Cameron Shorter</a> for introducing me
into the geospatial open source business and all people from
<a href="http://www.couch.io/">Couchio</a> for the
great two weeks in Oakland.</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future-is-now%3A2010-05-03%3Aen%2CCouchDB%2CPython%2CErlang%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>Processing PDF files: Auto advance
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/processing-pdf-files-auto-advance%3A2010-02-23%3Aen%2CPython</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/processing-pdf-files-auto-advance%3A2010-02-23%3Aen%2CPython#comments</comments>
<pubDate>Tue, 23 Feb 2010 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>Python</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/processing-pdf-files-auto-advance%3A2010-02-23%3Aen%2CPython/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>Sometimes you need a PDF file that auto advances (auto flip, slide show)
pages after a certain amount of seconds. For example for presenting a
<a href="http://en.wikipedia.org/wiki/Lightning_Talk">Lightning Talk</a> the
<a href="http://en.wikipedia.org/wiki/Ignite_(event)">Ingnite way</a>. There
are several ways to achieve this. Today I've spent hours to find the best way.
</p>

<p>You could just hope that your favourite PDF viewer supports changing slides
automatically in a certain interval
(<a href="http://http://projects.gnome.org/evince/">Evince</a> doesn't). But
you never know which viewer will be used when you rely on other people's
computers. The next step is obvious, try to get the PDF file itself to auto
advance. It is possible as
<a href="http://help.adobe.com/en_US/Acrobat/9.0/Standard/WS58a04a822e3e50102bd615109794195ff-7c68.w.html">Adobe
Acrobat supports such a setting</a> (it seems that even
<a href="http://pcsplace.com/tips-n-tricks/make-powerpoint-like-presentations-from-pdf-documents-with-acrobat-page-transitions/">Acrobat
Reader</a> does, though I can't find that option in my one under Linux), I just
need to find out how.
</p>

<p>After some further research I found out that Latex' hyperref package
<a href="http://agents.felk.cvut.cz/wiki/doku.php?id=tricks:latex">supports it as well</a> (no, I don't speak Czech). So I made some minimal
<a href="http://latex-beamer.sourceforge.net/">Latex Beamer</a> presentation to
give it a try. The important notice that the <code>\hypersetup{pdfpageduration=n}</code> must be the first item within a <code>\begin{frame}</code> was found
<a href="http://xavier.perseguers.ch/fileadmin/download/LaTeX/guidelines.pdf">in
some presentation guidelines</a>. Guess what? It even works with Evince (<a href="/blog/2010-02-23/beamer-autoflip.tex">tex file</a>, <a href="/blog/2010-02-23/beamer-autoflip.pdf">PDF file</a>).
</p>

<p>I'm getting closer. Though my problem is that I create my slides with
<a href="http://www.inkscape.org">Inkscape</a> (resp. <a
href="http://projects.abourget.net/inkscapeslide/">Inkscape Slide</a>), so I
can't really user Latex Beamer for it. But the previously mentioned
presentation guidelines also mention the <code>/Dur</code> entry in the PDF
page object. So it should be easy to add it manually. And it really is. A quick
search through the PDF file generated by Latex you can see that
<code>/Dur</code> occurs a close to <code>/MediaBox</code>. After adding those
<code>/Dur 2</code> to my original presentation PDF file right after
<code>\MediaBox</code> it auto flipped every 2 seconds.
</p>

<p>I could have written a simple script that adds it to the PDF at the right
place, but that sounds pretty fragile. A better approach would be to use a PDF
library that is meant for manipulating PDF files. As my favourite programming
language is Python at the moment, I came across
<a href="http://pybrary.net/pyPdf/">pyPdf</a>. A quick look at the internals
showed that it contains everything I need.</p>

<p>Here's my final solution for the problem of creating auto advancing PDF
slides. A small script that does exactly what I need (and not more). I've
used the Python 3 version of pyPdf, but the script should look similar for
Python 2.x.
</p>

<code><pre>
#!/usr/bin/env python3.1
# Copyright (c) 2010 Volker Mische (http://vmx.cx/)
# Licensed under MIT.

import sys
from pyPdf import PdfFileWriter, PdfFileReader
from pyPdf.generic import NameObject, NumberObject

def main(argv=None):
    if argv is None:
        argv = sys.argv

    if len(argv) != 4:
        print('Usage: setduration.py [duration-in-seconds] [input-pdf]',
              '[output-pdf]')
        return

    pdfin = PdfFileReader(open(argv[2], "rb"))
    pdfout = PdfFileWriter()

    for page in pdfin.pages:
        page[NameObject('/Dur')] = NumberObject(argv[1])
        pdfout.addPage(page)

    outputStream = open(argv[3], "wb")
    pdfout.write(outputStream)

if __name__ == '__main__':
    sys.exit(main())
</pre></code>

]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/processing-pdf-files-auto-advance%3A2010-02-23%3Aen%2CPython/feed/</wfw:commentRss>
</item>
<item>
<title>GeoCouch: The future
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future%3A2009-12-20%3Aen%2CCouchDB%2CPython%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future%3A2009-12-20%3Aen%2CCouchDB%2CPython%2Cgeo#comments</comments>
<pubDate>Sun, 20 Dec 2009 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future%3A2009-12-20%3Aen%2CCouchDB%2CPython%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p><a href="http://gitorious.org/geocouch/">GeoCouch</a> started as a <a href="/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb:2008-10-26:en,CouchDB,Python,geo">proof of concept</a> and was heavily rewritten for the <a href="/cgi-bin/blog/index.cgi/geocouch-new-release-0.10.0:2009-09-19:en,CouchDB,Python,geo">0.10 release</a>. As more and more people got interested, I got feedback to see what people really want/need. And now it's time to determine the future of GeoCouch. It's your chance to shape the future. In this blog entry I'll explain my ideas for the future, but I'm more than happy to get further ideas/complains from you. So please check if my ideas match your use-cases for GeoCouch.
</p>
<h3>Stripping it down</h3>
<p>GeoCouch needs an external spatial index, at the moment I use <a href="http://www.gaia-gis.it/spatialite/">SpatiaLite</a> for it, but a <a href="http://postgis.refractions.net/">PostGIS</a> backend would be easily possible. My inital idea was that it is better to use the existing power of spatial databases, rather than reinventing the wheel. I though I could use all the power they have, that I can even use them for complex analytics, but I can't. As I only store the geometries, I need to “ask” CouchDB for the attributes (no, I don't want to store attributes in my spatial index).
<!--This would be possible, but I'll explain the “analytics use-case” later.-->
</p>
<p>If I don't use the full power of the spatial databases, but only a small fraction, there might be better solution. Therefore I propose that GeoCouch will use a simple spatial index for storing the geometries, not a full blown spatial database. I haven't decided yet which one it'll be, but I really think about moving this part to Erlang (I know that quite a few people would love that move).
</p>
<p>You will loose functionality like reprojection. The spatial index won't know anything about projections. So GeoCouch won't be projection aware anymore, but you application still can be. For example if you want to return your data in a different projection than it was stored, you do the transformation after you've queried GeoCouch.
</p>
<p>You would also loose fancy things for geometries, like boolean operations on them. But this is something I'd call complex analytics, and not simple querying.
</p>
<p>GeoCouch would only support three simple queries: bounding search, polygon search and radius/distance search. If the search would be within a union of polygons, let's say all countries of the European Union, you would simply make the union operation before you query GeoCouch.
</p>

<h3>Complex analytics</h3>
<p>What I call “complex analytics” is things like: “return all apple trees that are located with a 10km range around buildings that have are over 100m high, but only in countries with a population over 50 million people” is not possible with GeoCouch as you would need the attribute values as well. Those are stored in CouchDB, so you would need to request them. What GeoCouch only supports is a simple: give me all IDs within a bounding box/polygon/radius.
</p>

<h3>Conclusion</h3>
<p>Simple requests are needed for everyday use, thus they should be incredibly fast. Complex analytics don't necessarily need to handle thousands of requests per second, in most cases they don't even need to be processed in real-time. I'd like to see some layer build above GeoCouch, so CouchDB can even be used for analytics (which is a thing I wanted to have right from the start).
</p>
<p>This means that GeoCouch will be mainly for high performance and massive sized projects that need some simple spatial bits, what I think the majority of users need.
</p>
<p>If you either think you really need only those simple queries, but you want them to be fast, or you think this is wrong, that you need dynamic reprojection I can only invite you to leave a comment below or drop a mail to <a href="mailto:volker.mische@gmail.com">volker.mische@gmail.com</a>. Thanks.
</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future%3A2009-12-20%3Aen%2CCouchDB%2CPython%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>FOSS4G 2009: “Geodata and CouchDB” presentation is online
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2009-presentation-is-online%3A2009-11-17%3Aen%2CCouchDB%2CPython%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2009-presentation-is-online%3A2009-11-17%3Aen%2CCouchDB%2CPython%2Cgeo#comments</comments>
<pubDate>Tue, 17 Nov 2009 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2009-presentation-is-online%3A2009-11-17%3Aen%2CCouchDB%2CPython%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>The final wrap-up of the <a href="http://2009.foss4g.org/">FOSS4G 2009</a>,
<a href="http://2009.foss4g.org/presentations/#presentation_78">my presentation
on “Geodata and CouchDB”</a> is available online in several formats. It should
also be of interest for people who are new to CouchDB as huge parts of the
talk are an introduction into CouchDB.
</p>
<ul>
  <li>The raw slides
<a href="/blog/2009-11-17/geodata-and-couchdb.pdf">as PDF</a> (licensed under
<a href="http://creativecommons.org/licenses/by/3.0/de/">CC-BY-3.0-de</a>).</li>
  <li>The slides with comments
<a href="/blog/2009-11-17/geodata-and-couchdb.htm">as HTML</a> (licensed under
<a href="http://creativecommons.org/licenses/by/3.0/de/">CC-BY-3.0-de</a>).</li>
  <li>The <a href="http://www.fosslc.org/drupal/node/595">slides with audio</a>
(<a href="http://blip.tv/file/2795979">or at blib.tv</a>). It’s the
recording of the actual talk at the conference</a>. Thanks
<a href="http://georaffe.org/">Alex</a> and
<a href="http://www.fosslc.org/">FOSSLC</a> for recording it (licensed under
<a href="http://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA-3.0</a>).</li>
</ul>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2009-presentation-is-online%3A2009-11-17%3Aen%2CCouchDB%2CPython%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>Benchmarking is not easy
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/benchmarking-is-not-easy%3A2009-09-23%3Aen%2CCouchDB%2CPython%2CTileCache%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/benchmarking-is-not-easy%3A2009-09-23%3Aen%2CCouchDB%2CPython%2CTileCache%2Cgeo#comments</comments>
<pubDate>Wed, 23 Sep 2009 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<category>TileCache</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/benchmarking-is-not-easy%3A2009-09-23%3Aen%2CCouchDB%2CPython%2CTileCache%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>There are so many ways to have a play with
<a href="http://couchdb.apache.org">CouchDB</a>. This time I thought about using
CouchDB as a <a href="http://tilecache.org/">TileCache</a> storage. 
Sounds easy, so it was.
</p>

<h3>What is a tilecache</h3>
<p>Everyone knows <a href="http://maps.google.com/">Google Maps</a> and its
small images, called <em>tiles</em>. Rendering those tiles for the whole world
for every zoom level can be quite time consuming, therefore you can render
them on demand and cache them once they are rendered. This is the business of
a tilecache.
</p>
<p>You can use the tilecache as a proxy to a remote tile server as well, that's
what I did for this benchmark.</p>

<h3>Coding</h3>
<p><a href="/blog/2009-09-23/Couchdb.py">The implementation</a> looks quite
similar to the
<a href="http://svn.tilecache.org/trunk/tilecache/TileCache/Caches/Memcached.py">memcache
one</a>. I haven't implemented locking as I was just after something working,
not a full-fledged backend.
</p>
<p>When I finished coding, it was time to find out how it performs. That should
be easy, as there's a tilecache_seeding script bundled with TileCache to fill
the cache. So you fill the cache, then you switch the remote server off and
test how long it takes if all requests are hits without any fails (i.e. all
tiles are in your cache and don't need to be requested from a remote server).
</p>
<p>The two contestants for the benchmark are the CouchDB backend and the one
that stores the tiles directly on the filesystem.</p>

<h3>Everyone loves numbers</h3>
<p>We keep it simple and measure the time for seeding with
<a href="http://www.gnu.org/software/time/">time</a>. How long will it take to
request 780 tiles? The first number is the average (in seconds), the one in
brackets the standard deviation.
</p>
<ul>
  <li><p>Filesystem:</p>
<pre>
real 0.35 (0.04)
user 0.16 (0.02)
sys  0.05 (0.01)
</pre>
  </li>
  <li><p>CouchDB:</p>
<pre>
real 3.03 (0.18)
user 0.96 (0.05)
sys  0.21 (0.03)
</pre>
  </li>
</ul>
<p>Let's say CouchDB is 10 times slower that the file system based cache. Wow,
CouchDB really sucks! Why would you use it as tile storage? Although you could:
</p>
<ul>
  <li>easily store metadata with every tile, like a date when it should
expire.</li>
  <li>keep a history of tiles and show them as "travel through time layers"
in your mapping application</li>
  <li>easy replication to other servers</li>
</ul>
<p>You just don't want such a slow hog. And those
<a href="http://wiki.apache.org/couchdb/People_on_the_Couch">CouchDB
people</a> try to tell me that CouchDB would be fast. Pha!</p>

<h3>Really??</h3>
<p>You might already wonder, where the details are, the software version
numbers, the specification of the system and all that stuff? These things are
missing with a good reason. This benchmark just isn't right, even if I would
add these details. The problem lies some layers deeper.
</p>
<p>This benchmark is way to far away from a real-life usage. You would request
much more tiles and not the same 780 ones with every run. When I was
benchmarking the filesystem cache, all tiles were already in the system's
cache, therefore it was <em>that</em> fast.
</p>
<p>Simple solution: clear the system cache and run the tests again. Here are
the results after as <code>echo 3 > /proc/sys/vm/drop_caches</drop>
<ul>
  <li><p>Filesystem:</p>
<pre>
real 8.36 (0.71)
user 0.29 (0.04)
sys  0.18 (0.03)
</pre>
  </li>
  <li><p>CouchDB:</p>
<pre>
real 6.64 (0.15)
user 1.13 (0.07)
sys  0.29 (0.06)
</pre>
  </li>
</ul>
<p>Wow, the CouchDB cache is faster than the filesystem cache. Too nice to be
true. The reason is easy: loading the CouchDB database file, thus one file
access on the disk, is way faster that 780 accesses.
</p>

<h3>Does it really matter?</h3>
<p>Let's take the first benchmark, if CouchDB would be that much slower, but
isn't it perhaps <em>fast enough</em>? Even with those measures (ten times
slower than the filesystem cache) it would mean your cache can take 250
requests per second. Let's say a user requests 9 tiles per second it would be
about 25 users at the same time. With every user staying 2 minutes on the map
it would mean 18&#160;000 users per day. Not bad.
</p>
<p>Additionally you gain some nice things you won't have with other
caches (as outlined above). And if you really need more performance you could
always dump the tiles to the filesystem with a cron job.
</p>

<h3>Conclusion</h3>
<ol>
  <li>Benchmarking is not easy, but easy to get wrong.</li>
  <li>Slow might be fast enough.</li>
  <li>Read more about benchmarking on
<a href="http://jan.prima.de/plok/archives/176-Caveats-of-Evaluating-Databases.html">Jan's
blog</a>.</li>
</ol>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/benchmarking-is-not-easy%3A2009-09-23%3Aen%2CCouchDB%2CPython%2CTileCache%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>GeoCouch: New release (0.10.0)
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-new-release-0.10.0%3A2009-09-19%3Aen%2CCouchDB%2CPython%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-new-release-0.10.0%3A2009-09-19%3Aen%2CCouchDB%2CPython%2Cgeo#comments</comments>
<pubDate>Sat, 19 Sep 2009 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-new-release-0.10.0%3A2009-09-19%3Aen%2CCouchDB%2CPython%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p style="border:10px solid #f00;font-size:2em;padding:1em">
<strong>Notice:</strong> This blog post is outdated, please move on :)
</p>

<p>It has been way to long since the initial release, but it’s finally there:
a new release of GeoCouch. For all first time visitors, GeoCouch is an
extension for <a href="http://couchdb.apache.org/">CouchDB</a> to support
geo-spatial queries like bounding box or polygon searches.
</p>
<p>I keep this blog entry relatively short and only outline the highlights and
requirements for the new release as GeoCouch finally has a real home at
<a href="http://gitorious.org/geocouch/">http://gitorious.org/geocouch/</a>.
Feel free to contribute to the wiki or fork the source.
</p>

<h3>Highlights</h3>
<ul>
  <li>Many geometries
<a href="http://gitorious.org/geocouch/pages/GeometryDefinition">are
supported</a>: points, lines, polygons (using Shapely).</li>
  <li>Queries are largely along the lines of the
<a href="http://www.opensearch.org/Specifications/OpenSearch/Extensions/Geo/1.0/Draft_1">OpenSearch-Geo
extension draft</a>. Currently
<a href="http://gitorious.org/geocouch/pages/Queries">supported</a> are
bounding box and polygon searches.</li>
  <li>Adding new backends (in addition to SpatiaLite) is easily possible.</li>
</ul>

<h3>Requirements</h3>
<ul>
  <li><a href="http://www.kernel.org/">Linux 2.6.26</a></li>
  <li><a href="http://couchdb.apache.org/">CouchDB 0.10.0</a></li>
  <li><a href="http://www.python.org/">Python 2.6.0</a></li>
  <li><a href="http://code.google.com/p/couchdb-python/">couchdb-python 0.6.x (0.6.0 doesn't work)</a></li>
  <li><a href="http://trac.gispython.org/lab/wiki/Shapely">Shapely 1.0.12</a></li>
  <li><a href="http://code.google.com/p/apsw/">APSW - Another Python SQLite Wrapper 3.5.9-r2</a></li>
  <li><a href="http://www.gaia-gis.it/spatialite/">SpatiaLite 2.3.1</a></li>
</ul>
<p>Other versions might work.</p>

<h3>Download</h3>
<p>If you don’t like Git, you can
<a href="/geocouch/downloads/geocouch-0.10.0.tar.bz2">download GeoCouch 0.10.0
here</a>.
</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-new-release-0.10.0%3A2009-09-19%3Aen%2CCouchDB%2CPython%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>CouchDB: Returning all design documents with Python
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/couchdb-all-design-docs%3A2009-08-21%3Aen%2CCouchDB%2CPython</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/couchdb-all-design-docs%3A2009-08-21%3Aen%2CCouchDB%2CPython#comments</comments>
<pubDate>Fri, 21 Aug 2009 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/couchdb-all-design-docs%3A2009-08-21%3Aen%2CCouchDB%2CPython/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>I just wanted to get all design documents of a
<a href="http://couchdb.apache.org/">CouchDB</a> database with
<a href="http://code.google.com/p/couchdb-python/">couchdb-python</a>. I
couldn’t find any hints how to do it, it took longer to find out than expected.
Therefore this blog entry, perhaps I save someone a few minutes of research.
</p>
<p>
  <pre>
<code>from couchdb.client import Server
couch_server = Server('http://localhost:5984/')
for designdoc in couch_server['yourdatabase']\
        .view('_all_docs', startkey='_design', endkey='_design0'):
    print 'designdoc: %s' % designdoc
</code></pre>
</p>
<p><strong>Update:</strong> even simpler with slicing:</p>
<p>
  <pre>
<code>from couchdb.client import Server
couch_server = Server('http://localhost:5984/')
for designdoc in couch_server['yourdatabase']\
        .view('_all_docs')['_design':'_design0']:
    print 'designdoc: %s' % designdoc
</code></pre>
</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/couchdb-all-design-docs%3A2009-08-21%3Aen%2CCouchDB%2CPython/feed/</wfw:commentRss>
</item>
<item>
<title>pythonpath: access nested data structures easily
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/pythonpath-access-nested-data-structures%3A2008-11-08%3Aen%2CPython</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/pythonpath-access-nested-data-structures%3A2008-11-08%3Aen%2CPython#comments</comments>
<pubDate>Sat, 08 Nov 2008 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>Python</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/pythonpath-access-nested-data-structures%3A2008-11-08%3Aen%2CPython/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>With pythonpath you can access values within nested Python data structures
easily. This is especially useful if you use JSON. If know which element you
want, you can access it directly with a string (a pythonpath).
</p>

<p>I created pythonpath for
<a href="geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo">GeoCouch</a>
as I needed a way to point to a specific element within a JSON structure. But
I think it might be useful for others as well, hence this blog entry.
</p>

<p>
Take the following data structure:
<code><pre>
{ "type": "Feature",
  "geometry": {"type": "Point", "coordinates": [151.21 -33.87]}
}
</pre></code>
</p>

<p>If you want to get the type of the geometry, you'd normally access it by
<code><pre>
type = geo['geometry']['type'].
</pre></code>
</p>

<p>With pythonpath it would be:
<code><pre>
type = pythonpath.get_item('geometry.type', geo)
</pre></code>
</p>

<p>Accessing array elements is just as easy:</p>
<code><pre>
lat = pythonpath.get_item('geometry.coordinates[1]', geo)
</pre></code>

<p>The syntax is quite simple, a dot (.propertyname) for dictionary element,
array notation for an array element ([position]). The escape character
is backslash (\).</p>

<p>Here's the code:</p>

<code><pre>
# Copyright (c) 2008 Volker Mische (http://vmx.cx/)
# Licensed under MIT.

import operator
import re

def parser(path):
    items = []

    for prop in re.split('(?<!\\\\)\.', path):
        m = re.search('(\[\d+\])+$', prop)

        brackets = ""
        if m is not None:
            brackets = m.group()

        # unescape characters
        prop = prop.replace('\[', '[').replace('\]',']') \
                   .replace('\\.', '.').replace('\\\\', '\\')

        if len(brackets) > 0:
            if len(prop) > len(brackets):
                items.append(prop[:-len(brackets)])

            for index in re.findall('\[(\d+)\]', brackets):
                items.append(int(index))

            continue

        items.append(prop)

    return items


def get_item(path, data):
    itemgetters = map(operator.itemgetter, parser(path))
    for getit in itemgetters:
        data = getit(data)
    return data
</pre></code>

<p>You can also download this code together with some tests.</p>
<ul>
  <li><a href="/blog/2008-11-08/pythonpath-1.0.tar.bz2">pythonpath 1.0</li>
</ul>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/pythonpath-access-nested-data-structures%3A2008-11-08%3Aen%2CPython/feed/</wfw:commentRss>
</item>
<item>
<title>GeoCouch: Geospatial queries with CouchDB
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo#comments</comments>
<pubDate>Sun, 26 Oct 2008 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>Python</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p style="border:10px solid #f00;font-size:2em;padding:1em">
<strong>Notice:</strong> This blog post is outdated, please move on :)
</p>


<p><strong>Update</strong> (2009-09-19): There's a new GeoCouch release. More information at <a href="/cgi-bin/blog/index.cgi/geocouch-new-release-0.10.0:2009-09-19:en,CouchDB,Python,geo">GeoCouch: New release 0.10.0</a>.</p>

<p>After almost six months of silence I finally managed to get a prototype done
(thanks <a href="http://jan.prima.de/~jan/">Jan</a> for keeping me motivated).
</p>

<h3>What do you get?</h3>
<p>You get some code to play around with, to get a slight idea of how such a
geospatial extension for <a href="http://couchdb.org/">CouchDB</a> could look
like. The code base isn’t polished yet, but it’s good enough to get it out of
the door. The current version only supports one geometry type
(<code>POINT</code>), and one operation (a bounding box search).
</p>
<p>As CouchDB doesn’t allow an intersection of results gathered from an
external service, the result of the bounding box search will be plain text
document IDs and their coordinates.
</p>

<h3>How does it work?</h3>
<p>GeoCouch consists of two parts, the indexer and the query processor.
Both are connected through stdin/out with CouchDB.</p>

<h4>Indexer (geostore)</h4>
<p>In order to make the indexer understand which fields in the document contain
geometries, a special design document is needed. As soon as a database has such
a document, the database is <em>geo-enabled</em> and the indexer will store the
geometries in a spatial index, which is a
<a href="http://www.gaia-gis.it/spatialite/">SpatiaLite</a> database at the
moment</a>.
</p>
<p>Everytime a database in CouchDB is altered (create, delete, update) the
indexer gets notified and will act accordingly to keep the spatial index
up to date with CouchDB.
</p>

<h4>Query processor (geoquery)</h4>
<p>To process queries with an external service is possible with
<a href="http://www.davispj.com/">Paul Joseph Davis’</a> excellent
<a href="http://github.com/davisp/couchdb/tree/external2">
external2 CouchDB branch</a>. Queries to CouchDB can get passed along to an
external service.
</p>
<p>At the moment the result is the output of this service, it’s plain text in
our case. In the future the external service will only return document IDs
which will be passed back to the view. The result will be an intersection of
document IDs of the view and the document IDs the external service returned.
</p>

<h3>How do I use it?</h3>
<p>When everything is installed correctly it’s quite easy to get started.</p>

<h4>Setting things up</h4>
<ul>
  <li>Create a new database named <code>geodata</code> (could be anything).</li>
  <li>Add a document named <code>myhome</code>, there you’ll store all the information
of your home including the coordinates. As we are only interested in a bounding
box search it’s enough to have a location:
      <pre>
<code>{
  "_id": "myhome",
  "_rev": "3358484250",
  "location": [ 151.208333, -33.869444 ]
}</code></pre>
  </li>
  <li>Add as many other documents like this, make sure all of them have a field
called <code>location</code> with the coordinates as array. As for the database,
the name of the field could be anything, but has to be the same in all
documents.
  </li>
  <li>Now we come to the interesting part, the special design view that
<em>geo-enables</em> the database. The document has to be named
“<code>_design/_geocouch</code>”. After creating it also needs some special fields and
will look like this:
    <p>
      <pre>
<code>{
  "_id": "_design/_geocouch",
  "_rev": "610069068",
  "srid": 4326,
  "loc": {
    "type": "POINT",
    "x": "location[0]",
    "y": "location[1]"
  }
}</code></pre>
    </p>
    <p>The coordinate system that should be used is specified by an
<a href="http://en.wikipedia.org/wiki/SRID">SRID</a>. If you don’t know which
value to use for <code>srid</code>, use <code>4326</code>. It’s assumed that
all geometries in your document belong to the same coordinate system.
    </p>
    <p>The other field is the information where to find the geometry in the
documents. The name you choose will be used for the bounding box queries,
I’ve chosen <code>loc</code>. It defines the type (<code>POINT</code>), and
where to find the x/y coordinate (this will probably be changed to lat/lon in
the future).
    </p>
    <p>The way to specify where to find the field is comparable to XPath, but
much simpler. As JSON consists of nested dictionaries and arrays, you can get a
property within an array with the index (e.g. <code>location[0]</code> is the
first element in an Array called <code>location</code>). If it is a dictionary
you specify it separated by a dot (e.g. <code>location.x</code> is a property
named <code>x</code> within another one called <code>location</code>). It can
of course be nested much deeper, the path always starts at the root of the
document (e.g. <code>bike.stolen.found[0]</code>).
    </p>
  </li>
</ul>

<h4>Bounding box search</h4>
<p>And finally you can make a bounding box search. Simply browse a URL like
this one (this is a bounding box that encloses the whole world):
</p>
<p>
  <pre>
<code>http://localhost:5984/geodata/_external/geo?q={"geom":"loc","bbox":[-180,-90,180,90]}
</code></pre>
</p>
<p>The expected result is:</p>
<p>
  <pre>
<code>myhome 151.208333 -33.869444</code></pre>
</p>

<h3>Requirements</h3>
<p>You’d like to give it a try? Here is a list of the software and their versions
I used to get it work on my system, but others might work as well. GeoCouch
includes installation/configuration instructions.</p>
<ul>
  <li><a href="http://www.kernel.org/">Linux 2.6.26</a></li>
  <li><a href="http://www.python.org/">Python 2.5.2</a></li>
  <li><a href=http://code.google.com/p/apsw/">APSW - Another Python SQLite Wrapper 3.5.9-r2</a></li>
  <li><a href="http://www.gaia-gis.it/spatialite/">SpatiaLite 2.2</a></li>
  <li><a href="http://github.com/davisp/couchdb/tree/external2">
davisp’s external2 branch of CouchDB</a>
  </li>
</ul>

<h3>Download GeoCouch</h3>
<p>Get SpacialCouch now! It’s new, it’s free
(<a href="http://www.opensource.org/licenses/mit-license.php">MIT</a>
licensed).</p>
<ul>
  <li><a href="/blog/2008-10-26/geocouch-0.0.1.tar.bz2">
GeoCouch 0.0.1</a></li>
</ul>

<h3>What’s next?</h3>
<p>The current version is meant to play with, many things are not possible,
many things needs to be improved. But with the power of SpatiaLite (and the
underlying libraries) it shouldn’t be too hard.
</p>
<p>Therefore I hope this will only be start and will end up in a discussion
on what should be done, what other things might be possible. I’d love to
hear your use cases for a geospatially enabled CouchDB.</p>

]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo/feed/</wfw:commentRss>
</item>
</channel>
</rss>
