3D ski maps. WIP.

esri.py 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. """
  2. This module contains ESRI grid (ASCII) specific functions.
  3. https://en.wikipedia.org/wiki/Esri_grid#ASCII
  4. """
  5. import math
  6. from . import tools
  7. def parse_header(fh):
  8. """
  9. Parses the header of an opened ESRI (ASCII) altitude file.
  10. """
  11. ncols = int(fh.readline().strip().split(" ")[-1])
  12. nrows = int(fh.readline().strip().split(" ")[-1])
  13. xllcorner = float(fh.readline().strip().split(" ")[-1])
  14. yllcorner = float(fh.readline().strip().split(" ")[-1])
  15. cellsize = float(fh.readline().strip().split(" ")[-1])
  16. nodata = float(fh.readline().strip().split(" ")[-1])
  17. return ncols, nrows, xllcorner, yllcorner, cellsize, nodata
  18. def find_relevant_points(x_min, y_min, x_max, y_max, in_files,
  19. verbose=True):
  20. """
  21. Finds the points in the target geographic region which are in the files in
  22. the in_files list.
  23. x_min, y_min, x_max, y_max specify the target geographic region, in
  24. Lambert93 coordinates.
  25. Returns a list of relevant points.
  26. """
  27. points = []
  28. for file in in_files:
  29. with open(file, 'r') as fh:
  30. # Parse file header
  31. ncols, nrows, xllcorner, yllcorner, cellsize, nodata = parse_header(fh)
  32. # Check overlap between area in the file and target area
  33. if((not tools.has_overlap([x_min, x_max],
  34. [xllcorner,
  35. xllcorner + cellsize * ncols])) or
  36. (not tools.has_overlap([y_min, y_max],
  37. [yllcorner,
  38. yllcorner + cellsize * nrows]))):
  39. # If no overlap, go on with next file
  40. continue
  41. if verbose:
  42. print("Relevant dataset: " + file)
  43. # Compute which part of the file to keep (rows / cols)
  44. col_min = math.floor((x_min - xllcorner) / cellsize)
  45. col_max = math.ceil((x_max - xllcorner) / cellsize)
  46. # The (0, 0) point is the lower left one, that is on the last line.
  47. row_max = nrows - math.floor((y_min - yllcorner) / cellsize)
  48. row_min = nrows - math.ceil((y_max - yllcorner) / cellsize)
  49. i = 0
  50. for line in fh.readlines():
  51. if i >= row_min and i <= row_max:
  52. row = [float(j) for j in line.strip().split(" ")]
  53. for j in range(col_min, col_max):
  54. points.append((xllcorner + j * cellsize,
  55. yllcorner + (nrows - i) * cellsize,
  56. row[j]))
  57. i += 1
  58. return points