v.import.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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. 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 = None
  124. if options['extent'] == 'region':
  125. vflags = 'r'
  126. vopts = {}
  127. if options['encoding']:
  128. vopts['encoding'] = options['encoding']
  129. if options['datum_trans'] and options['datum_trans'] == '-1':
  130. # list datum transform parameters
  131. if not options['epsg']:
  132. grass.fatal(_("Missing value for parameter <%s>") % 'epsg')
  133. return grass.run_command('g.proj', epsg=options['epsg'],
  134. datum_trans=options['datum_trans'])
  135. grassenv = grass.gisenv()
  136. tgtloc = grassenv['LOCATION_NAME']
  137. tgtmapset = grassenv['MAPSET']
  138. GISDBASE = grassenv['GISDBASE']
  139. tgtgisrc = os.environ['GISRC']
  140. SRCGISRC = grass.tempfile()
  141. TMPLOC = 'temp_import_location_' + str(os.getpid())
  142. f = open(SRCGISRC, 'w')
  143. f.write('MAPSET: PERMANENT\n')
  144. f.write('GISDBASE: %s\n' % GISDBASE)
  145. f.write('LOCATION_NAME: %s\n' % TMPLOC)
  146. f.write('GUI: text\n')
  147. f.close()
  148. tgtsrs = grass.read_command('g.proj', flags='j', quiet=True)
  149. # create temp location from input without import
  150. grass.verbose(_("Creating temporary location for <%s>...") % OGRdatasource)
  151. if layers:
  152. vopts['layer'] = layers
  153. if output:
  154. vopts['output'] = output
  155. vopts['snap'] = options['snap']
  156. try:
  157. grass.run_command('v.in.ogr', input=OGRdatasource,
  158. location=TMPLOC, flags='i', quiet=True, **vopts)
  159. except CalledModuleError:
  160. grass.fatal(_("Unable to create location from OGR datasource <%s>") % OGRdatasource)
  161. # switch to temp location
  162. os.environ['GISRC'] = str(SRCGISRC)
  163. if options['epsg']: # force given EPSG
  164. kwargs = {}
  165. if options['datum_trans']:
  166. kwargs['datum_trans'] = options['datum_trans']
  167. grass.run_command('g.proj', flags='c', epsg=options['epsg'], **kwargs)
  168. # switch to target location
  169. os.environ['GISRC'] = str(tgtgisrc)
  170. # try v.in.ogr directly
  171. if grass.run_command('v.in.ogr', input=OGRdatasource, flags='j',
  172. errors='status', quiet=True) == 0:
  173. try:
  174. grass.run_command('v.in.ogr', input=OGRdatasource,
  175. flags=vflags, **vopts)
  176. grass.message(_("Input <%s> successfully imported without reprojection") % OGRdatasource)
  177. return 0
  178. except CalledModuleError:
  179. grass.fatal(_("Unable to import <%s>") % OGRdatasource)
  180. # make sure target is not xy
  181. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  182. grass.fatal(_("Coordinate reference system not available for current location <%s>") % tgtloc)
  183. # switch to temp location
  184. os.environ['GISRC'] = str(SRCGISRC)
  185. # print projection at verbose level
  186. grass.verbose(grass.read_command('g.proj', flags='p').rstrip(os.linesep))
  187. # make sure input is not xy
  188. if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
  189. grass.fatal(_("Coordinate reference system not available for input <%s>") % OGRdatasource)
  190. if options['extent'] == 'region':
  191. # switch to target location
  192. os.environ['GISRC'] = str(tgtgisrc)
  193. # v.in.region in tgt
  194. vreg = 'vreg_' + str(os.getpid())
  195. grass.run_command('v.in.region', output=vreg, quiet=True)
  196. # reproject to src
  197. # switch to temp location
  198. os.environ['GISRC'] = str(SRCGISRC)
  199. try:
  200. grass.run_command('v.proj', input=vreg, output=vreg,
  201. location=tgtloc, mapset=tgtmapset, quiet=True)
  202. except CalledModuleError:
  203. grass.fatal(_("Unable to reproject to source location"))
  204. # set region from region vector
  205. grass.run_command('g.region', res='1')
  206. grass.run_command('g.region', vector=vreg)
  207. # import into temp location
  208. grass.message(_("Importing <%s> ...") % OGRdatasource)
  209. try:
  210. grass.run_command('v.in.ogr', input=OGRdatasource,
  211. flags=vflags, **vopts)
  212. except CalledModuleError:
  213. grass.fatal(_("Unable to import OGR datasource <%s>") % OGRdatasource)
  214. # if output is not define check source mapset
  215. if not output:
  216. output = grass.list_grouped('vector')['PERMANENT'][0]
  217. # switch to target location
  218. os.environ['GISRC'] = str(tgtgisrc)
  219. # check if map exists
  220. if not grass.overwrite() and \
  221. grass.find_file(output, element='vector', mapset='.')['mapset']:
  222. grass.fatal(_("option <%s>: <%s> exists.") % ('output', output))
  223. if options['extent'] == 'region':
  224. grass.run_command('g.remove', type='vector', name=vreg,
  225. flags='f', quiet=True)
  226. # v.proj
  227. grass.message(_("Reprojecting <%s>...") % output)
  228. try:
  229. grass.run_command('v.proj', location=TMPLOC,
  230. mapset='PERMANENT', input=output)
  231. except CalledModuleError:
  232. grass.fatal(_("Unable to to reproject vector <%s>") % output)
  233. return 0
  234. if __name__ == "__main__":
  235. options, flags = grass.parser()
  236. atexit.register(cleanup)
  237. sys.exit(main())