Skip to content

Commit

Permalink
Use orginfo json formatted output
Browse files Browse the repository at this point in the history
  • Loading branch information
eliotjordan committed Oct 3, 2024
1 parent 39f0ff0 commit 4ef1b25
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 61 deletions.
35 changes: 20 additions & 15 deletions app/derivative_services/geo_derivatives/processors/vector/info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ module GeoDerivatives
module Processors
module Vector
class Info
attr_accessor :doc
attr_accessor :path
attr_writer :name, :driver

def initialize(path)
@doc = ogrinfo(path)
@path = path
end

# Parsed json out from ogrinfo
# @return [Hash]
def doc
@doc ||= begin
JSON.parse(ogrinfo(path))
rescue
{}
end
end

# Returns the vector dataset name
Expand Down Expand Up @@ -40,7 +50,7 @@ def bounds
# @param path [String] path to vector file or shapefile directory
# @return [String] output of ogrinfo
def ogrinfo(path)
stdout, stderr, status = Open3.capture3("ogrinfo", "-ro", "-so", "-al", path.to_s)
stdout, stderr, status = Open3.capture3("ogrinfo", "-json", "-ro", "-so", "-al", path.to_s)
raise(GeoDerivatives::OgrError, stderr) unless status.success?
stdout
end
Expand All @@ -49,27 +59,25 @@ def ogrinfo(path)
# the vector dataset name.
# @return [String] vector dataset name
def vector_name
match = /(?<=Layer name:\s).*?(?=\n)/.match(doc)
match ? match[0] : ""
doc.dig("layers", 0, "name") || ""
end

# Given an output string from the ogrinfo command, returns
# the ogr driver used to read dataset.
# @return [String] ogr driver name
def driver_name
match = /(?<=driver\s`).*?(?=')/.match(doc)
match ? match[0] : ""
doc.fetch("driverShortName", "")
end

# Given an output string from the ogrinfo command, returns
# the vector geometry type.
# @return [String] vector geom
def vector_geom
match = /(?<=Geometry:\s).*?(?=\n)/.match(doc)
geom = match ? match[0] : ""
geom = doc.dig("layers", 0, "geometryFields", 0, "type") || ""

# Transform OGR-style 'Line String' into GeoJSON 'Line'
# Transform OGR-style '3D Multi Polygon' into GeoJSON 'Polygon'
if geom == "Line String"
if geom == "LineString"
geom = "Line"
elsif geom == "3D Multi Polygon"
geom = "Polygon"
Expand All @@ -82,12 +90,9 @@ def vector_geom
# the vector bounding box.
# @return [Hash] vector bounds
def vector_bounds
match = /(?<=Extent:\s).*?(?=\n)/.match(doc)
extent = match ? match[0] : ""
extent = doc.dig("layers", 0, "geometryFields", 0, "extent").map { |c| c.truncate(6) }

# remove parens and spaces, split into array, and assign elements to variables
w, s, e, n = extent.delete(" ").gsub(")-(", ",").delete("(").delete(")").split(",")
{ north: n.to_f, east: e.to_f, south: s.to_f, west: w.to_f }
{ north: extent[3].to_f, east: extent[2].to_f, south: extent[1].to_f, west: extent[0].to_f }
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
file_set = valid_file_set
new_file_set = described_class.new(file_set: file_set, persister: persister).characterize(save: false)
expect(new_file_set.original_file.mime_type).to eq ["application/vnd.geo+json"]
expect(new_file_set.original_file.geometry).to eq ["Multi Polygon"]
expect(new_file_set.original_file.geometry).to eq ["MultiPolygon"]
end
end

Expand All @@ -36,7 +36,7 @@
file_set = valid_file_set
new_file_set = described_class.new(file_set: file_set, persister: persister).characterize(save: false)
expect(new_file_set.original_file.mime_type).to eq ["application/vnd.geo+json"]
expect(new_file_set.original_file.geometry).to eq ["Multi Polygon"]
expect(new_file_set.original_file.geometry).to eq ["MultiPolygon"]
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

RSpec.describe GeoDerivatives::Processors::Vector::Info do
let(:processor) { described_class.new(path) }
let(:path) { "test.tif" }
let(:polygon_info_doc) { file_fixture("files/gdal/ogrinfo_polygon.txt").read }
let(:line_info_doc) { file_fixture("files/gdal/ogrinfo_line.txt").read }
let(:path) { "test.geojson" }
let(:polygon_info_doc) { file_fixture("files/gdal/ogrinfo_polygon.json").read }
let(:line_info_doc) { file_fixture("files/gdal/ogrinfo_line.json").read }
let(:status) { double(success?: true) }

before do
Expand All @@ -15,14 +15,14 @@

context "when initializing a new info class" do
it "shells out to ogrinfo and sets the doc variable to the output string" do
expect(processor.doc).to eq(polygon_info_doc)
expect(Open3).to have_received(:capture3).with("ogrinfo", "-ro", "-so", "-al", path.to_s)
expect(processor.doc).to eq(JSON.parse(polygon_info_doc))
expect(Open3).to have_received(:capture3).with("ogrinfo", "-json", "-ro", "-so", "-al", path.to_s)
end
end

context "with a polygon vector" do
before do
allow(processor).to receive(:doc).and_return(polygon_info_doc)
allow(Open3).to receive(:capture3).and_return([polygon_info_doc, "", status])
end

describe "#name" do
Expand All @@ -46,7 +46,7 @@
describe "#bounds" do
it "returns bounds hash" do
expect(processor.bounds).to eq(north: 42.408249,
east: -71.052853,
east: -71.052852,
south: 42.347654,
west: -71.163867)
end
Expand All @@ -55,7 +55,7 @@

context "with a line vector" do
before do
allow(processor).to receive(:doc).and_return(line_info_doc)
allow(Open3).to receive(:capture3).and_return([line_info_doc, "", status])
end

describe "#geom" do
Expand Down
Loading

0 comments on commit 4ef1b25

Please sign in to comment.