3D ski maps. WIP.

skimap.py 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env python3
  2. """
  3. This script filters the BD ALTI from IGN (ESRI grid) to keep only the relevant
  4. files for the specified area.
  5. Input is an ESRI grid (ASCII) file from the IGN BD ALTI database.
  6. (https://en.wikipedia.org/wiki/Esri_grid#ASCII)
  7. Output is an Azavea Raster Grid format (ARG) file.
  8. http://geotrellis.io/documentation/0.9.0/geotrellis/io/arg/
  9. Metadata are going to the standard output, and should be appended to
  10. config.json file in ressources folder.
  11. """
  12. import argparse
  13. import os
  14. from libskimap import esri, geodata, hgt, osm, output, tools
  15. def main(lat_min, lng_min, lat_max, lng_max,
  16. in_files, osm_file,
  17. out, out_geometadata):
  18. """
  19. Main function
  20. """
  21. print(("Looking for data between latitudes and longitudes " +
  22. "({0}, {1}) and ({2}, {3})").format(lat_min,
  23. lng_min,
  24. lat_max,
  25. lng_max))
  26. # Convert latitude / longitude coordinates to Lambert93 projection
  27. x_min, y_min = geodata.latlng_to_lambert93(lat_min, lng_min)
  28. x_max, y_max = geodata.latlng_to_lambert93(lat_max, lng_max)
  29. # Switch x_min and x_max if necessary
  30. if x_min > x_max:
  31. x_min, x_max = x_max, x_min
  32. # Switch y_min and y_may if necessary
  33. if y_min > y_max:
  34. y_min, y_max = y_max, y_min
  35. print(("Looking for data between map coordinates " +
  36. "({0}, {1}) and ({2}, {3})").format(x_min, y_min, x_max, y_max))
  37. # Loop over all the available data files and find those with relevant
  38. # points
  39. in_files_esri = [i for i in in_files if i.endswith(".asc")]
  40. points = esri.find_relevant_points(x_min, y_min, x_max, y_max,
  41. in_files_esri)
  42. in_files_hgt = [i for i in in_files if i.endswith(".hgt")]
  43. points.extend(hgt.find_relevant_points(x_min, y_min, x_max, y_max,
  44. in_files_hgt))
  45. # Get ARG formatted data
  46. out, arg_metadata = output.format_arg(points)
  47. # Filter ARG metadata according to our needs for config
  48. arg_metadata = output.arg_metadata_to_JSON_config(arg_metadata)
  49. # Fetch OSM metadata for the target geographic region
  50. osm_metadata = osm.fetch_metadata(lat_min, lng_min, lat_max, lng_max,
  51. osm_file)
  52. # Output the OSM metadata to relevant file
  53. with open(out_geometadata, "w") as fh:
  54. fh.write(tools.pretty_json(osm_metadata))
  55. # Write raw file to out_file
  56. with open(out, "wb") as fh:
  57. fh.write(out)
  58. # Print metadata to stdout, as JSON
  59. print("\n\nConfig file:")
  60. print(arg_metadata)
  61. if __name__ == "__main__":
  62. parser = argparse.ArgumentParser(
  63. description="Fetch height dataset from geodata.")
  64. parser.add_argument("--lat-min", dest="lat_min", action="store",
  65. required=True, type=float,
  66. help="Minimum latitude in the covered area.")
  67. parser.add_argument("--lat-max", dest="lat_max", action="store",
  68. required=True, type=float,
  69. help="Maximum latitude in the covered area.")
  70. parser.add_argument("--lng-min", dest="lng_min", action="store",
  71. required=True, type=float,
  72. help="Minimum longitude in the covered area.")
  73. parser.add_argument("--lng-max", dest="lng_max", action="store",
  74. required=True, type=float,
  75. help="Maximum longitude in the covered area.")
  76. parser.add_argument("--out", dest="out", action="store",
  77. required=True,
  78. help="Output heightmap metadata file name.")
  79. parser.add_argument("--osm-file", dest="osm_file", action="store",
  80. required=False, default="",
  81. help="Path to a downloaded OSM metadata XML file.")
  82. parser.add_argument("--out-geometadata", dest="out_geometadata",
  83. action="store", required=False, default="",
  84. help="Ouptut geographic metadata file name " +
  85. "(defaults to osm_(--out arg) file).")
  86. parser.add_argument("in_files", action="store", nargs="+",
  87. help="Input dataset files or folder containing input" +
  88. "files.")
  89. # Parse parameters
  90. args = parser.parse_args()
  91. in_files = args.in_files
  92. # If in_files has only one element which is a directory
  93. if len(in_files) == 1 and os.path.isdir(in_files[0]):
  94. # in_files is the list of all the files in this directory
  95. in_files = [os.path.join(in_files[0], f)
  96. for f in os.listdir(in_files[0])]
  97. out_geometadata = args.out_geometadata
  98. if out_geometadata is "":
  99. out_geometadata = "osm_" + args.out
  100. # Call main functions with arguments from command line
  101. main(args.lat_min, args.lng_min, args.lat_max, args.lng_max,
  102. in_files, args.osm_file, args.out, out_geometadata)