v.import.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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 G_OPT_F_BIN_INPUT
  24. #% description: Name of OGR datasource to be imported
  25. #% guisection: Input
  26. #%end
  27. #%option
  28. #% key: layer
  29. #% type: string
  30. #% multiple: yes
  31. #% description: OGR layer name. If not given, all available layers are imported
  32. #% guisection: Input
  33. #%end
  34. #%option G_OPT_V_OUTPUT
  35. #% description: Name for output vector map (default: input)
  36. #% required: no
  37. #% guisection: Output
  38. #%end
  39. #%option
  40. #% key: extent
  41. #% type: string
  42. #% options: input,region
  43. #% answer: input
  44. #% description: Output vector map extent
  45. #% descriptions: input;extent of input map;region;extent of current region
  46. #% guisection: Output
  47. #%end
  48. #%option
  49. #% key: encoding
  50. #% type: string
  51. #% label: Encoding value for attribute data
  52. #% descriptions: Overrides encoding interpretation, useful when importing ESRI Shapefile
  53. #% guisection: Output
  54. #%end
  55. #%option
  56. #% key: snap
  57. #% type: double
  58. #% label: Snapping threshold for boundaries (map units)
  59. #% description: '-1' for no snap
  60. #% answer: 1e-13
  61. #% guisection: Output
  62. #%end
  63. #%option
  64. #% key: epsg
  65. #% type: integer
  66. #% options: 1-1000000
  67. #% guisection: Input SRS
  68. #% description: EPSG projection code
  69. #%end
  70. #%option
  71. #% key: datum_trans
  72. #% type: integer
  73. #% options: -1-100
  74. #% guisection: Input SRS
  75. #% label: Index number of datum transform parameters
  76. #% description: -1 to list available datum transform parameters
  77. #%end
  78. #%flag
  79. #% key: f
  80. #% description: List supported OGR formats and exit
  81. #% suppress_required: yes
  82. #%end
  83. #%flag
  84. #% key: l
  85. #% description: List available OGR layers in data source and exit
  86. #%end
  87. #%flag
  88. #% key: o
  89. #% label: Override projection check (use current location's projection)
  90. #% description: Assume that the dataset has same projection as the current location
  91. #%end
  92. import sys
  93. import os
  94. import atexit
  95. import grass.script as grass
  96. from grass.exceptions import CalledModuleError
  97. # initialize global vars
  98. TMPLOC = None
  99. SRCGISRC = None
  100. GISDBASE = None
  101. def cleanup():
  102. # remove temp location
  103. if TMPLOC:
  104. grass.try_rmdir(os.path.join(GISDBASE, TMPLOC))
  105. if SRCGISRC:
  106. grass.try_remove(SRCGISRC)
  107. def main():
  108. global TMPLOC, SRCGISRC, GISDBASE
  109. # list formats and exit
  110. if flags['f']:
  111. grass.run_command('v.in.ogr', flags='f')
  112. return 0
  113. # list layers and exit
  114. if flags['l']:
  115. try:
  116. grass.run_command('v.in.ogr', flags='l', input=options['input'])
  117. except CalledModuleError:
  118. return 1
  119. return 0
  120. OGRdatasource = options['input']
  121. output = options['output']
  122. layers = options['layer']
  123. vflags = ''
  124. if options['extent'] == 'region':
  125. vflags += 'r'
  126. if flags['o']:
  127. vflags += 'o'
  128. vopts = {}
  129. if options['encoding']:
  130. vopts['encoding'] = options['encoding']
  131. if options['datum_trans'] and options['datum_trans'] == '-1':
  132. # list datum transform parameters
  133. if not options['epsg']:
  134. grass.fatal(_("Missing value for parameter <%s>") % 'epsg')
  135. return grass.run_command('g.proj', epsg=options['epsg'],
  136. datum_trans=options['datum_trans'])
  137. grassenv = grass.gisenv()
  138. tgtloc = grassenv['LOCATION_NAME']
  139. tgtmapset = grassenv['MAPSET']
  140. GISDBASE = grassenv['GISDBASE']
  141. tgtgisrc = os.environ['GISRC']
  142. SRCGISRC = grass.tempfile()
  143. TMPLOC = 'temp_import_location_' + str(os.getpid())
  144. f = open(SRCGISRC, 'w')
  145. f.write('MAPSET: PERMANENT\n')
  146. f.write('GISDBASE: %s\n' % GISDBASE)
  147. f.write('LOCATION_NAME: %s\n' % TMPLOC)
  148. f.write('GUI: text\n')
  149. f.close()
  150. tgtsrs = grass.read_command('g.proj', flags='j', quiet=True)
  151. # create temp location from input without import
  152. grass.verbose(_("Creating temporary location for <%s>...") % OGRdatasource)
  153. if layers:
  154. vopts['layer'] = layers
  155. if output:
  156. vopts['output'] = output
  157. vopts['snap'] = options['snap']
  158. try:
  159. grass.run_command('v.in.ogr', input=OGRdatasource,
  160. location=TMPLOC, flags='i', quiet=True, **vopts)
  161. except CalledModuleError:
  162. grass.fatal(_("Unable to create location from OGR datasource <%s>") % OGRdatasource)
  163. # switch to temp location
  164. os.environ['GISRC'] = str(SRCGISRC)
  165. if options['epsg']: # force given EPSG
  166. kwargs = {}
  167. if options['datum_trans']:
  168. kwargs['datum_trans'] = options['datum_trans']
  169. grass.run_command('g.proj', flags='c', epsg=options['epsg'], **kwargs)
  170. # switch to target location
  171. os.environ['GISRC'] = str(tgtgisrc)
  172. # try v.in.ogr directly
  173. if flags['o'] or grass.run_command('v.in.ogr', input=OGRdatasource, flags='j',
  174. errors='status', quiet=True) == 0:
  175. try:
  176. grass.run_command('v.in.ogr', input=OGRdatasource,
  177. flags=vflags, **vopts)
  178. grass.message(_("Input <%s> successfully imported without reprojection") % OGRdatasource)
  179. return 0
  180. except CalledModuleError:
  181. grass.fatal(_("Unable to import <%s>") % OGRdatasource)
  182. # make sure target is not xy
  183. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  184. grass.fatal(_("Coordinate reference system not available for current location <%s>") % tgtloc)
  185. # switch to temp location
  186. os.environ['GISRC'] = str(SRCGISRC)
  187. # print projection at verbose level
  188. grass.verbose(grass.read_command('g.proj', flags='p').rstrip(os.linesep))
  189. # make sure input is not xy
  190. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  191. grass.fatal(_("Coordinate reference system not available for input <%s>") % OGRdatasource)
  192. if options['extent'] == 'region':
  193. # switch to target location
  194. os.environ['GISRC'] = str(tgtgisrc)
  195. # v.in.region in tgt
  196. vreg = 'vreg_' + str(os.getpid())
  197. grass.run_command('v.in.region', output=vreg, quiet=True)
  198. # reproject to src
  199. # switch to temp location
  200. os.environ['GISRC'] = str(SRCGISRC)
  201. try:
  202. grass.run_command('v.proj', input=vreg, output=vreg,
  203. location=tgtloc, mapset=tgtmapset, quiet=True)
  204. except CalledModuleError:
  205. grass.fatal(_("Unable to reproject to source location"))
  206. # set region from region vector
  207. grass.run_command('g.region', res='1')
  208. grass.run_command('g.region', vector=vreg)
  209. # import into temp location
  210. grass.message(_("Importing <%s> ...") % OGRdatasource)
  211. try:
  212. grass.run_command('v.in.ogr', input=OGRdatasource,
  213. flags=vflags, **vopts)
  214. except CalledModuleError:
  215. grass.fatal(_("Unable to import OGR datasource <%s>") % OGRdatasource)
  216. # if output is not define check source mapset
  217. if not output:
  218. output = grass.list_grouped('vector')['PERMANENT'][0]
  219. # switch to target location
  220. os.environ['GISRC'] = str(tgtgisrc)
  221. # check if map exists
  222. if not grass.overwrite() and \
  223. grass.find_file(output, element='vector', mapset='.')['mapset']:
  224. grass.fatal(_("option <%s>: <%s> exists.") % ('output', output))
  225. if options['extent'] == 'region':
  226. grass.run_command('g.remove', type='vector', name=vreg,
  227. flags='f', quiet=True)
  228. # v.proj
  229. grass.message(_("Reprojecting <%s>...") % output)
  230. try:
  231. grass.run_command('v.proj', location=TMPLOC,
  232. mapset='PERMANENT', input=output)
  233. except CalledModuleError:
  234. grass.fatal(_("Unable to to reproject vector <%s>") % output)
  235. return 0
  236. if __name__ == "__main__":
  237. options, flags = grass.parser()
  238. atexit.register(cleanup)
  239. sys.exit(main())