IGN.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import os
  2. import json
  3. import tempfile
  4. import py7zr
  5. import numpy as np
  6. from scipy.ndimage import zoom
  7. def Construit(nom, listeLambert, dossier, reduction=1):
  8. """
  9. Construit un fichier RCL contenant une matrice d'altitudes.
  10. Args:
  11. nom:
  12. Nom du fichier de sortie sans extension.
  13. listeLambert:
  14. Liste des tuiles Lambert classées Nord-Ouest vers Sud-Est.
  15. dossier:
  16. Dossier contenant les archives RGEALTI .asc.7z.
  17. reduction:
  18. Facteur de réduction de résolution.
  19. 1 = résolution originale
  20. 2 = réduction par 2 avec interpolation bicubique
  21. 5 = réduction par 5 avec interpolation bicubique
  22. """
  23. if reduction < 1:
  24. raise ValueError("La réduction doit être >= 1")
  25. nom = nom + ".rcl"
  26. taille = int(len(listeLambert) ** 0.5)
  27. if taille * taille != len(listeLambert):
  28. raise ValueError("La liste ne forme pas un carré complet")
  29. resultat = []
  30. with tempfile.TemporaryDirectory() as tmp:
  31. # Parcours des lignes de tuiles du Nord vers le Sud
  32. for ligne_tuile in range(taille):
  33. ligne_fichiers = listeLambert[
  34. ligne_tuile * taille:
  35. (ligne_tuile + 1) * taille
  36. ]
  37. fichiers = []
  38. # Ouverture des tuiles Est-Ouest
  39. for lambert in ligne_fichiers:
  40. archive_path = os.path.join(
  41. dossier,
  42. f"RGEALTI_FXX_{lambert.replace(';', '_')}_MNT_LAMB93_IGN69.asc.7z"
  43. )
  44. with py7zr.SevenZipFile(
  45. archive_path,
  46. mode="r"
  47. ) as archive:
  48. noms = archive.getnames()
  49. archive.extractall(path=tmp)
  50. nom_asc = None
  51. for fichier in noms:
  52. if fichier.endswith(".asc"):
  53. nom_asc = os.path.join(tmp, fichier)
  54. break
  55. if nom_asc is None:
  56. raise FileNotFoundError(
  57. f"Aucun fichier ASC trouvé dans {archive_path}"
  58. )
  59. f = open(nom_asc, "r")
  60. # Suppression de l'entête ASC
  61. for _ in range(6):
  62. next(f)
  63. fichiers.append(f)
  64. # Lecture des 1000 lignes de cette bande
  65. for _ in range(1000):
  66. ligne_complete = []
  67. for f in fichiers:
  68. ligne_complete.extend(
  69. float(x)
  70. for x in f.readline().split()
  71. )
  72. resultat.append(ligne_complete)
  73. for f in fichiers:
  74. f.close()
  75. # Conversion numpy
  76. terrain = np.array(
  77. resultat,
  78. dtype=np.float32
  79. )
  80. # Réduction bicubique
  81. if reduction > 1:
  82. nouvelle_hauteur = terrain.shape[0] / reduction
  83. nouvelle_largeur = terrain.shape[1] / reduction
  84. terrain = zoom(
  85. terrain,
  86. (
  87. nouvelle_hauteur / terrain.shape[0],
  88. nouvelle_largeur / terrain.shape[1]
  89. ),
  90. order=3
  91. )
  92. # Retour en liste pour JSON
  93. resultat = terrain.tolist()
  94. with open(nom, "w") as f:
  95. json.dump(resultat, f)
  96. print(
  97. f"RCL créé : {nom} "
  98. f"({len(resultat)} x {len(resultat[0])})"
  99. )