v.import.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #!/usr/bin/env python
  2. ############################################################################
  3. #
  4. # MODULE: v.import
  5. #
  6. # AUTHOR(S): Markus Metz
  7. #
  8. # PURPOSE: Import and reproject vector data on the fly
  9. #
  10. # COPYRIGHT: (C) 2015 by GRASS development team
  11. #
  12. # This program is free software under the GNU General
  13. # Public License (>=v2). Read the file COPYING that
  14. # comes with GRASS for details.
  15. #
  16. #############################################################################
  17. #%module
  18. #% description: Imports vector data into a GRASS vector map using OGR library and reprojects on the fly.
  19. #% keyword: vector
  20. #% keyword: import
  21. #% keyword: projection
  22. #%end
  23. #%option
  24. #% key: input
  25. #% type: string
  26. #% required: yes
  27. #% description: Name of OGR datasource to be imported
  28. #% gisprompt: old,datasource,datasource
  29. #% guisection: Input
  30. #%end
  31. #%option
  32. #% key: layer
  33. #% type: string
  34. #% multiple: yes
  35. #% description: OGR layer name. If not given, all available layers are imported
  36. #% guisection: Input
  37. #% gisprompt: old,datasource_layer,datasource_layer
  38. #%end
  39. #%option G_OPT_V_OUTPUT
  40. #% description: Name for output vector map (default: input)
  41. #% required: no
  42. #% guisection: Output
  43. #%end
  44. #%option
  45. #% key: extent
  46. #% type: string
  47. #% options: input,region
  48. #% answer: input
  49. #% description: Output vector map extent
  50. #% descriptions: input;extent of input map;region;extent of current region
  51. #% guisection: Output
  52. #%end
  53. #%option
  54. #% key: encoding
  55. #% type: string
  56. #% label: Encoding value for attribute data
  57. #% descriptions: Overrides encoding interpretation, useful when importing ESRI Shapefile
  58. #% guisection: Output
  59. #%end
  60. #%option
  61. #% key: snap
  62. #% type: double
  63. #% label: Snapping threshold for boundaries (map units)
  64. #% description: '-1' for no snap
  65. #% answer: 1e-13
  66. #% guisection: Output
  67. #%end
  68. #%flag
  69. #% key: f
  70. #% description: List supported OGR formats and exit
  71. #% suppress_required: yes
  72. #%end
  73. #%flag
  74. #% key: l
  75. #% description: List available OGR layers in data source and exit
  76. #%end
  77. import sys
  78. import os
  79. import atexit
  80. import grass.script as grass
  81. from grass.exceptions import CalledModuleError
  82. # initialize global vars
  83. TMPLOC = None
  84. SRCGISRC = None
  85. GISDBASE = None
  86. def cleanup():
  87. # remove temp location
  88. if TMPLOC:
  89. grass.try_rmdir(os.path.join(GISDBASE, TMPLOC))
  90. if SRCGISRC:
  91. grass.try_remove(SRCGISRC)
  92. def main():
  93. global TMPLOC, SRCGISRC, GISDBASE
  94. # list formats and exit
  95. if flags['f']:
  96. grass.run_command('v.in.ogr', flags='f')
  97. return 0
  98. # list layers and exit
  99. if flags['l']:
  100. grass.run_command('v.in.ogr', flags='l', input=options['input'])
  101. return 0
  102. OGRdatasource = options['input']
  103. output = options['output']
  104. layers = options['layer']
  105. vflags = None
  106. if options['extent'] == 'region':
  107. vflags = 'r'
  108. vopts = {}
  109. if options['encoding']:
  110. vopts['encoding'] = options['encoding']
  111. grassenv = grass.gisenv()
  112. tgtloc = grassenv['LOCATION_NAME']
  113. tgtmapset = grassenv['MAPSET']
  114. GISDBASE = grassenv['GISDBASE']
  115. tgtgisrc = os.environ['GISRC']
  116. SRCGISRC = grass.tempfile()
  117. TMPLOC = 'temp_import_location_' + str(os.getpid())
  118. f = open(SRCGISRC, 'w')
  119. f.write('MAPSET: PERMANENT\n')
  120. f.write('GISDBASE: %s\n' % GISDBASE)
  121. f.write('LOCATION_NAME: %s\n' % TMPLOC)
  122. f.write('GUI: text\n')
  123. f.close()
  124. tgtsrs = grass.read_command('g.proj', flags='j', quiet=True)
  125. # create temp location from input without import
  126. grass.verbose(_("Creating temporary location for <%s>...") % OGRdatasource)
  127. if layers:
  128. vopts['layer'] = layers
  129. if output:
  130. vopts['output'] = output
  131. vopts['snap'] = options['snap']
  132. try:
  133. grass.run_command('v.in.ogr', input=OGRdatasource,
  134. location=TMPLOC, flags='i', quiet=True, **vopts)
  135. except CalledModuleError:
  136. grass.fatal(_("Unable to create location from OGR datasource <%s>") % OGRdatasource)
  137. # switch to temp location
  138. os.environ['GISRC'] = str(SRCGISRC)
  139. # switch to target location
  140. os.environ['GISRC'] = str(tgtgisrc)
  141. # try v.in.ogr directly
  142. if grass.run_command('v.in.ogr', input=OGRdatasource, flags='j',
  143. errors='status', quiet=True) == 0:
  144. try:
  145. grass.run_command('v.in.ogr', input=OGRdatasource,
  146. flags=vflags, **vopts)
  147. grass.message(_("Input <%s> successfully imported without reprojection") % OGRdatasource)
  148. return 0
  149. except CalledModuleError:
  150. grass.fatal(_("Unable to import <%s>") % OGRdatasource)
  151. # make sure target is not xy
  152. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  153. grass.fatal(_("Coordinate reference system not available for current location <%s>") % tgtloc)
  154. # switch to temp location
  155. os.environ['GISRC'] = str(SRCGISRC)
  156. # make sure input is not xy
  157. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  158. grass.fatal(_("Coordinate reference system not available for input <%s>") % OGRdatasource)
  159. if options['extent'] == 'region':
  160. # switch to target location
  161. os.environ['GISRC'] = str(tgtgisrc)
  162. # v.in.region in tgt
  163. vreg = 'vreg_' + str(os.getpid())
  164. grass.run_command('v.in.region', output=vreg, quiet=True)
  165. # reproject to src
  166. # switch to temp location
  167. os.environ['GISRC'] = str(SRCGISRC)
  168. try:
  169. grass.run_command('v.proj', input=vreg, output=vreg,
  170. location=tgtloc, mapset=tgtmapset, quiet=True)
  171. except CalledModuleError:
  172. grass.fatal(_("Unable to reproject to source location"))
  173. # set region from region vector
  174. grass.run_command('g.region', res='1')
  175. grass.run_command('g.region', vector=vreg)
  176. # import into temp location
  177. grass.message(_("Importing <%s> ...") % OGRdatasource)
  178. try:
  179. grass.run_command('v.in.ogr', input=OGRdatasource,
  180. flags=vflags, **vopts)
  181. except CalledModuleError:
  182. grass.fatal(_("Unable to import OGR datasource <%s>") % OGRdatasource)
  183. # if output is not define check source mapset
  184. if not output:
  185. output = grass.list_grouped('vector')['PERMANENT'][0]
  186. # switch to target location
  187. os.environ['GISRC'] = str(tgtgisrc)
  188. # check if map exists
  189. if not grass.overwrite() and \
  190. grass.find_file(output, element='vector', mapset='.')['mapset']:
  191. grass.fatal(_("option <%s>: <%s> exists.") % ('output', output))
  192. if options['extent'] == 'region':
  193. grass.run_command('g.remove', type='vector', name=vreg,
  194. flags='f', quiet=True)
  195. # v.proj
  196. grass.message(_("Reprojecting <%s>...") % output)
  197. try:
  198. grass.run_command('v.proj', location=TMPLOC,
  199. mapset='PERMANENT', input=output,
  200. quiet=True)
  201. except CalledModuleError:
  202. grass.fatal(_("Unable to to reproject vector <%s>") % output)
  203. return 0
  204. if __name__ == "__main__":
  205. options, flags = grass.parser()
  206. atexit.register(cleanup)
  207. sys.exit(main())