<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sean Gillies (Posts about 2011)</title><link>https://sgillies.net/</link><description></description><atom:link href="https://sgillies.net/tags/cat_2011.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Sun, 31 Dec 2023 01:26:19 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Shapely from the outside</title><link>https://sgillies.net/2011/12/30/shapely-from-the-outside.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;Right before the the start of my holiday, I stumbled onto a &lt;a class="reference external" href="http://www.chopshopgeo.com/blog/?p=89"&gt;post&lt;/a&gt; from a GIS blog
I'd never seen before. It's an older post that compares Shapely to OGR's Python
module and GeoScript. As comments are disabled on that post, I'll make a few here.
At the time the post was written, Shapely 1.2.8 was released
and the manual was fully mature. Greg Corradini writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Shapely is a little bit different than OGR and GeoScript. One big difference
is that you can’t read and write to file formats with it. The idea, at least
the idea that I’ve taken from it’s website, is that Shapely is
a “swiss-army-knife” spatial analysis tool — it does some things really
really fast and pythonic but it isn’t going to fix a flat tire. Or something
like that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Shapely is more limited than a Swiss Army knife. It's just a wrapper for the
GEOS library, using idiommatic Python. It tries to do one thing – or rather,
one fairly large set of related things – very well. It doesn't read or write
GIS data formats, so if it's a Swiss Army knife it's one without can and bottle
openers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The coolo-neato things about Shapely include the ability to
serialize/deserialize to/from data formats that implement a GeoJson-like
interface and to/from numpy arrays. There’s also a couple helpful methods
— linemerge and polygonize — that it wraps from the GEOS library.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I'm glad to see that somebody appreciates the GeoJSON-like Python geo interface.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These methods aren’t as easy to reach in GeoScript or OGR built with GEOS
support off the proverbial ‘shelf’ because you’d have to call Java libraries
in the case of GeoScript and C++ libraries using Python ctypes. Shapely makes
using these methods easy, even though you could develop your own wrappers to
get at them in GeoScript and OGR with GEOS support.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hadn't thought of these functions as killer features. I suspect they're
probably available in osgeo.ogr by now.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I want to say one last thing about Shapely, though it might reflect some
naivete on my part about the functionality of this tool. It seems to me that
you can do about 80% of what Shapely does if you build OGR against GEOS and
use those bindings. Although it might be more pythonic, optimized in certain
ways and syntactically simpler, I’m still unsure who the users are and why.
I think the TileStache project uses this library on the backend. I’m
interested to find more examples.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I used to work in a GIS shop where at least half of the work was taking some
data in one obscure format, doing something relatively simple to it
(reprojection, for example), and writing it out in some other arcane format.
Shapely &lt;em&gt;by itself&lt;/em&gt; is practically useless for that kind of work, and
I understand that it's purpose can be baffling to the programming GIS analyst.
I think I might have found it baffling before my career change.&lt;/p&gt;
&lt;p&gt;Finally, Corradini writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since Shapely can’t read or write geometries we have to lean on an existing
interop library. Example 3 will use OGR for reads and writes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or better yet: &lt;a class="reference external" href="https://github.com/sgillies/Fiona"&gt;Fiona&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's an interesting post, and the way it weighs a few different software packages is rare these days. It also has me thinking about whether I should be benchmarking Shapely
and Fiona versus GeoScript. Assuming the &lt;code class="docutils literal"&gt;testit&lt;/code&gt; module is supported by
Jython and produces directly comparable numbers (because I won't be able to benchmark my C Python modules in the same process), it should be pretty easy to do.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-shapely-from-the-outside"&gt;
&lt;h3&gt;Re: Shapely from the outside&lt;/h3&gt;
&lt;p&gt;Author: &lt;a class="reference external" href="http://kralidis.ca/blog/"&gt;Tom Kralidis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We use Shapely in&lt;/p&gt;&lt;a href="http://pycsw.org/"&gt;pycsw&lt;/a&gt;&lt;p&gt;to do low level geometry operations (for spatial filters) as well as manage the geometry lifecycle of metadata records.  IMHO, it's a portable approach to acheiving this functionality without having to carry OGR, etc.&lt;/p&gt;&lt;/section&gt;
&lt;/section&gt;</description><category>programming</category><category>python</category><category>the lab</category><category>work</category><guid>https://sgillies.net/2011/12/30/shapely-from-the-outside.html</guid><pubDate>Fri, 30 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Fiona and matplotlib: simply plotting features</title><link>https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;Fiona goes very well with matplotlib and &lt;a class="reference external" href="http://pypi.python.org/pypi/descartes"&gt;descartes&lt;/a&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-1" name="rest_code_2926d4d241cd4d939a2bc605314633b8-1" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;matplotlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pyplot&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-2" name="rest_code_2926d4d241cd4d939a2bc605314633b8-2" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-2"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;descartes&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PolygonPatch&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-3" name="rest_code_2926d4d241cd4d939a2bc605314633b8-3" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-4" name="rest_code_2926d4d241cd4d939a2bc605314633b8-4" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-4"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fiona&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-5" name="rest_code_2926d4d241cd4d939a2bc605314633b8-5" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-5"&gt;&lt;/a&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-6" name="rest_code_2926d4d241cd4d939a2bc605314633b8-6" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-6"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Set up the figure and axes.&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-7" name="rest_code_2926d4d241cd4d939a2bc605314633b8-7" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-7"&gt;&lt;/a&gt;&lt;span class="n"&gt;BLUE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'#6699cc'&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-8" name="rest_code_2926d4d241cd4d939a2bc605314633b8-8" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-8"&gt;&lt;/a&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pyplot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dpi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-9" name="rest_code_2926d4d241cd4d939a2bc605314633b8-9" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-9"&gt;&lt;/a&gt;&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-10" name="rest_code_2926d4d241cd4d939a2bc605314633b8-10" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-11" name="rest_code_2926d4d241cd4d939a2bc605314633b8-11" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-11"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# For each feature in the collection, add a patch to the axes.&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-12" name="rest_code_2926d4d241cd4d939a2bc605314633b8-12" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-12"&gt;&lt;/a&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"docs/data/test_uk.shp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-13" name="rest_code_2926d4d241cd4d939a2bc605314633b8-13" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-13"&gt;&lt;/a&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-14" name="rest_code_2926d4d241cd4d939a2bc605314633b8-14" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-14"&gt;&lt;/a&gt;        &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-15" name="rest_code_2926d4d241cd4d939a2bc605314633b8-15" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-15"&gt;&lt;/a&gt;            &lt;span class="n"&gt;PolygonPatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-16" name="rest_code_2926d4d241cd4d939a2bc605314633b8-16" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-16"&gt;&lt;/a&gt;                &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BLUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BLUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;))&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-17" name="rest_code_2926d4d241cd4d939a2bc605314633b8-17" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-17"&gt;&lt;/a&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-18" name="rest_code_2926d4d241cd4d939a2bc605314633b8-18" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-18"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Should be able to get extents from the collection in a future version&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-19" name="rest_code_2926d4d241cd4d939a2bc605314633b8-19" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-19"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# of Fiona.&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-20" name="rest_code_2926d4d241cd4d939a2bc605314633b8-20" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-20"&gt;&lt;/a&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_xlim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;9.25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-21" name="rest_code_2926d4d241cd4d939a2bc605314633b8-21" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-21"&gt;&lt;/a&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ylim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;49.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;61.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-22" name="rest_code_2926d4d241cd4d939a2bc605314633b8-22" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-22"&gt;&lt;/a&gt;
&lt;a id="rest_code_2926d4d241cd4d939a2bc605314633b8-23" name="rest_code_2926d4d241cd4d939a2bc605314633b8-23" href="https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html#rest_code_2926d4d241cd4d939a2bc605314633b8-23"&gt;&lt;/a&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;savefig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'test_uk.png'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The resulting image:&lt;/p&gt;
&lt;img alt="http://farm8.staticflickr.com/7005/6554613263_9bc5761f72_o_d.png" src="http://farm8.staticflickr.com/7005/6554613263_9bc5761f72_o_d.png" style="width: 600px; height: 600px;"&gt;
&lt;p&gt;I value simplicity. The problems I work on are complex and tools with extra, incidental complexity wear me out needlessly. How about you? Fiona, unlike other geospatial software, is designed to be simple.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-fiona-and-matplotlib-simply-plotting-features"&gt;
&lt;h3&gt;Re: Fiona and matplotlib: simply plotting features&lt;/h3&gt;
&lt;p&gt;Author: &lt;a class="reference external" href="Http://Reinout.vanrees.org"&gt;Reinout van Rees&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wow, this looks neat. The simplicity here and in your previous example make it feel very thought-out and practical.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I have a django project where we use shape files. Small errors in them keep bringing parts of sites down. Sending them through Fiona and using the filtered and clean geojson output should help a lot. And simplify our code a lot.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Now all I have to do is get rid of my back pain and start experimenting with this. I already sent off an email to work to look at this :-)&lt;/p&gt;&lt;/section&gt;
&lt;section id="re-fiona-and-matplotlib-simply-plotting-features-1"&gt;
&lt;h3&gt;Re: Fiona and matplotlib: simply plotting features&lt;/h3&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
&lt;p&gt;Well, remember that my earlier script only gets out mild stains. Geodata is about as dirty as data gets.&lt;/p&gt;&lt;/section&gt;
&lt;/section&gt;</description><category>programming</category><category>python</category><category>the lab</category><category>work</category><guid>https://sgillies.net/2011/12/22/fiona-and-matplotlib-simply-plotting-features.html</guid><pubDate>Thu, 22 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Fiona and Shapely: spatially cleaning features</title><link>https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;Inspired by comments I saw today on the internet, this is how you spatially clean features using Fiona and Shapely (for small values of dirty).&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-1" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-1" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-2" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-2" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-2"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-3" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-3" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-4" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-4" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-4"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;shapely.geometry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-5" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-5" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-5"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-6" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-6" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-6"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fiona&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-7" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-7" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-7"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-8" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-8" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-8"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-9" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-9" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-9"&gt;&lt;/a&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-10" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-10" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-11" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-11" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-11"&gt;&lt;/a&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"docs/data/test_uk.shp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-12" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-12" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-12"&gt;&lt;/a&gt;    &lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-13" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-13" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-13"&gt;&lt;/a&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-14" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-14" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-14"&gt;&lt;/a&gt;            &lt;span class="s2"&gt;"with-shapely.shp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ESRI Shapefile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-15" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-15" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-15"&gt;&lt;/a&gt;            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-16" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-16" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-16"&gt;&lt;/a&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-17" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-17" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-17"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-18" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-18" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-18"&gt;&lt;/a&gt;            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-19" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-19" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-19"&gt;&lt;/a&gt;                &lt;span class="c1"&gt;# Make a shapely object from the dict.&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-20" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-20" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-20"&gt;&lt;/a&gt;                &lt;span class="n"&gt;geom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-21" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-21" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-21"&gt;&lt;/a&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;geom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-22" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-22" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-22"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-23" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-23" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-23"&gt;&lt;/a&gt;                    &lt;span class="c1"&gt;# Use the 0-buffer polygon cleaning trick&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-24" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-24" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-24"&gt;&lt;/a&gt;                    &lt;span class="n"&gt;clean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-25" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-25" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-25"&gt;&lt;/a&gt;                    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;geom_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'Polygon'&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-26" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-26" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-26"&gt;&lt;/a&gt;                    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-27" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-27" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-27"&gt;&lt;/a&gt;                    &lt;span class="n"&gt;geom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-28" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-28" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-28"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-29" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-29" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-29"&gt;&lt;/a&gt;                &lt;span class="c1"&gt;# Make a dict from the shapely object.&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-30" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-30" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-30"&gt;&lt;/a&gt;                &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;geom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-31" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-31" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-31"&gt;&lt;/a&gt;                &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-32" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-32" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-32"&gt;&lt;/a&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-33" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-33" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-33"&gt;&lt;/a&gt;            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-34" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-34" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-34"&gt;&lt;/a&gt;                &lt;span class="c1"&gt;# Writing uncleanable features to a different shapefile&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-35" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-35" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-35"&gt;&lt;/a&gt;                &lt;span class="c1"&gt;# is another option.&lt;/span&gt;
&lt;a id="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-36" name="rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-36" href="https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html#rest_code_6c1ec21b4c4748e5ac7c3d2811e101db-36"&gt;&lt;/a&gt;                &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Error cleaning feature &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Makes a neat example, I think. Shapely just happens to provide this handy zero buffer feature (via GEOS), it's not required at all. Fiona just reads and writes GeoJSON-like mappings (like Python's &lt;code class="docutils literal"&gt;dict&lt;/code&gt;), it doesn't care what you do in between or what you do it with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; (2011-12-25): The error I noted in the comments is fixed above.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-fiona-and-shapely-spatially-cleaning-features"&gt;
&lt;h3&gt;Re: Fiona and Shapely: spatially cleaning features&lt;/h3&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
&lt;p&gt;Oops, there's an error above. I mean to assert that the cleaned geom is valid.&lt;/p&gt;&lt;/section&gt;
&lt;/section&gt;</description><category>programming</category><category>python</category><category>the lab</category><category>work</category><guid>https://sgillies.net/2011/12/21/fiona-and-shapely-spatially-cleaning-features.html</guid><pubDate>Wed, 21 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Fiona's half-way mark</title><link>https://sgillies.net/2011/12/21/fionas-half-way-mark.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;By my measure, Fiona is half-way to production readiness. Version 0.5 is up on
PyPI: &lt;a class="reference external" href="http://pypi.python.org/pypi/Fiona/0.5"&gt;http://pypi.python.org/pypi/Fiona/0.5&lt;/a&gt;. It now writes mapping features to
almost any of OGR's formats. Almost.&lt;/p&gt;
&lt;p&gt;In Python, I'm not very interested in OGR's support for databases or services,
and so Fiona isn't either. I'd rather use httplib2 to connect fetch any JSON or
XML (KML, GML, GeoRSS) document on the web, and Python's built-in json or
xml.etree modules to parse them with some help from geojson and keytree. For
databases, I'll use SQLAlchemy or GeoAlchemy. Fiona is mainly about reading and
writing the arcane file formats like shapefiles, GPX, etc for which there is
pretty much no other access than through OGR's drivers. Fiona doesn't do OGR
"data sources". It has collections of a single feature type. Think shapefile or
single PostGIS table. The door isn't completely shut on databases; the first
version of Fiona had the concept of a "workspace", and we could bring that back
if needed.&lt;/p&gt;
&lt;p&gt;The latest installation instructions and usage example are on Fiona's GitHub
page: &lt;a class="reference external" href="https://github.com/sgillies/Fiona"&gt;https://github.com/sgillies/Fiona&lt;/a&gt; and there's more documentation to come.
A Shapely-level manual will be the cornerstone of a 1.0 release, although
I expect the Fiona manual to be much smaller.&lt;/p&gt;
&lt;section id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;If you've got GDAL installed in a well-known location and Python 2.6, you may be
able to install as easily as:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_2b658e98b04f4be58c3c2fdd0c5aa78d-1" name="rest_code_2b658e98b04f4be58c3c2fdd0c5aa78d-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_2b658e98b04f4be58c3c2fdd0c5aa78d-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;pip install Fiona
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If, like me, you have virtualenvs with their own GDAL libs, you'll need to do
something like this.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_8594111d93b64f4a859857982a3c6528-1" name="rest_code_8594111d93b64f4a859857982a3c6528-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_8594111d93b64f4a859857982a3c6528-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;virtualenv .
&lt;a id="rest_code_8594111d93b64f4a859857982a3c6528-2" name="rest_code_8594111d93b64f4a859857982a3c6528-2" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_8594111d93b64f4a859857982a3c6528-2"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; bin/activate
&lt;a id="rest_code_8594111d93b64f4a859857982a3c6528-3" name="rest_code_8594111d93b64f4a859857982a3c6528-3" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_8594111d93b64f4a859857982a3c6528-3"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;pip install -d Fiona http://pypi.python.org/packages/source/F/Fiona/Fiona-0.5.tar.gz
&lt;a id="rest_code_8594111d93b64f4a859857982a3c6528-4" name="rest_code_8594111d93b64f4a859857982a3c6528-4" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_8594111d93b64f4a859857982a3c6528-4"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;GDAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PATH_TO_GDAL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;a id="rest_code_8594111d93b64f4a859857982a3c6528-5" name="rest_code_8594111d93b64f4a859857982a3c6528-5" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_8594111d93b64f4a859857982a3c6528-5"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; Fiona
&lt;a id="rest_code_8594111d93b64f4a859857982a3c6528-6" name="rest_code_8594111d93b64f4a859857982a3c6528-6" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_8594111d93b64f4a859857982a3c6528-6"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;python setup.py build_ext -I &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GDAL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/include -L &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GDAL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/lib install
&lt;/pre&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id="reading-benchmark"&gt;
&lt;h2&gt;Reading benchmark&lt;/h2&gt;
&lt;p&gt;Is Fiona anywhere as fast as osgeo.ogr? Benchmark: get all polygon-type
features from a shapefile, read their attributes into a dict, get a reference
to their geometry (in the OGR case) or geometry as GeoJSON (in the Fiona
case), and get their unique ids. Here's the script:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-1" name="rest_code_b0b783adb58b42da84d36014900189df-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;timeit&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-2" name="rest_code_b0b783adb58b42da84d36014900189df-2" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-2"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fiona&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-3" name="rest_code_b0b783adb58b42da84d36014900189df-3" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-3"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;osgeo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ogr&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-4" name="rest_code_b0b783adb58b42da84d36014900189df-4" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-5" name="rest_code_b0b783adb58b42da84d36014900189df-5" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'docs/data/test_uk.shp'&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-6" name="rest_code_b0b783adb58b42da84d36014900189df-6" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-6"&gt;&lt;/a&gt;&lt;span class="n"&gt;NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test_uk'&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-7" name="rest_code_b0b783adb58b42da84d36014900189df-7" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-7"&gt;&lt;/a&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-8" name="rest_code_b0b783adb58b42da84d36014900189df-8" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-8"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Fiona&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-9" name="rest_code_b0b783adb58b42da84d36014900189df-9" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-9"&gt;&lt;/a&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-10" name="rest_code_b0b783adb58b42da84d36014900189df-10" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-10"&gt;&lt;/a&gt;&lt;span class="s2"&gt;with collection(PATH, "r") as c:&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-11" name="rest_code_b0b783adb58b42da84d36014900189df-11" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-11"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    for f in c:&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-12" name="rest_code_b0b783adb58b42da84d36014900189df-12" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-12"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        id = f["id"]&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-13" name="rest_code_b0b783adb58b42da84d36014900189df-13" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-13"&gt;&lt;/a&gt;&lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-14" name="rest_code_b0b783adb58b42da84d36014900189df-14" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-14"&gt;&lt;/a&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-15" name="rest_code_b0b783adb58b42da84d36014900189df-15" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-15"&gt;&lt;/a&gt;    &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-16" name="rest_code_b0b783adb58b42da84d36014900189df-16" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-16"&gt;&lt;/a&gt;    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'from __main__ import collection, PATH, NAME'&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-17" name="rest_code_b0b783adb58b42da84d36014900189df-17" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-17"&gt;&lt;/a&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-18" name="rest_code_b0b783adb58b42da84d36014900189df-18" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-18"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Fiona 0.5"&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-19" name="rest_code_b0b783adb58b42da84d36014900189df-19" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-19"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;%.2f&lt;/span&gt;&lt;span class="s2"&gt; usec/pass"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-20" name="rest_code_b0b783adb58b42da84d36014900189df-20" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-20"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-21" name="rest_code_b0b783adb58b42da84d36014900189df-21" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-21"&gt;&lt;/a&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-22" name="rest_code_b0b783adb58b42da84d36014900189df-22" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-22"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# OGR&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-23" name="rest_code_b0b783adb58b42da84d36014900189df-23" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-23"&gt;&lt;/a&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-24" name="rest_code_b0b783adb58b42da84d36014900189df-24" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-24"&gt;&lt;/a&gt;&lt;span class="s2"&gt;source = ogr.Open(PATH)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-25" name="rest_code_b0b783adb58b42da84d36014900189df-25" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-25"&gt;&lt;/a&gt;&lt;span class="s2"&gt;layer = source.GetLayerByName(NAME)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-26" name="rest_code_b0b783adb58b42da84d36014900189df-26" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-26"&gt;&lt;/a&gt;&lt;span class="s2"&gt;schema = []&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-27" name="rest_code_b0b783adb58b42da84d36014900189df-27" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-27"&gt;&lt;/a&gt;&lt;span class="s2"&gt;ldefn = layer.GetLayerDefn()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-28" name="rest_code_b0b783adb58b42da84d36014900189df-28" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-28"&gt;&lt;/a&gt;&lt;span class="s2"&gt;for n in range(ldefn.GetFieldCount()):&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-29" name="rest_code_b0b783adb58b42da84d36014900189df-29" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-29"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    fdefn = ldefn.GetFieldDefn(n)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-30" name="rest_code_b0b783adb58b42da84d36014900189df-30" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-30"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    schema.append((fdefn.name, fdefn.type))&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-31" name="rest_code_b0b783adb58b42da84d36014900189df-31" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-31"&gt;&lt;/a&gt;&lt;span class="s2"&gt;layer.ResetReading()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-32" name="rest_code_b0b783adb58b42da84d36014900189df-32" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-32"&gt;&lt;/a&gt;&lt;span class="s2"&gt;while 1:&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-33" name="rest_code_b0b783adb58b42da84d36014900189df-33" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-33"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feature = layer.GetNextFeature()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-34" name="rest_code_b0b783adb58b42da84d36014900189df-34" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-34"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    if not feature:&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-35" name="rest_code_b0b783adb58b42da84d36014900189df-35" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-35"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        break&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-36" name="rest_code_b0b783adb58b42da84d36014900189df-36" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-36"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    id = feature.GetFID()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-37" name="rest_code_b0b783adb58b42da84d36014900189df-37" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-37"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    props = &lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s2"&gt;&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-38" name="rest_code_b0b783adb58b42da84d36014900189df-38" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-38"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    for i in range(feature.GetFieldCount()):&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-39" name="rest_code_b0b783adb58b42da84d36014900189df-39" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-39"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        props[schema[i][0]] = feature.GetField(i)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-40" name="rest_code_b0b783adb58b42da84d36014900189df-40" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-40"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    geometry = feature.GetGeometryRef()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-41" name="rest_code_b0b783adb58b42da84d36014900189df-41" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-41"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feature.Destroy()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-42" name="rest_code_b0b783adb58b42da84d36014900189df-42" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-42"&gt;&lt;/a&gt;&lt;span class="s2"&gt;source.Destroy()&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-43" name="rest_code_b0b783adb58b42da84d36014900189df-43" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-43"&gt;&lt;/a&gt;&lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-44" name="rest_code_b0b783adb58b42da84d36014900189df-44" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-44"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"osgeo.ogr 1.7.2"&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-45" name="rest_code_b0b783adb58b42da84d36014900189df-45" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-45"&gt;&lt;/a&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-46" name="rest_code_b0b783adb58b42da84d36014900189df-46" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-46"&gt;&lt;/a&gt;    &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-47" name="rest_code_b0b783adb58b42da84d36014900189df-47" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-47"&gt;&lt;/a&gt;    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'from __main__ import ogr, PATH, NAME'&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-48" name="rest_code_b0b783adb58b42da84d36014900189df-48" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-48"&gt;&lt;/a&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_b0b783adb58b42da84d36014900189df-49" name="rest_code_b0b783adb58b42da84d36014900189df-49" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_b0b783adb58b42da84d36014900189df-49"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;%.2f&lt;/span&gt;&lt;span class="s2"&gt; usec/pass"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That's just 3 statements with Fiona, 19 with osgeo.ogr. Do you like that? I like
that. A lot. Next are the numbers.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_788e9e4549024b5dbbecb280bad6615d-1" name="rest_code_788e9e4549024b5dbbecb280bad6615d-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_788e9e4549024b5dbbecb280bad6615d-1"&gt;&lt;/a&gt;&lt;span class="gp gp-VirtualEnv"&gt;(Fiona)&lt;/span&gt;&lt;span class="gp"&gt;krusty-2:Fiona seang$ &lt;/span&gt;python benchmark.py
&lt;a id="rest_code_788e9e4549024b5dbbecb280bad6615d-2" name="rest_code_788e9e4549024b5dbbecb280bad6615d-2" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_788e9e4549024b5dbbecb280bad6615d-2"&gt;&lt;/a&gt;&lt;span class="go"&gt;Fiona 0.5&lt;/span&gt;
&lt;a id="rest_code_788e9e4549024b5dbbecb280bad6615d-3" name="rest_code_788e9e4549024b5dbbecb280bad6615d-3" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_788e9e4549024b5dbbecb280bad6615d-3"&gt;&lt;/a&gt;&lt;span class="go"&gt;2579.40 usec/pass&lt;/span&gt;
&lt;a id="rest_code_788e9e4549024b5dbbecb280bad6615d-4" name="rest_code_788e9e4549024b5dbbecb280bad6615d-4" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_788e9e4549024b5dbbecb280bad6615d-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_788e9e4549024b5dbbecb280bad6615d-5" name="rest_code_788e9e4549024b5dbbecb280bad6615d-5" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_788e9e4549024b5dbbecb280bad6615d-5"&gt;&lt;/a&gt;&lt;span class="go"&gt;osgeo.ogr 1.7.2&lt;/span&gt;
&lt;a id="rest_code_788e9e4549024b5dbbecb280bad6615d-6" name="rest_code_788e9e4549024b5dbbecb280bad6615d-6" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_788e9e4549024b5dbbecb280bad6615d-6"&gt;&lt;/a&gt;&lt;span class="go"&gt;3355.43 usec/pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result: even though Fiona is doing a fair amount of extra coordinate copying,
it's still faster than the Python bindings for OGR 1.7.2. Simpler + faster seems
like a big win.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="writing-benchmark"&gt;
&lt;h2&gt;Writing benchmark&lt;/h2&gt;
&lt;p&gt;How about writing speed? Benchmark: open a shapefile for writing and write 50
identical (other than their local ids) point-type features to it.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-1" name="rest_code_182b1d37cadb46c78016218f414009fc-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-2" name="rest_code_182b1d37cadb46c78016218f414009fc-2" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-2"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;timeit&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-3" name="rest_code_182b1d37cadb46c78016218f414009fc-3" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-4" name="rest_code_182b1d37cadb46c78016218f414009fc-4" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-4"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fiona&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-5" name="rest_code_182b1d37cadb46c78016218f414009fc-5" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-5"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;osgeo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ogr&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-6" name="rest_code_182b1d37cadb46c78016218f414009fc-6" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-7" name="rest_code_182b1d37cadb46c78016218f414009fc-7" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-7"&gt;&lt;/a&gt;&lt;span class="n"&gt;FEATURE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Point'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'coordinates'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-8" name="rest_code_182b1d37cadb46c78016218f414009fc-8" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-8"&gt;&lt;/a&gt;           &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s2"&gt;"Foo"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-9" name="rest_code_182b1d37cadb46c78016218f414009fc-9" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-9"&gt;&lt;/a&gt;&lt;span class="n"&gt;SCHEMA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Point'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'str'&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-10" name="rest_code_182b1d37cadb46c78016218f414009fc-10" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-11" name="rest_code_182b1d37cadb46c78016218f414009fc-11" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-11"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Fiona&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-12" name="rest_code_182b1d37cadb46c78016218f414009fc-12" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-12"&gt;&lt;/a&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-13" name="rest_code_182b1d37cadb46c78016218f414009fc-13" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-13"&gt;&lt;/a&gt;&lt;span class="s2"&gt;with collection("fiona.shp", "w", "ESRI Shapefile", SCHEMA) as c:&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-14" name="rest_code_182b1d37cadb46c78016218f414009fc-14" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-14"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    for i in range(50):&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-15" name="rest_code_182b1d37cadb46c78016218f414009fc-15" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-15"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        f = FEATURE.copy()&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-16" name="rest_code_182b1d37cadb46c78016218f414009fc-16" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-16"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        f['id'] = str(i)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-17" name="rest_code_182b1d37cadb46c78016218f414009fc-17" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-17"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        c.write(f)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-18" name="rest_code_182b1d37cadb46c78016218f414009fc-18" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-18"&gt;&lt;/a&gt;&lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-19" name="rest_code_182b1d37cadb46c78016218f414009fc-19" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-19"&gt;&lt;/a&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-20" name="rest_code_182b1d37cadb46c78016218f414009fc-20" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-20"&gt;&lt;/a&gt;    &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-21" name="rest_code_182b1d37cadb46c78016218f414009fc-21" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-21"&gt;&lt;/a&gt;    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'from __main__ import collection, SCHEMA, FEATURE'&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-22" name="rest_code_182b1d37cadb46c78016218f414009fc-22" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-22"&gt;&lt;/a&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-23" name="rest_code_182b1d37cadb46c78016218f414009fc-23" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-23"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Fiona 0.5"&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-24" name="rest_code_182b1d37cadb46c78016218f414009fc-24" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-24"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;%.2f&lt;/span&gt;&lt;span class="s2"&gt; usec/pass"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-25" name="rest_code_182b1d37cadb46c78016218f414009fc-25" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-25"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-26" name="rest_code_182b1d37cadb46c78016218f414009fc-26" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-26"&gt;&lt;/a&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-27" name="rest_code_182b1d37cadb46c78016218f414009fc-27" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-27"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# OGR&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-28" name="rest_code_182b1d37cadb46c78016218f414009fc-28" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-28"&gt;&lt;/a&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-29" name="rest_code_182b1d37cadb46c78016218f414009fc-29" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-29"&gt;&lt;/a&gt;&lt;span class="s2"&gt;drv = ogr.GetDriverByName("ESRI Shapefile")&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-30" name="rest_code_182b1d37cadb46c78016218f414009fc-30" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-30"&gt;&lt;/a&gt;&lt;span class="s2"&gt;if os.path.exists('ogr.shp'):&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-31" name="rest_code_182b1d37cadb46c78016218f414009fc-31" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-31"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    drv.DeleteDataSource('ogr.shp')&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-32" name="rest_code_182b1d37cadb46c78016218f414009fc-32" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-32"&gt;&lt;/a&gt;&lt;span class="s2"&gt;ds = drv.CreateDataSource("ogr.shp")&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-33" name="rest_code_182b1d37cadb46c78016218f414009fc-33" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-33"&gt;&lt;/a&gt;&lt;span class="s2"&gt;lyr = ds.CreateLayer("ogr", None, ogr.wkbPoint)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-34" name="rest_code_182b1d37cadb46c78016218f414009fc-34" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-34"&gt;&lt;/a&gt;&lt;span class="s2"&gt;field_defn = ogr.FieldDefn("label", ogr.OFTString)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-35" name="rest_code_182b1d37cadb46c78016218f414009fc-35" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-35"&gt;&lt;/a&gt;&lt;span class="s2"&gt;lyr.CreateField(field_defn)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-36" name="rest_code_182b1d37cadb46c78016218f414009fc-36" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-36"&gt;&lt;/a&gt;&lt;span class="s2"&gt;for i in range(50):&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-37" name="rest_code_182b1d37cadb46c78016218f414009fc-37" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-37"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feat = ogr.Feature(lyr.GetLayerDefn())&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-38" name="rest_code_182b1d37cadb46c78016218f414009fc-38" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-38"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feat.SetField("label", u"Foo")&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-39" name="rest_code_182b1d37cadb46c78016218f414009fc-39" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-39"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    pt = ogr.Geometry(ogr.wkbPoint)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-40" name="rest_code_182b1d37cadb46c78016218f414009fc-40" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-40"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    x, y = FEATURE['geometry']['coordinates']&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-41" name="rest_code_182b1d37cadb46c78016218f414009fc-41" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-41"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    pt.SetPoint_2D(0, x, y)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-42" name="rest_code_182b1d37cadb46c78016218f414009fc-42" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-42"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feat.SetGeometry(pt)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-43" name="rest_code_182b1d37cadb46c78016218f414009fc-43" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-43"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feat.SetFID(i)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-44" name="rest_code_182b1d37cadb46c78016218f414009fc-44" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-44"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    lyr.CreateFeature(feat)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-45" name="rest_code_182b1d37cadb46c78016218f414009fc-45" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-45"&gt;&lt;/a&gt;&lt;span class="s2"&gt;    feat.Destroy()&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-46" name="rest_code_182b1d37cadb46c78016218f414009fc-46" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-46"&gt;&lt;/a&gt;&lt;span class="s2"&gt;ds.Destroy()&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-47" name="rest_code_182b1d37cadb46c78016218f414009fc-47" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-47"&gt;&lt;/a&gt;&lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-48" name="rest_code_182b1d37cadb46c78016218f414009fc-48" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-48"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"osgeo.ogr 1.7.2"&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-49" name="rest_code_182b1d37cadb46c78016218f414009fc-49" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-49"&gt;&lt;/a&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-50" name="rest_code_182b1d37cadb46c78016218f414009fc-50" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-50"&gt;&lt;/a&gt;    &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-51" name="rest_code_182b1d37cadb46c78016218f414009fc-51" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-51"&gt;&lt;/a&gt;    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'from __main__ import ogr, os, FEATURE'&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-52" name="rest_code_182b1d37cadb46c78016218f414009fc-52" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-52"&gt;&lt;/a&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_182b1d37cadb46c78016218f414009fc-53" name="rest_code_182b1d37cadb46c78016218f414009fc-53" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_182b1d37cadb46c78016218f414009fc-53"&gt;&lt;/a&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;%.2f&lt;/span&gt;&lt;span class="s2"&gt; usec/pass"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fiona only needs five statements compared to 18 for osgeo.ogr, and Fiona writes
these features faster.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_014efa0d292743aba868c42f47cd1787-1" name="rest_code_014efa0d292743aba868c42f47cd1787-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_014efa0d292743aba868c42f47cd1787-1"&gt;&lt;/a&gt;&lt;span class="gp gp-VirtualEnv"&gt;(Fiona)&lt;/span&gt;&lt;span class="gp"&gt;krusty-2:Fiona seang$ &lt;/span&gt;python write-benchmark.py
&lt;a id="rest_code_014efa0d292743aba868c42f47cd1787-2" name="rest_code_014efa0d292743aba868c42f47cd1787-2" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_014efa0d292743aba868c42f47cd1787-2"&gt;&lt;/a&gt;&lt;span class="go"&gt;Fiona 0.5&lt;/span&gt;
&lt;a id="rest_code_014efa0d292743aba868c42f47cd1787-3" name="rest_code_014efa0d292743aba868c42f47cd1787-3" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_014efa0d292743aba868c42f47cd1787-3"&gt;&lt;/a&gt;&lt;span class="go"&gt;4435.63 usec/pass&lt;/span&gt;
&lt;a id="rest_code_014efa0d292743aba868c42f47cd1787-4" name="rest_code_014efa0d292743aba868c42f47cd1787-4" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_014efa0d292743aba868c42f47cd1787-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_014efa0d292743aba868c42f47cd1787-5" name="rest_code_014efa0d292743aba868c42f47cd1787-5" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_014efa0d292743aba868c42f47cd1787-5"&gt;&lt;/a&gt;&lt;span class="go"&gt;osgeo.ogr 1.7.2&lt;/span&gt;
&lt;a id="rest_code_014efa0d292743aba868c42f47cd1787-6" name="rest_code_014efa0d292743aba868c42f47cd1787-6" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_014efa0d292743aba868c42f47cd1787-6"&gt;&lt;/a&gt;&lt;span class="go"&gt;4565.33 usec/pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I was rather surprised by this. I've been benchmarking feature reading for a while
but this is the first time I've done it for writes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="tests"&gt;
&lt;h2&gt;Tests&lt;/h2&gt;
&lt;p&gt;Do you like tests?&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-1" name="rest_code_d742947dd22a4de0b78d2a9504166ace-1" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-1"&gt;&lt;/a&gt;&lt;span class="gp gp-VirtualEnv"&gt;(Fiona)&lt;/span&gt;&lt;span class="gp"&gt;krusty-2:Fiona seang$ &lt;/span&gt;python setup.py nosetests --nologcapture --with-coverage --cover-package&lt;span class="o"&gt;=&lt;/span&gt;fiona
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-2" name="rest_code_d742947dd22a4de0b78d2a9504166ace-2" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-2"&gt;&lt;/a&gt;&lt;span class="go"&gt;running nosetests&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-3" name="rest_code_d742947dd22a4de0b78d2a9504166ace-3" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-3"&gt;&lt;/a&gt;&lt;span class="go"&gt;running egg_info&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-4" name="rest_code_d742947dd22a4de0b78d2a9504166ace-4" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-4"&gt;&lt;/a&gt;&lt;span class="go"&gt;writing src/Fiona.egg-info/PKG-INFO&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-5" name="rest_code_d742947dd22a4de0b78d2a9504166ace-5" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-5"&gt;&lt;/a&gt;&lt;span class="go"&gt;writing top-level names to src/Fiona.egg-info/top_level.txt&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-6" name="rest_code_d742947dd22a4de0b78d2a9504166ace-6" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-6"&gt;&lt;/a&gt;&lt;span class="go"&gt;writing dependency_links to src/Fiona.egg-info/dependency_links.txt&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-7" name="rest_code_d742947dd22a4de0b78d2a9504166ace-7" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-7"&gt;&lt;/a&gt;&lt;span class="go"&gt;reading manifest file 'src/Fiona.egg-info/SOURCES.txt'&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-8" name="rest_code_d742947dd22a4de0b78d2a9504166ace-8" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-8"&gt;&lt;/a&gt;&lt;span class="go"&gt;reading manifest template 'MANIFEST.in'&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-9" name="rest_code_d742947dd22a4de0b78d2a9504166ace-9" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-9"&gt;&lt;/a&gt;&lt;span class="go"&gt;warning: no files found matching '*.txt' under directory 'tests'&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-10" name="rest_code_d742947dd22a4de0b78d2a9504166ace-10" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-10"&gt;&lt;/a&gt;&lt;span class="go"&gt;writing manifest file 'src/Fiona.egg-info/SOURCES.txt'&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-11" name="rest_code_d742947dd22a4de0b78d2a9504166ace-11" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-11"&gt;&lt;/a&gt;&lt;span class="go"&gt;running build_ext&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-12" name="rest_code_d742947dd22a4de0b78d2a9504166ace-12" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-12"&gt;&lt;/a&gt;&lt;span class="go"&gt;copying build/lib.macosx-10.5-i386-2.6/fiona/ogrinit.so -&amp;gt; src/fiona&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-13" name="rest_code_d742947dd22a4de0b78d2a9504166ace-13" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-13"&gt;&lt;/a&gt;&lt;span class="go"&gt;copying build/lib.macosx-10.5-i386-2.6/fiona/ogrext.so -&amp;gt; src/fiona&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-14" name="rest_code_d742947dd22a4de0b78d2a9504166ace-14" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-14"&gt;&lt;/a&gt;&lt;span class="go"&gt;nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$']&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-15" name="rest_code_d742947dd22a4de0b78d2a9504166ace-15" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-15"&gt;&lt;/a&gt;&lt;span class="go"&gt;nose.plugins.cover: INFO: Coverage report will include only packages: ['fiona']&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-16" name="rest_code_d742947dd22a4de0b78d2a9504166ace-16" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-16"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_invalid_mode (tests.test_collection.CollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-17" name="rest_code_d742947dd22a4de0b78d2a9504166ace-17" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-17"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_no_path (tests.test_collection.CollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-18" name="rest_code_d742947dd22a4de0b78d2a9504166ace-18" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-18"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_w_args (tests.test_collection.CollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-19" name="rest_code_d742947dd22a4de0b78d2a9504166ace-19" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-19"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_append_point (tests.test_collection.ShapefileAppendTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-20" name="rest_code_d742947dd22a4de0b78d2a9504166ace-20" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-20"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_context (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-21" name="rest_code_d742947dd22a4de0b78d2a9504166ace-21" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-21"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_filter_1 (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-22" name="rest_code_d742947dd22a4de0b78d2a9504166ace-22" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-22"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_io (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-23" name="rest_code_d742947dd22a4de0b78d2a9504166ace-23" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-23"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_iter_list (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-24" name="rest_code_d742947dd22a4de0b78d2a9504166ace-24" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-24"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_iter_one (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-25" name="rest_code_d742947dd22a4de0b78d2a9504166ace-25" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-25"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_len (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-26" name="rest_code_d742947dd22a4de0b78d2a9504166ace-26" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-26"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_no_write (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-27" name="rest_code_d742947dd22a4de0b78d2a9504166ace-27" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-27"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_schema (tests.test_collection.ShapefileCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-28" name="rest_code_d742947dd22a4de0b78d2a9504166ace-28" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-28"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_no_read (tests.test_collection.ShapefileWriteCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-29" name="rest_code_d742947dd22a4de0b78d2a9504166ace-29" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-29"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_write_point (tests.test_collection.ShapefileWriteCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-30" name="rest_code_d742947dd22a4de0b78d2a9504166ace-30" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-30"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_write_polygon (tests.test_collection.ShapefileWriteCollectionTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-31" name="rest_code_d742947dd22a4de0b78d2a9504166ace-31" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-31"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_linestring (tests.test_feature.PointTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-32" name="rest_code_d742947dd22a4de0b78d2a9504166ace-32" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-32"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_point (tests.test_feature.PointTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-33" name="rest_code_d742947dd22a4de0b78d2a9504166ace-33" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-33"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_polygon (tests.test_feature.PointTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-34" name="rest_code_d742947dd22a4de0b78d2a9504166ace-34" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-34"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.GeometryCollectionRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-35" name="rest_code_d742947dd22a4de0b78d2a9504166ace-35" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-35"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.LineStringRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-36" name="rest_code_d742947dd22a4de0b78d2a9504166ace-36" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-36"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_line (tests.test_geometry.LineStringTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-37" name="rest_code_d742947dd22a4de0b78d2a9504166ace-37" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-37"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.MultiLineStringRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-38" name="rest_code_d742947dd22a4de0b78d2a9504166ace-38" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-38"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_multilinestring (tests.test_geometry.MultiLineStringTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-39" name="rest_code_d742947dd22a4de0b78d2a9504166ace-39" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-39"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.MultiPointRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-40" name="rest_code_d742947dd22a4de0b78d2a9504166ace-40" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-40"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_multipoint (tests.test_geometry.MultiPointTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-41" name="rest_code_d742947dd22a4de0b78d2a9504166ace-41" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-41"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.MultiPolygonRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-42" name="rest_code_d742947dd22a4de0b78d2a9504166ace-42" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-42"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_multipolygon (tests.test_geometry.MultiPolygonTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-43" name="rest_code_d742947dd22a4de0b78d2a9504166ace-43" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-43"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.PointRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-44" name="rest_code_d742947dd22a4de0b78d2a9504166ace-44" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-44"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_point (tests.test_geometry.PointTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-45" name="rest_code_d742947dd22a4de0b78d2a9504166ace-45" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-45"&gt;&lt;/a&gt;&lt;span class="go"&gt;test (tests.test_geometry.PolygonRoundTripTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-46" name="rest_code_d742947dd22a4de0b78d2a9504166ace-46" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-46"&gt;&lt;/a&gt;&lt;span class="go"&gt;test_polygon (tests.test_geometry.PolygonTest) ... ok&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-47" name="rest_code_d742947dd22a4de0b78d2a9504166ace-47" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-47"&gt;&lt;/a&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-48" name="rest_code_d742947dd22a4de0b78d2a9504166ace-48" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-48"&gt;&lt;/a&gt;&lt;span class="go"&gt;Name               Stmts   Miss  Cover   Missing&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-49" name="rest_code_d742947dd22a4de0b78d2a9504166ace-49" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-49"&gt;&lt;/a&gt;&lt;span class="go"&gt;------------------------------------------------&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-50" name="rest_code_d742947dd22a4de0b78d2a9504166ace-50" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-50"&gt;&lt;/a&gt;&lt;span class="go"&gt;fiona                 15      0   100%&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-51" name="rest_code_d742947dd22a4de0b78d2a9504166ace-51" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-51"&gt;&lt;/a&gt;&lt;span class="go"&gt;fiona.collection      56      0   100%&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-52" name="rest_code_d742947dd22a4de0b78d2a9504166ace-52" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-52"&gt;&lt;/a&gt;&lt;span class="go"&gt;------------------------------------------------&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-53" name="rest_code_d742947dd22a4de0b78d2a9504166ace-53" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-53"&gt;&lt;/a&gt;&lt;span class="go"&gt;TOTAL                 71      0   100%&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-54" name="rest_code_d742947dd22a4de0b78d2a9504166ace-54" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-54"&gt;&lt;/a&gt;&lt;span class="go"&gt;----------------------------------------------------------------------&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-55" name="rest_code_d742947dd22a4de0b78d2a9504166ace-55" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-55"&gt;&lt;/a&gt;&lt;span class="go"&gt;Ran 31 tests in 4.955s&lt;/span&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-56" name="rest_code_d742947dd22a4de0b78d2a9504166ace-56" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-56"&gt;&lt;/a&gt;
&lt;a id="rest_code_d742947dd22a4de0b78d2a9504166ace-57" name="rest_code_d742947dd22a4de0b78d2a9504166ace-57" href="https://sgillies.net/2011/12/21/fionas-half-way-mark.html#rest_code_d742947dd22a4de0b78d2a9504166ace-57"&gt;&lt;/a&gt;&lt;span class="go"&gt;OK&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I haven't figured out how to get Fiona's OGR extension module covered, but I'd
be surprised if it wasn't &amp;gt; 90%.&lt;/p&gt;
&lt;p&gt;I've been telling people that Fiona's objective was 80% of osgeo.ogr's
functionality at 20% of the complexity. Maybe it can have 5% better
performance, too?&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h3&gt;Comments&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="re-fiona-s-half-way-mark"&gt;
&lt;h2&gt;Re: Fiona's half-way mark&lt;/h2&gt;
&lt;p&gt;Author: &lt;a class="reference external" href="http://woostuff.wordpress.com/"&gt;NathanW&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;gt;&amp;gt;That's just 3 statements with Fiona, 19 with osgeo.ogr. Do you like that? I like that.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Like it?  Love it! So much cleaner; less stuffing around just get in and do what you what.  The less red (read: noise code) the better.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Keep up the good work!  Looking at ways I can apply the same kind of API logic to QGIS, as the API is a little verbose sometimes just to do simple thing.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Any reason why you use f['id'] vs something like f.id and do some magic in __getattr__() and __setattr__()?&lt;/p&gt;&lt;/section&gt;
&lt;section id="re-fiona-s-half-way-mark-1"&gt;
&lt;h2&gt;Re: Fiona's half-way mark&lt;/h2&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
&lt;p&gt;Fiona originally had such GeoJSON-like objects with `id`, `geometry`, and `properties` attributes. But as I coded, I kept asking myself "this is redundant: why not just use GeoJSON-like mappings?" This question never went away, and I finally decided to ditch the classes and just use dicts. Dicts and other mappings are thoroughly documented, well-tested, and built-in. The GeoJSON format is also very well known these days and maps easily to Python dicts. I feel like I'm trading less code for more usability: win-win.&lt;/p&gt;&lt;/section&gt;
&lt;section id="re-fiona-s-half-way-mark-2"&gt;
&lt;h2&gt;Re: Fiona's half-way mark&lt;/h2&gt;
&lt;p&gt;Author: Howard Butler&lt;/p&gt;
&lt;p&gt;Most of your performance win is probably related to cython vs SWIG. SWIG can generate terrible Python from a performance perspective.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;What's cython's story with regard to PyPy or IronPython? A Fiona based on ctypes would get access to those interpeters for practically no effort.  Maybe cython's story with regard to that is the same...&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;What about coordinate systems? Do they live in Fiona? Should they?&lt;/p&gt;&lt;/section&gt;
&lt;section id="re-fiona-s-half-way-mark-3"&gt;
&lt;h2&gt;Re: Fiona's half-way mark&lt;/h2&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
&lt;p&gt;I'm not interested in IronPython anymore. For PyPy, ctypes definitely seems to be the way to go: &lt;a href="http://codespeak.net/pypy/dist/pypy/doc/extending.html."&gt;http://codespeak.net/pypy/dist/pypy/doc/extending.html.&lt;/a&gt; Cython's PyPy story isn't so clear. Switching Fiona to ctypes shouldn't be that hard.&lt;/p&gt;&lt;/section&gt;</description><category>data</category><category>programming</category><category>python</category><category>the lab</category><category>work</category><guid>https://sgillies.net/2011/12/21/fionas-half-way-mark.html</guid><pubDate>Wed, 21 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Lessons learned from Zope</title><link>https://sgillies.net/2011/12/21/lessons-learned-from-zope.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;&lt;a class="reference external" href="http://plope.com/Members/chrism/in_defense_of_zope_libraries"&gt;Chris McDonough&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Most developers are very, very risk-averse. They like taking small steps, or
no steps at all. You have to allow them to consume familiar technologies and
allow them to disuse things that get in their way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The allure of a completely integrated, monolithic system that effectively
prevents the use of alternate development techniques and technologies
eventually wears off. And when it does, it wears off with a vengeance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The natural reaction to the problems caused by monolithic systems, which is
to make anything and everything uniformly "pluggable" is also a net lose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests are very important.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation is even more important than tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When trying to replace a complex system, make it simpler, don't just push the
complexity around.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brands are important. You, ideally, must make sure that the question "what is
'noun'" have one answer. Sublety and branding do not mix; they produce
a toxic haze of confusion.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;My story with Zope parallels Chris's, though not as nearly as deep, and
trailing by about a year and a half. I've been using his software and docs for
about a decade now. For the past 4-5 years I've been trying to apply the Zope
lessons above to GIS software; Shapely and Fiona are thoroughly steeped in
them.&lt;/p&gt;</description><category>programming</category><category>python</category><category>work</category><category>zope</category><guid>https://sgillies.net/2011/12/21/lessons-learned-from-zope.html</guid><pubDate>Wed, 21 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Flickr support for ancient world places</title><link>https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;I've already written a little about the extra love &lt;a class="reference external" href="http://pleiades.stoa.org"&gt;Pleiades&lt;/a&gt; is getting from
Flickr on the &lt;a class="reference external" href="http://pleiades.stoa.org/Members/sgillies/news-items/eye-on-the-sidebar-related-photos-from-flickr"&gt;Pleiades blog&lt;/a&gt;. This post is the version for developers, and
also appears on the Flickr developer blog:
&lt;a class="reference external" href="http://code.flickr.com/blog/2011/12/16/pleiades-a-guest-post/"&gt;http://code.flickr.com/blog/2011/12/16/pleiades-a-guest-post/&lt;/a&gt;. I think this may
be my first guest blog post ever.&lt;/p&gt;
&lt;section id="background"&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;In August of 2010, Dan Pett and Ryan Baumann suggested that we coin Flickr
&lt;a class="reference external" href="http://flickr.com/groups/api/discuss/72157594497877875"&gt;machine tags&lt;/a&gt; in a "pleiades" namespace so that Flickr users could assert
connections between their photos and places in antiquity and search for photos
based on these connections. Ryan is a programmer for the University of
Kentucky's &lt;a class="reference external" href="http://www.vis.uky.edu/index.php"&gt;Center for Visualization and Virtual Environments&lt;/a&gt; and
collaborates with NYU and &lt;a class="reference external" href="http://isaw.nyu.edu"&gt;ISAW&lt;/a&gt; on &lt;a class="reference external" href="http://papyri.info/"&gt;Papyri.info&lt;/a&gt;. Dan works at the British
Museum and is the developer of the Portable Antiquities Scheme's website:
&lt;a class="reference external" href="http://finds.org.uk/"&gt;finds.org.uk&lt;/a&gt;. At about the same time, ISAW had launched its &lt;a class="reference external" href="http://flickr.com/photos/isawnyu/collections/"&gt;Flickr-hosted&lt;/a&gt;
&lt;a class="reference external" href="http://isaw.nyu.edu/ancient-world-image-bank"&gt;Ancient World Image Bank&lt;/a&gt; and was looking for ways to exploit these images,
many of which were on the web for the first time.  AWIB lead Tom Elliott,
ISAW's Associate Director for Digital Programs, and AWIB Managing Editor Nate
Nagy started machine tagging AWIB photos in December 2010. When Dan wrote "Now
to get flickr's system to link back a la openplaques etc." in an email, we all
agreed that would be quite cool, but weren't really sure how to make it happen.&lt;/p&gt;
&lt;p&gt;As AWIB picked up steam this year, Tom blogged about the machine tags. His
&lt;a class="reference external" href="http://horothesia.blogspot.com/2011/09/feeds-of-flickr-photos-depicting.html"&gt;post&lt;/a&gt; was read by &lt;a class="reference external" href="http://www.flickr.com/people/dandiffendale/"&gt;Dan Diffendale&lt;/a&gt;, who began tagging his photos of cultural
objects to indicate their places of origin or discovery. In email, Tom and Dan
agreed that it would be useful to distinguish between findspot and place of
origin in photos of objects and to distinguish these from photos depicting the
physical site of an ancient place. They resolved to use some of the predicates
from the &lt;a class="reference external" href="http://atlantides.org/trac/concordia/wiki"&gt;Concordia&lt;/a&gt; project, a collaboration between ISAW and the Center for
Computing in the Humanities at King's College, London (now the Arts and
Humanities Research Institute), jointly funded by the &lt;a class="reference external" href="http://www.neh.gov/"&gt;NEH&lt;/a&gt; and &lt;a class="reference external" href="http://www.jisc.ac.uk/"&gt;JISC&lt;/a&gt;. For
findspots, &lt;code class="docutils literal"&gt;pleiades:findspot=PID&lt;/code&gt; (where PID is the short key of a Pleiades
place) would be used. Place of origin would be tagged by &lt;code class="docutils literal"&gt;pleiades:origin=PID&lt;/code&gt;.
A photo depicting a place would be tagged &lt;code class="docutils literal"&gt;pleiades:depicts=PID&lt;/code&gt;. The original
&lt;code class="docutils literal"&gt;pleiades:place=PID&lt;/code&gt; tag would be for a geographic-historic but otherwise
unspecified relationship between a photo and a place. Concordia's original
approach was not quite RDF forced into Atom links, and was easily adapted to
Flickr's "&lt;a class="reference external" href="http://geobloggers.com/2007/01/24/offtopic-ish-flickr-ramps-up-triple-tag-support/"&gt;not quite RDF forced into tags&lt;/a&gt;" infrastructure.&lt;/p&gt;
&lt;p&gt;I heard from &lt;a class="reference external" href="http://www.aaronstraupcope.com/"&gt;Aaron Straup Cope&lt;/a&gt; at State of the Map (the OpenStreetMap annual
meeting) in Denver that he'd seen Tom's blog post and, soon after, that it was
on the radar at Flickr.  OpenStreetMap machine tags (among some others) get
&lt;a class="reference external" href="http://code.flickr.com/blog/2009/07/06/extraextraextra/"&gt;extra love&lt;/a&gt; at Flickr, meaning that Flickr uses the machine tag as a key to
external data shown on or used by photo pages. In the OSM case, that means
structured data about ways &lt;a class="reference external" href="http://code.flickr.com/blog/2009/09/28/thats-maybe-a-bit-too-dorky-even-for-us/"&gt;ways and nodes&lt;/a&gt;, structured data that surfaces on
photo pages like &lt;a class="reference external" href="http://flickr.com/photos/frankieroberto/3396068360/"&gt;http://flickr.com/photos/frankieroberto/3396068360/&lt;/a&gt; as "St
George's House is a building in OpenStreetMap." Outside Flickr, OSM
users can query the Flickr API for photos related to any particular way or
node, enabling street views (for example) not as a product, but as an
grassroots project. Two weeks later, to our delight, Daniel Bogan contacted Tom
about giving Pleiades machine tags the same kind of treatment. He and Tom
quickly came up with good short labels for our predicates and support for the
Pleiades machine tags went live on Flickr in the middle of November.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-pleiades-machine-tags"&gt;
&lt;h2&gt;The Pleiades machine tags&lt;/h2&gt;
&lt;p&gt;Pleiades mainly covers the Greek and Roman world from about 900 BC - 600 AD. It
is expanding somewhat into older Egyptian, Near East and Celtic places, and
more recent Byzantine and early Medieval Europe places. Every place has a URL
of the form &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;http://pleiades.stoa.org/places/$PID&lt;/span&gt;&lt;/code&gt; and it is these &lt;code class="docutils literal"&gt;PID&lt;/code&gt;
values that go in machine tags. It's quite easy to find Pleiades places through
the major search engines as well as through the site's own &lt;a class="reference external" href="http://pleiades.stoa.org/search"&gt;search form&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The semantics of the tags are as follows:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;strong&gt;pleiades:depicts=PID&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;code class="docutils literal"&gt;PID&lt;/code&gt; place (or what remains) is depicted in the photo&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;pleiades:findspot=PID&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;code class="docutils literal"&gt;PID&lt;/code&gt; place is where a photo subject was found&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;pleiades:origin=PID&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;code class="docutils literal"&gt;PID&lt;/code&gt; place is where a photo subject was produced&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;pleiades:where=PID&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;code class="docutils literal"&gt;PID&lt;/code&gt; place is the location of the photo subject&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;pleiades:place=PID&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;code class="docutils literal"&gt;PID&lt;/code&gt; place is otherwise related to the photo or its subject&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;At Pleiades, our immediate use for the machine tags is giving our ancient
places excellent portrait photos.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="on-the-flickr-side"&gt;
&lt;h2&gt;On the Flickr Side&lt;/h2&gt;
&lt;p&gt;Here's how it works on the Flickr side, as seen by a user. When you coin a new,
never before used on Flickr machine tag like &lt;code class="docutils literal"&gt;pleiades:depicts=440947682&lt;/code&gt; (as
seen on AWIB's photo &lt;a class="reference external" href="http://flickr.com/photos/isawnyu/6437728435/"&gt;Tombs at El Kab&lt;/a&gt; by Iris Fernandez), Flickr fetches the
JSON data at &lt;a class="reference external" href="http://pleiades.stoa.org/places/440947682/json"&gt;http://pleiades.stoa.org/places/440947682/json&lt;/a&gt; in which the
ancient place is represented as a &lt;a class="reference external" href="http://geojson.org"&gt;GeoJSON&lt;/a&gt; feature collection. A snippet of
that JSON, fetched with curl and pretty printed with python&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_dbba50244bdc425aa34979f60be73511-1" name="rest_code_dbba50244bdc425aa34979f60be73511-1" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_dbba50244bdc425aa34979f60be73511-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;curl http://pleiades.stoa.org/places/440947682/json &lt;span class="p"&gt;|&lt;/span&gt; python -mjson.tool
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;is shown here:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code javascript"&gt;&lt;a id="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-1" name="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-1" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_8bf2548617b0492c9bebc1b6274f3eb4-1"&gt;&lt;/a&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;a id="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-2" name="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-2" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_8bf2548617b0492c9bebc1b6274f3eb4-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;a id="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-3" name="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-3" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_8bf2548617b0492c9bebc1b6274f3eb4-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"440947682"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;a id="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-4" name="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-4" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_8bf2548617b0492c9bebc1b6274f3eb4-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"El Kab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;a id="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-5" name="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-5" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_8bf2548617b0492c9bebc1b6274f3eb4-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FeatureCollection"&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;a id="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-6" name="rest_code_8bf2548617b0492c9bebc1b6274f3eb4-6" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_8bf2548617b0492c9bebc1b6274f3eb4-6"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;[Gist: &lt;a class="reference external" href="https://gist.github.com/1488270"&gt;https://gist.github.com/1488270&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;The title is extracted and used to label a link to the Pleiades place under the
photo's "Additional info".&lt;/p&gt;
&lt;img alt="http://farm8.staticflickr.com/7161/6522002861_537ca823d4_b_d.jpg" src="http://farm8.staticflickr.com/7161/6522002861_537ca823d4_b_d.jpg" style="width: 501px; height: 678px;"&gt;
&lt;p&gt;Flickr is in this way a user of the &lt;a class="reference external" href="http://sgillies.net/blog/1101/does-pleiades-have-an-api"&gt;Pleiades not-quite-an-API&lt;/a&gt; that I blogged
about two weeks ago.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="flickr-as-external-pleiades-editor"&gt;
&lt;h2&gt;Flickr as external Pleiades editor&lt;/h2&gt;
&lt;p&gt;On the Pleiades end, we're using the Flickr website to identify and collect
openly licensed photos that will serve as portraits for our ancient places. We
can't control use of tags but would like some editorial control over images,
so we've created a Pleiades Places group and pull portrait photos from its pool.
The process goes like this:&lt;/p&gt;
&lt;img alt="http://farm8.staticflickr.com/7172/6522275377_bbda2a70ac_o_d.png" src="http://farm8.staticflickr.com/7172/6522275377_bbda2a70ac_o_d.png" style="width: 487px; height: 605px;"&gt;
&lt;p&gt;We're editing (in this one way) Pleiades pages entirely via Flickr. We get a kick
out of this sort of thing at Pleiades. Not only do we love to see small pieces
loosely joined in action, we also love not reinventing applications that already
exist.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="watch-the-birdie"&gt;
&lt;h2&gt;Watch the birdie&lt;/h2&gt;
&lt;p&gt;This system for acquiring portraits uses two Flickr API methods:
&lt;code class="docutils literal"&gt;flickr.photos.search&lt;/code&gt; and &lt;code class="docutils literal"&gt;flickr.groups.pools.getPhotos&lt;/code&gt;. The guts of it
is &lt;a class="reference external" href="https://gist.github.com/1482469"&gt;this Python class&lt;/a&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-1" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-1" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RelatedFlickrJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BrowserView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-2" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-2" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-2"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-3" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-3" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-3"&gt;&lt;/a&gt;    &lt;span class="sd"&gt;"""Makes two Flickr API calls and writes the number of related&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-4" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-4" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-4"&gt;&lt;/a&gt;&lt;span class="sd"&gt;    photos and URLs for the most viewed related photo from the Pleiades&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-5" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-5" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-5"&gt;&lt;/a&gt;&lt;span class="sd"&gt;    Places group to JSON like&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-6" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-6" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-7" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-7" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-7"&gt;&lt;/a&gt;&lt;span class="sd"&gt;    {"portrait": {&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-8" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-8" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-8"&gt;&lt;/a&gt;&lt;span class="sd"&gt;       "url": "http://flickr.com/photos/27621672@N04/3734425631/in/pool-1876758@N22",&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-9" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-9" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-9"&gt;&lt;/a&gt;&lt;span class="sd"&gt;       "img": "http://farm3.staticflickr.com/2474/3734425631_b15979f2cd_m.jpg",&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-10" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-10" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-10"&gt;&lt;/a&gt;&lt;span class="sd"&gt;       "title": "Pont d'Ambroix by sgillies" },&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-11" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-11" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-11"&gt;&lt;/a&gt;&lt;span class="sd"&gt;     "related": {&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-12" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-12" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-12"&gt;&lt;/a&gt;&lt;span class="sd"&gt;       "url": ["http://www.flickr.com/photos/tags/pleiades:*=149492/"],&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-13" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-13" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-13"&gt;&lt;/a&gt;&lt;span class="sd"&gt;       "total": 2 }}&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-14" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-14" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-14"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-15" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-15" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-15"&gt;&lt;/a&gt;&lt;span class="sd"&gt;    for use in the Flickr Photos portlet on every Pleiades place page.&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-16" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-16" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-16"&gt;&lt;/a&gt;&lt;span class="sd"&gt;    """&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-17" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-17" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-17"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-18" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-18" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-18"&gt;&lt;/a&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kw&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-19" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-19" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-19"&gt;&lt;/a&gt;        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-20" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-20" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-20"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-21" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-21" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-21"&gt;&lt;/a&gt;        &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# local id like "149492"&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-22" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-22" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-22"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-23" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-23" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-23"&gt;&lt;/a&gt;        &lt;span class="c1"&gt;# Count of related photos&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-24" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-24" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-24"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-25" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-25" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-25"&gt;&lt;/a&gt;        &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pleiades:*="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-26" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-26" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-26"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-27" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-27" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-27"&gt;&lt;/a&gt;        &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httplib2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Http&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-28" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-28" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-28"&gt;&lt;/a&gt;        &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-29" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-29" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-29"&gt;&lt;/a&gt;            &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"flickr.photos.search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-30" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-30" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-30"&gt;&lt;/a&gt;            &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;FLICKR_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-31" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-31" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-31"&gt;&lt;/a&gt;            &lt;span class="n"&gt;machine_tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"pleiades:*=&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-32" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-32" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-32"&gt;&lt;/a&gt;            &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-33" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-33" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-33"&gt;&lt;/a&gt;            &lt;span class="n"&gt;nojsoncallback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-34" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-34" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-34"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-35" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-35" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-35"&gt;&lt;/a&gt;        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FLICKR_API_ENDPOINT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"?"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-36" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-36" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-36"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-37" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-37" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-37"&gt;&lt;/a&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"200"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-38" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-38" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-38"&gt;&lt;/a&gt;            &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-39" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-39" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-39"&gt;&lt;/a&gt;            &lt;span class="n"&gt;photos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simplejson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'photos'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-40" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-40" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-40"&gt;&lt;/a&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-41" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-41" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-41"&gt;&lt;/a&gt;                &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'total'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-42" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-42" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-42"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-43" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-43" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-43"&gt;&lt;/a&gt;            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'related'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;FLICKR_TAGS_BASE&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-44" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-44" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-44"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-45" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-45" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-45"&gt;&lt;/a&gt;        &lt;span class="c1"&gt;# Get portrait photo from group pool&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-46" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-46" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-46"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-47" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-47" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-47"&gt;&lt;/a&gt;        &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pleiades:depicts="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-48" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-48" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-48"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-49" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-49" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-49"&gt;&lt;/a&gt;        &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httplib2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Http&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-50" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-50" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-50"&gt;&lt;/a&gt;        &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-51" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-51" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-51"&gt;&lt;/a&gt;            &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"flickr.groups.pools.getPhotos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-52" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-52" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-52"&gt;&lt;/a&gt;            &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;FLICKR_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-53" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-53" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-53"&gt;&lt;/a&gt;            &lt;span class="n"&gt;group_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PLEIADES_PLACES_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-54" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-54" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-54"&gt;&lt;/a&gt;            &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-55" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-55" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-55"&gt;&lt;/a&gt;            &lt;span class="n"&gt;extras&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"views"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-56" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-56" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-56"&gt;&lt;/a&gt;            &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-57" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-57" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-57"&gt;&lt;/a&gt;            &lt;span class="n"&gt;nojsoncallback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-58" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-58" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-58"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-59" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-59" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-59"&gt;&lt;/a&gt;        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FLICKR_API_ENDPOINT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"?"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-60" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-60" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-60"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-61" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-61" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-61"&gt;&lt;/a&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'200'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-62" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-62" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-62"&gt;&lt;/a&gt;            &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-63" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-63" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-63"&gt;&lt;/a&gt;            &lt;span class="n"&gt;photos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simplejson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'photos'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-64" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-64" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-64"&gt;&lt;/a&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-65" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-65" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-65"&gt;&lt;/a&gt;                &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'total'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-66" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-66" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-66"&gt;&lt;/a&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-67" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-67" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-67"&gt;&lt;/a&gt;                &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'portrait'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-68" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-68" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-68"&gt;&lt;/a&gt;            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-69" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-69" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-69"&gt;&lt;/a&gt;                &lt;span class="c1"&gt;# Sort found photos by number of views, descending&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-70" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-70" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-70"&gt;&lt;/a&gt;                &lt;span class="n"&gt;most_viewed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-71" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-71" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-71"&gt;&lt;/a&gt;                    &lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'photo'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'views'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-72" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-72" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-72"&gt;&lt;/a&gt;                &lt;span class="n"&gt;photo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;most_viewed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-73" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-73" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-73"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-74" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-74" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-74"&gt;&lt;/a&gt;                &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;" by "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'ownername'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-75" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-75" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-75"&gt;&lt;/a&gt;                &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'portrait'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-76" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-76" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-76"&gt;&lt;/a&gt;                    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;IMG_TMPL&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PAGE_TMPL&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-77" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-77" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-77"&gt;&lt;/a&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-78" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-78" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-78"&gt;&lt;/a&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-79" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-79" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-79"&gt;&lt;/a&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_454a07ae60dc4bec885d84598e1f93ac-80" name="rest_code_454a07ae60dc4bec885d84598e1f93ac-80" href="https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html#rest_code_454a07ae60dc4bec885d84598e1f93ac-80"&gt;&lt;/a&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;simplejson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;[Gist: &lt;a class="reference external" href="https://gist.github.com/1482469"&gt;https://gist.github.com/1482469&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;The same thing could be done with urllib, of course, but I'm a fan of httplib2.
Javascript on Pleiades place pages asynchronously fetches data from this view
and updates the DOM. The end result is a "Flickr Photos" section at the bottom
right of every place page that looks (when we have a portrait) like this:&lt;/p&gt;
&lt;img alt="http://farm8.staticflickr.com/7012/6522002865_350997d652_o_d.jpg" src="http://farm8.staticflickr.com/7012/6522002865_350997d652_o_d.jpg" style="width: 599px; height: 529px;"&gt;
&lt;p&gt;We're excited about the extra love for Pleiades places and can clearly see it
working. The number of places tagged &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;pleiades:*=&lt;/span&gt;&lt;/code&gt; is rising quickly – up 50%
just this week – and we've gained new portraits for many of our well-known
places. I think it will be interesting to see what developers at Flickr, ISAW,
or museums make of the &lt;code class="docutils literal"&gt;pleiades:findspot=&lt;/code&gt; and &lt;code class="docutils literal"&gt;pleiades:origin=&lt;/code&gt; tags.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="thanks"&gt;
&lt;h2&gt;Thanks&lt;/h2&gt;
&lt;p&gt;We're grateful to Flickr and Daniel Bogan for the extra love and opportunity to
blog about it. Work on Pleiades is supported by the NEH and ISAW. Our machine tag
predicates come from a NEH-JISC project – still bearing fruit several years later.&lt;/p&gt;
&lt;/section&gt;</description><category>pleiades</category><category>web</category><category>work</category><guid>https://sgillies.net/2011/12/16/flickr-support-for-ancient-world-places.html</guid><pubDate>Fri, 16 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Yours truly, Fiona</title><link>https://sgillies.net/2011/12/09/yours-truly-fiona.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;Fiona now writes feature collections to disk. Here's a bit of code from the
&lt;a class="reference external" href="https://github.com/sgillies/Fiona/blob/writing/tests/test_collection.py"&gt;tests&lt;/a&gt;, dressed up with extra comments:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-1" name="rest_code_13cd889ff8424427893288c972d3a062-1" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fiona&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-2" name="rest_code_13cd889ff8424427893288c972d3a062-2" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-2"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;shapely&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asShape&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-3" name="rest_code_13cd889ff8424427893288c972d3a062-3" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-4" name="rest_code_13cd889ff8424427893288c972d3a062-4" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-4"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Open a source of features&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-5" name="rest_code_13cd889ff8424427893288c972d3a062-5" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-5"&gt;&lt;/a&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"docs/data/test_uk.shp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-6" name="rest_code_13cd889ff8424427893288c972d3a062-6" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-7" name="rest_code_13cd889ff8424427893288c972d3a062-7" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-7"&gt;&lt;/a&gt;    &lt;span class="c1"&gt;# Define a schema for the feature sink&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-8" name="rest_code_13cd889ff8424427893288c972d3a062-8" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-8"&gt;&lt;/a&gt;    &lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-9" name="rest_code_13cd889ff8424427893288c972d3a062-9" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-9"&gt;&lt;/a&gt;    &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Point'&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-10" name="rest_code_13cd889ff8424427893288c972d3a062-10" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-11" name="rest_code_13cd889ff8424427893288c972d3a062-11" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-11"&gt;&lt;/a&gt;    &lt;span class="c1"&gt;# Open a new sink for features&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-12" name="rest_code_13cd889ff8424427893288c972d3a062-12" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-12"&gt;&lt;/a&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-13" name="rest_code_13cd889ff8424427893288c972d3a062-13" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-13"&gt;&lt;/a&gt;        &lt;span class="s2"&gt;"test_write.shp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ESRI Shapefile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-14" name="rest_code_13cd889ff8424427893288c972d3a062-14" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-14"&gt;&lt;/a&gt;        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-15" name="rest_code_13cd889ff8424427893288c972d3a062-15" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-15"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-16" name="rest_code_13cd889ff8424427893288c972d3a062-16" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-16"&gt;&lt;/a&gt;        &lt;span class="c1"&gt;# Process only the features intersecting a box&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-17" name="rest_code_13cd889ff8424427893288c972d3a062-17" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-17"&gt;&lt;/a&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bbox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;55.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;60.0&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-18" name="rest_code_13cd889ff8424427893288c972d3a062-18" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-18"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-19" name="rest_code_13cd889ff8424427893288c972d3a062-19" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-19"&gt;&lt;/a&gt;            &lt;span class="c1"&gt;# Get their centroids using Shapely&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-20" name="rest_code_13cd889ff8424427893288c972d3a062-20" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-20"&gt;&lt;/a&gt;            &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asShape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'geometry'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;centroid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-21" name="rest_code_13cd889ff8424427893288c972d3a062-21" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-21"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-22" name="rest_code_13cd889ff8424427893288c972d3a062-22" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-22"&gt;&lt;/a&gt;            &lt;span class="c1"&gt;# Stage feature for writing&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-23" name="rest_code_13cd889ff8424427893288c972d3a062-23" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-23"&gt;&lt;/a&gt;            &lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-24" name="rest_code_13cd889ff8424427893288c972d3a062-24" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-24"&gt;&lt;/a&gt;
&lt;a id="rest_code_13cd889ff8424427893288c972d3a062-25" name="rest_code_13cd889ff8424427893288c972d3a062-25" href="https://sgillies.net/2011/12/09/yours-truly-fiona.html#rest_code_13cd889ff8424427893288c972d3a062-25"&gt;&lt;/a&gt;    &lt;span class="c1"&gt;# The sink shapefile is written to disk when its ``with`` block ends&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That's just 9 statements. Fiona isn't just about less code, it's
about taking advantage of Python built-ins and idioms to shrink the API's
cranial memory footprint. You already know dicts, and data are better than
objects, so features are modeled as GeoJSON-like mappings. Feature schemas are
mappings, too. You already know how Python file I/O works, so persisted
featured collections are modeled like files. Obviousness and familiarity are what
I'm going for here. If you have to call &lt;code class="docutils literal"&gt;help(fiona)&lt;/code&gt; more than 8 times in
your entire life, I'll have failed.&lt;/p&gt;
&lt;p&gt;I still need to work on support for writing geometry types other than 'Point',
coordinate reference systems and make sure it's tight memory-wise (Fiona is all
C underneath). It also might be nice to let the sink collection's schema be set
from the first written feature, making the above example only 7 statements.
The OGR library is so loaded with features – making a simple wrapper API is
almost entirely about saying no and throwing features out. And how I've thrown
things out. Geometries, out. Fields, out. Features, out. Cursors, out. Layers, out.
There's almost nothing left except "open file", "filter iterator", "next dict", "append dict" and "close file". It almost goes without saying that
this is for minimalists only.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; (2011-12-10): the "writing" branch of Fiona now writes polylines and &lt;a class="reference external" href="https://github.com/sgillies/Fiona/blob/writing/tests/test_collection.py#L82"&gt;polygons&lt;/a&gt;. Multipart geometry types coming soon.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-yours-truly-fiona"&gt;
&lt;h3&gt;Re: Yours truly, Fiona&lt;/h3&gt;
&lt;p&gt;Author: &lt;a class="reference external" href="http://stuff.wordpress.com"&gt;Nathan W&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Very cool! Nice job.  I like the look of this very much and how much more readable it makes OGR.  I have tried a few times to use OGR from Python and while it wasn't hard it still felt very "this is a C++ API with Python on top" this makes it feel a lot more native Python.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Will keep an eye on the projects progress.&lt;/p&gt;&lt;/section&gt;
&lt;section id="re-yours-truly-fiona-1"&gt;
&lt;h3&gt;Re: Yours truly, Fiona&lt;/h3&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
&lt;p&gt;Thanks, Nathan. Follow on GitHub if you haven't already and let me know how the library suits your own data access needs.&lt;/p&gt;&lt;/section&gt;
&lt;/section&gt;</description><category>programming</category><category>python</category><category>the lab</category><category>work</category><guid>https://sgillies.net/2011/12/09/yours-truly-fiona.html</guid><pubDate>Fri, 09 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Does Pleiades have an API?</title><link>https://sgillies.net/2011/12/01/does-pleiades-have-an-api.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;This is a becoming a frequently asked question, and as I work on the definitive
answer for the Pleiades FAQ, I'll think out loud about it here in my blog. Does
Pleiades have an API? In truth, it has a number of APIs, some good and some bad.
Does it have a HTTP + JSON API like all the cool kids do? No. Well, yes, sort of.&lt;/p&gt;
&lt;p&gt;Before I get into tl;dr territory, I'll write down one of the guiding principles
of the Pleiades project:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Data is usually better than an API.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It's not that we're uncomfortable with interfaces in Pleiades. Our application
is based on Zope and Plone, so you know it has all kinds of interfaces under
the hood. I'm even a bit of a geek about designing nice APIs (see also Shapely,
Fiona, etc). It's just that data is better ... usually.&lt;/p&gt;
&lt;p&gt;By "data" above, I mean a document or file or sequence of bytes containing
related information, in bulk. The entire text of a book, for example, is better
to have than an API for fetching the N-th sentence on page M. All the
coordinates of a simple feature linestring (as GeoJSON, say) are better to have
than an API for getting the N-th coordinate value of the M-th vertex of a line
object. Given all the data, we're not bound to a particular way of indexing and
searching it and can use the tools of our choice. APIs are typically chatty,
slow and pointlessly different from others in the same line of business. Subbu
Allamaraju goes deep into the trouble of working with inconsistent systems in
"&lt;a class="reference external" href="http://www.subbu.org/blog/2011/11/apis-are-a-pain"&gt;APIs are a Pain&lt;/a&gt;" and with more hard earned wisdom than I have, so I won't
pile on here. Data is better ... usually.&lt;/p&gt;
&lt;p&gt;An API, and here I mean "web API", can be better in the following and probably not
exhaustive list of situations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sheer mass of data making dissemination practically impossible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rapidly changing data making dumps and downloads out of date&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desire to control access to individual data records&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desire to monetize data (ads, for example)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desire to impose a certain point of view&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desire to track use&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tracking use lets us tweak the experience of users. "People who viewed record
M might also be interested in record N" and the like. It doesn't have to be
nefarious tracking, just nudging users into useful and mutually profitable
patterns. Only one of these situations is very relevant to Pleiades and so
we're not designing APIs to sort them all out like other enterprises must. The RDF
and KML serializations of the entire 34,000 place Pleiades dataset are not
large by modern standards and don't change very rapidly. An application (like the
&lt;a class="reference external" href="http://pelagios.dme.ait.ac.at/graph-explorer/"&gt;Pelagios Graph Explorer&lt;/a&gt; or &lt;a class="reference external" href="http://gap.alexandriaarchive.org/gapvis/index.html#index"&gt;GapVis&lt;/a&gt;) that
fetched and cached them once a day could stay quite up to date. The number of
Pleiades contributors is growing, but they are primarily enriching existing
places; I don't expect Pleiades to ever become so large that those files
couldn't be transferred in less than a minute on a good internet connection.
We control access to data that's in development, yes, but the locations, names
and places that pass through review into a published state are completely open
access and not private to any individual user or group of users. In only one
part of Pleiades are we concerned about controlling a narrative through an API:
the slideshow that plays on the Pleiades home page uses an API that stumbles
through the most recently modified places and progressively mixes in more
randomly selected ones.&lt;/p&gt;
&lt;p&gt;Instead of fancy APIs, then, we have boring CSV, KML, and RDF &lt;a class="reference external" href="http://pleiades.stoa.org/downloads"&gt;downloads&lt;/a&gt;. The
shapefile format, by the way, is inadequate for our purposes. Information will
be lost in making a shapefile from the Pleiades model (any number of locations
and names per place) and we're going to let people decide for themselves what
to give up if they want this. The downloads are updated daily.&lt;/p&gt;
&lt;p&gt;Pleiades also has JSON, KML, and RDF data for any particular place. Data that
is current and linked from every page (&lt;a class="reference external" href="http://pleiades.stoa.org/places/422987"&gt;http://pleiades.stoa.org/places/422987&lt;/a&gt;,
for example) with HTML &amp;lt;link&amp;gt; and &amp;lt;a&amp;gt; elements. It's not an API ... or is it?
The map on the page about Norba gets its overlay features from those very same
JSON and KML resources. Looking at it in this way, you could say we do have an
API here: the web is the API. When I finally finish the Pleiades implementation
of OpenSearch (with Geo extension by Andrew Turner), I can replace Plone's
crufty search API with even more consistency and interoperability from The Web
as API.&lt;/p&gt;
&lt;p&gt;Pleiades doesn't need the same kind of API that Twitter or Facebook have
(obviously) or that OpenStreetMap has. We simply don't have anywhere near that
much data, that much churn or (in the Twitter/Facebook case) that much need to
control what you access.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-does-pleiades-have-an-api"&gt;
&lt;h3&gt;Re: Does Pleiades have an API?&lt;/h3&gt;
&lt;p&gt;Author: josh livni&lt;/p&gt;
&lt;p&gt;Another reason for an API would be a desire to allow adding new data or modifying a subset of the data, using different tools than your default web ui, no?&lt;/p&gt;&lt;/section&gt;
&lt;section id="re-does-pleiades-have-an-api-1"&gt;
&lt;h3&gt;Re: Does Pleiades have an API?&lt;/h3&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
&lt;p&gt;Maybe ... edits change everything (so to speak), so I'll have to mull that over. There are certainly other ways to incorporate changes that don't involve web APIs: diff and patch, for example, or git.&lt;/p&gt;&lt;/section&gt;
&lt;/section&gt;</description><category>data</category><category>pleiades</category><category>work</category><guid>https://sgillies.net/2011/12/01/does-pleiades-have-an-api.html</guid><pubDate>Thu, 01 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Simple in theory</title><link>https://sgillies.net/2011/11/18/simple-in-theory.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;Rich Hickey's "Simple Made Easy" &lt;a class="reference external" href="http://www.infoq.com/presentations/Simple-Made-Easy"&gt;presentation&lt;/a&gt; at Strange Loop, recommended to
me by my Clojure programming co-worker &lt;a class="reference external" href="http://philomousos.blogspot.com/"&gt;Hugh Cayless&lt;/a&gt;, is flat out awesome.
"Guardrail Programming" and "Knitted Castle" are my new favorite metaphors. Hickey has a compelling theory about complexity
and after watching the presentation, I feel like I can be a better advocate for
simplicity. Advocate to those who like theory, at least. For others, the proof
remains in the pudding, whether simple means better software.&lt;/p&gt;
&lt;p&gt;REST, the architectural style, didn't factor into Hickey's talk at all, but is a
great example of an approach that chooses simplicity over ease. REST is hard.
It is. You're wrong if you've been thinking that REST is easier than SOAP or
COM. Look at almost any (there are exceptions, yes) so called "REST API" and
you'll see something produced by web programmers that tried to apply the REST
style and either couldn't get their heads around it or gave up on it under
pressure to deliver. REST is hard to understand and it can be difficult to
explain its benefits to managers and customers that prioritize ease over
simplicity. REST is hard, but REST is simple. It is predictable and you can
reason about what you can or cannot do with it.&lt;/p&gt;
&lt;p&gt;There's a notion in the humanities that DH (digital humanities) is
&lt;a class="reference external" href="http://digitalhumanitiesnow.org/2011/11/digital-humanities-and-theory-round-up-part-2/"&gt;undertheorized&lt;/a&gt;. I'm not a humanist, really, just a programmer, but
I strongly disagree. Programmers in the humanities are doing a great amount of
theoretical work. As well as reading Hugh's &lt;a class="reference external" href="http://philomousos.blogspot.com/2011/11/tei-in-other-formats-part-first-html.html"&gt;recent&lt;/a&gt; &lt;a class="reference external" href="http://philomousos.blogspot.com/2011/11/tei-in-other-formats-part-second-theory.html"&gt;posts&lt;/a&gt;, digital humanities
theorists owe themselves a look at Hickey's theory of complexity and Roy
Fielding's theory of representational state transfer. The world of programming
and the field of humanities programming and computer are more theorized than
they appears to non-programmers.&lt;/p&gt;</description><category>digital humanities</category><category>programming</category><category>rest</category><category>web</category><category>work</category><guid>https://sgillies.net/2011/11/18/simple-in-theory.html</guid><pubDate>Fri, 18 Nov 2011 07:00:00 GMT</pubDate></item><item><title>GeoJSON wrap up</title><link>https://sgillies.net/2011/11/14/geojson-wrap-up.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;We collected 16 bullet points worth of &lt;a class="reference external" href="https://github.com/GeoJSONWG/geojson-spec/wiki/Scope"&gt;potential proposals&lt;/a&gt; and 2 of these
matured enough to be seriously considered for inclusion in the specification. In
the end, there was no consensus for accepting them among the authors of the 1.0
document. The specification will not now be revised and will stay at 1.0.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/GeoJSONWG/geojson-spec/wiki/wiki/Proposal%20Circles%20and%20Ellipses%20Geoms"&gt;Ellipses and circles&lt;/a&gt; were not accepted because authors were not all willing
to add a feature that would require knowledge and parameterization of the World
Geodetic System for computing new latitudes and longitudes from distances
measured in meters in the most common, no-CRS GeoJSON situation. Another
concern was that the proposal couldn't provide any basis for representing
semi-circles or products of circles, ellipses and other GeoJSON geometry types and
that since consumers would be required to approximate them as polygons in most
cases, why not just make them polygons to begin with?&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://github.com/GeoJSONWG/geojson-spec/wiki/wiki/Data-Series-Proposal"&gt;Data Series&lt;/a&gt; proposal struck authors as too far outside the scope of
describing simple geographic features and as something that wasn't precluded by
the current 1.0 specification.&lt;/p&gt;
&lt;p&gt;Work on a 1.1 version has ended for now. I did my best to keep the process
short and avoid burning people out so that we may start up again when the time
is right.  You can follow the entire discussion and consensus making process in
the GeoJSON list archive from &lt;a class="reference external" href="http://lists.geojson.org/pipermail/geojson-geojson.org/2011-September/thread.html"&gt;September&lt;/a&gt;, through &lt;a class="reference external" href="http://lists.geojson.org/pipermail/geojson-geojson.org/2011-October/thread.html"&gt;October&lt;/a&gt; and ending in
&lt;a class="reference external" href="http://lists.geojson.org/pipermail/geojson-geojson.org/2011-November/thread.html"&gt;November&lt;/a&gt;.&lt;/p&gt;</description><category>community</category><category>data</category><category>standards</category><category>work</category><guid>https://sgillies.net/2011/11/14/geojson-wrap-up.html</guid><pubDate>Mon, 14 Nov 2011 07:00:00 GMT</pubDate></item></channel></rss>