2012-11-04 11:39:51 -08:00

54 lines
1.5 KiB
Python
Executable File

from sys import stdin, stdout
from json import load, JSONEncoder
from optparse import OptionParser
from re import compile
float_pat = compile(r'^-?\d+\.\d+(e-?\d+)?$')
charfloat_pat = compile(r'^[\[,\,]-?\d+\.\d+(e-?\d+)?$')
parser = OptionParser(usage="""%prog [options]
Make JSON smaller by reducing precision of floating point values
and removing white space. Works great for GeoJSON!
Examples:
cat input.json | python %prog --precision 2 > output.json
python %prog --precision 2 input.json > output.json
python %prog -p 2 input.json output.json""")
defaults = dict(precision=3)
parser.set_defaults(**defaults)
parser.add_option('-p', '--precision', dest='precision',
type='int', help='Digits of precision, default %(precision)d.' % defaults)
if __name__ == '__main__':
options, args = parser.parse_args()
#
# Read!
#
input = len(args) and open(args[0]) or stdin
data = load(input)
#
# Write!
#
encoder = JSONEncoder(separators=(',', ':'))
encoded = encoder.iterencode(data)
format = '%.' + str(options.precision) + 'f'
output = len(args) == 2 and open(args[1], 'w') or stdout
for token in encoded:
if charfloat_pat.match(token):
# in python 2.7, we see a character followed by a float literal
output.write(token[0] + format % float(token[1:]))
elif float_pat.match(token):
# in python 2.6, we see a simple float literal
output.write(format % float(token))
else:
output.write(token)