aqila-mapas 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +1223 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +14 -0
  7. data/Gemfile.lock +49 -0
  8. data/README.md +31 -0
  9. data/Rakefile +8 -0
  10. data/aqila-mapas.gemspec +36 -0
  11. data/bin/console +15 -0
  12. data/bin/setup +8 -0
  13. data/lib/aqila/mapas/railtie.rb +13 -0
  14. data/lib/aqila/mapas/version.rb +7 -0
  15. data/lib/aqila/mapas.rb +57 -0
  16. data/lib/map/download_tiles_service.rb +74 -0
  17. data/lib/map/file_import_basic.rb +30 -0
  18. data/lib/map/float.rb +13 -0
  19. data/lib/map/gdal/base.rb +66 -0
  20. data/lib/map/gdal/colorize_service.rb +82 -0
  21. data/lib/map/gdal/contrast_stretch_service.rb +26 -0
  22. data/lib/map/gdal/crop_service.rb +36 -0
  23. data/lib/map/gdal/gdal_info_service.rb +32 -0
  24. data/lib/map/gdal/grid_service.rb +36 -0
  25. data/lib/map/gdal/merge_service.rb +22 -0
  26. data/lib/map/gdal/ndvi_service.rb +32 -0
  27. data/lib/map/gdal/ogr2ogr_service.rb +23 -0
  28. data/lib/map/gdal/ogri_info_service.rb +35 -0
  29. data/lib/map/gdal/polygonize_service.rb +36 -0
  30. data/lib/map/gdal/raster_service.rb +36 -0
  31. data/lib/map/gdal/rgb_service.rb +27 -0
  32. data/lib/map/gdal/table_colors.txt +52 -0
  33. data/lib/map/gdal/tiles_service.rb +21 -0
  34. data/lib/map/gdal/translate_service.rb +37 -0
  35. data/lib/map/gdal/warp_service.rb +22 -0
  36. data/lib/map/gleba_tiles_service.rb +29 -0
  37. data/lib/map/gpx_service.rb +34 -0
  38. data/lib/map/kml_creator_line_service.rb +31 -0
  39. data/lib/map/kml_creator_service.rb +31 -0
  40. data/lib/map/kml_edit_service.rb +122 -0
  41. data/lib/map/kml_offset_service.rb +59 -0
  42. data/lib/map/kml_service.rb +35 -0
  43. data/lib/map/lat_lon_service.rb +93 -0
  44. data/lib/map/polygon_service.rb +100 -0
  45. data/lib/map/rgeo_service.rb +42 -0
  46. data/lib/map/shape_to_tif_service.rb +89 -0
  47. data/lib/map/tile_service.rb +22 -0
  48. data/lib/map/tiles_base.rb +11 -0
  49. data/lib/map/tracking_cleaner_service.rb +78 -0
  50. data/lib/satellite/imagery_proccessor.rb +70 -0
  51. data/lib/satellite/landsat8/coordinate_converter_service.rb +40 -0
  52. data/lib/satellite/landsat8/imagery_service.rb +113 -0
  53. data/lib/satellite/sentinel2/coordinate_converter_service.rb +90 -0
  54. data/lib/satellite/sentinel2/imagery_service.rb +144 -0
  55. metadata +137 -0
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open-uri'
4
+
5
+ module Satellite
6
+ module Sentinel2
7
+ class CoordinateConverterService
8
+ # Arquivo baixado em https://sentinel.esa.int/web/sentinel/missions/sentinel-2/data-products
9
+ KML_FILE = 'S2A_OPER_GIP_TILPAR_MPC__20151209T095117_V20150622T000000_21000101T000000_B00.kml'
10
+ KML_FILE_URL = "https://sentinel.esa.int/documents/247904/1955685/#{KML_FILE}"
11
+ FILE_SIZE = 108817408
12
+
13
+ attr_accessor :lat, :lon
14
+
15
+ def initialize(lat, lon)
16
+ self.lat = lat
17
+ self.lon = lon
18
+ end
19
+
20
+ def convert
21
+ cache_key = "Sentinel2KML-#{FILE_SIZE}"
22
+ cached = Redis.current.get(cache_key)
23
+ if cached
24
+ cached = JSON.parse(cached)
25
+ else
26
+ cached = parsed_kml
27
+ Redis.current.set(cache_key, cached.to_json, ex: 86400)
28
+ end
29
+
30
+ found = cached.find do |polygon|
31
+ Map::PolygonService.new.inside_polygons?({latitude: lat, longitude: lon}, polygon['coordinates'])
32
+ end
33
+
34
+ return unless found
35
+
36
+ creator = Map::KmlCreatorService.new
37
+ found['coordinates'].each { |c| creator.add_polygon(c) }
38
+ kml_service = Map::KmlService.new(creator.to_xml)
39
+ bounds = {
40
+ point_more_south_west: kml_service.point_more_south_west,
41
+ point_more_north_east: kml_service.point_more_north_east
42
+ }
43
+
44
+ {
45
+ name: found['name'],
46
+ bounds: bounds
47
+ }
48
+ end
49
+
50
+ private
51
+
52
+ def parsed_kml
53
+ FileUtils.mkdir_p(File.dirname(kml_file_path))
54
+
55
+ download_kml_file! unless kml_file_exists? && kml_file_is_valid?
56
+
57
+ File.open(kml_file_path) do |file|
58
+ Nokogiri::XML::Reader.from_io(file).map do |node|
59
+ next unless node.name == 'Placemark'
60
+
61
+ root = Nokogiri::XML(node.outer_xml).root
62
+ coordinates = Map::KmlService.new(root).coordinates
63
+ {
64
+ 'name' => root&.at('name')&.text,
65
+ 'coordinates' => coordinates
66
+ }
67
+ end.compact
68
+ end
69
+ end
70
+
71
+ def download_kml_file!
72
+ open(kml_file_path, 'wb') do |file|
73
+ file << URI.open(KML_FILE_URL).read
74
+ end
75
+ end
76
+
77
+ def kml_file_exists?
78
+ File.exist?(kml_file_path)
79
+ end
80
+
81
+ def kml_file_is_valid?
82
+ File.size(kml_file_path) == FILE_SIZE
83
+ end
84
+
85
+ def kml_file_path
86
+ File.join(Dir.pwd, 'public', 'system', 'data', KML_FILE)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Satellite Sentinel2
4
+ # 10m de resolução
5
+ # Banda 2 = Azul
6
+ # Banda 3 = Verde
7
+ # Banda 4 = Vermelho
8
+ # Banda 8 = Infravermelho próximo
9
+ module Satellite
10
+ module Sentinel2
11
+ class ImageryService
12
+ # Informações sobre --region eu-central-1 --request-payer requester:
13
+ # https://forum.sentinel-hub.com/t/changes-of-the-access-rights-to-l1c-bucket-at-aws-public-datasets-requester-pays/172
14
+ AWS_URL = '--region eu-central-1 --request-payer requester s3://sentinel-s2-l1c/tiles'
15
+
16
+ attr_accessor :scene, :quantity
17
+
18
+ # $scene = '12ABC' String(5)
19
+ def initialize(scene, quantity = 2)
20
+ self.scene = "#{scene[0..1]}/#{scene[2]}/#{scene[3..4]}"
21
+ self.quantity = quantity
22
+ end
23
+
24
+ def download_and_proccess
25
+ Rails.logger.info "[Sentinel2 | #{scene}] Listando últimos #{quantity} arquivos..."
26
+ files = last_scene_dates
27
+
28
+ Rails.logger.info "[Sentinel2 | #{scene}] Checando arquivos que precisam ser baixados..."
29
+ files.reject!{ |scene_date| scene_already_proccessed?(scene_date) }
30
+
31
+ Rails.logger.info "[Sentinel2 | #{scene}] Baixando #{files.length} cenas..."
32
+ files.each_with_index do |scene_date, index|
33
+ Rails.logger.info "[Sentinel2 | #{scene}] Fazendo download da cena do dia #{scene_date}..."
34
+ useful_files(scene_date).map do |useful_file|
35
+ Thread.new {
36
+ Rails.logger.info "[Sentinel2 | #{scene}] Fazendo download do arquivo #{useful_file}..."
37
+ `aws s3 cp #{AWS_URL}/#{scene}/#{scene_date}/0/#{useful_file} "#{output_path}/#{scene}/#{scene_date}/#{useful_file}"`
38
+ raise 'Error to execute aws s3 cp' unless $?.success?
39
+ }
40
+ end.map(&:join)
41
+
42
+ Rails.logger.info "[Sentinel2 | #{scene}] Processando arquivos #{index.next}/#{files.length}."
43
+ Satellite::ImageryProccessor.new(band_object(scene_date)).proccess
44
+ end
45
+ end
46
+
47
+ def last_scene_dates
48
+ return @last_scene_dates if @last_scene_dates.present?
49
+
50
+ @last_scene_dates = []
51
+
52
+ scene_years.sort.reverse.each do |year|
53
+ break if @last_scene_dates.size == quantity
54
+ scene_months(year).sort.reverse.each do |month|
55
+ break if @last_scene_dates.size == quantity
56
+ scene_days(year, month).sort.reverse.each do |day|
57
+ break if @last_scene_dates.size == quantity
58
+ @last_scene_dates << "#{year}/#{month}/#{day}"
59
+ end
60
+ end
61
+ end
62
+
63
+ @last_scene_dates
64
+ end
65
+
66
+ def string_as_integer
67
+ ->(string) { string[/(\d+)/, 1].to_i }
68
+ end
69
+
70
+ def scene_years
71
+ return @scene_years if @scene_years.present?
72
+
73
+ years_list = `aws s3 ls #{AWS_URL}/#{scene}/`
74
+ raise 'Falha ao executar comando para adquirir os anos da cena' unless $?.success?
75
+ @scene_years = years_list.split("\n").map(&string_as_integer)
76
+ end
77
+
78
+ def scene_months(year)
79
+ months_list = `aws s3 ls #{AWS_URL}/#{scene}/#{year}/`
80
+ raise 'Falha ao executar comando para adquirir o mês da última cena' unless $?.success?
81
+
82
+ months_list.split("\n").map(&string_as_integer)
83
+ end
84
+
85
+ def scene_days(year, month)
86
+ days_list = `aws s3 ls #{AWS_URL}/#{scene}/#{year}/#{month}/`
87
+ raise 'Falha ao executar comando para adquirir o dia da última cena' unless $?.success?
88
+
89
+ days_list.split("\n").map(&string_as_integer)
90
+ end
91
+
92
+ def useful_files(scene_date)
93
+ # O parâmetro 0 no fim da string é por que caso o satélite tire mais de uma foto no mesmo dia
94
+ # estas serão armazenadas em /1, /2, etc... porém isso só ocorre em latitudes do norte.
95
+ all_files_from_last_scene = `aws s3 ls #{AWS_URL}/#{scene}/#{scene_date}/0/`
96
+ raise 'Falha ao executar comando para adquirir a lista de arquivos' unless $?.success?
97
+
98
+ @useful_files = all_files_from_last_scene.split("\n").inject([]) do |useful_files, current_file|
99
+ filtered_file = current_file[/.*(B0[2-4].jp2|B08.jp2|preview.jpg)$/, 1]
100
+ useful_files << filtered_file if filtered_file.present?
101
+ useful_files
102
+ end
103
+ end
104
+
105
+ def output_path
106
+ return @path if @path.present?
107
+
108
+ @path = File.join(Dir.pwd, 'public', 'system', 'data', 'imagens', 'sentinel2')
109
+ FileUtils.mkdir_p(@path)
110
+ @path
111
+ end
112
+
113
+ def scene_already_proccessed?(scene_date)
114
+ Scene
115
+ .sentinel2
116
+ .by_date(scene_date.to_date)
117
+ .by_scene(scene.delete('/'))
118
+ .exists?
119
+ end
120
+
121
+ def info_object(scene_date)
122
+ {
123
+ date: scene_date.to_date,
124
+ cloud_cover: nil,
125
+ scene: scene.delete('/'),
126
+ source: :sentinel2,
127
+ base_path: output_path,
128
+ files_path: "#{output_path}/#{scene}/#{scene_date}"
129
+ }
130
+ end
131
+
132
+ def band_object(scene_date)
133
+ {
134
+ blue: "#{output_path}/#{scene}/#{scene_date}/B02.jp2",
135
+ green: "#{output_path}/#{scene}/#{scene_date}/B03.jp2",
136
+ red: "#{output_path}/#{scene}/#{scene_date}/B04.jp2",
137
+ near_infrared: "#{output_path}/#{scene}/#{scene_date}/B08.jp2",
138
+ large_thumb: "#{output_path}/#{scene}/#{scene_date}/preview.jpg",
139
+ info: info_object(scene_date)
140
+ }
141
+ end
142
+ end
143
+ end
144
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aqila-mapas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.4
5
+ platform: ruby
6
+ authors:
7
+ - lucasferronato
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-02-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Documentar
56
+ email:
57
+ - lucas_ferronato@hotmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".rubocop.yml"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - README.md
69
+ - Rakefile
70
+ - aqila-mapas.gemspec
71
+ - bin/console
72
+ - bin/setup
73
+ - lib/aqila/mapas.rb
74
+ - lib/aqila/mapas/railtie.rb
75
+ - lib/aqila/mapas/version.rb
76
+ - lib/map/download_tiles_service.rb
77
+ - lib/map/file_import_basic.rb
78
+ - lib/map/float.rb
79
+ - lib/map/gdal/base.rb
80
+ - lib/map/gdal/colorize_service.rb
81
+ - lib/map/gdal/contrast_stretch_service.rb
82
+ - lib/map/gdal/crop_service.rb
83
+ - lib/map/gdal/gdal_info_service.rb
84
+ - lib/map/gdal/grid_service.rb
85
+ - lib/map/gdal/merge_service.rb
86
+ - lib/map/gdal/ndvi_service.rb
87
+ - lib/map/gdal/ogr2ogr_service.rb
88
+ - lib/map/gdal/ogri_info_service.rb
89
+ - lib/map/gdal/polygonize_service.rb
90
+ - lib/map/gdal/raster_service.rb
91
+ - lib/map/gdal/rgb_service.rb
92
+ - lib/map/gdal/table_colors.txt
93
+ - lib/map/gdal/tiles_service.rb
94
+ - lib/map/gdal/translate_service.rb
95
+ - lib/map/gdal/warp_service.rb
96
+ - lib/map/gleba_tiles_service.rb
97
+ - lib/map/gpx_service.rb
98
+ - lib/map/kml_creator_line_service.rb
99
+ - lib/map/kml_creator_service.rb
100
+ - lib/map/kml_edit_service.rb
101
+ - lib/map/kml_offset_service.rb
102
+ - lib/map/kml_service.rb
103
+ - lib/map/lat_lon_service.rb
104
+ - lib/map/polygon_service.rb
105
+ - lib/map/rgeo_service.rb
106
+ - lib/map/shape_to_tif_service.rb
107
+ - lib/map/tile_service.rb
108
+ - lib/map/tiles_base.rb
109
+ - lib/map/tracking_cleaner_service.rb
110
+ - lib/satellite/imagery_proccessor.rb
111
+ - lib/satellite/landsat8/coordinate_converter_service.rb
112
+ - lib/satellite/landsat8/imagery_service.rb
113
+ - lib/satellite/sentinel2/coordinate_converter_service.rb
114
+ - lib/satellite/sentinel2/imagery_service.rb
115
+ homepage: https://github.com/mateusnava/aqila-mapas
116
+ licenses: []
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.0.9
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Documentar
137
+ test_files: []