aqila-mapas 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
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: []