Permalink
Browse files

Add CRS support to csvjson.

  • Loading branch information...
1 parent 0128a84 commit cd4be027d69ad0ce555b23a8f0e592172bef6bbd @onyxfish onyxfish committed Aug 15, 2012
Showing with 51 additions and 3 deletions.
  1. +16 −0 csvkit/utilities/csvjson.py
  2. +14 −3 docs/scripts/csvjson.rst
  3. +21 −0 tests/test_utilities/test_csvjson.py
@@ -19,6 +19,8 @@ def add_arguments(self):
help='A column index or name containing a latitude. Output will be GeoJSON instead of JSON. Only valid if --lon is also specified.')
self.argparser.add_argument('--lon', dest='lon', type=str, default=None,
help='A column index or name containing a longitude. Output will be GeoJSON instead of JSON. Only valid if --lat is also specified.')
+ self.argparser.add_argument('--crs', dest='crs', type=str, default=None,
+ help='A coordinate reference system string to be included with GeoJSON output. Only valid if --lat and --lon are also specified.')
def main(self):
"""
@@ -30,11 +32,15 @@ def main(self):
if self.args.lon and not self.args.lat:
self.argparser.error('--lat is required whenever --lon is specified.')
+ if self.args.crs and not self.args.lat:
+ self.argparser.error('--crs is only allowed when --lat and --lon are also specified.')
+
rows = CSVKitReader(self.args.file, **self.reader_kwargs)
column_names = rows.next()
stream = codecs.getwriter('utf-8')(self.output_file)
+ # GeoJSON
if self.args.lat and self.args.lon:
features = []
min_lon = None
@@ -96,6 +102,15 @@ def main(self):
'bbox': [min_lon, min_lat, max_lon, max_lat],
'features': features
}
+
+ if self.args.crs:
+ output['crs'] = {
+ 'type': 'name',
+ 'properties': {
+ 'name': self.args.crs
+ }
+ }
+ # Keyed JSON
elif self.args.key:
output = {}
@@ -107,6 +122,7 @@ def main(self):
raise NonUniqueKeyColumnException('Value %s is not unique in the key column.' % unicode(k))
output[k] = row_dict
+ # Boring JSON
else:
output = [dict(zip(column_names, row)) for row in rows]
View
@@ -8,7 +8,9 @@ Description
Converts a CSV file into JSON or GeoJSON (depending on flags)::
usage: csvjson [-h] [-d DELIMITER] [-t] [-q QUOTECHAR] [-u {0,1,2,3}] [-b]
- [-p ESCAPECHAR] [-e ENCODING] [-v] [-l] [-i INDENT] [-k KEY]
+ [-p ESCAPECHAR] [-z MAXFIELDSIZE] [-e ENCODING] [-v] [-l]
+ [--zero] [-i INDENT] [-k KEY] [--lat LAT] [--lon LON]
+ [--crs CRS]
[FILE]
Convert a CSV file into JSON (or GeoJSON).
@@ -32,7 +34,9 @@ Converts a CSV file into JSON or GeoJSON (depending on flags)::
--lon LON A column index or name containing a longitude. Output
will be GeoJSON instead of JSON. Only valid if --lat
is also specified.
-
+ --crs CRS A coordinate reference system string to be included
+ with GeoJSON output. Only valid if --lat and --lon are
+ also specified.
Also see: :doc:`common_arguments`.
@@ -65,7 +69,7 @@ Results in a JSON document like::
Converting locations of public art into GeoJSON::
- $ csvjson --lat latitude --lon longitude --k slug -i 4 examples/test_geo.csv
+ $ csvjson --lat latitude --lon longitude --k slug --crs EPSG:4269 -i 4 examples/test_geo.csv
Results in a GeoJSON document like::
@@ -77,6 +81,12 @@ Results in a GeoJSON document like::
-95.250699,
32.351434
],
+ "crs": {
+ "type": "name",
+ "properties": {
+ "name": "EPSG:4269"
+ }
+ },
"features": [
{
"geometry": {
@@ -103,3 +113,4 @@ Results in a GeoJSON document like::
[...]
]
}
+
@@ -53,6 +53,7 @@ def test_geojson(self):
geojson = json.loads(output_file.getvalue())
self.assertEqual(geojson['type'], 'FeatureCollection')
+ self.assertFalse('crs' in geojson)
self.assertEqual(geojson['bbox'], [-95.334619, 32.299076986939205, -95.250699, 32.351434])
self.assertEqual(len(geojson['features']), 17)
@@ -77,6 +78,7 @@ def test_geojson_with_id(self):
geojson = json.loads(output_file.getvalue())
self.assertEqual(geojson['type'], 'FeatureCollection')
+ self.assertFalse('crs' in geojson)
self.assertEqual(geojson['bbox'], [-95.334619, 32.299076986939205, -95.250699, 32.351434])
self.assertEqual(len(geojson['features']), 17)
@@ -91,3 +93,22 @@ def test_geojson_with_id(self):
self.assertTrue(isinstance(geometry['coordinates'][0], float))
self.assertTrue(isinstance(geometry['coordinates'][1], float))
+ def test_geojson_with_crs(self):
+ args = ['--lat', 'latitude', '--lon', 'longitude', '--crs', 'EPSG:4269', 'examples/test_geo.csv']
+ output_file = StringIO.StringIO()
+
+ utility = CSVJSON(args, output_file)
+ utility.main()
+
+ geojson = json.loads(output_file.getvalue())
+
+ self.assertEqual(geojson['type'], 'FeatureCollection')
+ self.assertTrue('crs' in geojson)
+ self.assertEqual(geojson['bbox'], [-95.334619, 32.299076986939205, -95.250699, 32.351434])
+ self.assertEqual(len(geojson['features']), 17)
+
+ crs = geojson['crs']
+
+ self.assertEqual(crs['type'], 'name')
+ self.assertEqual(crs['properties']['name'], 'EPSG:4269')
+

0 comments on commit cd4be02

Please sign in to comment.