App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / lib / django_1_4 / django / contrib / gis / management / commands / ogrinspect.py
blobfbc6f53c0c623fdcaf8be3501881dc488d0d162b
1 import os
2 from optparse import make_option
3 from django.contrib.gis import gdal
4 from django.core.management.base import LabelCommand, CommandError
6 def layer_option(option, opt, value, parser):
7 """
8 Callback for `make_option` for the `ogrinspect` `layer_key`
9 keyword option which may be an integer or a string.
10 """
11 try:
12 dest = int(value)
13 except ValueError:
14 dest = value
15 setattr(parser.values, option.dest, dest)
17 def list_option(option, opt, value, parser):
18 """
19 Callback for `make_option` for `ogrinspect` keywords that require
20 a string list. If the string is 'True'/'true' then the option
21 value will be a boolean instead.
22 """
23 if value.lower() == 'true':
24 dest = True
25 else:
26 dest = [s for s in value.split(',')]
27 setattr(parser.values, option.dest, dest)
29 class Command(LabelCommand):
30 help = ('Inspects the given OGR-compatible data source (e.g., a shapefile) and outputs\n'
31 'a GeoDjango model with the given model name. For example:\n'
32 ' ./manage.py ogrinspect zipcode.shp Zipcode')
33 args = '[data_source] [model_name]'
35 option_list = LabelCommand.option_list + (
36 make_option('--blank', dest='blank', type='string', action='callback',
37 callback=list_option, default=False,
38 help='Use a comma separated list of OGR field names to add '
39 'the `blank=True` option to the field definition. Set with'
40 '`true` to apply to all applicable fields.'),
41 make_option('--decimal', dest='decimal', type='string', action='callback',
42 callback=list_option, default=False,
43 help='Use a comma separated list of OGR float fields to '
44 'generate `DecimalField` instead of the default '
45 '`FloatField`. Set to `true` to apply to all OGR float fields.'),
46 make_option('--geom-name', dest='geom_name', type='string', default='geom',
47 help='Specifies the model name for the Geometry Field '
48 '(defaults to `geom`)'),
49 make_option('--layer', dest='layer_key', type='string', action='callback',
50 callback=layer_option, default=0,
51 help='The key for specifying which layer in the OGR data '
52 'source to use. Defaults to 0 (the first layer). May be '
53 'an integer or a string identifier for the layer.'),
54 make_option('--multi-geom', action='store_true', dest='multi_geom', default=False,
55 help='Treat the geometry in the data source as a geometry collection.'),
56 make_option('--name-field', dest='name_field',
57 help='Specifies a field name to return for the `__unicode__` function.'),
58 make_option('--no-imports', action='store_false', dest='imports', default=True,
59 help='Do not include `from django.contrib.gis.db import models` '
60 'statement.'),
61 make_option('--null', dest='null', type='string', action='callback',
62 callback=list_option, default=False,
63 help='Use a comma separated list of OGR field names to add '
64 'the `null=True` option to the field definition. Set with'
65 '`true` to apply to all applicable fields.'),
66 make_option('--srid', dest='srid',
67 help='The SRID to use for the Geometry Field. If it can be '
68 'determined, the SRID of the data source is used.'),
69 make_option('--mapping', action='store_true', dest='mapping',
70 help='Generate mapping dictionary for use with `LayerMapping`.')
73 requires_model_validation = False
75 def handle(self, *args, **options):
76 try:
77 data_source, model_name = args
78 except ValueError:
79 raise CommandError('Invalid arguments, must provide: %s' % self.args)
81 if not gdal.HAS_GDAL:
82 raise CommandError('GDAL is required to inspect geospatial data sources.')
84 # Removing options with `None` values.
85 options = dict([(k, v) for k, v in options.items() if not v is None])
87 # Getting the OGR DataSource from the string parameter.
88 try:
89 ds = gdal.DataSource(data_source)
90 except gdal.OGRException, msg:
91 raise CommandError(msg)
93 # Whether the user wants to generate the LayerMapping dictionary as well.
94 show_mapping = options.pop('mapping', False)
96 # Getting rid of settings that `_ogrinspect` doesn't like.
97 verbosity = options.pop('verbosity', False)
98 settings = options.pop('settings', False)
100 # Returning the output of ogrinspect with the given arguments
101 # and options.
102 from django.contrib.gis.utils.ogrinspect import _ogrinspect, mapping
103 output = [s for s in _ogrinspect(ds, model_name, **options)]
104 if show_mapping:
105 # Constructing the keyword arguments for `mapping`, and
106 # calling it on the data source.
107 kwargs = {'geom_name' : options['geom_name'],
108 'layer_key' : options['layer_key'],
109 'multi_geom' : options['multi_geom'],
111 mapping_dict = mapping(ds, **kwargs)
112 # This extra legwork is so that the dictionary definition comes
113 # out in the same order as the fields in the model definition.
114 rev_mapping = dict([(v, k) for k, v in mapping_dict.items()])
115 output.extend(['', '# Auto-generated `LayerMapping` dictionary for %s model' % model_name,
116 '%s_mapping = {' % model_name.lower()])
117 output.extend([" '%s' : '%s'," % (rev_mapping[ogr_fld], ogr_fld) for ogr_fld in ds[options['layer_key']].fields])
118 output.extend([" '%s' : '%s'," % (options['geom_name'], mapping_dict[options['geom_name']]), '}'])
119 return '\n'.join(output) + '\n'