# frozen_string_literal: true
require 'spec_helper'
require 'ogr/geometry'
RSpec.describe OGR::Geometry do
describe '.create_from_wkt' do
subject { OGR::Geometry.create_from_wkt(wkt) }
context 'a 2D Point' do
let(:wkt) { 'POINT(1 32)' }
it { is_expected.to be_a OGR::Point }
end
context 'a 2.5D Point' do
let(:wkt) { 'POINT(1 32 100)' }
it { is_expected.to be_a OGR::Point25D }
end
context 'a 2D LineString' do
let(:wkt) { 'LINESTRING(3 19,12 20)' }
it { is_expected.to be_a OGR::LineString }
end
context 'a 2.5D LineString' do
let(:wkt) { 'LINESTRING(3 4 19,12 23 20)' }
it { is_expected.to be_a OGR::LineString25D }
end
context 'a 2D Polygon' do
let(:wkt) { 'POLYGON((1 1,2 2,3 3))' }
it { is_expected.to be_a OGR::Polygon }
end
context 'a 2.5D Polygon' do
let(:wkt) { 'POLYGON((1 1 1,2 2 2,3 3 3))' }
it { is_expected.to be_a OGR::Polygon25D }
end
context 'a 2D MultiPoint' do
let(:wkt) { 'MULTIPOINT((1 1),(2 2))' }
it { is_expected.to be_a OGR::MultiPoint }
end
context 'a 2.5D MultiPoint' do
let(:wkt) { 'MULTIPOINT((1 1 1),(2 2 2))' }
it { is_expected.to be_a OGR::MultiPoint25D }
end
context 'a 2D MultiLineString' do
let(:wkt) { 'MULTILINESTRING((3 4),(100 20))' }
it { is_expected.to be_a OGR::MultiLineString }
end
context 'a 2.5D MultiLineString' do
let(:wkt) { 'MULTILINESTRING((3 4 19),(100 20 40))' }
it { is_expected.to be_a OGR::MultiLineString25D }
end
context 'a 2D MultiPolygon' do
let(:wkt) do
'MULTIPOLYGON(((1 1,2 2,3 3)),((100 100, 20 20, 30 30)))'
end
it { is_expected.to be_a OGR::MultiPolygon }
end
context 'a 2.5D MultiPolygon' do
let(:wkt) do
'MULTIPOLYGON(((1 1 1,2 2 2,3 3 3)),((100 100 100, 20 20 20, 30 30 30)))'
end
it { is_expected.to be_a OGR::MultiPolygon25D }
end
end
describe '.create_from_json' do
subject { OGR::Geometry.create_from_json(json) }
context 'a 2D Point' do
let(:json) do
{ type: :Point, coordinates: [1.0, 7.0] }.to_json
end
it { is_expected.to be_a OGR::Point }
end
context 'a 2.5D Point' do
let(:json) do
{ type: :Point, coordinates: [1.0, 2.0, 3.0] }.to_json
end
it { is_expected.to be_a OGR::Point25D }
end
context 'a 2D LineString' do
let(:json) do
{
type: :LineString,
coordinates: [
[3.0, 4.0], [20.0, 30.0]
]
}.to_json
end
it { is_expected.to be_a OGR::LineString }
end
context 'a 2.5D LineString' do
let(:json) do
{
type: :LineString,
coordinates: [
[3.0, 4.0, 19.0], [20.0, 30.0, 45.0]
]
}.to_json
end
it { is_expected.to be_a OGR::LineString25D }
end
context 'a 2D Polygon' do
let(:json) do
{
type: :Polygon,
coordinates: [
[
[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 5.0], [1.0, 1.0]
]
]
}.to_json
end
it { is_expected.to be_a OGR::Polygon }
end
context 'a 2.5D Polygon' do
let(:json) do
{
type: :Polygon,
coordinates: [
[
[1.0, 1.0, 1.0], [5.0, 1.0, 1.0], [5.0, 5.0, 1.0], [1.0, 5.0, 1.0], [1.0, 1.0]
]
]
}.to_json
end
it { is_expected.to be_a OGR::Polygon25D }
end
context 'a 2D MultiPoint' do
let(:json) do
{
type: :MultiPoint,
coordinates: [
[1.0, 1.0], [2.0, 2.0], [2.0, 1.0], [1.0, 1.0]
]
}.to_json
end
it { is_expected.to be_a OGR::MultiPoint }
end
context 'a 2.5D MultiPoint' do
let(:json) do
{
type: :MultiPoint,
coordinates: [
[1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [2.0, 1.0, 2.0], [1.0, 1.0, 1.0]
]
}.to_json
end
it { is_expected.to be_a OGR::MultiPoint25D }
end
context 'a 2D MultiLineString' do
let(:json) do
{
type: :MultiLineString,
coordinates: [
[
[3.0, 4.0], [21.0, 27.0], [2.0, 5.0]
], [
[100.0, 20.0], [982.0, 6.0]
]
]
}.to_json
end
it { is_expected.to be_a OGR::MultiLineString }
end
context 'a 2.5D MultiLineString' do
let(:json) do
{
type: :MultiLineString,
coordinates: [
[
[3.0, 4.0, 19.0], [21.0, 27.0, 30.0]
], [
[100.0, 20.0, 400.0], [92.0, 6.0, 47.1]
]
]
}.to_json
end
it { is_expected.to be_a OGR::MultiLineString25D }
end
context 'a 2D MultiPolygon' do
let(:json) do
{
type: :MultiPolygon,
coordinates: [
[
[
[1.0, 1.0], [2.0, 2.0], [3.0, 3.0]
], [
[11.0, 11.0], [10.0, 10.0], [9.0, 9.0]
]
], [
[
[100.0, 100.0], [20.0, 20.0], [30.0, 30.0]
], [
[10.0, 10.0], [20.0, 20.0], [30.0, 30.0]
]
]
]
}.to_json
end
it { is_expected.to be_a OGR::MultiPolygon }
end
context 'a 2.5D MultiPolygon' do
let(:json) do
{
type: :MultiPolygon,
coordinates: [
[
[
[1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 3.0, 3.0]
], [
[11.0, 11.0, 11.0], [10.0, 10.0, 10.0], [9.0, 9.0, 9.0]
]
], [
[
[100.0, 100.0, 100.0], [20.0, 20.0, 20.0], [30.0, 30.0, 30.0]
], [
[10.0, 10.0, 10.0], [20.0, 20.0, 20.0], [30.0, 30.0, 30.0]
]
]
]
}.to_json
end
it { is_expected.to be_a OGR::MultiPolygon25D }
end
end
describe '.create_from_gml' do
subject { OGR::Geometry.create_from_gml(gml) }
context 'a 2D Point' do
let(:gml) do
'1,7'
end
it { is_expected.to be_a OGR::Point }
end
context 'a 2.5D Point' do
let(:gml) do
'1,7,25'
end
it { is_expected.to be_a OGR::Point25D }
end
context 'a 2D LineString' do
let(:gml) do
'3,4'
end
it { is_expected.to be_a OGR::LineString }
end
context 'a 2.5D LineString' do
let(:gml) do
'3,4,19'
end
it { is_expected.to be_a OGR::LineString25D }
end
context 'a 2D Polygon' do
let(:gml) do
<<-GML
1,1 5,1 5,5 1,5 1,1
GML
end
it { is_expected.to be_a OGR::Polygon }
end
context 'a 2.5D Polygon' do
let(:gml) do
<<-GML
1,1,3 5,1,3 5,5,3 1,5,3 1,1,3
GML
end
it { is_expected.to be_a OGR::Polygon25D }
end
context 'a 2D MultiPoint' do
let(:gml) do
<<-GML
1,1
2,2
2,1
1,1
GML
end
it { is_expected.to be_a OGR::MultiPoint }
end
context 'a 2.5D MultiPoint' do
let(:gml) do
<<-GML
1,1,3
2,2,3
2,1,3
1,1,3
GML
end
it { is_expected.to be_a OGR::MultiPoint25D }
end
context 'a 2D MultiLineString' do
let(:gml) do
<<-GML
3,4
100,20
GML
end
it { is_expected.to be_a OGR::MultiLineString }
end
context 'a 2.5D MultiLineString' do
let(:gml) do
<<-GML
3,4,19
100,20,40
GML
end
it { is_expected.to be_a OGR::MultiLineString25D }
end
context 'a 2D MultiPolygon' do
let(:gml) do
<<-GML
1,1 2,2 3,3
100,100 20,20 30,30
GML
end
it { is_expected.to be_a OGR::MultiPolygon }
end
context 'a 2.5D MultiPolygon' do
let(:gml) do
<<-GML
1,1,9 2,2,9 3,3,9
100,100,9 20,20,9 30,30,9
GML
end
it { is_expected.to be_a OGR::MultiPolygon25D }
end
end
describe '.create_from_wkb' do
subject { OGR::Geometry.create_from_wkb(wkb) }
context 'a 2D Point' do
# POINT(1 32)
let(:wkb) { ['0101000000000000000000f03f0000000000004040'].pack('H*') }
it { is_expected.to be_a OGR::Point }
end
context 'a 2.5D Point' do
# POINT(1 32 100)
let(:wkb) { ['01e9030000000000000000f03f00000000000040400000000000005940'].pack('H*') }
it { is_expected.to be_a OGR::Point }
end
context 'a 2D LineString' do
# LINESTRING(3 19,12 20)
let(:wkb) do
['0102000000020000000000000000000840000000000000334000000000000028400000000000003440'].pack('H*')
end
it { is_expected.to be_a OGR::LineString }
end
context 'a 2.5D LineString' do
# LINESTRING(3 4 19,12 13 20)
let(:wkb) do
hex = '01ea030000020000000000000000000840000000000000104000000000000' \
'03340000000000000284000000000000037400000000000003440'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::LineString25D }
end
context 'a 2D Polygon' do
# 'POLYGON((1 1,2 1,3 0,1 1))'
let(:wkb) do
hex = '01030000000100000004000000000000000000f03f000000000000f03f0000' \
'000000000040000000000000f03f00000000000008400000000000000000000000' \
'000000f03f000000000000f03f'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::Polygon }
end
context 'a 2.5D Polygon' do
let(:wkb) do
# 'POLYGON((1 1 1,2 1 1,2 0 1,1 1 1))'
hex = '01eb0300000100000004000000000000000000f03f000000000000f03f0000' \
'00000000f03f0000000000000040000000000000f03f000000000000f03f000000' \
'00000000400000000000000000000000000000f03f000000000000f03f00000000' \
'0000f03f000000000000f03f'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::Polygon25D }
end
context 'a 2D MultiPoint' do
let(:wkb) do
# 'MULTIPOINT((0 0),(1 1))'
hex = '01040000000200000001010000000000000000000000000000000000000001' \
'01000000000000000000f03f000000000000f03f'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::MultiPoint }
end
context 'a 2.5D MultiPoint' do
let(:wkb) do
# 'MULTIPOINT((0 0 0),(1 1 1))'
hex = '01ec0300000200000001e90300000000000000000000000000000000000000' \
'0000000000000001e9030000000000000000f03f000000000000f03f0000000000' \
'00f03f'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::MultiPoint25D }
end
context 'a 2D MultiLineString' do
let(:wkb) do
# 'MULTILINESTRING((1 1,2 2, 3 3),(10 10,20 20,30 30))'
hex = '010500000002000000010200000003000000000000000000f03f0000000000' \
'00f03f000000000000004000000000000000400000000000000840000000000000' \
'084001020000000300000000000000000024400000000000002440000000000000' \
'344000000000000034400000000000003e400000000000003e40'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::MultiLineString }
end
context 'a 2.5D MultiLineString' do
let(:wkb) do
# MULTILINESTRING((3 4 19,100 20 40),(5 5 5,6 6 6,7 7 7))
hex = '01ed0300000200000001ea0300000200000000000000000008400000000000' \
'001040000000000000334000000000000059400000000000003440000000000000' \
'444001ea0300000300000000000000000014400000000000001440000000000000' \
'14400000000000001840000000000000184000000000000018400000000000001c' \
'400000000000001c400000000000001c40'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::MultiLineString25D }
end
context 'a 2D MultiPolygon' do
# 'MULTIPOLYGON(((1 1,2 1,2 0,1 1)),((100 100,20 20,30 30,100 100)))'
let(:wkb) do
hex = '01060000000200000001030000000100000004000000000000000000f03f00' \
'0000000000f03f0000000000000040000000000000f03f00000000000000400000' \
'000000000000000000000000f03f000000000000f03f0103000000010000000400' \
'000000000000000059400000000000005940000000000000344000000000000034' \
'400000000000003e400000000000003e4000000000000059400000000000005940'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::MultiPolygon }
end
context 'a 2.5D MultiPolygon' do
# 'MULTIPOLYGON(((1 1 1,2 1 2,2 0 3,1 1 1)),((100 100 100,20 20 20,30 30 30,100 100 100)))'
let(:wkb) do
hex = '01ee0300000200000001eb0300000100000004000000000000000000f03f00' \
'0000000000f03f000000000000f03f0000000000000040000000000000f03f0000' \
'000000000040000000000000004000000000000000000000000000000840000000' \
'000000f03f000000000000f03f000000000000f03f01eb03000001000000040000' \
'000000000000005940000000000000594000000000000059400000000000003440' \
'000000000000344000000000000034400000000000003e400000000000003e4000' \
'00000000003e40000000000000594000000000000059400000000000005940'
[hex].pack('H*')
end
it { is_expected.to be_a OGR::MultiPolygon25D }
end
end
describe '.type_to_name' do
context 'wkbUnknown' do
subject { described_class.type_to_name(:wkbUnknown) }
it { is_expected.to eq 'Unknown (any)' }
end
context 'wkbPoint' do
subject { described_class.type_to_name(:wkbPoint) }
it { is_expected.to eq 'Point' }
end
context 'wkbLineString' do
subject { described_class.type_to_name(:wkbLineString) }
it { is_expected.to eq 'Line String' }
end
context 'wkbPolygon' do
subject { described_class.type_to_name(:wkbPolygon) }
it { is_expected.to eq 'Polygon' }
end
context 'wkbMultiPoint' do
subject { described_class.type_to_name(:wkbMultiPoint) }
it { is_expected.to eq 'Multi Point' }
end
context 'wkbMultiLineString' do
subject { described_class.type_to_name(:wkbMultiLineString) }
it { is_expected.to eq 'Multi Line String' }
end
context 'wkbMultiPolygon' do
subject { described_class.type_to_name(:wkbMultiPolygon) }
it { is_expected.to eq 'Multi Polygon' }
end
context 'wkbGeometryCollection' do
subject { described_class.type_to_name(:wkbGeometryCollection) }
it { is_expected.to eq 'Geometry Collection' }
end
context 'wkbNone' do
subject { described_class.type_to_name(:wkbNone) }
it { is_expected.to eq 'None' }
end
context 'wkbLinearRing' do
subject { described_class.type_to_name(:wkbLinearRing) }
# Per GDAL docs, LinearRing is only used for geometry creation.
it { is_expected.to eq 'Unrecognized: 101' }
end
end
describe '#utm_zone' do
let(:geom) { OGR::Geometry.create_from_wkt(wkt) }
let(:wkt) do
'LINESTRING(100 100, 20 20, 30 30, 100 100)'
end
context 'no spatial_reference' do
subject { geom.utm_zone }
it { is_expected.to be_nil }
end
context 'SRID is 4326' do
subject { geom.utm_zone }
before { geom.spatial_reference = OGR::SpatialReference.new_from_epsg(4326) }
it { is_expected.to eq(36) }
end
context 'SRID is not 4326' do
before { geom.spatial_reference = OGR::SpatialReference.new_from_epsg(3857) }
it 'transforms to 4326 then figures out the zone' do
duped_subject = geom.dup
expect(geom).to receive(:dup).and_return(duped_subject)
expect(duped_subject).to receive(:transform_to!).and_call_original
geom.utm_zone
end
end
end
end