v.import.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #!/usr/bin/env python3
  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: A suitable threshold is estimated during import
  65. #% answer: -1
  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. TGTGISRC = None
  106. GISDBASE = None
  107. def cleanup():
  108. if TGTGISRC:
  109. os.environ['GISRC'] = str(TGTGISRC)
  110. # remove temp location
  111. if TMPLOC:
  112. grass.try_rmdir(os.path.join(GISDBASE, TMPLOC))
  113. if SRCGISRC:
  114. grass.try_remove(SRCGISRC)
  115. def main():
  116. global TMPLOC, SRCGISRC, TGTGISRC, GISDBASE
  117. overwrite = grass.overwrite()
  118. # list formats and exit
  119. if flags['f']:
  120. grass.run_command('v.in.ogr', flags='f')
  121. return 0
  122. # list layers and exit
  123. if flags['l']:
  124. try:
  125. grass.run_command('v.in.ogr', flags='l', input=options['input'])
  126. except CalledModuleError:
  127. return 1
  128. return 0
  129. OGRdatasource = options['input']
  130. output = options['output']
  131. layers = options['layer']
  132. vflags = ''
  133. if options['extent'] == 'region':
  134. vflags += 'r'
  135. if flags['o']:
  136. vflags += 'o'
  137. vopts = {}
  138. if options['encoding']:
  139. vopts['encoding'] = options['encoding']
  140. if options['datum_trans'] and options['datum_trans'] == '-1':
  141. # list datum transform parameters
  142. if not options['epsg']:
  143. grass.fatal(_("Missing value for parameter <%s>") % 'epsg')
  144. return grass.run_command('g.proj', epsg=options['epsg'],
  145. datum_trans=options['datum_trans'])
  146. if layers:
  147. vopts['layer'] = layers
  148. if output:
  149. vopts['output'] = output
  150. vopts['snap'] = options['snap']
  151. # try v.in.ogr directly
  152. if flags['o'] or grass.run_command('v.in.ogr', input=OGRdatasource, flags='j',
  153. errors='status', quiet=True, overwrite=overwrite,
  154. **vopts) == 0:
  155. try:
  156. grass.run_command('v.in.ogr', input=OGRdatasource,
  157. flags=vflags, overwrite=overwrite, **vopts)
  158. grass.message(
  159. _("Input <%s> successfully imported without reprojection") %
  160. OGRdatasource)
  161. return 0
  162. except CalledModuleError:
  163. grass.fatal(_("Unable to import <%s>") % OGRdatasource)
  164. grassenv = grass.gisenv()
  165. tgtloc = grassenv['LOCATION_NAME']
  166. # make sure target is not xy
  167. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  168. grass.fatal(
  169. _("Coordinate reference system not available for current location <%s>") %
  170. tgtloc)
  171. tgtmapset = grassenv['MAPSET']
  172. GISDBASE = grassenv['GISDBASE']
  173. TGTGISRC = os.environ['GISRC']
  174. SRCGISRC = grass.tempfile()
  175. TMPLOC = 'temp_import_location_' + str(os.getpid())
  176. f = open(SRCGISRC, 'w')
  177. f.write('MAPSET: PERMANENT\n')
  178. f.write('GISDBASE: %s\n' % GISDBASE)
  179. f.write('LOCATION_NAME: %s\n' % TMPLOC)
  180. f.write('GUI: text\n')
  181. f.close()
  182. tgtsrs = grass.read_command('g.proj', flags='j', quiet=True)
  183. # create temp location from input without import
  184. grass.verbose(_("Creating temporary location for <%s>...") % OGRdatasource)
  185. try:
  186. grass.run_command('v.in.ogr', input=OGRdatasource,
  187. location=TMPLOC, flags='i', quiet=True, overwrite=overwrite, **vopts)
  188. except CalledModuleError:
  189. grass.fatal(_("Unable to create location from OGR datasource <%s>") % OGRdatasource)
  190. # switch to temp location
  191. os.environ['GISRC'] = str(SRCGISRC)
  192. if options['epsg']: # force given EPSG
  193. kwargs = {}
  194. if options['datum_trans']:
  195. kwargs['datum_trans'] = options['datum_trans']
  196. grass.run_command('g.proj', flags='c', epsg=options['epsg'], **kwargs)
  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())