aqila-mapas 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1223 -0
- data/.travis.yml +5 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +49 -0
- data/README.md +31 -0
- data/Rakefile +8 -0
- data/aqila-mapas.gemspec +36 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/aqila/mapas/railtie.rb +13 -0
- data/lib/aqila/mapas/version.rb +7 -0
- data/lib/aqila/mapas.rb +57 -0
- data/lib/map/download_tiles_service.rb +74 -0
- data/lib/map/file_import_basic.rb +30 -0
- data/lib/map/float.rb +13 -0
- data/lib/map/gdal/base.rb +66 -0
- data/lib/map/gdal/colorize_service.rb +82 -0
- data/lib/map/gdal/contrast_stretch_service.rb +26 -0
- data/lib/map/gdal/crop_service.rb +36 -0
- data/lib/map/gdal/gdal_info_service.rb +32 -0
- data/lib/map/gdal/grid_service.rb +36 -0
- data/lib/map/gdal/merge_service.rb +22 -0
- data/lib/map/gdal/ndvi_service.rb +32 -0
- data/lib/map/gdal/ogr2ogr_service.rb +23 -0
- data/lib/map/gdal/ogri_info_service.rb +35 -0
- data/lib/map/gdal/polygonize_service.rb +36 -0
- data/lib/map/gdal/raster_service.rb +36 -0
- data/lib/map/gdal/rgb_service.rb +27 -0
- data/lib/map/gdal/table_colors.txt +52 -0
- data/lib/map/gdal/tiles_service.rb +21 -0
- data/lib/map/gdal/translate_service.rb +37 -0
- data/lib/map/gdal/warp_service.rb +22 -0
- data/lib/map/gleba_tiles_service.rb +29 -0
- data/lib/map/gpx_service.rb +34 -0
- data/lib/map/kml_creator_line_service.rb +31 -0
- data/lib/map/kml_creator_service.rb +31 -0
- data/lib/map/kml_edit_service.rb +122 -0
- data/lib/map/kml_offset_service.rb +59 -0
- data/lib/map/kml_service.rb +35 -0
- data/lib/map/lat_lon_service.rb +93 -0
- data/lib/map/polygon_service.rb +100 -0
- data/lib/map/rgeo_service.rb +42 -0
- data/lib/map/shape_to_tif_service.rb +89 -0
- data/lib/map/tile_service.rb +22 -0
- data/lib/map/tiles_base.rb +11 -0
- data/lib/map/tracking_cleaner_service.rb +78 -0
- data/lib/satellite/imagery_proccessor.rb +70 -0
- data/lib/satellite/landsat8/coordinate_converter_service.rb +40 -0
- data/lib/satellite/landsat8/imagery_service.rb +113 -0
- data/lib/satellite/sentinel2/coordinate_converter_service.rb +90 -0
- data/lib/satellite/sentinel2/imagery_service.rb +144 -0
- metadata +137 -0
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
git_source(:github) {|repo_name| "https://github.com/#{repo_name}"}
|
6
|
+
|
7
|
+
# Specify your gem's dependencies in aqila-mapas.gemspec
|
8
|
+
gemspec
|
9
|
+
|
10
|
+
gem 'httparty', '~> 0.13.7'
|
11
|
+
|
12
|
+
group :development, :test do
|
13
|
+
gem 'pry-rails', '0.3.4'
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
aqila-mapas (0.4.4)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.1.2)
|
10
|
+
diff-lcs (1.3)
|
11
|
+
httparty (0.13.7)
|
12
|
+
json (~> 1.8)
|
13
|
+
multi_xml (>= 0.5.2)
|
14
|
+
json (1.8.6)
|
15
|
+
method_source (0.9.0)
|
16
|
+
multi_xml (0.6.0)
|
17
|
+
pry (0.11.3)
|
18
|
+
coderay (~> 1.1.0)
|
19
|
+
method_source (~> 0.9.0)
|
20
|
+
pry-rails (0.3.4)
|
21
|
+
pry (>= 0.9.10)
|
22
|
+
rake (10.4.2)
|
23
|
+
rspec (3.7.0)
|
24
|
+
rspec-core (~> 3.7.0)
|
25
|
+
rspec-expectations (~> 3.7.0)
|
26
|
+
rspec-mocks (~> 3.7.0)
|
27
|
+
rspec-core (3.7.1)
|
28
|
+
rspec-support (~> 3.7.0)
|
29
|
+
rspec-expectations (3.7.0)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.7.0)
|
32
|
+
rspec-mocks (3.7.0)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.7.0)
|
35
|
+
rspec-support (3.7.1)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
aqila-mapas!
|
42
|
+
bundler (~> 1.16)
|
43
|
+
httparty (~> 0.13.7)
|
44
|
+
pry-rails (= 0.3.4)
|
45
|
+
rake (~> 10.0)
|
46
|
+
rspec (~> 3.0)
|
47
|
+
|
48
|
+
BUNDLED WITH
|
49
|
+
1.17.3
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Aqila::Mapas
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem 'aqila-mapas'
|
9
|
+
```
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install aqila-mapas
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Development
|
24
|
+
|
25
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
26
|
+
|
27
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mateusnava/aqila-mapas.
|
data/Rakefile
ADDED
data/aqila-mapas.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "aqila/mapas/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "aqila-mapas"
|
9
|
+
spec.version = Aqila::Mapas::VERSION
|
10
|
+
spec.authors = ["lucasferronato"]
|
11
|
+
spec.email = ["lucas_ferronato@hotmail.com"]
|
12
|
+
|
13
|
+
spec.summary = %q{Documentar} # FIXME
|
14
|
+
spec.description = %q{Documentar} # FIXME
|
15
|
+
spec.homepage = "https://github.com/mateusnava/aqila-mapas"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
# else
|
22
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
# "public gem pushes."
|
24
|
+
# end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
36
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "aqila/mapas"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/aqila/mapas.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aqila/mapas/version'
|
4
|
+
if defined?(Rails)
|
5
|
+
require 'rails'
|
6
|
+
require 'aqila/mapas/railtie'
|
7
|
+
end
|
8
|
+
|
9
|
+
module Map
|
10
|
+
module Gdal; end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Satellite
|
14
|
+
module Landsat8; end
|
15
|
+
module Sentinel2; end
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'map/download_tiles_service'
|
19
|
+
require 'map/file_import_basic'
|
20
|
+
require 'map/float'
|
21
|
+
require 'map/gleba_tiles_service'
|
22
|
+
require 'map/gpx_service'
|
23
|
+
require 'map/kml_creator_service'
|
24
|
+
require 'map/kml_creator_line_service'
|
25
|
+
require 'map/kml_edit_service'
|
26
|
+
require 'map/kml_offset_service'
|
27
|
+
require 'map/kml_service'
|
28
|
+
require 'map/lat_lon_service'
|
29
|
+
require 'map/polygon_service'
|
30
|
+
require 'map/rgeo_service'
|
31
|
+
require 'map/tile_service'
|
32
|
+
require 'map/tiles_base'
|
33
|
+
require 'map/tracking_cleaner_service'
|
34
|
+
require 'map/shape_to_tif_service'
|
35
|
+
|
36
|
+
require 'map/gdal/base'
|
37
|
+
require 'map/gdal/colorize_service'
|
38
|
+
require 'map/gdal/crop_service'
|
39
|
+
require 'map/gdal/grid_service'
|
40
|
+
require 'map/gdal/merge_service'
|
41
|
+
require 'map/gdal/ndvi_service'
|
42
|
+
require 'map/gdal/raster_service'
|
43
|
+
require 'map/gdal/rgb_service'
|
44
|
+
require 'map/gdal/tiles_service'
|
45
|
+
require 'map/gdal/translate_service'
|
46
|
+
require 'map/gdal/ogri_info_service'
|
47
|
+
require 'map/gdal/warp_service'
|
48
|
+
require 'map/gdal/ogr2ogr_service'
|
49
|
+
require 'map/gdal/gdal_info_service'
|
50
|
+
require 'map/gdal/contrast_stretch_service'
|
51
|
+
require 'map/gdal/polygonize_service'
|
52
|
+
|
53
|
+
require 'satellite/imagery_proccessor'
|
54
|
+
require 'satellite/landsat8/coordinate_converter_service'
|
55
|
+
require 'satellite/landsat8/imagery_service'
|
56
|
+
require 'satellite/sentinel2/coordinate_converter_service'
|
57
|
+
require 'satellite/sentinel2/imagery_service'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
class Map::DownloadTilesService
|
6
|
+
include HTTParty
|
7
|
+
TILES_OVERHEAD = 1
|
8
|
+
MIN_FILE_SIZE = 500
|
9
|
+
|
10
|
+
SERVERS_OPEN_STREET_MAPS = [
|
11
|
+
'http://a.tile.openstreetmap.org',
|
12
|
+
'http://b.tile.openstreetmap.org',
|
13
|
+
'http://c.tile.openstreetmap.org'
|
14
|
+
].freeze
|
15
|
+
MAP_BOX_SERVER = 'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/256'
|
16
|
+
MAP_BOX_TOKEN = 'pk.eyJ1IjoiYWdybzEtaW5vdmFjYW8iLCJhIjoiY2lqdmRub3MyMDVyNXVjbTVwOXF2bnVvMSJ9.M6MRl61WC_fKEv6B6y72Ug'
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
@zoom_min = options[:zoom] || options[:zoom_min]
|
20
|
+
@zoom_max = options[:zoom] || options[:zoom_max]
|
21
|
+
@boundary_ne = options[:boundary] || options[:boundary_ne]
|
22
|
+
@boundary_sw = options[:boundary] || options[:boundary_sw]
|
23
|
+
@output_directory = options[:output_directory]
|
24
|
+
@server = options[:server]
|
25
|
+
end
|
26
|
+
|
27
|
+
def download
|
28
|
+
ret = []
|
29
|
+
|
30
|
+
(@zoom_min..@zoom_max).each do |zoom|
|
31
|
+
tile_NE = Map::TileService.new(@boundary_ne.second, @boundary_ne.first, zoom).points
|
32
|
+
tile_SW = Map::TileService.new(@boundary_sw.second, @boundary_sw.first, zoom).points
|
33
|
+
|
34
|
+
(tile_SW[:x]-TILES_OVERHEAD..tile_NE[:x]+TILES_OVERHEAD).each do |point_x|
|
35
|
+
(tile_NE[:y]-TILES_OVERHEAD..tile_SW[:y]+TILES_OVERHEAD).each do |point_y|
|
36
|
+
ret << {
|
37
|
+
x: point_x,
|
38
|
+
y: point_y,
|
39
|
+
z: zoom,
|
40
|
+
file: get_tile([point_x, point_y], zoom)
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
ret
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def valid_file?(file_name)
|
52
|
+
File.exist?(file_name) && File.size(file_name) > MIN_FILE_SIZE
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_tile(points, zoom)
|
56
|
+
dir = "#{@output_directory}/#{zoom}/#{points.first}"
|
57
|
+
file_name = "#{dir}/#{points.second}.jpg"
|
58
|
+
|
59
|
+
return file_name if valid_file?(file_name)
|
60
|
+
|
61
|
+
FileUtils.mkdir_p(dir)
|
62
|
+
|
63
|
+
url = if @server
|
64
|
+
"#{@server}/#{zoom}/#{points.first}/#{points.second}.png"
|
65
|
+
else
|
66
|
+
"#{MAP_BOX_SERVER}/#{zoom}/#{points.first}/#{points.second}/?access_token=#{MAP_BOX_TOKEN}"
|
67
|
+
end
|
68
|
+
|
69
|
+
response = self.class.get(url)
|
70
|
+
IO.binwrite(file_name, response)
|
71
|
+
|
72
|
+
file_name
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Map::FileImportBasic
|
4
|
+
def polygons_rgeo
|
5
|
+
service = Map::RgeoService.new
|
6
|
+
coordinates.map { |coordinate| service.create_polygon(coordinate) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def point_more_south_west
|
10
|
+
[
|
11
|
+
all_longitudes.min,
|
12
|
+
all_latitudes.min
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
def point_more_north_east
|
17
|
+
[
|
18
|
+
all_longitudes.max,
|
19
|
+
all_latitudes.max
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def all_latitudes
|
24
|
+
@all_latitudes ||= coordinates.flatten.each_slice(2).map(&:second)
|
25
|
+
end
|
26
|
+
|
27
|
+
def all_longitudes
|
28
|
+
@all_longitudes ||= coordinates.flatten.each_slice(2).map(&:first)
|
29
|
+
end
|
30
|
+
end
|
data/lib/map/float.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Map::Gdal::Base
|
4
|
+
attr_reader :files_to_clean
|
5
|
+
|
6
|
+
# verifica se gdal está rodando
|
7
|
+
# checa 3 vezes fazendo um pequeno sleep entre as vezes para garantia
|
8
|
+
def gdal_running?(times = nil)
|
9
|
+
`ps aux | grep gdal | grep -v grep`
|
10
|
+
if $?.success?
|
11
|
+
true
|
12
|
+
elsif times.to_i < 3
|
13
|
+
sleep 0.1
|
14
|
+
gdal_running?(times.to_i + 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_layer_name
|
19
|
+
Map::Gdal::OgriInfoService.new(@file).layer_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def store_kml
|
23
|
+
@file = get_path_to_temp_file('kml', 'kml')
|
24
|
+
add_to_clean(@file)
|
25
|
+
IO.write(@file, @kml)
|
26
|
+
end
|
27
|
+
|
28
|
+
def clean
|
29
|
+
@files_to_clean.to_a.compact.each do |path|
|
30
|
+
FileUtils.rm_rf(path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_to_clean(path)
|
35
|
+
@files_to_clean ||= []
|
36
|
+
@files_to_clean << path
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_path_to_temp_file(prefix, extension, file_id="#{Time.current.to_i}-#{(rand * 1_000).to_i}")
|
40
|
+
tmp_file("#{prefix}-#{file_id}.#{extension}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def options_to_command_line(options, reject = [])
|
44
|
+
reject = [reject] unless reject.is_a?(Array)
|
45
|
+
|
46
|
+
options.map do |key, value|
|
47
|
+
"-#{key} #{value}" unless reject.to_a.include?(key)
|
48
|
+
end.compact.join(' ')
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_command(command)
|
52
|
+
out = `#{command} 2>&1`
|
53
|
+
raise "Falha ao rodar comando [$ #{command}]\n[#{out}]" unless $?.success?
|
54
|
+
out
|
55
|
+
end
|
56
|
+
|
57
|
+
def tmp_file(file_name)
|
58
|
+
FileUtils.mkdir_p(File.join(Dir.pwd, 'tmp'))
|
59
|
+
File.join(Dir.pwd, 'tmp', file_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_file_name_with_path(file)
|
63
|
+
file_name = File.basename(file, '.*' )
|
64
|
+
File.join(File.dirname(file), "#{file_name}")
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Map::Gdal::ColorizeService
|
4
|
+
include Map::Gdal::Base
|
5
|
+
|
6
|
+
REFERENCE_TABLE_COLOR_RED_TO_GREEN = [
|
7
|
+
'215,25,28,255',
|
8
|
+
'246,144,83,255',
|
9
|
+
'255,223,154,255',
|
10
|
+
'222,242,180,255',
|
11
|
+
'145,203,169,255',
|
12
|
+
'43,131,186,255'
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
def initialize(file)
|
16
|
+
@file = file
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(options = {})
|
20
|
+
color_table = options[:color_table]
|
21
|
+
color_table ||= File.join(Gem.loaded_specs['aqila-mapas'].full_gem_path, 'lib', 'map', 'gdal', 'table_colors.txt')
|
22
|
+
out = get_path_to_temp_file('color', 'tif')
|
23
|
+
|
24
|
+
color_table = generate_color_table(options[:inverse]) if color_table == :auto
|
25
|
+
|
26
|
+
run_command("gdaldem color-relief -alpha #{@file} #{color_table} #{out}")
|
27
|
+
|
28
|
+
add_to_clean(out)
|
29
|
+
out
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_color_table(inverse = false)
|
33
|
+
service_contrast = Map::Gdal::ConstrastStretchService.new(@file)
|
34
|
+
result_contrast = service_contrast.call
|
35
|
+
min = result_contrast[:min]
|
36
|
+
max = result_contrast[:max]
|
37
|
+
service_contrast.clean
|
38
|
+
|
39
|
+
intervalo = (max - min) / (REFERENCE_TABLE_COLOR_RED_TO_GREEN.length - 1)
|
40
|
+
temp_file = get_path_to_temp_file('table-color', 'txt')
|
41
|
+
add_to_clean(temp_file)
|
42
|
+
|
43
|
+
File.open(temp_file, 'a') do |file|
|
44
|
+
# Transparência (alpha) para zero
|
45
|
+
file.puts '0,255,255,255,0,0'
|
46
|
+
|
47
|
+
Array.new(REFERENCE_TABLE_COLOR_RED_TO_GREEN.length) do |index|
|
48
|
+
value = min + (intervalo * index)
|
49
|
+
file.puts line_color_table(value, inverse ? (REFERENCE_TABLE_COLOR_RED_TO_GREEN.length - 1 - index) : index)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
temp_file
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.format_color_table(color_table)
|
57
|
+
lines = IO.read(color_table)
|
58
|
+
.split("\n")
|
59
|
+
.reject{ |line| line.start_with?('#') }
|
60
|
+
|
61
|
+
formated = lines.map do |color_line|
|
62
|
+
splited = color_line.split(',').map(&:strip)
|
63
|
+
{
|
64
|
+
min: splited.first.to_f,
|
65
|
+
max: nil,
|
66
|
+
color_rgba: "#{splited.second},#{splited.third},#{splited.fourth},#{splited.fifth}"
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
formated.each_with_index.map do |item, index|
|
71
|
+
next_element = formated[index.next]
|
72
|
+
item[:max] = next_element[:min] if next_element
|
73
|
+
item
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def line_color_table(value, index)
|
80
|
+
"#{value},#{REFERENCE_TABLE_COLOR_RED_TO_GREEN[index]},#{value}"
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Map::Gdal::ConstrastStretchService
|
4
|
+
include Map::Gdal::Base
|
5
|
+
|
6
|
+
attr_reader :file
|
7
|
+
def initialize(file)
|
8
|
+
raise 'File does not exist' unless File.exist?(file)
|
9
|
+
@file = file
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(options = {})
|
13
|
+
file_out = get_path_to_temp_file(:gdal_contrast_stretch, :tif)
|
14
|
+
add_to_clean(file_out)
|
15
|
+
|
16
|
+
options['percentile-range'] = '0.02 0.98' if options.empty?
|
17
|
+
|
18
|
+
result = run_command(%{gdal_contrast_stretch #{options_to_command_line(options)} "#{file}" "#{file_out}"})
|
19
|
+
found_min_max = result.match(/src_range=\[(.+), (.+)\]/)
|
20
|
+
{
|
21
|
+
file: file_out,
|
22
|
+
min: found_min_max[1].to_f,
|
23
|
+
max: found_min_max[2].to_f,
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Map::Gdal::CropService
|
4
|
+
include Map::Gdal::Base
|
5
|
+
|
6
|
+
def initialize(tif)
|
7
|
+
@tif = tif
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(options = {})
|
11
|
+
raise 'Reference file is not defined' unless options[:reference]
|
12
|
+
shp_folder = File.join(Dir.tmpdir, "shp-#{(Time.current.to_i * rand).to_i}")
|
13
|
+
kml = get_path_to_temp_file('table-color', 'kml')
|
14
|
+
add_to_clean(shp_folder)
|
15
|
+
add_to_clean(kml)
|
16
|
+
|
17
|
+
IO.write(kml, Map::KmlEditService.new(options[:reference]).to_xml)
|
18
|
+
run_command(%{ogr2ogr -f "ESRI Shapefile" #{shp_folder} #{kml}})
|
19
|
+
service = Map::Gdal::WarpService.new(@tif)
|
20
|
+
options_to_warp = {
|
21
|
+
'-config': 'GDALWARP_IGNORE_BAD_CUTLINE YES',
|
22
|
+
crop_to_cutline: '',
|
23
|
+
cutline: shp_folder
|
24
|
+
}
|
25
|
+
|
26
|
+
options_to_warp[:dstalpha] = options[:dstalpha] if options[:dstalpha]
|
27
|
+
options_to_warp[:dstnodata] = options[:dstnodata] if options[:dstnodata]
|
28
|
+
options_to_warp[:s_srs] = options[:s_srs] if options[:s_srs]
|
29
|
+
options_to_warp[:tr] = options[:tr].gsub('-tr ', '') if options[:tr]
|
30
|
+
out = service.call(options_to_warp)
|
31
|
+
add_to_clean(out)
|
32
|
+
|
33
|
+
out
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Map::Gdal::GdalInfoService
|
4
|
+
include Map::Gdal::Base
|
5
|
+
|
6
|
+
attr_reader :file
|
7
|
+
def initialize(file)
|
8
|
+
raise 'File does not exist' unless File.exist?(file)
|
9
|
+
@file = file
|
10
|
+
end
|
11
|
+
|
12
|
+
def same_min_max?
|
13
|
+
json_info = get_json
|
14
|
+
min = json_info['bands'].first['computedMin'].to_f
|
15
|
+
max = json_info['bands'].first['computedMax'].to_f
|
16
|
+
|
17
|
+
min == max
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_json(options = {})
|
21
|
+
result = call(options.merge({
|
22
|
+
mm: '',
|
23
|
+
json: ''
|
24
|
+
}))
|
25
|
+
|
26
|
+
JSON.parse(result)
|
27
|
+
end
|
28
|
+
|
29
|
+
def call(options = {})
|
30
|
+
run_command(%{gdalinfo #{options_to_command_line(options)} "#{file}"})
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Map::Gdal::GridService
|
4
|
+
include Map::Gdal::Base
|
5
|
+
|
6
|
+
def initialize(kml)
|
7
|
+
@kml = kml
|
8
|
+
store_kml
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(options = {})
|
12
|
+
raise 'Invalid field' unless options[:field]
|
13
|
+
|
14
|
+
out = get_path_to_temp_file('out', 'kml')
|
15
|
+
where = options[:where] ? "-where \"#{options[:where]}\"" : ''
|
16
|
+
algorithm = options[:algorithm] ? "-a #{options[:algorithm]}" : ''
|
17
|
+
|
18
|
+
run_command(
|
19
|
+
%{
|
20
|
+
gdal_grid
|
21
|
+
-q
|
22
|
+
#{algorithm}
|
23
|
+
#{where}
|
24
|
+
-zfield "#{options[:field]}"
|
25
|
+
-of GTiff
|
26
|
+
-ot Float64
|
27
|
+
-l "#{get_layer_name}"
|
28
|
+
#{@file}
|
29
|
+
#{out}
|
30
|
+
}.squish
|
31
|
+
)
|
32
|
+
|
33
|
+
add_to_clean(out)
|
34
|
+
out
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Map::Gdal::MergeService
|
4
|
+
include Map::Gdal::Base
|
5
|
+
|
6
|
+
def initialize(files)
|
7
|
+
raise 'Files is not an array' unless files.is_a?(Array)
|
8
|
+
@files = files
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(options = [])
|
12
|
+
files = @files.select{ |file| file.downcase[/(.jp2|.tif)$/, 1].present? }.join(' ')
|
13
|
+
out = get_path_to_temp_file('merge', 'tif')
|
14
|
+
|
15
|
+
run_command("gdal_merge.py #{options.join(' ')} #{files} -o #{out}")
|
16
|
+
|
17
|
+
add_to_clean(out)
|
18
|
+
add_to_clean(out.gsub('tif', 'tfw'))
|
19
|
+
|
20
|
+
out
|
21
|
+
end
|
22
|
+
end
|