Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial import.

  • Loading branch information...
commit 9551452e82c506f9d237a684faa5a102a381c695 0 parents
@onyxfish authored
4 .gitignore
@@ -0,0 +1,4 @@
+.DS_Store
+*.swp
+*.swo
+*.pyc
21 COPYING
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2011 Christopher Groskopf
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
28 README.rst
@@ -0,0 +1,28 @@
+ogrkit
+======
+
+A suite of command-line utilities implementing basic geometric operations. (Difference, Intersection, etc.)
+
+This project is a cousin of `csvkit <http://github.com/onyxfish/csvkit>`_.
+
+*Note: This is only a proof-of-concept to see if this idea makes sense.*
+
+Usage
+-----
+
+To try the difference utility::
+
+ ./ogrdifference INPUT_SHAPEFILE OUTPUT_SHAPEFILE [MASK_SHAPEFILES...]
+
+Note: this currently only works with shapefiles, but could be extended to work with any format supported by `OGR <http:/www.gdal.org/>`_.
+
+Authors
+-------
+
+* Christopher Groskopf (`@onyxfish <http://twitter.com/onyxfish>`_)
+
+License
+-------
+
+MIT
+
7 ogrdifference
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+from ogrkit.utilities.difference import OGRDifference
+
+if __name__ == '__main__':
+ OGRDifference().main()
+
0  ogrkit/__init__.py
No changes.
70 ogrkit/cli.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+
+class OGRKitUtility(object):
+ description = ''
+ epilog = ''
+ override_flags = ''
+
+ def __init__(self, args=None, output_file=None):
+ """
+ Perform argument processing and other setup for a CSVKitUtility.
+ """
+ self._init_common_parser()
+ self.add_arguments()
+ self.args = self.argparser.parse_args(args)
+
+ self._install_exception_handler()
+
+ if output_file is None:
+ self.output_file = sys.stdout
+ else:
+ self.output_file = output_file
+
+ def add_arguments(self):
+ """
+ Called upon initialization once the parser for common arguments has been constructed.
+
+ Should be overriden by individual utilities.
+ """
+ raise NotImplementedError('add_arguments must be provided by each subclass of CSVKitUtility.')
+
+ def main(self):
+ """
+ Main loop of the utility.
+
+ Should be overriden by individual utilities and explicitly called by the executing script.
+ """
+ raise NotImplementedError(' must be provided by each subclass of CSVKitUtility.')
+
+ def _init_common_parser(self):
+ """
+ Prepare a base argparse argument parser so that flags are consistent across different shell command tools.
+ If you want to constrain which common args are present, you can pass a string for 'omitflags'. Any argument
+ whose single-letter form is contained in 'omitflags' will be left out of the configured parser. Use 'f' for
+ file.
+ """
+ self.argparser = argparse.ArgumentParser(description=self.description, epilog=self.epilog)
+
+ self.argparser.add_argument('input', metavar='INPUT', type=str,
+ help='The datasource to operate on.')
+ self.argparser.add_argument('output', metavar='OUTPUT', type=str,
+ help='The datasource to write to. Existing files will be deleted')
+
+ if 'v' not in self.override_flags:
+ self.argparser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
+ help='Print detailed tracebacks when errors occur.')
+
+ def _install_exception_handler(self):
+ """
+ Installs a replacement for sys.excepthook, which handles pretty-printing uncaught exceptions.
+ """
+ def handler(t, value, traceback):
+ if self.args.verbose:
+ sys.__excepthook__(t, value, traceback)
+ else:
+ print value
+
+ sys.excepthook = handler
0  ogrkit/utilities/__init__.py
No changes.
54 ogrkit/utilities/difference.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import shutil
+
+from osgeo import ogr
+
+from ogrkit.cli import OGRKitUtility
+
+class OGRDifference(OGRKitUtility):
+ description = 'Produce a shapefile by subtracting a set of shapefiles from the input.'
+
+ def add_arguments(self):
+ self.argparser.add_argument('masks', metavar='MASKS', nargs='+', type=str)
+
+ def main(self):
+ source = ogr.Open(self.args.input, False)
+ source_layer = source.GetLayer(0)
+
+ try:
+ shutil.rmtree(self.args.output)
+ except OSError:
+ pass
+
+ driver = ogr.GetDriverByName('ESRI Shapefile')
+ dest = driver.CreateDataSource(self.args.output)
+ dest_layer = dest.CreateLayer('masked', geom_type=ogr.wkbMultiPolygon)
+
+ for i in range(source_layer.GetLayerDefn().GetFieldCount()):
+ dest_layer.CreateField(source_layer.GetLayerDefn().GetFieldDefn(i))
+
+ mask_features = []
+
+ for mask in self.args.masks:
+ geo = ogr.Open(mask)
+ layer = geo.GetLayer(0)
+
+ for feature in layer:
+ mask_features.append(feature)
+
+ for feature in source_layer:
+ masked_feature = ogr.Feature(feature_def=source_layer.GetLayerDefn())
+ masked_feature.SetFrom(feature)
+
+ masked_geometry = feature.GetGeometryRef().Clone()
+
+ for mask_feature in mask_features:
+ masked_geometry = masked_geometry.Difference(mask_feature.GetGeometryRef())
+
+ masked_feature.SetGeometryDirectly(masked_geometry)
+ dest_layer.CreateFeature(masked_feature)
+
+if __name__ == '__main__':
+ OGRDifference().main()
+
Please sign in to comment.
Something went wrong with that request. Please try again.