v.import.py 8.6 KB

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