Curation of digital projects and media seems to be in my future. I'm not a repository critter of any kind, and have much to learn, but I know for certain what kind of architecture I want to use. Take the indexable, mashable feed (Atom, naturally) representations of collections that Leslie Carr writes about, pair with upload of Atom-wrapped items to the same collections ala SWORD, and then add hypertext-constrained methods for item and metadata modification and deletion. In a word: AtomPub. Less like EPrints, DSpace, or Fedora; more like Google's data APIs, more like what Peter Keane is doing with DASe. Why not?
If I were superstitious, I wouldn't post a link to http://pypi.python.org/pypi/Shapely/1.0.11. Tests pass, the release candidate checked out, it's good to go. There's a Windows installer (containing GEOS 3.0.0) as well as generic sdist.
GEOS 3.1 is now on the horizon. The next minor version of Shapely – presuming all its users haven't been shed – will use prepared geometries to make iterative operations rip, and we'll continue to refactor and improve the code. Integration with Numpy is not as efficient as it could be, and I'd like to switch to a cleaner implementation of memoization using a decorator. I've been asked if there will ever be a version of Shapely that works with Google's App Engine. Unless Google builds GEOS (or something like it that could be accessed through ctypes) into the environment, such a thing would require rather a lot of Python programming. I suspect an automated translation of JTS from Java to Python would produce sub-optimal code. In other words: doubtful, but patches are gratefully accepted.
Yesterday, I received in the mail my grandfather's cloth escape maps of France, Holland, Belgium, Luxembourg, and Germany. He flew a Piper Cub for the US Army, mainly shuttling brass between England and France. Never used, the maps went from a pocket in his jacket to an envelope in a foot locker; they're in great condition.
Above is a 1:2,000,000 scale map entitled "Zones of France", second edition, and dated "MAR 44". Silk or rayon. I know little about the origins of this one.
It features 4 hand-drawn "placemarks" South of Cherbourg. Positions of forces? Airfields supplied with beer?
I'll be having these framed soon.
$ easy_install http://trac.gispython.org/lab/attachment/ticket/178/Shapely-1.0.11.tar.gz?format=raw
Well, let's try that again: http://pypi.python.org/pypi/Shapely/1.0.10. Somewhere along the way I became too lax about testing compatibility with GEOS 2.2.3, and it was broken in the 1.0.8 release. I've mentioned before how handily zc.buildout makes isolated repeatable environments, and am now using this one with GEOS 2.2.3.
Upload of Windows installers to PyPI seems to be broken at the moment. The 1.0.8 installer bundles GEOS 3.0 and remains free of the recent problem: http://pypi.python.org/packages/2.5/S/Shapely/Shapely-1.0.8.win32.exe.
Shapely 1.0.9 works with a MacPorts libgeos. No need to upgrade otherwise.
The GeoJSON working group chose to omit links from the specification (outside of coordinate reference systems). In conclusion, GeoJSON 1.0 is not a hypermedia format. Without links there are no levers of application state to be seized, no hypertext constraint, and therefore no REST.
Consider, as an example of a hypermedia format, Atom and extensions in AtomPub: "alternate", "related", "self", and "edit" links are designed to satisfy REST's hypertext constraint and permit hypertext to be used as the engine of application state. Without links of the edit kind (especially), HTTP Geo-CRUD protocols using GeoJSON couple clients and servers together, an undesirable property in a system like the Web. This is not to say that coupling is going to kill your applications, just that the components don't have much freedom to evolve (think migrate or upgrade) separately.
Are there any good linking options for JSON? Subbu Allamaraju explores that question here and here and floats an object not unlike the only link example in GeoJSON. Both are inspired by atom:link and HTML's link.
Should GeoJSON become a hypermedia format? I don't know the answer to that, but I think it's more likely that GeoJSON geometry (and maybe feature) objects will find their way into other yet-to-emerge JSON-based media types.
A book excerpt meme is propagating through Python blogs. Why not?
If it should become necessary to reconsider the whole matter
William Strunk Jr. and E. B. White, The Elements of Style, 4th edition. The phrase demonstrates how to recast awkward usage of a possessive participle. I reread this book about once a season in my never-ending quest to suck less as a writer.
The viral part:
- Grab the nearest book.
- Open it to page 56.
- Find the fifth sentence.
- Post the text of the sentence in your journal along with these instructions.
- Don’t dig for your favorite book, the cool book, or the intellectual one: pick the CLOSEST.
Update (2009-09-29): see http://plumberjack.blogspot.com/2009/09/python-logging-101.html
A friend at the local Park Service office mentioned to me that he's become a Python user and has been looking at some of my published code examples. I'm inspired to post more of these, and more that are useful to the ESRI ArcGIS scripting user. Python serves the ESRI community as a replacement for Avenue, but is a far more rich language and platform. Today's tip: excellent application logging and how to avoid using print statements in your production code.
I tripped myself using print statements recently, and have seen it in the code of others. While not a mortal sin, it does reduce the code's potential for reuse. A print statement might be tolerable when you're running the code at a shell prompt, but what if you wanted to execute the same code in a service? Better not to fill your service logs (or wherever stdout goes) with unnecessary debugging noise, yes? Here's where Python's logging module steps in to help: your information-processing classes write messages to a logging interface, any Python application then configures the logger appropriately. Log messages can be sent to single files on disk, rotating log files, sent to SMTP servers -- you could probably even create your own XMPP handler.
Say, for example, you have a class that patches elements into XML files (inspired by Dave Bouwman's post). Using a Python logger instead of a print statement requires only 2 extra lines of code (zero if you use the root logger):
import getopt import glob import logging import sys from lxml import etree # Create a logger log = logging.getLogger('file-patcher') # Example of reusable code class FilePatcher(object): """ Patch edit permissions into an XML configuration file and write new files to disk. """ def __call__(self): for infilename in glob.glob('*.xml'): tree = etree.parse(infilename) log.info('Opening file %s.', infilename) root = tree.getroot() for perms in root.xpath(".//property[@name='permissions']"): if not perms.xpath("element[@value='Edit']"): e = etree.SubElement(perms, 'element') e.attrib['value'] = 'Edit' log.info('Patched perms: %s.', str(perms)) outfilename = 'patched-%s' % infilename fout = file(outfilename, 'w') fout.write(etree.tostring(root, pretty_print=True)) log.info('Wrote file %s.', outfilename)
Now, we can make a script that uses this class in a verbose (all logged info) mode or a quieter (logged errors only) mode:
# Script if __name__ == '__main__': verbose = False # Get command line options and args opts, args = getopt.getopt(sys.argv[1:], 'v') for o, a in opts: if o == '-v': verbose = True # Get the file patching logger log = logging.getLogger('file-patcher') # Logging configuration, to stdout in this case console = logging.StreamHandler() log.addHandler(console) if verbose: log.setLevel(logging.INFO) else: log.setLevel(logging.ERROR) # Process data patch_files = FilePatcher() patch_files()
Duke University's GeoEco project has more examples of professional logging, many in an ArcGIS scripting context.