gdal/autotest/ogr/ogr_geom.py

4099 строки
145 KiB
Python
Исполняемый файл

#!/usr/bin/env pytest
# -*- coding: utf-8 -*-
###############################################################################
# $Id$
#
# Project: GDAL/OGR Test Suite
# Purpose: Test Misc. OGRGeometry operations.
# Author: Frank Warmerdam <warmerdam@pobox.com>
#
###############################################################################
# Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
# Copyright (c) 2008-2014, Even Rouault <even dot rouault at spatialys.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
###############################################################################
import copy
import math
import pickle
import random
import gdaltest
import ogrtest
import pytest
from osgeo import gdal, ogr, osr
###############################################################################
@pytest.fixture(autouse=True, scope="module")
def module_disable_exceptions():
with gdaltest.disable_exceptions():
yield
###############################################################################
# Test Area calculation for a MultiPolygon (which exercises lower level
# get_Area() methods as well).
def test_ogr_geom_area():
geom_wkt = "MULTIPOLYGON( ((0 0,1 1,1 0,0 0)),((0 0,10 0, 10 10, 0 10),(1 1,1 2,2 2,2 1)) )"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
area = geom.GetArea()
assert area == pytest.approx(99.5, abs=0.00000000001), (
"GetArea() result wrong, got %g." % area
)
# OGR >= 1.8.0
area = geom.Area()
assert area == pytest.approx(99.5, abs=0.00000000001), (
"Area() result wrong, got %g." % area
)
###############################################################################
# Test Area calculation for a LinearRing (which exercises special case of
# getGeometryType value).
def test_ogr_geom_area_linearring():
geom = ogr.Geometry(type=ogr.wkbLinearRing)
geom.AddPoint_2D(0, 0)
geom.AddPoint_2D(10, 0)
geom.AddPoint_2D(10, 10)
geom.AddPoint_2D(0, 10)
geom.AddPoint_2D(0, 0)
area = geom.GetArea()
assert area == pytest.approx(100.0, abs=0.00000000001), (
"Area result wrong, got %g." % area
)
###############################################################################
# Test Area calculation for a GeometryCollection
def test_ogr_geom_area_geometrycollection():
# OGR >= 1.8.0
geom_wkt = "GEOMETRYCOLLECTION( POLYGON((0 0,1 1,1 0,0 0)), MULTIPOLYGON(((0 0,1 1,1 0,0 0))), LINESTRING(0 0,1 1), POINT(0 0), GEOMETRYCOLLECTION EMPTY )"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
area = geom.Area()
assert area == pytest.approx(1, abs=0.00000000001), (
"Area() result wrong, got %g." % area
)
###############################################################################
# Test Area calculation for a LinearRing whose coordinates are shifted by a
# huge value With algorithm prior to #3556, this would return 0.
def test_ogr_geom_area_linearring_big_offset():
geom = ogr.Geometry(type=ogr.wkbLinearRing)
BIGOFFSET = 1.0e11
geom.AddPoint_2D(BIGOFFSET + 0, BIGOFFSET + 0)
geom.AddPoint_2D(BIGOFFSET + 10, BIGOFFSET + 0)
geom.AddPoint_2D(BIGOFFSET + 10, BIGOFFSET + 10)
geom.AddPoint_2D(BIGOFFSET + 0, BIGOFFSET + 10)
geom.AddPoint_2D(BIGOFFSET + 0, BIGOFFSET + 0)
area = geom.GetArea()
assert area == pytest.approx(100.0, abs=0.00000000001), (
"Area result wrong, got %g." % area
)
###############################################################################
# Test Area calculation for a Triangle
def test_ogr_geom_area_triangle():
geom_wkt = "TRIANGLE((0 0,100 0,0 100,0 0))"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
area = geom.GetArea()
assert area != pytest.approx(4999.5, abs=0.00000000001), (
"GetArea() result wrong, got %g." % area
)
# OGR >= 1.8.0
area = geom.Area()
assert area != pytest.approx(4999.5, abs=0.00000000001), (
"Area() result wrong, got %g." % area
)
def test_ogr_geom_is_empty():
geom_wkt = "LINESTRING EMPTY"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom.IsEmpty(), "IsEmpty returning false for an empty geometry"
geom_wkt = "POINT( 1 2 )"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom, "A geometry could not be created from wkt: %s" % geom_wkt
assert not geom.IsEmpty(), "IsEmpty returning true for a non-empty geometry"
###############################################################################
# Test if a Triangle is Empty
def test_ogr_geom_is_empty_triangle():
geom_wkt = "TRIANGLE EMPTY"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom.IsEmpty(), "IsEmpty returning false for an empty geometry"
geom = ogr.CreateGeometryFromWkb(geom.ExportToWkb())
assert geom.IsEmpty(), "IsEmpty returning false for an empty geometry"
geom_wkt = "TRIANGLE((0 0,100 0,0 100,0 0))"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom, "A geometry could not be created from wkt: %s" % geom_wkt
assert not geom.IsEmpty(), "IsEmpty returning true for a non-empty geometry"
def test_ogr_geom_pickle():
geom_wkt = "MULTIPOLYGON( ((0 0,1 1,1 0,0 0)),((0 0,10 0, 10 10, 0 10),(1 1,1 2,2 2,2 1)) )"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
p = pickle.dumps(geom)
with gdaltest.error_handler():
g = pickle.loads(p)
assert geom.Equal(g), "pickled geometries were not equal"
###############################################################################
# Test suite for PolyhedralSurface
def test_ogr_geom_polyhedral_surface():
wkt_original = "POLYHEDRALSURFACE Z (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),\
((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),\
((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),\
((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),\
((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),\
((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)))"
ps = ogr.CreateGeometryFromWkt(wkt_original)
wkb_string = ps.ExportToWkb(ogr.wkbXDR)
geom = ogr.CreateGeometryFromWkb(wkb_string)
wkt_string = geom.ExportToWkt()
assert wkt_string == wkt_original, "Failure in Wkb methods of PolyhedralSurface"
wkt_string = geom.Clone().ExportToWkt()
assert wkt_string == wkt_original, "Failure in Clone()"
polygon_wkt = ogr.ForceTo(geom.Clone(), ogr.wkbPolygon).ExportToWkt()
assert polygon_wkt == wkt_original
polygon_wkt = ogr.ForceTo(geom.Clone(), ogr.wkbMultiPolygon).ExportToWkt()
assert (
polygon_wkt
== "MULTIPOLYGON (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)))"
)
if ogrtest.have_sfcgal():
area = ps.Area()
assert area == 6.0, "Wrong area of PolyhedralSurface"
size = ps.WkbSize()
assert size == 807, "Wrong WkbSize() of PolyhedralSurface"
# if ogrtest.have_sfcgal():
# geom = ps.DelaunayTriangulation(0.0,True)
# wkt_geom_dt = 'MULTILINESTRING ((0 1 0,1 1 0),(0 0 0,0 1 0),(0 0 0,1 0 0),(1 0 0,1 1 0),(0 1 0,1 0 0))'
# wkt_geom = geom.ExportToWkt()
# if wkt_geom != wkt_geom_dt:
# gdaltest.post_reason ("Failure in DelaunayTriangulation() of PolyhedralSurface")
# print(wkt_geom)
# return 'fail'
if ogrtest.have_geos() or ogrtest.have_sfcgal():
geom = ogr.CreateGeometryFromWkb(wkb_string)
assert ps.Contains(geom), "Failure in Contains() of PolyhedralSurface"
assert not ps.IsEmpty(), "Failure in IsEmpty() of PolyhedralSurface"
ps.Empty()
wkt_string = ps.ExportToWkt()
assert (
wkt_string == "POLYHEDRALSURFACE Z EMPTY"
), "Failure in Empty() of PolyhedralSurface"
g = ogr.CreateGeometryFromWkt(
"POLYHEDRALSURFACE (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)))"
)
assert g.Equals(g) != 0
for wkt in [
"MULTIPOLYGON (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)))",
"POLYHEDRALSURFACE (((0 0 0,0 0 1,0 1 1,0 0 0)))",
"POLYHEDRALSURFACE (((0 0 0,0 0 1,0 1 1,0 0 0)),((0 0 0,0 0 1,0 1 1,0 0 0)))",
"POLYHEDRALSURFACE EMPTY",
]:
g2 = ogr.CreateGeometryFromWkt(wkt)
if g.Equals(g2):
print(wkt)
pytest.fail("Unexpected true Equals() return")
# Error
assert g.AddGeometry(ogr.CreateGeometryFromWkt("POINT (0 0)")) != 0
# Error
assert g.AddGeometryDirectly(ogr.CreateGeometryFromWkt("POINT (0 0)")) != 0
# Test dimension promotion
g = ogr.CreateGeometryFromWkt("POLYHEDRALSURFACE EMPTY")
g.AddGeometryDirectly(
ogr.CreateGeometryFromWkt("POLYGON ZM ((0 0 1 2,0 1 1 2,1 1 1 2,0 0 1 2))")
)
g.AddGeometryDirectly(
ogr.CreateGeometryFromWkt("POLYGON ((10 10,10 11,11 11,10 10))")
)
wkt = g.ExportToIsoWkt()
assert (
wkt
== "POLYHEDRALSURFACE ZM (((0 0 1 2,0 1 1 2,1 1 1 2,0 0 1 2)),((10 10 0 0,10 11 0 0,11 11 0 0,10 10 0 0)))"
)
###############################################################################
# Test suite for TIN
def test_ogr_geom_tin():
poly1 = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0 0,0 0 1,0 1 0,0 0 0))")
poly2 = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0 0,0 1 0,1 1 0,0 0 0))")
tin = ogr.Geometry(ogr.wkbTIN)
tin.AddGeometry(poly1)
tin.AddGeometry(poly2)
polygon_wkt = [poly1.ExportToWkt(), poly2.ExportToWkt()]
for i in range(0, tin.GetGeometryCount()):
geom = tin.GetGeometryRef(i)
wkt_geom = geom.ExportToWkt()
assert polygon_wkt[i] == wkt_geom, "Failure in getting geometries of TIN"
wkt_original = "TIN Z (((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,0 0 0)))"
tin = ogr.CreateGeometryFromWkt(wkt_original)
wkb_string = tin.ExportToWkb(ogr.wkbXDR)
geom = ogr.CreateGeometryFromWkb(wkb_string)
wkt_string = geom.ExportToWkt()
assert wkt_string == wkt_original, "Failure in Wkb methods of TIN"
wkt_string = geom.Clone().ExportToWkt()
assert wkt_string == wkt_original, "Failure in Clone()"
if ogrtest.have_sfcgal():
area = 12.3 * tin.Area()
assert area == 12.3, "Wrong area of TIN"
size = tin.WkbSize()
assert size == 227, "Wrong WkbSize() of TIN"
# geom = tin.DelaunayTriangulation(0.0,True)
# wkt_geom_dt = 'MULTILINESTRING ((0 1 0,1 1 0),(0 0 0,0 1 0),(0 0 0,1 1 0))'
# wkt_geom = geom.ExportToWkt()
# if wkt_geom != wkt_geom_dt:
# gdaltest.post_reason ("Failure in DelaunayTriangulation() of TIN")
# print(wkt_geom)
# return 'fail'
# geom = ogr.CreateGeometryFromWkb(wkb_string)
# if tin.Contains(geom) != True:
# gdaltest.post_reason ("Failure in Contains() of TIN")
# return 'fail'
assert not tin.IsEmpty(), "Failure in IsEmpty() of TIN"
tin.Empty()
wkt_string = tin.ExportToWkt()
assert wkt_string == "TIN Z EMPTY", "Failure in Empty() of TIN"
wrong_polygon = ogr.CreateGeometryFromWkt("POLYGON ((0 0 0,0 1 0,1 1 0,0 0 1))")
geom_count = tin.GetGeometryCount()
with gdaltest.error_handler():
x = tin.AddGeometry(wrong_polygon)
assert (
tin.GetGeometryCount() == geom_count
), "Added wrong geometry in TIN, error has code " + str(x)
if ogrtest.have_geos() or ogrtest.have_sfcgal():
point = tin.PointOnSurface()
point_wkt = point.ExportToWkt()
point_correct_wkt = "POINT EMPTY"
assert (
point_wkt == point_correct_wkt
), "Wrong Point Obtained for PointOnSurface() in TIN"
tin = ogr.CreateGeometryFromWkt(wkt_original)
# point = tin.PointOnSurface()
# point_wkt = point.ExportToWkt()
# point_correct_wkt = 'POINT (0.25 0.5)'
# if point_wkt != point_correct_wkt:
# gdaltest.post_reason ("Wrong Point Obtained for PointOnSurface() in TIN")
# print(point_wkt)
# return 'fail'
tin.FlattenTo2D()
assert not tin.IsValid(), "Problem with IsValid() in TIN"
# 4 points
invalid_wkt = "TIN (((0 0,0 1,1 1,1 0,0 0)))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(invalid_wkt)
assert g is None
# hole
invalid_wkt = "TIN(((0 0,0 1,1 1,0 0),(0.1 0.1,0.1 0.2,0.2 0.2,0.1 0.1)))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(invalid_wkt)
assert g is None
invalid_wkt = "TIN (POLYGON((0 0,0 1,1 1,0 0)))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(invalid_wkt)
assert g is None
# Add a POLYGON that can be cast as a TRIANGLE
g = ogr.Geometry(ogr.wkbTIN)
assert g.AddGeometry(ogr.CreateGeometryFromWkt("POLYGON ((0 0,0 1,1 1,0 0))")) == 0
assert g.ExportToIsoWkt() == "TIN (((0 0,0 1,1 1,0 0)))"
###############################################################################
# Test OGRGeometry::getBoundary() result for point.
@pytest.mark.require_geos
def test_ogr_geom_boundary_point():
geom_wkt = "POINT(1 1)"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
bnd = geom.GetBoundary()
assert (
bnd.GetGeometryType() == ogr.wkbGeometryCollection
), "GetBoundary not reported as GEOMETRYCOLLECTION EMPTY"
bnd = geom.Boundary()
assert (
bnd.GetGeometryType() == ogr.wkbGeometryCollection
), "Boundary not reported as GEOMETRYCOLLECTION EMPTY"
###############################################################################
# Test OGRGeometry::getBoundary() result for multipoint.
@pytest.mark.require_geos
def test_ogr_geom_boundary_multipoint():
geom_wkt = "MULTIPOINT((0 0),(1 1))"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
bnd = geom.GetBoundary()
assert (
bnd.GetGeometryType() == ogr.wkbGeometryCollection
), "Boundary not reported as GEOMETRYCOLLECTION EMPTY"
###############################################################################
# Test OGRGeometry::getBoundary() result for linestring.
@pytest.mark.require_geos
def test_ogr_geom_boundary_linestring():
geom_wkt = "LINESTRING(0 0, 1 1, 2 2, 3 2, 4 2)"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
bnd = geom.GetBoundary()
assert (
bnd.GetGeometryType() == ogr.wkbMultiPoint
), "Boundary not reported as MULTIPOINT"
assert (
bnd.GetGeometryCount() == 2
), "Boundary not reported as MULTIPOINT consisting of 2 points"
geom_wkt = "LINESTRING(0 0, 1 0, 1 1, 0 1, 0 0)"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
bnd = geom.GetBoundary()
assert (
bnd.GetGeometryType() == ogr.wkbMultiPoint
), "Boundary not reported as MULTIPOINT"
assert bnd.GetGeometryCount() == 0, "Boundary not reported as MULTIPOINT EMPTY"
###############################################################################
# Test OGRGeometry::getBoundary() result for polygon.
@pytest.mark.require_geos
def test_ogr_geom_boundary_polygon():
geom_wkt = "POLYGON((0 0,1 1,1 0,0 0))"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
bnd = geom.GetBoundary()
assert (
bnd.GetGeometryType() == ogr.wkbLineString
), "Boundary not reported as non-empty LINESTRING"
###############################################################################
# Test OGRBuildPolygonFromEdges() on a geometry collection of line strings
@pytest.mark.require_geos
def test_ogr_geom_build_from_edges_1():
link_coll = ogr.Geometry(type=ogr.wkbGeometryCollection)
wkt_array = [
"LINESTRING (-87.601595 30.999522,-87.599623 31.000059,-87.599219 31.00017)",
"LINESTRING (-87.601595 30.999522,-87.604349 30.999493,-87.606935 30.99952)",
"LINESTRING (-87.59966 31.000756,-87.599851 31.000805,-87.599992 31.000805,-87.600215 31.000761,-87.600279 31.000723,-87.600586 31.000624,-87.601256 31.000508,-87.602501 31.000447,-87.602801 31.000469,-87.603108 31.000579,-87.603331 31.000716,-87.603523 31.000909,-87.603766 31.001233,-87.603913 31.00136)",
"LINESTRING (-87.606134 31.000182,-87.605885 31.000325,-87.605343 31.000716,-87.60466 31.001117,-87.604468 31.0012,-87.603913 31.00136)",
"LINESTRING (-87.599219 31.00017,-87.599289 31.0003,-87.599398 31.000426,-87.599564 31.000547,-87.599609 31.000701,-87.59966 31.000756)",
"LINESTRING (-87.606935 30.99952,-87.606713 30.999799,-87.6064 30.999981,-87.606134 31.000182)",
]
for wkt in wkt_array:
geom = ogr.CreateGeometryFromWkt(wkt)
# print "geom is",geom
link_coll.AddGeometry(geom)
try:
poly = ogr.BuildPolygonFromEdges(link_coll)
assert poly is not None
except Exception:
pytest.fail()
###############################################################################
# Test OGRBuildPolygonFromEdges() on a multilinestring
@pytest.mark.require_geos
def test_ogr_geom_build_from_edges_2():
link_coll = ogr.Geometry(type=ogr.wkbMultiLineString)
wkt_array = [
"LINESTRING (-87.601595 30.999522,-87.599623 31.000059,-87.599219 31.00017)",
"LINESTRING (-87.601595 30.999522,-87.604349 30.999493,-87.606935 30.99952)",
"LINESTRING (-87.59966 31.000756,-87.599851 31.000805,-87.599992 31.000805,-87.600215 31.000761,-87.600279 31.000723,-87.600586 31.000624,-87.601256 31.000508,-87.602501 31.000447,-87.602801 31.000469,-87.603108 31.000579,-87.603331 31.000716,-87.603523 31.000909,-87.603766 31.001233,-87.603913 31.00136)",
"LINESTRING (-87.606134 31.000182,-87.605885 31.000325,-87.605343 31.000716,-87.60466 31.001117,-87.604468 31.0012,-87.603913 31.00136)",
"LINESTRING (-87.599219 31.00017,-87.599289 31.0003,-87.599398 31.000426,-87.599564 31.000547,-87.599609 31.000701,-87.59966 31.000756)",
"LINESTRING (-87.606935 30.99952,-87.606713 30.999799,-87.6064 30.999981,-87.606134 31.000182)",
]
for wkt in wkt_array:
geom = ogr.CreateGeometryFromWkt(wkt)
link_coll.AddGeometry(geom)
try:
poly = ogr.BuildPolygonFromEdges(link_coll)
assert poly is not None
except Exception:
pytest.fail()
###############################################################################
# Test OGRBuildPolygonFromEdges() on invalid geometries
@pytest.mark.require_geos
def test_ogr_geom_build_from_edges_3():
src_geom = ogr.CreateGeometryFromWkt("POINT (0 1)")
try:
with gdaltest.error_handler():
poly = ogr.BuildPolygonFromEdges(src_geom)
assert poly is None
except Exception:
pass
src_geom = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION (LINESTRING(0 1,2 3),POINT(0 1),LINESTRING(0 1,-2 3),LINESTRING(-2 3,2 3))"
)
try:
with gdaltest.error_handler():
poly = ogr.BuildPolygonFromEdges(src_geom)
assert poly is None
except Exception:
pass
###############################################################################
# Test OGRBuildPolygonFromEdges() and identify exterior ring (#3610)
@pytest.mark.require_geos
def test_ogr_geom_build_from_edges_4():
if int(gdal.VersionInfo("VERSION_NUM")) < 1900:
pytest.skip("would crash")
link_coll = ogr.Geometry(type=ogr.wkbGeometryCollection)
wkt_array = [
"LINESTRING EMPTY",
"LINESTRING (1 1,1 2)",
"LINESTRING EMPTY",
"LINESTRING (1 2,2 2)",
"LINESTRING (2 2,2 1)",
"LINESTRING (2 1,1 1)",
"LINESTRING (0 0,0 10)",
"LINESTRING (0 10,10 10)",
"LINESTRING (10 10,10 0)",
"LINESTRING (10 0,0 0)",
]
for wkt in wkt_array:
geom = ogr.CreateGeometryFromWkt(wkt)
# print "geom is",geom
link_coll.AddGeometry(geom)
try:
poly = ogr.BuildPolygonFromEdges(link_coll)
assert poly is not None
wkt = poly.ExportToWkt()
assert wkt == "POLYGON ((0 0,0 10,10 10,10 0,0 0),(1 1,1 2,2 2,2 1,1 1))"
except Exception:
pytest.fail()
###############################################################################
# Test GetArea() on empty linear ring (#2792)
def test_ogr_geom_area_empty_linearring():
geom = ogr.Geometry(type=ogr.wkbLinearRing)
area = geom.GetArea()
assert area == 0
###############################################################################
# Test TransformTo()
def test_ogr_geom_transform_to():
# Somewhere in Paris suburbs...
geom = ogr.CreateGeometryFromWkt("POINT(2 49)")
# Input SRS is EPSG:4326
sr = osr.SpatialReference()
sr.ImportFromEPSG(4326)
sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
geom.AssignSpatialReference(sr)
# Output SRS is EPSG:32631
sr2 = osr.SpatialReference()
sr2.ImportFromEPSG(32631)
ret = geom.TransformTo(sr2)
assert (
ret == 0
and geom.GetX() == pytest.approx(426857, abs=1)
and geom.GetY() == pytest.approx(5427937, abs=1)
), geom.ExportToWkt()
# Geometry without SRS
geom = ogr.CreateGeometryFromWkt("POINT(2 49)")
gdal.ErrorReset()
with gdaltest.error_handler():
ret = geom.TransformTo(sr2)
assert not (ret == 0 or gdal.GetLastErrorMsg() == "")
###############################################################################
# Test Transform()
def test_ogr_geom_transform():
# Somewhere in Paris suburbs...
geom = ogr.CreateGeometryFromWkt("POINT(2 49)")
# Input SRS is EPSG:4326
sr = osr.SpatialReference()
sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
sr.ImportFromEPSG(4326)
# Output SRS is EPSG:32631
sr2 = osr.SpatialReference()
sr2.ImportFromEPSG(32631)
ct = osr.CoordinateTransformation(sr, sr2)
geom.Transform(ct)
assert geom.GetX() == pytest.approx(426857, abs=1) and geom.GetY() == pytest.approx(
5427937, abs=1
), geom.ExportToWkt()
###############################################################################
# Test Transform() from a geographic CRS to WGS 84 (https://github.com/OSGeo/gdal/issues/5660)
def test_ogr_geom_transform_geogcrs_to_wgs84():
srs_4326 = osr.SpatialReference()
srs_4326.ImportFromEPSG(4326)
srs_4326.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
srs_7683 = osr.SpatialReference()
srs_7683.ImportFromEPSG(7683)
srs_7683.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
wkt = "POLYGON ((44.0 43.1666666666667,44.0 43.3333333333333,44.25 43.3333333333333,44.25 43.1666666666667,44.0 43.1666666666667))"
options = osr.CoordinateTransformationOptions()
# Setting the pipeline is not compulsory, but this enables us to be independent
# of PROJ transformation database
assert options.SetOperation(
"+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=GSK2011 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"
)
ct = osr.CoordinateTransformation(srs_7683, srs_4326)
tr = ogr.GeomTransformer(ct)
polygon = ogr.CreateGeometryFromWkt(wkt)
polygon.AssignSpatialReference(srs_7683)
gdal.ErrorReset()
polygon = tr.Transform(polygon)
assert gdal.GetLastErrorMsg() == ""
assert (
ogrtest.check_feature_geometry(
polygon,
"POLYGON ((44.0 43.1666661611411,44.0 43.3333328276326,44.25 43.3333328276326,44.25 43.1666661611411,44.0 43.1666661611411))",
)
== 0
)
###############################################################################
# Test ogr.GeomTransformer()
@pytest.mark.require_geos
def test_ogr_geomtransfomer_default():
src = osr.SpatialReference()
src.ImportFromEPSG(32660)
dst = osr.SpatialReference()
dst.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
dst.ImportFromEPSG(4326)
ct = osr.CoordinateTransformation(src, dst)
geom = ogr.CreateGeometryFromWkt(
"LINESTRING(832864.275023695 0,835092.849076364 0)"
)
transformer = ogr.GeomTransformer(ct)
geom_dst = transformer.Transform(geom)
assert (
geom_dst.ExportToWkt()
== "MULTILINESTRING ((179.99 0.0,180 0),(-180 0,-179.99 0.0))"
)
###############################################################################
# Test ogr.GeomTransformer()
@pytest.mark.require_geos
def test_ogr_geomtransfomer_wrapdateline_with_ct():
src = osr.SpatialReference()
src.ImportFromEPSG(3857)
dst = osr.SpatialReference()
dst.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
dst.ImportFromEPSG(4326)
ct = osr.CoordinateTransformation(src, dst)
geom = ogr.CreateGeometryFromWkt(
"LINESTRING(20026376.3937099 0,-20026376.3937099 0)"
)
transformer = ogr.GeomTransformer(ct, ["WRAPDATELINE=YES"])
geom_dst = geom.Transform(transformer)
assert (
ogrtest.check_feature_geometry(
geom_dst, "MULTILINESTRING ((179.9 0.0,180 0),(-180 0,-179.9 0.0))"
)
== 0
)
###############################################################################
# Test ogr.GeomTransformer()
@pytest.mark.require_geos
def test_ogr_geomtransfomer_wrapdateline_no_ct():
geom = ogr.CreateGeometryFromWkt("LINESTRING(-179 0,179 0)")
transformer = ogr.GeomTransformer(None, ["WRAPDATELINE=YES"])
geom_dst = geom.Transform(transformer)
assert geom_dst.ExportToWkt() == "MULTILINESTRING ((-179 0,-180 0),(180 0,179 0))"
###############################################################################
# Test CloseRings()
def test_ogr_geom_closerings():
geom = ogr.CreateGeometryFromWkt("POLYGON((0 0,0 1,1 1,1 0))")
geom.CloseRings()
assert geom.ExportToWkt() == "POLYGON ((0 0,0 1,1 1,1 0,0 0))"
geom.CloseRings()
assert geom.ExportToWkt() == "POLYGON ((0 0,0 1,1 1,1 0,0 0))"
###############################################################################
# Test Segmentize()
def test_ogr_geom_segmentize():
# 2D
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0,0 10)")
geom.Segmentize(1.00001)
assert (
ogrtest.check_feature_geometry(
geom, "LINESTRING (0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10)"
)
== 0
)
# 2D + Z
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0 1,0 10 1)")
geom.Segmentize(1.00001)
assert (
ogrtest.check_feature_geometry(
geom,
"LINESTRING (0 0 1,0 1 1,0 2 1,0 3 1,0 4 1,0 5 1,0 6 1,0 7 1,0 8 1,0 9 1,0 10 1)",
)
== 0
)
assert str(geom) == geom.ExportToIsoWkt()
# 2D + M
geom = ogr.CreateGeometryFromWkt("LINESTRING M(0 0 1,0 10 2)")
geom.Segmentize(5)
assert geom.ExportToIsoWkt() == "LINESTRING M (0 0 1,0 5 2,0 10 2)"
assert str(geom) == geom.ExportToIsoWkt()
# 2D + ZM
geom = ogr.CreateGeometryFromWkt("LINESTRING ZM(0 0 1 2,0 10 1 2)")
geom.Segmentize(5)
assert geom.ExportToIsoWkt() == "LINESTRING ZM (0 0 1 2,0 5 1 2,0 10 1 2)"
assert str(geom) == geom.ExportToIsoWkt()
# Test distance between points <<<< segmentization threshold
# https://github.com/OSGeo/gdal/issues/1414
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0,0 1)")
geom.Segmentize(10000)
assert geom.ExportToWkt() == "LINESTRING (0 0,0 1)"
# Check segmentize symmetry : do exact binary comparison.
in_wkt = "LINESTRING (0 0,1.2 1,2 0)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
g1.Segmentize(0.25)
in_wkt = "LINESTRING (2 0,1.2 1,0 0)"
g2 = ogr.CreateGeometryFromWkt(in_wkt)
g2.Segmentize(0.25)
for i in range(g1.GetPointCount()):
if g1.GetPoint(i) != g2.GetPoint(g1.GetPointCount() - 1 - i):
print(
"%.18g"
% (g1.GetPoint(i)[0] - g2.GetPoint(g1.GetPointCount() - 1 - i)[0])
)
pytest.fail(
"%.18g"
% (g1.GetPoint(i)[1] - g2.GetPoint(g1.GetPointCount() - 1 - i)[1])
)
# Test extremely small threshold
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0,0 1)")
with gdaltest.error_handler():
geom.Segmentize(1e-30)
assert gdal.GetLastErrorMsg() != ""
def test_ogr_geom_segmentize_issue_1341():
expected_geom = "LINESTRING (0 0,0.4 0.0,0.8 0.0,1.2 0.0,1.6 0.0,2 0,2.4 0.0,2.8 0.0,3.2 0.0,3.6 0.0,4 0,4.4 0.0,4.8 0.0,5.2 0.0,5.6 0.0,6 0,6.4 0.0,6.8 0.0,7.2 0.0,7.6 0.0,8 0,8.4 0.0,8.8 0.0,9.2 0.0,9.6 0.0,10 0)"
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0,10 0)")
geom.Segmentize(0.399999999999)
assert geom.ExportToWkt() == expected_geom
geom.Segmentize(0.399999999999)
assert geom.ExportToWkt() == expected_geom
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0,10 0)")
geom.Segmentize(0.4)
assert geom.ExportToWkt() == expected_geom
geom.Segmentize(0.4)
assert geom.ExportToWkt() == expected_geom
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0,10 0)")
geom.Segmentize(0.400000000001)
assert geom.ExportToWkt() == expected_geom
geom.Segmentize(0.400000000001)
assert geom.ExportToWkt() == expected_geom
###############################################################################
# Test Value()
def test_ogr_geom_value():
geom = ogr.CreateGeometryFromWkt("LINESTRING(2 3,5 3,5 0)")
p = geom.Value(-1e-3)
expected_p = ogr.CreateGeometryFromWkt("POINT (2 3)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = geom.Value(geom.Length() / 4)
expected_p = ogr.CreateGeometryFromWkt("POINT (3.5 3)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = geom.Value(geom.Length() / 2)
expected_p = ogr.CreateGeometryFromWkt("POINT (5 3)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = geom.Value(3 * geom.Length() / 4)
expected_p = ogr.CreateGeometryFromWkt("POINT (5 1.5)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = geom.Value(geom.Length() + 1e-3)
expected_p = ogr.CreateGeometryFromWkt("POINT (5 0)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
###############################################################################
# Test FlattenTo2D(), GetDimension() and GetCoordinateDimension()
def test_ogr_geom_flattenTo2D():
geom = ogr.CreateGeometryFromWkt("POINT (1 2 3)")
# Point is 0 dimension, LineString 1, ...
assert geom.GetDimension() == 0
assert geom.GetCoordinateDimension() == 3
geom.FlattenTo2D()
assert geom.GetCoordinateDimension() == 2
assert geom.ExportToWkt() == "POINT (1 2)"
###############################################################################
# Test FlattenTo2D(), GetDimension() and GetCoordinateDimension() for Triangle
def test_ogr_geom_flattenTo2D_triangle():
geom = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0 0,100 0 100,0 100 100,0 0 0))")
# Point is 0 dimension, LineString 1, ...
assert geom.GetDimension() == 2
assert geom.GetCoordinateDimension() == 3
geom.FlattenTo2D()
assert geom.GetCoordinateDimension() == 2
assert geom.ExportToWkt() == "TRIANGLE ((0 0,100 0,0 100,0 0))"
###############################################################################
def test_ogr_geom_linestring_limits():
geom = ogr.CreateGeometryFromWkt("LINESTRING EMPTY")
assert geom.Length() == 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.GetPoint(-1)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.GetPoint(0)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.GetPoint_2D(-1)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.GetPoint_2D(0)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.SetPoint(-1, 5, 6, 7)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.SetPoint_2D(-1, 5, 6)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.SetPoint(2147000000, 5, 6, 7)
assert gdal.GetLastErrorType() != 0
gdal.ErrorReset()
with gdaltest.error_handler():
geom.SetPoint_2D(2147000000, 5, 6)
assert gdal.GetLastErrorType() != 0
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0)")
assert geom.Length() == 0
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 0, 1 0)")
assert geom.Length() == 1
###############################################################################
def test_ogr_geom_coord_round():
geom = ogr.CreateGeometryFromWkt("POINT(370441.860 5591000.590)")
wkt = geom.ExportToWkt()
assert wkt == "POINT (370441.86 5591000.59)", "did not get expected WKT"
###############################################################################
def test_ogr_geom_coord_round_2():
geom = ogr.CreateGeometryFromWkt("POINT(1.0 169.600374)")
wkt = geom.ExportToWkt()
assert wkt == "POINT (1.0 169.600374)", "did not get expected WKT"
###############################################################################
# Test Area calculation for a Point
def test_ogr_geom_area_point():
geom_wkt = "POINT(0 0)"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
with gdaltest.error_handler():
area = geom.Area()
assert area == 0, "Area() result wrong, got %g." % area
###############################################################################
# Test Length calculation for a Point
def test_ogr_geom_length_point():
# OGR >= 1.8.0
geom_wkt = "POINT(0 0)"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
with gdaltest.error_handler():
length = geom.Length()
assert length == 0, "Length() result wrong, got %g." % length
###############################################################################
# Test Length calculation for a MultiLineString
def test_ogr_geom_length_multilinestring():
# OGR >= 1.8.0
geom_wkt = "MULTILINESTRING((0 0,0 1),(0 0,0 1))"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
length = geom.Length()
assert length == pytest.approx(2, abs=0.00000000001), (
"Length() result wrong, got %g." % length
)
###############################################################################
# Test Length calculation for a GeometryCollection
def test_ogr_geom_length_geometrycollection():
# OGR >= 1.8.0
geom_wkt = "GEOMETRYCOLLECTION( POLYGON((0 0,0 1,1 1,1 0,0 0)), MULTILINESTRING((0 0,0 1),(0 0,0 1)), LINESTRING(0 0,0 1), LINESTRING(0 0,0 1), POINT(0 0), GEOMETRYCOLLECTION EMPTY )"
geom = ogr.CreateGeometryFromWkt(geom_wkt)
length = geom.Length()
assert length == pytest.approx(4, abs=0.00000000001), (
"Length() result wrong, got %g." % length
)
###############################################################################
# Test Geometry.GetPoints() (#4016)
def test_ogr_geom_getpoints():
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 1,2 3)")
points = geom.GetPoints()
assert points == [(0.0, 1.0), (2.0, 3.0)], "did not get expected points (1)"
points = geom.GetPoints(nCoordDimension=3)
assert points == [
(0.0, 1.0, 0.0),
(2.0, 3.0, 0.0),
], "did not get expected points (2)"
geom = ogr.CreateGeometryFromWkt("LINESTRING(0 1 2,3 4 5)")
points = geom.GetPoints()
assert points == [
(0.0, 1.0, 2.0),
(3.0, 4.0, 5.0),
], "did not get expected points (3)"
points = geom.GetPoints(nCoordDimension=2)
assert points == [(0.0, 1.0), (3.0, 4.0)], "did not get expected points (4)"
geom = ogr.CreateGeometryFromWkt("POINT(0 1)")
points = geom.GetPoints()
assert points == [(0.0, 1.0)], "did not get expected points (5)"
points = geom.GetPoints(nCoordDimension=3)
assert points == [(0.0, 1.0, 0.0)], "did not get expected points (6)"
geom = ogr.CreateGeometryFromWkt("POINT(0 1 2)")
points = geom.GetPoints()
assert points == [(0.0, 1.0, 2.0)], "did not get expected points (7)"
points = geom.GetPoints(nCoordDimension=2)
assert points == [(0.0, 1.0)], "did not get expected points (8)"
###############################################################################
# Test OGRGeometry::empty()
def test_ogr_geom_empty():
g1 = ogr.CreateGeometryFromWkt("POLYGON((0 0,1 1,1 2,1 1,0 0))")
g1.Empty()
wkt = g1.ExportToWkt()
assert wkt == "POLYGON EMPTY"
###############################################################################
# Test OGRGeometry::empty() for Triangle
def test_ogr_geom_empty_triangle():
g1 = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0,100 0,0 100,0 0))")
g1.Empty()
wkt = g1.ExportToWkt()
assert wkt == "TRIANGLE EMPTY"
###############################################################################
# Test parsing WKT made of 2D and 3D parts
def test_ogr_geom_mixed_coordinate_dimension():
# first part is 3D, second part is 2D of same length
wkt = "MULTIPOLYGON (((1 2 -4,1 3 -3,2 3 -3,2 2 -3,1 2 -6)),((-1 -2,-1 -3,-2 -3,-2 -2,-1 -2,50 60)))"
expected_wkt = "MULTIPOLYGON (((1 2 -4,1 3 -3,2 3 -3,2 2 -3,1 2 -6)),((-1 -2 0,-1 -3 0,-2 -3 0,-2 -2 0,-1 -2 0,50 60 0)))"
g = ogr.CreateGeometryFromWkt(wkt)
got_wkt = g.ExportToWkt()
assert got_wkt == expected_wkt, "for %s: got %s, expected %s" % (
wkt,
got_wkt,
expected_wkt,
)
# first part is 3D, second part is 2D of same length, except the last point which is 3D
wkt = "MULTIPOLYGON (((1 2 -4,1 3 -3,2 3 -3,2 2 -3,1 2 -6)),((-1 -2,-1 -3,-2 -3,-2 -2,-1 -2,50 60 7)))"
expected_wkt = "MULTIPOLYGON (((1 2 -4,1 3 -3,2 3 -3,2 2 -3,1 2 -6)),((-1 -2 0,-1 -3 0,-2 -3 0,-2 -2 0,-1 -2 0,50 60 7)))"
g = ogr.CreateGeometryFromWkt(wkt)
got_wkt = g.ExportToWkt()
assert got_wkt == expected_wkt, "for %s: got %s, expected %s" % (
wkt,
got_wkt,
expected_wkt,
)
###############################################################################
# Test GetEnvelope3D()
def test_ogr_geom_getenvelope3d():
g = ogr.CreateGeometryFromWkt("POINT EMPTY")
envelope = g.GetEnvelope3D()
expected_envelope = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
assert envelope == expected_envelope, "did not get expected envelope (1)"
g = ogr.CreateGeometryFromWkt("POINT(1 2)")
envelope = g.GetEnvelope3D()
expected_envelope = (1.0, 1.0, 2.0, 2.0, 0.0, 0.0)
assert envelope == expected_envelope, "did not get expected envelope (2)"
g = ogr.CreateGeometryFromWkt("POINT(1 2 3)")
envelope = g.GetEnvelope3D()
expected_envelope = (1.0, 1.0, 2.0, 2.0, 3.0, 3.0)
assert envelope == expected_envelope, "did not get expected envelope (3)"
g = ogr.CreateGeometryFromWkt("POLYGON EMPTY")
envelope = g.GetEnvelope3D()
expected_envelope = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
assert envelope == expected_envelope, "did not get expected envelope (4)"
g = ogr.CreateGeometryFromWkt("LINESTRING(1 2,3 4)")
envelope = g.GetEnvelope3D()
expected_envelope = (1, 3, 2, 4, 0, 0)
assert envelope == expected_envelope, "did not get expected envelope (5)"
g = ogr.CreateGeometryFromWkt(
"MULTIPOLYGON(((1 2 3,-1 2 3,-1 -2 3,-1 2 3,1 2 3),(0.1 0.2 0.3,-0.1 0.2 0.3,-0.1 -0.2 0.3,-0.1 0.2 0.3,0.1 0.2 0.3)),((10 20 -30,-10 20 -30,-10 -20 -30,-10 20 -30,10 20 -30)))"
)
envelope = g.GetEnvelope3D()
expected_envelope = (-10, 10, -20, 20, -30, 3.0)
assert envelope == expected_envelope, "did not get expected envelope (6)"
g = ogr.CreateGeometryFromWkt("MULTIPOLYGON EMPTY")
envelope = g.GetEnvelope3D()
expected_envelope = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
assert envelope == expected_envelope, "did not get expected envelope (7)"
g = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0 0,100 0 100,0 100 100,0 0 0))")
envelope = g.GetEnvelope3D()
expected_envelope = (0.0, 100.0, 0.0, 100.0, 0.0, 100.0)
assert envelope == expected_envelope, "did not get expected envelope (8)"
###############################################################################
# Test importing/exporting XXX Z EMPTY
def test_ogr_geom_z_empty():
for geom in [
"POINT",
"LINESTRING",
"POLYGON",
"MULTIPOINT",
"MULTILINESTRING",
"MULTIPOLYGON",
"GEOMETRYCOLLECTION",
"CIRCULARSTRING",
"COMPOUNDCURVE",
"CURVEPOLYGON",
"MULTICURVE",
"MULTISURFACE",
]:
in_wkt = geom + " Z EMPTY"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
out_wkt = g1.ExportToIsoWkt()
assert in_wkt == out_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToIsoWkb())
out_wkt = g2.ExportToIsoWkt()
assert in_wkt == out_wkt
###############################################################################
# Test HasCurveGeometry and GetLinearGeometry
def test_ogr_geom_getlineargeometry():
for geom in [
"POINT",
"LINESTRING",
"POLYGON",
"MULTIPOINT",
"MULTILINESTRING",
"MULTIPOLYGON",
"GEOMETRYCOLLECTION",
("CIRCULARSTRING", "LINESTRING"),
("COMPOUNDCURVE", "LINESTRING"),
("CURVEPOLYGON", "POLYGON"),
("MULTICURVE", "MULTILINESTRING"),
("MULTISURFACE", "MULTIPOLYGON"),
]:
try:
(geom_in, geom_out) = geom
except Exception:
geom_in = geom_out = geom
in_wkt = geom_in + " EMPTY"
g = ogr.CreateGeometryFromWkt(in_wkt)
g2 = g.GetLinearGeometry()
assert geom_in == geom_out or g.HasCurveGeometry()
assert g2.ExportToWkt() == geom_out + " EMPTY", g
g = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION(POINT (0 1))")
assert not g.HasCurveGeometry()
assert not g.HasCurveGeometry(True)
g = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION(CIRCULARSTRING (0 0,0 1,0 0))")
assert g.HasCurveGeometry()
assert g.HasCurveGeometry(True)
###############################################################################
# Test GetDimension()
def test_ogr_geom_getdimension():
for (geom, dim) in [
("POINT EMPTY", 0),
("LINESTRING EMPTY", 1),
("POLYGON EMPTY", 2),
("MULTIPOINT EMPTY", 0),
("MULTILINESTRING EMPTY", 1),
("MULTIPOLYGON EMPTY", 2),
("GEOMETRYCOLLECTION EMPTY", 0),
("CIRCULARSTRING EMPTY", 1),
("COMPOUNDCURVE EMPTY", 1),
("CURVEPOLYGON EMPTY", 2),
("MULTICURVE EMPTY", 1),
("TRIANGLE EMPTY", 2),
("MULTISURFACE EMPTY", 2),
("POLYHEDRALSURFACE EMPTY", 2),
("TIN EMPTY", 2),
]:
g = ogr.CreateGeometryFromWkt(geom)
assert g.GetDimension() == dim
g = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION(LINESTRING EMPTY, POINT (0 1))")
assert g.GetDimension() == 1
g = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION(POINT (0 1), LINESTRING EMPTY, POLYGON EMPTY)"
)
assert g.GetDimension() == 2
###############################################################################
# Test triangle
def test_ogr_geom_triangle():
wkt_original = "TRIANGLE ((0 0,0 1,1 1,0 0))"
geom = ogr.CreateGeometryFromWkt(wkt_original)
wkb_string = geom.ExportToWkb(ogr.wkbXDR)
geom = ogr.CreateGeometryFromWkb(wkb_string)
wkt_string = geom.ExportToWkt()
assert wkt_string == wkt_original, "Failure in Wkb methods of Triangle"
wkt_string = geom.Clone().ExportToWkt()
assert wkt_string == wkt_original, "Failure in Clone()"
polygon_wkt = ogr.ForceTo(geom.Clone(), ogr.wkbPolygon).ExportToWkt()
assert polygon_wkt == "POLYGON ((0 0,0 1,1 1,0 0))"
polygon_wkt = ogr.ForceTo(geom.Clone(), ogr.wkbMultiPolygon).ExportToWkt()
assert polygon_wkt == "MULTIPOLYGON (((0 0,0 1,1 1,0 0)))"
###############################################################################
# Test importing invalid triangle WKT
def test_ogr_geom_triangle_invalid_wkt():
geom_wkt = "TRIANGLE (0 0)"
with gdaltest.error_handler():
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom is None
geom_wkt = "TRIANGLE ((0 0))"
with gdaltest.error_handler():
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom is None
geom_wkt = "TRIANGLE ((0 0,0 1,1 1,1 0))"
with gdaltest.error_handler():
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom is None
geom_wkt = "TRIANGLE ((0 0,0 1,1 1,1 0,0 0))"
with gdaltest.error_handler():
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom is None
geom_wkt = "TRIANGLE ((0 0,0 1,1 1,0 0),(0 0,0 1,1 1,0 0))"
with gdaltest.error_handler():
geom = ogr.CreateGeometryFromWkt(geom_wkt)
assert geom is None
###############################################################################
# Test OGRTriangle. Tests if the GEOS/SFCGAL methods are working
def test_ogr_geom_triangle_sfcgal():
if not ogrtest.have_sfcgal():
pytest.skip("SFCGAL is not available")
g1 = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0,100 0 100,0 100 100,0 0))")
g2 = ogr.CreateGeometryFromWkt("TRIANGLE ((-1 -1,100 0 100,0 100 100,-1 -1))")
assert g2.Intersects(g1)
g1 = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0,1 0,0 1,0 0))")
g2 = ogr.CreateGeometryFromWkt("TRIANGLE ((0 0,1 0,1 1,0 0))")
g3 = g1.Intersection(g2)
g4 = ogr.CreateGeometryFromWkt("TRIANGLE ((0.5 0.5 0,0 0 0,1 0 0,0.5 0.5 0))")
assert g4.Equals(g3)
###############################################################################
# Test OGRCircularString
def test_ogr_geom_circularstring():
in_wkt = "CIRCULARSTRING (0 0,1 1,1 -1)"
# Test export/import Wkt
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCircularString
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
if ogrtest.have_geos():
assert g1.IsValid()
# Test GetEnvelope()
env = g1.GetEnvelope()
expected_env = (0.0, 2.0, -1.0, 1.0)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# Test Length()
length = g1.Length()
expected_length = 1.5 * math.pi
assert length == pytest.approx(expected_length, abs=1e-8)
# Test Value()
p = g1.Value(-1)
expected_p = ogr.CreateGeometryFromWkt("POINT (0 0)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(0)
expected_p = ogr.CreateGeometryFromWkt("POINT (0 0)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(length / 6.0)
expected_p = ogr.CreateGeometryFromWkt(
"POINT (0.292893218813453 0.707106781186548)"
)
if ogrtest.check_feature_geometry(p, expected_p) != 0:
print(p)
p = g1.Value(length / 3.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (1 1)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(length / 2.0)
expected_p = ogr.CreateGeometryFromWkt(
"POINT (1.707106781186547 0.707106781186547)"
)
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(2 * length / 3.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (2 0)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(length)
expected_p = ogr.CreateGeometryFromWkt("POINT (1 -1)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(length + 1)
expected_p = ogr.CreateGeometryFromWkt("POINT (1 -1)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
# Test export/import Wkb
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# With Z
in_wkt = "CIRCULARSTRING Z (0 0 10,1 1 20,2 0 30)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCircularStringZ
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
wkb = g1.ExportToWkb()
isowkb = g1.ExportToIsoWkb()
assert wkb == isowkb
g2 = ogr.CreateGeometryFromWkb(wkb)
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Test stroking
with gdal.config_options({"OGR_STROKE_CURVE": "TRUE", "OGR_ARC_STEPSIZE": "45"}):
in_wkt = "CIRCULARSTRING (0 0,1 1,1 -1)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.218168517531969 0.623489801858729,0.777479066043687 0.974927912181831,1.433883739117561 0.900968867902435,1.900968867902463 0.433883739117562,1.974927912181821 -0.222520933956316,1.623489801858719 -0.78183148246804,1 -1)"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
in_wkt = "CIRCULARSTRING (0 0,1 1,1 -1)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
in_wkb = g1.ExportToWkb()
with gdal.config_options({"OGR_STROKE_CURVE": "TRUE", "OGR_ARC_STEPSIZE": "45"}):
g2 = ogr.CreateGeometryFromWkb(in_wkb)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test HasCurveGeometry
assert g1.HasCurveGeometry()
assert g1.HasCurveGeometry(True)
# Test GetLinearGeometry
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test ForceToLineString
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToLineString(g1)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test ForceToMultiLineString
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
expected_g2 = ogr.CreateGeometryFromWkt(
"MULTILINESTRING ((0 0,0.218168517531969 0.623489801858729,0.777479066043687 0.974927912181831,1.433883739117561 0.900968867902435,1.900968867902463 0.433883739117562,1.974927912181821 -0.222520933956316,1.623489801858719 -0.78183148246804,1 -1))"
)
g2 = ogr.ForceToMultiLineString(g1)
assert ogrtest.check_feature_geometry(g2, expected_g2) == 0
# Test GEOS operations
if ogrtest.have_geos():
g2 = g1.Intersection(g1)
assert g2 is not None
# Test CIRCULARSTRING wrapped in a GEOMETRYCOLLECTION
in_wkt = "GEOMETRYCOLLECTION(CIRCULARSTRING (0 0,1 1,1 -1))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
# Test GEOS operations
if ogrtest.have_geos():
g2 = g1.Intersection(g1)
assert g2 is not None
# Test ForceToLineString
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToLineString(g1)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test ForceToMultiLineString
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToMultiLineString(g1)
assert ogrtest.check_feature_geometry(g2, expected_g2) == 0
# Test stroking of full circle with 3 points. ISO draft
# mentions that this should define a full circle, but there's an
# ambiguity on the winding order. We choose counter-clock-wise order like
# PostGIS. On the contrary, Microsoft for example forbids
# such a possibility : http://msdn.microsoft.com/en-us/library/ff929141.aspx
in_wkt = "CIRCULARSTRING (0 0,1 0,0 0)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.116977778440514 -0.321393804843282,0.413175911166547 -0.49240387650611,0.75 -0.433012701892224,0.969846310392967 -0.171010071662835,0.969846310392967 0.171010071662835,0.75 0.433012701892224,0.413175911166547 0.49240387650611,0.116977778440514 0.321393804843282,0 0)"
)
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
length = g1.Length()
expected_length = 2 * math.pi * 0.5
assert length == pytest.approx(expected_length, abs=1e-8)
# Test stroking of full circle (well defined)
in_wkt = "CIRCULARSTRING (0 0,0.5 0.5,1.0 0.0,0.5 -0.5,0.0 0.0)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.049515566048791 0.216941869558781,0.188255099070638 0.390915741234018,0.388739533021848 0.48746395609092,0.611260466978166 0.48746395609092,0.811744900929369 0.390915741234018,0.950484433951232 0.216941869558781,1 0,0.950484433951232 -0.216941869558781,0.811744900929369 -0.390915741234018,0.611260466978166 -0.48746395609092,0.388739533021848 -0.48746395609092,0.188255099070638 -0.390915741234018,0.049515566048791 -0.216941869558781,0 0)"
)
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
length = g1.Length()
expected_length = 2 * math.pi * 0.5
assert length == pytest.approx(expected_length, abs=1e-8)
# Check segmentize
g1.Segmentize(0.5)
expected_g = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING (0 0,0.146446609406726 0.353553390593274,0.5 0.5,0.853553390593274 0.353553390593274,1 0,0.853553390593274 -0.353553390593274,0.5 -0.5,0.146446609406726 -0.353553390593274,0 0)"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
# Sanity check: the length must remain the same
length = g1.Length()
expected_length = 2 * math.pi * 0.5
assert length == pytest.approx(expected_length, abs=1e-8)
# Check segmentize symmetry : do exact binary comparison
in_wkt = "CIRCULARSTRING (0 0,1.2 1,2 0)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
g1.Segmentize(0.25)
in_wkt = "CIRCULARSTRING (2 0,1.2 1,0 0)"
g2 = ogr.CreateGeometryFromWkt(in_wkt)
g2.Segmentize(0.25)
for i in range(g1.GetPointCount()):
if g1.GetPoint(i) != g2.GetPoint(g1.GetPointCount() - 1 - i):
print(
"%.18g"
% (g1.GetPoint(i)[0] - g2.GetPoint(g1.GetPointCount() - 1 - i)[0])
)
pytest.fail(
"%.18g"
% (g1.GetPoint(i)[1] - g2.GetPoint(g1.GetPointCount() - 1 - i)[1])
)
# Test stroking of full circle with Z
in_wkt = "CIRCULARSTRING (0 0 1,1 0 2,0 0 1)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0 1,0.116977778440514 -0.321393804843282 1,0.413175911166547 -0.49240387650611 1,0.75 -0.433012701892224 1,0.969846310392967 -0.171010071662835 1,0.969846310392967 0.171010071662835 1,0.75 0.433012701892224 1,0.413175911166547 0.49240387650611 1,0.116977778440514 0.321393804843282 1,0 0 1)"
)
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Check segmentize
g1.Segmentize(0.5)
expected_g = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING Z (0 0 1,0.146446609406726 -0.353553390593274 1.25,0.5 -0.5 1.5,0.853553390593274 -0.353553390593274 1.75,1 0 2,0.853553390593274 0.353553390593274 1.75,0.5 0.5 1.5,0.146446609406727 0.353553390593274 1.25,0 0 1)"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
# Same as above but reverse order
in_wkt = "CIRCULARSTRING (0 0,0.5 -0.5,1.0 0.0,0.5 0.5,0.0 0.0)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.049515566048791 -0.216941869558781,0.188255099070638 -0.390915741234018,0.388739533021848 -0.48746395609092,0.611260466978166 -0.48746395609092,0.811744900929369 -0.390915741234018,0.950484433951232 -0.216941869558781,1 0,0.950484433951232 0.216941869558781,0.811744900929369 0.390915741234018,0.611260466978166 0.48746395609092,0.388739533021848 0.48746395609092,0.188255099070638 0.390915741234018,0.049515566048791 0.216941869558781,0 0)"
)
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
length = g1.Length()
expected_length = 2 * math.pi * 0.5
assert length == pytest.approx(expected_length, abs=1e-8)
# Test stroking of a circular string with 3 colinear points
in_wkt = "CIRCULARSTRING (0 0,1 1,2 2)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt("LINESTRING (0 0,1 1,2 2)")
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
length = g1.Length()
expected_length = 2 * math.sqrt(2)
assert length == pytest.approx(expected_length, abs=1e-8)
# Test Value()
p = g1.Value(length / 4.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (0.5 0.5)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(3.0 * length / 4.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (1.5 1.5)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
# Check segmentize
g1.Segmentize(0.5)
expected_g = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING (0 0,0.166666666666667 0.166666666666667,0.333333333333333 0.333333333333333,0.5 0.5,0.666666666666667 0.666666666666667,0.833333333333333 0.833333333333333,1 1,1.166666666666667 1.166666666666667,1.333333333333333 1.333333333333333,1.5 1.5,1.666666666666667 1.666666666666667,1.833333333333333 1.833333333333333,2 2)"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
# Sanity check: the length must remain the same
length = g1.Length()
expected_length = 2 * math.sqrt(2)
assert length == pytest.approx(expected_length, abs=1e-8)
# Same with Z
in_wkt = "CIRCULARSTRING (0 0 1,1 1 2,2 2 1)"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt("LINESTRING (0 0 1,1 1 2,2 2 1)")
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Check segmentize
g1.Segmentize(0.5)
expected_g = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING Z (0 0 1,0.166666666666667 0.166666666666667 1.166666666666667,0.333333333333333 0.333333333333333 1.333333333333333,0.5 0.5 1.5,0.666666666666667 0.666666666666667 1.666666666666667,0.833333333333333 0.833333333333333 1.833333333333333,1 1 2,1.166666666666667 1.166666666666667 1.833333333333333,1.333333333333333 1.333333333333333 1.666666666666667,1.5 1.5 1.5,1.666666666666667 1.666666666666667 1.333333333333333,1.833333333333333 1.833333333333333 1.166666666666667,2 2 1)"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
# Test Value()
p = g1.Value(length / 4.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (0.5 0.5 1.5)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(3.0 * length / 4.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (1.5 1.5 1.5)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
in_wkt = "CIRCULARSTRING (0 0,1 1,1 -1)"
# Test GetEnvelope() in various cases
cx = 1
cy = 2
r = 3
# In quadrant 0
a0 = math.pi / 3
a1 = math.pi / 4
a2 = math.pi / 6
in_wkt = "CIRCULARSTRING(%.16g %.16g,%.16g %.16g,%.16g %.16g)" % (
cx + r * math.cos(a0),
cy + r * math.sin(a0),
cx + r * math.cos(a1),
cy + r * math.sin(a1),
cx + r * math.cos(a2),
cy + r * math.sin(a2),
)
g1 = ogr.CreateGeometryFromWkt(in_wkt)
env = g1.GetEnvelope()
expected_env = (
cx + r * math.cos(a0),
cx + r * math.cos(a2),
cy + r * math.sin(a2),
cy + r * math.sin(a0),
)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# From quadrant 0 to quadrant -1
a0 = math.pi / 3
a1 = math.pi / 6
a2 = -math.pi / 6
in_wkt = "CIRCULARSTRING(%.16g %.16g,%.16g %.16g,%.16g %.16g)" % (
cx + r * math.cos(a0),
cy + r * math.sin(a0),
cx + r * math.cos(a1),
cy + r * math.sin(a1),
cx + r * math.cos(a2),
cy + r * math.sin(a2),
)
g1 = ogr.CreateGeometryFromWkt(in_wkt)
env = g1.GetEnvelope()
expected_env = (
cx + r * math.cos(a0),
cx + r,
cy + r * math.sin(a2),
cy + r * math.sin(a0),
)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# From quadrant 0 to quadrant 3
a0 = math.pi / 3
a1 = math.pi - math.pi / 3
a2 = -math.pi / 6
in_wkt = "CIRCULARSTRING(%.16g %.16g,%.16g %.16g,%.16g %.16g)" % (
cx + r * math.cos(a0),
cy + r * math.sin(a0),
cx + r * math.cos(a1),
cy + r * math.sin(a1),
cx + r * math.cos(a2),
cy + r * math.sin(a2),
)
g1 = ogr.CreateGeometryFromWkt(in_wkt)
env = g1.GetEnvelope()
expected_env = (cx - r, cx + r * math.cos(a2), cy - r, cy + r)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# From quadrant 0 to quadrant 4
a0 = math.pi / 3
a1 = math.pi - math.pi / 3
a2 = math.pi / 6
in_wkt = "CIRCULARSTRING(%.16g %.16g,%.16g %.16g,%.16g %.16g)" % (
cx + r * math.cos(a0),
cy + r * math.sin(a0),
cx + r * math.cos(a1),
cy + r * math.sin(a1),
cx + r * math.cos(a2),
cy + r * math.sin(a2),
)
g1 = ogr.CreateGeometryFromWkt(in_wkt)
env = g1.GetEnvelope()
expected_env = (cx - r, cx + r, cy - r, cy + r)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# Full circle
a0 = math.pi / 3
a1 = math.pi + math.pi / 3
a2 = math.pi / 3
in_wkt = "CIRCULARSTRING(%.16g %.16g,%.16g %.16g,%.16g %.16g)" % (
cx + r * math.cos(a0),
cy + r * math.sin(a0),
cx + r * math.cos(a1),
cy + r * math.sin(a1),
cx + r * math.cos(a2),
cy + r * math.sin(a2),
)
g1 = ogr.CreateGeometryFromWkt(in_wkt)
env = g1.GetEnvelope()
expected_env = (cx - r, cx + r, cy - r, cy + r)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# Error case : not enough points
in_wkt = "CIRCULARSTRING (0 0)"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# EMPTY
for in_wkt in ["CIRCULARSTRING EMPTY", "CIRCULARSTRING Z EMPTY"]:
g1 = ogr.CreateGeometryFromWkt(in_wkt)
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.Length() == 0.0, in_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
###############################################################################
# Test OGRCompoundCurve
def test_ogr_geom_compoundcurve():
in_wkt = "COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,1 -1))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCompoundCurve
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.GetGeometryCount() == 1
assert g1.GetGeometryRef(0).ExportToWkt() == "CIRCULARSTRING (0 0,1 1,1 -1)"
env = g1.GetEnvelope()
expected_env = (0.0, 2.0, -1.0, 1.0)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
length = g1.Length()
expected_length = 1.5 * math.pi
assert length == pytest.approx(expected_length, abs=1e-8)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.HasCurveGeometry()
assert g1.HasCurveGeometry(True)
# CreateGeometryFromWkt of LINESTRING
in_wkt = "COMPOUNDCURVE ((0 0,0 10))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.HasCurveGeometry()
assert not g1.HasCurveGeometry(True)
# With Z
in_wkt = "COMPOUNDCURVE Z (CIRCULARSTRING Z (0 0 10,1 1 20,2 0 30),(2 0 30,0 0 10))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCompoundCurveZ
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
env = g1.GetEnvelope()
expected_env = (0.0, 2.0, 0.0, 1.0)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
env = g1.GetEnvelope3D()
expected_env = (0.0, 2.0, 0.0, 1.0, 10, 30)
for i in range(6):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
# Test Value()
p = g1.Value(-1e-3)
expected_p = ogr.CreateGeometryFromWkt("POINT (0 0 10)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(math.pi / 2.0)
expected_p = ogr.CreateGeometryFromWkt("POINT (1 1 20)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(math.pi)
expected_p = ogr.CreateGeometryFromWkt("POINT (2 0 30)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(math.pi + 1)
expected_p = ogr.CreateGeometryFromWkt("POINT (1 0 20)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
p = g1.Value(math.pi + 2 + 1e-3)
expected_p = ogr.CreateGeometryFromWkt("POINT (0 0 10)")
assert ogrtest.check_feature_geometry(p, expected_p) == 0
wkb = g1.ExportToWkb()
isowkb = g1.ExportToIsoWkb()
assert wkb == isowkb
g2 = ogr.CreateGeometryFromWkb(wkb)
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Several parts
in_wkt = "COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,1 -1),(1 -1,0 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCompoundCurve
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.Equals(g1)
assert g1.Equals(g1.Clone())
assert not g1.Equals(ogr.CreateGeometryFromWkt("POINT(0 0)"))
assert not g1.Equals(
ogr.CreateGeometryFromWkt("COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,1 -1))")
)
assert not g1.Equals(
ogr.CreateGeometryFromWkt(
"COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,1 -1),(1 -1,0 1))"
)
)
length = g1.Length()
expected_length = 1.5 * math.pi + math.sqrt(2)
assert length == pytest.approx(expected_length, abs=1e-8)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Test stroking
with gdal.config_options({"OGR_STROKE_CURVE": "TRUE", "OGR_ARC_STEPSIZE": "45"}):
in_wkt = "COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,1 -1))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.218168517531969 0.623489801858729,0.777479066043687 0.974927912181831,1.433883739117561 0.900968867902435,1.900968867902463 0.433883739117562,1.974927912181821 -0.222520933956316,1.623489801858719 -0.78183148246804,1 -1)"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
in_wkt = "COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,1 -1))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
in_wkb = g1.ExportToWkb()
with gdal.config_options({"OGR_STROKE_CURVE": "TRUE", "OGR_ARC_STEPSIZE": "45"}):
g2 = ogr.CreateGeometryFromWkb(in_wkb)
expected_g = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.218168517531969 0.623489801858729,0.777479066043687 0.974927912181831,1.433883739117561 0.900968867902435,1.900968867902463 0.433883739117562,1.974927912181821 -0.222520933956316,1.623489801858719 -0.78183148246804,1 -1)"
)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
assert g1.HasCurveGeometry()
assert g1.HasCurveGeometry(True)
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToLineString(g1)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
expected_g = ogr.CreateGeometryFromWkt(
"MULTILINESTRING ((0 0,0.218168517531969 0.623489801858729,0.777479066043687 0.974927912181831,1.433883739117561 0.900968867902435,1.900968867902463 0.433883739117562,1.974927912181821 -0.222520933956316,1.623489801858719 -0.78183148246804,1 -1))"
)
g2 = ogr.ForceToMultiLineString(g1)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Check segmentize
g1.Segmentize(0.5)
expected_g = ogr.CreateGeometryFromWkt(
"COMPOUNDCURVE (CIRCULARSTRING (0 0,0.076120467488713 0.38268343236509,0.292893218813453 0.707106781186548,0.61731656763491 0.923879532511287,1 1,1.38268343236509 0.923879532511287,1.707106781186547 0.707106781186547,1.923879532511287 0.38268343236509,2 0,1.923879532511287 -0.38268343236509,1.707106781186547 -0.707106781186547,1.38268343236509 -0.923879532511287,1 -1))"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
# Error case : not enough points
in_wkt = "COMPOUNDCURVE ((0 0))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Error case : invalid curve
in_wkt = "COMPOUNDCURVE (COMPOUNDCURVE EMPTY)"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Error case : non contiguous curves
in_wkt = "COMPOUNDCURVE ((0 0,1 1),(2 2,3 3))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Error case : non contiguous curves
in_wkt = "COMPOUNDCURVE (EMPTY,(2 2,3 3))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Error case : non contiguous curves
in_wkt = "COMPOUNDCURVE ((2 2,3 3), EMPTY)"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
g = ogr.Geometry(ogr.wkbCompoundCurve)
g.AddGeometry(ogr.CreateGeometryFromWkt("LINESTRING(0 0,1 1)"))
assert g.ExportToWkt() == "COMPOUNDCURVE ((0 0,1 1))"
with gdaltest.error_handler():
g.AddGeometry(ogr.CreateGeometryFromWkt("LINESTRING(0 0,1 1)"))
assert g.ExportToWkt() == "COMPOUNDCURVE ((0 0,1 1),(1 1,0 0))"
g = ogr.Geometry(ogr.wkbCompoundCurve)
g.AddGeometryDirectly(ogr.CreateGeometryFromWkt("LINESTRING(0 0,1 1)"))
assert g.ExportToWkt() == "COMPOUNDCURVE ((0 0,1 1))"
with gdaltest.error_handler():
g.AddGeometryDirectly(ogr.CreateGeometryFromWkt("LINESTRING(0 0,1 1)"))
assert g.ExportToWkt() == "COMPOUNDCURVE ((0 0,1 1),(1 1,0 0))"
# Cannot add compoundcurve in compoundcurve
g = ogr.Geometry(ogr.wkbCompoundCurve)
with gdaltest.error_handler():
g.AddGeometryDirectly(ogr.CreateGeometryFromWkt("COMPOUNDCURVE((1 1,2 2))"))
assert g.ExportToWkt() == "COMPOUNDCURVE EMPTY"
# Check that discretization is not sensitive to winding order
g1 = ogr.CreateGeometryFromWkt(
"COMPOUNDCURVE((-1 0,0 1),CIRCULARSTRING (0 1,0.25 0,0.1 -0.5),(0.1 -0.5,-1 0))"
)
g2 = g1.GetLinearGeometry(1.5)
g1 = ogr.CreateGeometryFromWkt(
"COMPOUNDCURVE((-1 0,0.1 -0.5),CIRCULARSTRING (0.1 -0.5,0.25 0,0 1),(0 1,-1 0))"
)
g3 = g1.GetLinearGeometry(1.5)
p_count = g2.GetPointCount()
for i in range(p_count):
# yes we do strict (binary) comparison. This is really intended.
# The curves must be exactly the same, despite our stealth mode
if g2.GetX(i) != g3.GetX(p_count - 1 - i) or g2.GetY(i) != g3.GetY(
p_count - 1 - i
):
print(abs(g2.GetX(i) - g3.GetX(p_count - 1 - i)))
pytest.fail(abs(g2.GetY(i) - g3.GetY(p_count - 1 - i)))
# Test Transform
sr = osr.SpatialReference()
sr.ImportFromEPSG(4326)
g.AssignSpatialReference(sr)
g.TransformTo(sr)
# Invalid wkb
wkb_list = [
"\x01\x09\x00\x00\x00\x01\x00\x00\x00", # subgeometry declared but not present
"\x01\x09\x00\x00\x00\xff\xff\xff\x7f", # 2 billion subgeometries declared !
"\x01\x09\x00\x00\x00\x01\x00\x00\x00\x01\xff\x00\x00\x00\x00\x00\x00\x00", # subgeometry invalid: unknown type
"\x01\x09\x00\x00\x00\x01\x00\x00\x00\x01\x02\x00\x00\x00\x01\x00\x00\x00", # subgeometry invalid: linestring truncated
"\x01\x09\x00\x00\x00\x01\x00\x00\x00\x01\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # subgeometry invalid: linestring with one point
"\x01\x09\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # subgeometry invalid: point
"\x01\x09\x00\x00\x00\x01\x00\x00\x00\x01\x09\x00\x00\x00\x00\x00\x00\x00", # subgeometry invalid: compoundcurve
]
for wkb in wkb_list:
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkb(wkb)
assert g is None, wkb
# EMPTY
for in_wkt in ["COMPOUNDCURVE EMPTY", "COMPOUNDCURVE Z EMPTY"]:
g1 = ogr.CreateGeometryFromWkt(in_wkt)
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.Length() == 0.0, in_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
###############################################################################
# Test OGRCurvePolygon
def test_ogr_geom_curvepolygon():
in_wkt = "CURVEPOLYGON (CIRCULARSTRING (0 0,1 0,0 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCurvePolygon
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
if ogrtest.have_geos():
p1 = g1.PointOnSurface()
assert (p1.GetX() - 0.5) * (
p1.GetX() - 0.5
) + p1.GetY() * p1.GetY() <= 0.5 * 0.5
env = g1.GetEnvelope()
expected_env = (0.0, 1.0, -0.5, 0.5)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
area = g1.Area()
expected_area = math.pi * 0.5 * 0.5
assert area == pytest.approx(expected_area, abs=1e-8)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# CURVEPOLYGON of LINESTRING
in_wkt = "CURVEPOLYGON ((0 0,0 10,10 10,10 0,0 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.HasCurveGeometry()
assert not g1.HasCurveGeometry(True)
# With Z
in_wkt = "CURVEPOLYGON Z (CIRCULARSTRING Z (0 0 10,1 0 10,0 0 10))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbCurvePolygonZ
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
wkb = g1.ExportToWkb()
isowkb = g1.ExportToIsoWkb()
assert wkb == isowkb
g2 = ogr.CreateGeometryFromWkb(wkb)
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Test stroking
with gdal.config_options({"OGR_STROKE_CURVE": "TRUE", "OGR_ARC_STEPSIZE": "45"}):
in_wkt = "CURVEPOLYGON (CIRCULARSTRING (0 0,1 0,0 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
expected_g = ogr.CreateGeometryFromWkt(
"POLYGON ((0 0,0.116977778440514 -0.321393804843282,0.413175911166547 -0.49240387650611,0.75 -0.433012701892224,0.969846310392967 -0.171010071662835,0.969846310392967 0.171010071662835,0.75 0.433012701892224,0.413175911166547 0.49240387650611,0.116977778440514 0.321393804843282,0 0))"
)
assert ogrtest.check_feature_geometry(g1, expected_g) == 0
in_wkt = "CURVEPOLYGON (CIRCULARSTRING (0 0,1 0,0 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
in_wkb = g1.ExportToWkb()
with gdal.config_options({"OGR_STROKE_CURVE": "TRUE", "OGR_ARC_STEPSIZE": "45"}):
g2 = ogr.CreateGeometryFromWkb(in_wkb)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test HasCurveGeometry
assert g1.HasCurveGeometry()
assert g1.HasCurveGeometry(True)
# Test GetLinearGeometry
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test ForceToPolygon
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToPolygon(g1)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test ForceToMultiPolygon
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
expected_g2 = ogr.CreateGeometryFromWkt(
"MULTIPOLYGON (((0 0,0.116977778440514 -0.321393804843282,0.413175911166547 -0.49240387650611,0.75 -0.433012701892224,0.969846310392967 -0.171010071662835,0.969846310392967 0.171010071662835,0.75 0.433012701892224,0.413175911166547 0.49240387650611,0.116977778440514 0.321393804843282,0 0)))"
)
g2 = ogr.ForceToMultiPolygon(g1)
assert ogrtest.check_feature_geometry(g2, expected_g2) == 0
# Test ForceToMultiLineString
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToMultiLineString(g1)
expected_g3 = ogr.CreateGeometryFromWkt(
"MULTILINESTRING ((0 0,0.116977778440514 -0.321393804843282,0.413175911166547 -0.49240387650611,0.75 -0.433012701892224,0.969846310392967 -0.171010071662835,0.969846310392967 0.171010071662835,0.75 0.433012701892224,0.413175911166547 0.49240387650611,0.116977778440514 0.321393804843282,0 0))"
)
assert ogrtest.check_feature_geometry(g2, expected_g3) == 0
# Test GEOS operations
if ogrtest.have_geos():
g2 = g1.Intersection(g1)
assert g2 is not None
# Test CURVEPOLYGON and COMPOUNDCURVE, CIRCULARSTRING, LINESTRING
in_wkt = "CURVEPOLYGON (COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,2 0),(2 0,0 0)),(0.1 0.1,0.1 0.2,0.2 0.2,0.2 0.1,0.1 0.1),CIRCULARSTRING (0.25 0.25,0.75 0.25,0.25 0.25))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
assert g2.ExportToWkt() == in_wkt
# Test CURVEPOLYGON wrapped in a GEOMETRYCOLLECTION
in_wkt = "GEOMETRYCOLLECTION(CURVEPOLYGON(CIRCULARSTRING (0 0,1 0,0 0)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
assert g1.Equals(g2)
# Test GEOS operations
if ogrtest.have_geos():
g2 = g1.Intersection(g1)
assert g2 is not None
# Test ForceToPolygon
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToPolygon(g1)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test ForceToMultiPolygon
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToMultiPolygon(g1)
assert ogrtest.check_feature_geometry(g2, expected_g2) == 0
# Error case : not enough points
in_wkt = "CURVEPOLYGON ((0 0,0 1,0 0))"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Error case : wrong sub-geometry type
in_wkt = "CURVEPOLYGON (POINT EMPTY)"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Error case: non closed ring
in_wkt = "CURVEPOLYGON ((0 0,0 1,1 1,1 0))"
with gdaltest.error_handler():
with gdaltest.config_option("OGR_GEOMETRY_ACCEPT_UNCLOSED_RING", "NO"):
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
# Area
g = ogr.CreateGeometryFromWkt("CURVEPOLYGON ((0 0,1 1,1 0,0 0))")
assert g.Area() == 0.5
g = ogr.CreateGeometryFromWkt("CURVEPOLYGON (COMPOUNDCURVE((0 0,1 1,1 0,0 0)))")
assert g.Area() == 0.5
g = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (COMPOUNDCURVE((0 0,1 1),(1 1,1 0,0 0)))"
)
assert g.Area() == 0.5
g = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON ((100000000 100000000,100000001 100000001,100000001 100000000,100000000 100000000))"
)
assert g.Area() == 0.5
# Equals
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON ((0 0,1 1,1 0,0 0),CIRCULARSTRING(0.75 0.5,0.85 0.5,0.75 0.5))"
)
assert g1.Equals(g1)
assert g1.Equals(g1.Clone())
assert not g1.Equals(ogr.CreateGeometryFromWkt("POINT(0 0)"))
assert not g1.Equals(ogr.CreateGeometryFromWkt("CURVEPOLYGON ((0 0,1 1,1 0,0 0))"))
# Intersects optimizations on a circle
g1 = ogr.CreateGeometryFromWkt("CURVEPOLYGON (CIRCULARSTRING (0 0,2 0,0 0))")
# Point slightly within circle
p1 = ogr.CreateGeometryFromWkt(
"POINT (%.16g %.16g)"
% (1 + math.cos(math.pi / 6) - 1e-4, math.sin(math.pi / 6))
)
# To prove that we don't use discretization
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
res = g1.Intersects(p1)
res = res & p1.Intersects(g1)
res = res & g1.Contains(p1)
res = res & p1.Within(g1)
assert res
# Test point slightly outside circle
p2 = ogr.CreateGeometryFromWkt(
"POINT (%.16g %.16g)"
% (1 + math.cos(math.pi / 6) + 1e-4, math.sin(math.pi / 6))
)
assert not p2.Within(g1)
# Full circle defined by 2 arcs
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (CIRCULARSTRING (0 0,1 1,2 0,1 -1,0 0))"
)
assert p1.Within(g1)
# Same but in reverse order
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (CIRCULARSTRING (0 0,1 -1,2 0,1 1,0 0))"
)
assert p1.Within(g1)
# This is not a circle
p2 = ogr.CreateGeometryFromWkt(
"POINT (%.16g %.16g)"
% (1 + math.cos(math.pi / 6) - 1e-2, math.sin(math.pi / 6))
)
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (CIRCULARSTRING (0 0,1 1,2 0,1 1,0 0))"
)
assert not p2.Within(g1)
# Test area on circle in 2 pieces
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (CIRCULARSTRING (0 0,1 1,2 0,1 -1,0 0))"
)
area = g1.Area()
expected_area = math.pi
assert area == pytest.approx(expected_area, abs=1e-10)
# Test area on hippodrome
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (CIRCULARSTRING (0 0,1 1,2 0,2 -1,2 -2,1 -3,0 -2,0 -1,0 0))"
)
area = g1.Area()
expected_area = math.pi + 2 * 2
assert area == pytest.approx(expected_area, abs=1e-10)
# Same hippodrome but with different WKT
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING (0 0,1 1,2 0),(2 0,2 -2),CIRCULARSTRING(2 -2,1 -3,0 -2),(0 -2,0 0)))"
)
area = g1.Area()
expected_area = math.pi + 2 * 2
assert area == pytest.approx(expected_area, abs=1e-10)
# Similar, but with concave part (does not trigger optimization)
g1 = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING (0 0,1 1,2 0),(2 0,2 -2),CIRCULARSTRING(2 -2,1 -1,0 -2),(0 -2,0 0)))"
)
area = g1.Area()
expected_area = 2 * 2
assert area == pytest.approx(expected_area, abs=1e-10)
# EMPTY
for in_wkt in ["CURVEPOLYGON EMPTY", "CURVEPOLYGON Z EMPTY"]:
g1 = ogr.CreateGeometryFromWkt(in_wkt)
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.Area() == 0.0, in_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Empty CircularString
g = ogr.Geometry(ogr.wkbCurvePolygon)
g.AddGeometry(ogr.Geometry(ogr.wkbCircularString))
assert g.Area() == 0
# Non-convex CircularString
g = ogr.CreateGeometryFromWkt(
"CURVEPOLYGON( COMPOUNDCURVE( CIRCULARSTRING(0 0,0.5 -0.5,1 0,1.5 0.5,2 0), (2 0,2 1,0 1,0 0) ) )"
)
assert g.Area() == pytest.approx(2.0, abs=1e-10)
###############################################################################
# Test OGRMultiCurve
def test_ogr_geom_multicurve():
# Simple test
in_wkt = "MULTICURVE (CIRCULARSTRING (0 0,1 0,0 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbMultiCurve
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.GetDimension() == 1
env = g1.GetEnvelope()
expected_env = (0.0, 1.0, -0.5, 0.5)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
length = g1.Length()
expected_length = 2 * math.pi * 0.5
assert length == pytest.approx(expected_length, abs=1e-8)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
assert g1.HasCurveGeometry()
assert g1.HasCurveGeometry(True)
# MULTICURVE of LINESTRING
in_wkt = "MULTICURVE ((0 0,1 0))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.HasCurveGeometry()
assert not g1.HasCurveGeometry(True)
# Z
in_wkt = "MULTICURVE Z (CIRCULARSTRING Z (0 0 10,1 0 10,0 0 10))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbMultiCurveZ
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# WKT with all possible sub geometries
in_wkt = "MULTICURVE (CIRCULARSTRING (0 0,1 0,0 0),(0 0,1 1),COMPOUNDCURVE ((0 0,1 1),CIRCULARSTRING (1 1,2 2,3 3)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Test ForceToMultiLineString
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToMultiLineString(g1)
expected_g = "MULTILINESTRING ((0 0,0.116977778440514 -0.321393804843282,0.413175911166547 -0.49240387650611,0.75 -0.433012701892224,0.969846310392967 -0.171010071662835,0.969846310392967 0.171010071662835,0.75 0.433012701892224,0.413175911166547 0.49240387650611,0.116977778440514 0.321393804843282,0 0),(0 0,1 1),(0 0,1 1,2 2,3 3))"
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test GetLinearGeometry
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Error case : wrong sub-geometry type
in_wkt = "MULTILINESTRING (POINT EMPTY)"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
###############################################################################
# Test OGRMultiSurface
def test_ogr_geom_multisurface():
# Simple test
in_wkt = "MULTISURFACE (CURVEPOLYGON (CIRCULARSTRING (0 0,1 0,0 0)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbMultiSurface
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
assert g1.GetDimension() == 2
env = g1.GetEnvelope()
expected_env = (0.0, 1.0, -0.5, 0.5)
for i in range(4):
assert env[i] == pytest.approx(expected_env[i], abs=1e-8)
area = g1.Area()
expected_area = math.pi * 0.5 * 0.5
assert area == pytest.approx(expected_area, abs=1e-8)
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
assert g1.HasCurveGeometry()
assert g1.HasCurveGeometry(True)
# Z
in_wkt = "MULTISURFACE Z (CURVEPOLYGON Z (CIRCULARSTRING Z (0 0 10,1 0 10,0 0 10)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.GetGeometryType() == ogr.wkbMultiSurfaceZ
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# MULTISURFACE of POLYGON
in_wkt = "MULTISURFACE (((0 0,0 10,10 10,10 0,0 0)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
assert g1.HasCurveGeometry()
assert not g1.HasCurveGeometry(True)
# WKT with all possible sub geometries
in_wkt = "MULTISURFACE (((0 0,0 10,10 10,10 0,0 0)),CURVEPOLYGON (CIRCULARSTRING (0 0,1 0,0 0)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
out_wkt = g1.ExportToWkt()
assert in_wkt == out_wkt
g2 = ogr.CreateGeometryFromWkb(g1.ExportToWkb())
out_wkt = g2.ExportToWkt()
assert in_wkt == out_wkt
# Test ForceToMultiPolygon
with gdal.config_option("OGR_ARC_STEPSIZE", "45"):
g2 = ogr.ForceToMultiPolygon(g1)
expected_g = "MULTIPOLYGON (((0 0,0 10,10 10,10 0,0 0)),((0 0,0.116977778440514 -0.321393804843282,0.413175911166547 -0.49240387650611,0.75 -0.433012701892224,0.969846310392967 -0.171010071662835,0.969846310392967 0.171010071662835,0.75 0.433012701892224,0.413175911166547 0.49240387650611,0.116977778440514 0.321393804843282,0 0)))"
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Test GetLinearGeometry
g2 = g1.GetLinearGeometry(45)
assert ogrtest.check_feature_geometry(g2, expected_g) == 0
# Check that GetLinearGeometry() is idem-potent on MULTIPOLYGON
g3 = g2.GetLinearGeometry(45)
assert g3.Equals(g2)
# PointOnSurface
if ogrtest.have_geos():
in_wkt = "MULTISURFACE (((0 0,0 10,10 10,10 0,0 0),(1 1,1 9,9 9,9 1,1 1)),((10 0,10 10,20 10,20 0,10 0),(11 1,11 9,19 9,19 1,11 1)))"
g1 = ogr.CreateGeometryFromWkt(in_wkt)
p1 = g1.PointOnSurface()
assert p1.ExportToWkt() == "POINT (0.5 5.0)"
# Error case : wrong sub-geometry type
in_wkt = "MULTIPOLYGON (POINT EMPTY)"
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkt(in_wkt)
assert g is None
###############################################################################
# Test GetCurveGeometry
def test_ogr_geom_getcurvegeometry():
for geom in [
"POINT",
"LINESTRING",
"POLYGON",
"MULTIPOINT",
"MULTILINESTRING",
"MULTIPOLYGON",
"GEOMETRYCOLLECTION",
"CIRCULARSTRING",
"COMPOUNDCURVE",
"CURVEPOLYGON",
"MULTICURVE",
"MULTISURFACE",
]:
in_wkt = geom + " EMPTY"
g = ogr.CreateGeometryFromWkt(in_wkt)
g2 = g.GetCurveGeometry()
assert g2.ExportToWkt() == in_wkt, g
g = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION(POINT (0 1))")
g2 = g.GetCurveGeometry()
assert g.Equals(g2)
g = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION(LINESTRING (0 0,0 1,0 0))")
g2 = g.GetCurveGeometry()
assert g.Equals(g2)
g = ogr.CreateGeometryFromWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))")
g2 = g.GetCurveGeometry()
assert g.Equals(g2)
g = ogr.CreateGeometryFromWkt("POLYGON Z ((0 0 10,0 1 10,1 1 10,1 0 10,0 0 10))")
g2 = g.GetCurveGeometry()
assert g.Equals(g2)
# CircularString with large step
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1 1,2 0)")
g2 = g1.GetLinearGeometry(15)
g3 = g2.GetCurveGeometry()
assert (
g3.GetGeometryType() == ogr.wkbCircularString
and g1.GetPoint(0) == g3.GetPoint(0)
and g1.GetPoint(2) == g3.GetPoint(2)
and abs((g3.GetX(1) - 1) * (g3.GetX(1) - 1) + g3.GetY(1) * g3.GetY(1) - 1)
<= 1e-8
)
# CurvePolygon with large step
g1 = ogr.CreateGeometryFromWkt("CURVEPOLYGON( CIRCULARSTRING (0 0,1 1,0 0))")
g2 = g1.GetLinearGeometry(15)
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# This is a straight line
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (1 2,3 4,5 6)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.ExportToWkt() == "LINESTRING (1 2,3 4,5 6)"
# "Random" arcs
for wkt in [
"CIRCULARSTRING (1 2,3 1,5 6)",
"CIRCULARSTRING (1 -2,3 -1,5 -6)",
"CIRCULARSTRING (-1 2,-3 1,-5 6)",
"CIRCULARSTRING (5 6,3 1,1 2)",
"CIRCULARSTRING (-5 6,-3 1,-1 2)",
"CIRCULARSTRING (5 -6,3 -1,1 -2)",
"CIRCULARSTRING (215725 -977513,872751 872597,560240 -7500)",
"CIRCULARSTRING (-492367 816163,537838 -421954,745494 -65479)",
"CIRCULARSTRING (543208 -865295,582257 635396,563925 -68156)",
"CIRCULARSTRING (-481 -193,1 329,-692 -421)",
"CIRCULARSTRING (525407 781005,710737 463833,-674365 340022)",
"CIRCULARSTRING (743949 709309,743952 709307,743964 709298)",
"CIRCULARSTRING (283167 -48388,536492 -197399,-449301 382451)",
]:
g1 = ogr.CreateGeometryFromWkt(wkt)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Really random arcs with coordinates in the [-1000,1000] range
for i in range(1000):
v = [random.randint(-1000, 1000) for i in range(6)]
if v[0] != v[4] or v[1] != v[5]:
wkt = "CIRCULARSTRING (%d %d,%d %d,%d %d)" % (
v[0],
v[1],
v[2],
v[3],
v[4],
v[5],
)
g1 = ogr.CreateGeometryFromWkt(wkt)
g2 = g1.GetLinearGeometry()
if g2.GetPointCount() != 3:
g3 = g2.GetCurveGeometry()
if not g3.Equals(g1):
# FIXME sometime... but avoid failing. for now. This randomly fails, but this is not
# the end of the world...
# gdaltest.post_reason('fail')
print("Difference found :")
print(g1)
print(g3)
# return 'fail'
# Really random arcs in random displacements, but with small radius
for i in range(1000):
x = random.randint(-1000000, 1000000)
y = random.randint(-1000000, 1000000)
v = [random.randint(-10, 10) for i in range(6)]
if v[0] != v[4] or v[1] != v[5]:
wkt = "CIRCULARSTRING (%d %d,%d %d,%d %d)" % (
x + v[0],
y + v[1],
x + v[2],
y + v[3],
x + v[4],
y + v[5],
)
g1 = ogr.CreateGeometryFromWkt(wkt)
g2 = g1.GetLinearGeometry()
if g2.GetPointCount() != 3:
g3 = g2.GetCurveGeometry()
if not g3.Equals(g1):
# FIXME sometime... but avoid failing. for now. This randomly fails, but this is not
# the end of the world...
# gdaltest.post_reason('fail')
print("Difference found :")
print(g1)
print(g3)
# return 'fail'
# Really random arcs with coordinates in the [-1000000,1000000] range
for i in range(1000):
v = [random.randint(-1000000, 1000000) for i in range(6)]
if v[0] != v[4] or v[1] != v[5]:
wkt = "CIRCULARSTRING (%d %d,%d %d,%d %d)" % (
v[0],
v[1],
v[2],
v[3],
v[4],
v[5],
)
g1 = ogr.CreateGeometryFromWkt(wkt)
g2 = g1.GetLinearGeometry()
if g2.GetPointCount() != 3:
g3 = g2.GetCurveGeometry()
if not g3.Equals(g1):
# FIXME sometime... but avoid failing. for now. This randomly fails, but this is not
# the end of the world...
# gdaltest.post_reason('fail')
print("Difference found :")
print(g1)
print(g3)
# return 'fail'
# 5 points full circle
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,0.5 -0.5,1 0,0.5 0.5,0 0)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# 3 points full circle
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1 0,0 0)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert (
g3.GetGeometryType() == ogr.wkbCircularString
and g1.GetPoint(0) == g3.GetPoint(0)
and g1.GetPoint(1) == g3.GetPoint(2)
and g1.GetPoint(2) == g3.GetPoint(4)
and abs(
(g3.GetX(1) - 0.5) * (g3.GetX(1) - 0.5)
+ g3.GetY(1) * g3.GetY(1)
- 0.5 * 0.5
)
<= 1e-12
and abs(
(g3.GetX(3) - 0.5) * (g3.GetX(3) - 0.5)
+ g3.GetY(3) * g3.GetY(3)
- 0.5 * 0.5
)
<= 1e-12
)
# 3 points full circle in a CurvePolygon
for wkt in [
"CURVEPOLYGON( CIRCULARSTRING (0 0,1 0,0 0))",
"CURVEPOLYGON( CIRCULARSTRING (0 0,0 1,0 0))",
"CURVEPOLYGON( CIRCULARSTRING (0 0,-1 0,0 0))",
"CURVEPOLYGON( CIRCULARSTRING (0 0,0 -1,0 0))",
]:
g1 = ogr.CreateGeometryFromWkt(wkt)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# 2 curves in the CircularString
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1 1,2 0,3 -1,4 0)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# 3 curves in the CircularString
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1 1,2 0,3 -1,4 0,5 1,6 0)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# CircularString, LineString, CircularString
g1 = ogr.CreateGeometryFromWkt(
"COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,2 0),(2 0,3 0,4 0),CIRCULARSTRING (4 0,5 1,6 0))"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# LineString, CircularString, LineString, CircularString, LineString
g1 = ogr.CreateGeometryFromWkt(
"COMPOUNDCURVE ((-1 0,-0.5 0.5,0 0),CIRCULARSTRING (0 0,1 1,2 0),(2 0,3 0,4 0),CIRCULARSTRING (4 0,5 1,6 0),(6 0,7 0))"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Check with default discretization method
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.000997093138961 0.068920262501281,0.006738548124866 0.137608197923873,0.017197098230267 0.205737600590167,0.032323074784779 0.272984917348872,0.052044643056421 0.339030784160355,0.076268143401735 0.403561542787492,0.104878536064531 0.466270730389102,0.137739947510866 0.526860534941749,0.174696315705653 0.585043209577972,0.215572131266425 0.640542439124111,0.260173270974444 0.693094652347904,0.30828791968472 0.742450273683876,0.359687576256715 0.788374908491942,0.414128138728451 0.830650456220319,0.471351063580441 0.869076146186235,0.531084593583979 0.903469491055406,0.593045048402615 0.933667153492107,0.656938171817632 0.959525721864054,0.722460529179411 0.980922391318168,0.789300948448056 0.99775554699276,0.857141997979641 1.009945246596371,0.925661494039921 1.017433600061489,0.994534030886182 1.020185044470095,1.063432526150724 1.01818651294542,1.132029774186796 1.01144749670781,1.2 1.0,1.267547127648721 0.983752320094182,1.333803428245673 0.962854851656094,1.398449236893265 0.937408418110045,1.461172658788815 0.907535790143504,1.521671074014578 0.873381093378847,1.579652597579492 0.835109113014538,1.634837487668428 0.792904498790658,1.686959495304612 0.746970874114522,1.73576714891352 0.697529853644598,1.781024967590663 0.644819974072535,1.822514597219645 0.589095543261942,1.860035863959079 0.53062541329644,1.89340774001566 0.469691683356621,1.922469217043826 0.406588338684124,1.94708008295817 0.341619832199361,1.967121598410718 0.27509961561613,1.982497069669296 0.207348627140011,1.993132315133044 0.138693743046887,1.998976023234287 0.069466200612231,2 0)"
)
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Check with alternate discretization method : ROUND_ANGLE_METHOD
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,-0.000199980003999 0.02,0.002236456877416 0.089770423644023,0.009533897446083 0.159200932797352,0.021656789305088 0.227953268998521,0.038546070943884 0.295692477776518,0.060119459480029 0.362088540515299,0.086271851533127 0.426817982271309,0.116875835277923 0.489565447710894,0.151782311181914 0.550025237489786,0.190821218403283 0.607902797589577,0.233802363310224 0.662916154355295,0.280516346085201 0.7147972882427,0.330735580899807 0.763293439582565,0.384215404690045 0.80816834000038,0.440695269130182 0.849203363492117,0.499900009998002 0.886198591548151,0.561541187747236 0.918973787136141,0.62531849275604 0.947369272797732,0.690921208405283 0.971246708581086,0.758029724858684 0.990489766019218,0.826317096169807 1.005004694870594,0.895450633129846 1.014720779860886,0.965093524096011 1.019590685200679,1.034906475903993 1.019590685200679,1.104549366870158 1.014720779860886,1.173682903830197 1.005004694870593,1.2 1.0,1.241970275141317 0.990489766019217,1.309078791594718 0.971246708581085,1.374681507243961 0.947369272797731,1.438458812252765 0.91897378713614,1.500099990002 0.886198591548151,1.559304730869819 0.849203363492116,1.615784595309956 0.808168340000379,1.669264419100194 0.763293439582565,1.7194836539148 0.714797288242699,1.766197636689777 0.662916154355294,1.809178781596718 0.607902797589576,1.848217688818087 0.550025237489785,1.883124164722078 0.489565447710893,1.913728148466874 0.426817982271308,1.939880540519971 0.362088540515298,1.961453929056117 0.295692477776516,1.978343210694912 0.227953268998519,1.990466102553917 0.15920093279735,1.997763543122584 0.089770423644022,2.000199980003999 0.02,2 0)"
)
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Check with PostgreSQL output of SELECT ST_CurveToLine(ST_GeomFromText('CIRCULARSTRING (0 0,1.2 1.0,2 0)'))
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = ogr.CreateGeometryFromWkt(
"LINESTRING (0 0,0.000223190308279 0.049091765203314,0.002854930521212 0.098113445796116,0.007888880546112 0.146946944256066,0.015312913156447 0.195474616408063,0.025109143207391 0.243579554839372,0.037253970722702 0.291145870539817,0.051718137749134 0.338058972088558,0.068466798841411 0.384205841714863,0.08745960500795 0.429475307567812,0.108650800915124 0.473758311539029,0.131989335115863 0.516948171993215,0.157418983037062 0.558940840773549,0.184878482429505 0.599635153862819,0.214301680953989 0.638933075096389,0.245617695548099 0.676739932339917,0.27875108318972 0.712964645562815,0.31362202264588 0.747519946258017,0.350146506769097 0.780322587679462,0.388236544877951 0.811293545390794,0.427800374734344 0.840358207642151,0.46874268360677 0.867446555116406,0.510964837887032 0.892493329611833,0.554365120707246 0.915438191254836,0.598838976984681 0.936225863863983,0.644279265304116 0.954806268115175,0.690576516030889 0.971134642187118,0.737619195032841 0.985171649596477,0.785293972375802 0.996883473962907,0.833485995345338 1.006241900475673,0.88207916513699 1.013224383865605,0.930956416548473 1.017814102718623,0.98 1.02,1.029091765203309 1.019776809691721,1.078113445796111 1.017145069478788,1.12694694425606 1.012111119453889,1.175474616408058 1.004687086843554,1.223579554839367 0.994890856792611,1.271145870539812 0.9827460292773,1.318058972088553 0.968281862250867,1.364205841714858 0.951533201158591,1.409475307567807 0.932540394992052,1.453758311539024 0.911349199084878,1.49694817199321 0.88801066488414,1.538940840773545 0.862581016962941,1.579635153862814 0.835121517570498,1.618933075096384 0.805698319046015,1.656739932339913 0.774382304451905,1.692964645562811 0.741248916810284,1.727519946258013 0.706377977354124,1.760322587679458 0.669853493230907,1.791293545390791 0.631763455122053,1.820358207642148 0.59219962526566,1.847446555116403 0.551257316393235,1.872493329611831 0.509035162112973,1.895438191254833 0.465634879292759,1.916225863863981 0.421161023015324,1.934806268115173 0.37572073469589,1.951134642187117 0.329423483969116,1.965171649596476 0.282380804967164,1.976883473962906 0.234706027624203,1.986241900475672 0.186514004654668,1.993224383865604 0.137920834863015,1.997814102718623 0.089043583451532,2.0 0.04,2 0)"
)
g3 = g2.GetCurveGeometry()
g1_expected = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,0.98 1.02,2 0)")
assert g3.Equals(g1_expected)
# Test default ( implicit option ADD_INTERMEDIATE_POINT=STEALTH )
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test with Z
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0 1,1 1 2,2 0 3)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (2 0 3,1 1 2,0 0 1)")
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test option ADD_INTERMEDIATE_POINT=STEALTH
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = g1.GetLinearGeometry(options=["ADD_INTERMEDIATE_POINT=STEALTH"])
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test option ADD_INTERMEDIATE_POINT=YES
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = g1.GetLinearGeometry(options=["ADD_INTERMEDIATE_POINT=YES"])
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test with big coordinates. The points are (2,49),(3,50),(4,49) reprojected from EPSG:4326 to EPSG:32631
g1 = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING (426857.987717275 5427937.52346616,500000.000000001 5538630.70286887,573142.012282726 5427937.52346616)"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert ogrtest.check_feature_geometry(g3, g1) == 0
# Same with integer coordinates
g1 = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING (426858 5427938,500000 5538632,573142 5427938)"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test option ADD_INTERMEDIATE_POINT=FALSE
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1.2 1.0,2 0)")
g2 = g1.GetLinearGeometry(options=["ADD_INTERMEDIATE_POINT=FALSE"])
g3 = g2.GetCurveGeometry()
g1_expected = ogr.CreateGeometryFromWkt(
"CIRCULARSTRING (0 0,1.0 1.020199980003999,2 0)"
)
assert ogrtest.check_feature_geometry(g3, g1_expected) == 0
# Test with unrecognized options
with gdaltest.error_handler():
g2_new = g1.GetLinearGeometry(
options=["bla", "ADD_INTERMEDIATE_POINT=FALSE", "foo=bar"]
)
assert g2_new.Equals(g2)
# Add repeated point at end of line
g2 = g1.GetLinearGeometry()
g2.AddPoint_2D(2 - 1e-9, 0)
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Add repeated point at end of line
g2 = g1.GetLinearGeometry()
g2_new = ogr.Geometry(ogr.wkbLineString)
g2_new.AddPoint_2D(0, 1e-9)
for i in range(g2.GetPointCount()):
g2_new.AddPoint_2D(g2.GetX(i), g2.GetY(i))
g3 = g2_new.GetCurveGeometry()
assert g3.Equals(g1)
# Test various configurations
for (wkt, eps) in [
("CIRCULARSTRING (0 0,0.5 0.5,0 1,-0.5 0.5,0 0)", 0),
("CIRCULARSTRING (0 0,-0.5 0.5,0 1,0.5 0.5,0 0)", 0),
("CIRCULARSTRING (0 0,0.5 -0.5,0 -1,-0.5 -0.5,0 0)", 0),
("CIRCULARSTRING (0 0,-0.5 -0.5,0 -1,0.5 -0.5,0 0)", 0),
("CIRCULARSTRING (-1 -1,-1 1,1 1,1 -1,-1 -1)", 0),
("CIRCULARSTRING (-1 -1,1 -1,1 1,-1 1,-1 -1)", 0),
("CIRCULARSTRING (0 1,1 0,0 -1,-1 0,0 1)", 0),
("CIRCULARSTRING (0 0.01,0.01 0,0 -0.01,-0.01 0,0 0.01)", 0),
("CIRCULARSTRING (0 0.0001,0.0001 0,0 -0.0001,-0.0001 0,0 0.0001)", 0),
("CIRCULARSTRING (0 1000000,1000000 0,0 -1000000,-1000000 0,0 1000000)", 0),
("CIRCULARSTRING (1234567 8901234,5678901 23456789,0123456 78901234)", 0),
(
"CIRCULARSTRING (1234567.12 8901234.34,5678901.56 23456789.01,0123456.78 78901234.56)",
1e-1,
),
("CIRCULARSTRING (1234567 -8901234,-5678901 23456789,0123456 -78901234)", 0),
(
"CIRCULARSTRING (0 0.000001,0.000001 0,0 -0.000001,-0.000001 0,0 0.000001)",
1e-12,
),
(
"CIRCULARSTRING (0 0.00000001,0.00000001 0,0 -0.00000001,-0.00000001 0,0 0.00000001)",
1e-12,
),
(
"CIRCULARSTRING (1 0.00000001,1.00000001 0,1 -0.00000001,0.99999999 0,1 0.00000001)",
1e-12,
),
(
"CIRCULARSTRING (100000000 1,100000001 0,100000000 -1,99999999 0,100000000 1)",
0,
),
(
"CIRCULARSTRING (-100000000 1,-100000001 0,-100000000 -1,-99999999 0,-100000000 1)",
0,
),
(
"CIRCULARSTRING (100000000 100000001,100000001 100000000,100000000 99999999,99999999 100000000,100000000 100000001)",
0,
),
(
"CIRCULARSTRING (760112.098000001162291 207740.096999999135733,760116.642489952617325 207741.101843414857285,760120.967999998480082 207742.820000000298023,760123.571822694852017 207744.275888498465065,760126.011999998241663 207745.991999998688698,760127.330062366439961 207747.037052432337077,760128.585999999195337 207748.155999999493361)",
1e-5,
),
]:
g1 = ogr.CreateGeometryFromWkt(wkt)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert not (eps == 0 and not g3.Equals(g1)) or (
eps > 0 and ogrtest.check_feature_geometry(g3, g1, eps) != 0
), ""
# Test with GEOMETRYCOLLECTION container
g1 = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION(CIRCULARSTRING (0 0,0.5 0.5,0 1,-0.5 0.5,0 0))"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test with MULTICURVE container
g1 = ogr.CreateGeometryFromWkt(
"MULTICURVE(CIRCULARSTRING (0 0,0.5 0.5,0 1,-0.5 0.5,0 0))"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
# Test with MULTISURFACE container
g1 = ogr.CreateGeometryFromWkt(
"MULTISURFACE(CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING (0 0,0.5 0.5,1 0),(1 0,0 0))))"
)
g2 = g1.GetLinearGeometry()
g3 = g2.GetCurveGeometry()
assert g3.Equals(g1)
if ogrtest.have_geos():
g1 = ogr.CreateGeometryFromWkt("CURVEPOLYGON(CIRCULARSTRING (0 0,2 0,0 0))")
g2 = ogr.CreateGeometryFromWkt("CURVEPOLYGON(CIRCULARSTRING (1 0,3 1,1 0))")
g3 = g1.Intersection(g2)
assert g3.GetGeometryType() == ogr.wkbCurvePolygon
g1 = ogr.CreateGeometryFromWkt("CURVEPOLYGON(CIRCULARSTRING (0 0,2 0,0 0))")
g2 = ogr.CreateGeometryFromWkt("CURVEPOLYGON((1 -1,1 1,3 1,3 -1,1 -1))")
g3 = g1.Intersection(g2)
assert g3.GetGeometryType() == ogr.wkbCurvePolygon
g1 = ogr.CreateGeometryFromWkt("CURVEPOLYGON(CIRCULARSTRING (0 0,2 0,0 0))")
g2 = ogr.CreateGeometryFromWkt("CURVEPOLYGON(CIRCULARSTRING (3 0,5 0,3 0))")
g3 = g1.Union(g2)
assert (
g3.ExportToWkt()
== "MULTISURFACE (CURVEPOLYGON (CIRCULARSTRING (0 0,2 0,0 0)),CURVEPOLYGON (CIRCULARSTRING (3 0,5 0,3 0)))"
)
g1 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (0 0,1 1,2 0))")
g2 = ogr.CreateGeometryFromWkt("CIRCULARSTRING (2 0,1 -1,0 0))")
g3 = g1.Union(g2)
assert (
g3.ExportToWkt()
== "MULTICURVE (CIRCULARSTRING (0 0,1 1,2 0),CIRCULARSTRING (2 0,1 -1,0 0))"
or g3.ExportToWkt()
== "MULTICURVE (CIRCULARSTRING (2 0,1 -1,0 0),CIRCULARSTRING (0 0,1 1,2 0))"
) # GEOS OverlayNG
g1 = ogr.CreateGeometryFromWkt("POINT(1 2)")
g1 = g1.Buffer(0.5)
g1 = g1.GetCurveGeometry()
assert (
g1.ExportToWkt()
== "CURVEPOLYGON (CIRCULARSTRING (1.5 2.0,0.5 2.0,1.5 2.0))"
)
###############################################################################
# Test OGR_GT_ functions
def test_ogr_geom_gt_functions():
# GT_HasZ
tuples = [
(ogr.wkbPoint, 0),
(ogr.wkbPoint25D, 1),
(ogr.wkbPointM, 0),
(ogr.wkbPointZM, 1),
(ogr.wkbCircularString, 0),
(ogr.wkbCircularStringZ, 1),
(ogr.wkbCircularStringM, 0),
(ogr.wkbCircularStringZM, 1),
]
for (gt, res) in tuples:
assert ogr.GT_HasZ(gt) == res
# GT_SetZ
tuples = [
(ogr.wkbPoint, ogr.wkbPoint25D),
(ogr.wkbPoint25D, ogr.wkbPoint25D),
(ogr.wkbPointM, ogr.wkbPointZM),
(ogr.wkbPointZM, ogr.wkbPointZM),
(ogr.wkbCircularString, ogr.wkbCircularStringZ),
(ogr.wkbCircularStringZ, ogr.wkbCircularStringZ),
(ogr.wkbCircularStringM, ogr.wkbCircularStringZM),
(ogr.wkbCircularStringZM, ogr.wkbCircularStringZM),
]
for (gt, res) in tuples:
assert ogr.GT_SetZ(gt) == res
# GT_HasM
tuples = [
(ogr.wkbPoint, 0),
(ogr.wkbPoint25D, 0),
(ogr.wkbPointM, 1),
(ogr.wkbPointZM, 1),
(ogr.wkbCircularString, 0),
(ogr.wkbCircularStringZ, 0),
(ogr.wkbCircularStringM, 1),
(ogr.wkbCircularStringZM, 1),
]
for (gt, res) in tuples:
assert ogr.GT_HasM(gt) == res
# GT_SetM
tuples = [
(ogr.wkbPoint, ogr.wkbPointM),
(ogr.wkbPoint25D, ogr.wkbPointZM),
(ogr.wkbPointM, ogr.wkbPointM),
(ogr.wkbPointZM, ogr.wkbPointZM),
(ogr.wkbCircularString, ogr.wkbCircularStringM),
(ogr.wkbCircularStringZ, ogr.wkbCircularStringZM),
(ogr.wkbCircularStringM, ogr.wkbCircularStringM),
(ogr.wkbCircularStringZM, ogr.wkbCircularStringZM),
]
for (gt, res) in tuples:
assert ogr.GT_SetM(gt) == res
# OGR_GT_SetModifier
tuples = [
(ogr.wkbPoint, 0, 0, ogr.wkbPoint),
(ogr.wkbPoint, 1, 0, ogr.wkbPoint25D),
(ogr.wkbPoint, 0, 1, ogr.wkbPointM),
(ogr.wkbPoint, 1, 1, ogr.wkbPointZM),
(ogr.wkbPoint25D, 0, 0, ogr.wkbPoint),
(ogr.wkbPoint25D, 1, 0, ogr.wkbPoint25D),
(ogr.wkbPoint25D, 0, 1, ogr.wkbPointM),
(ogr.wkbPoint25D, 1, 1, ogr.wkbPointZM),
(ogr.wkbPointM, 0, 0, ogr.wkbPoint),
(ogr.wkbPointM, 1, 0, ogr.wkbPoint25D),
(ogr.wkbPointM, 0, 1, ogr.wkbPointM),
(ogr.wkbPointM, 1, 1, ogr.wkbPointZM),
(ogr.wkbCircularString, 1, 0, ogr.wkbCircularStringZ),
(ogr.wkbCircularStringZ, 1, 0, ogr.wkbCircularStringZ),
(ogr.wkbPoint, 0, 0, ogr.wkbPoint),
(ogr.wkbPoint25D, 0, 0, ogr.wkbPoint),
(ogr.wkbCircularString, 0, 0, ogr.wkbCircularString),
(ogr.wkbCircularStringZ, 0, 0, ogr.wkbCircularString),
]
for (gt, modZ, modM, res) in tuples:
assert ogr.GT_SetModifier(gt, modZ, modM) == res
# GT_Flatten
tuples = [
(ogr.wkbPoint, ogr.wkbPoint),
(ogr.wkbPoint25D, ogr.wkbPoint),
(ogr.wkbPointM, ogr.wkbPoint),
(ogr.wkbPointZM, ogr.wkbPoint),
(ogr.wkbCircularString, ogr.wkbCircularString),
(ogr.wkbTriangleZ, ogr.wkbTriangle),
(ogr.wkbCircularStringZ, ogr.wkbCircularString),
(ogr.wkbCircularStringM, ogr.wkbCircularString),
(ogr.wkbCircularStringZM, ogr.wkbCircularString),
]
for (gt, res) in tuples:
assert ogr.GT_Flatten(gt) == res
# GT_IsSubClassOf
tuples = [
(ogr.wkbPoint, ogr.wkbPoint, 1),
(ogr.wkbPoint25D, ogr.wkbPoint, 1),
(ogr.wkbPoint, ogr.wkbUnknown, 1),
(ogr.wkbPoint, ogr.wkbLineString, 0),
(ogr.wkbPolygon, ogr.wkbCurvePolygon, 1),
(ogr.wkbTriangle, ogr.wkbCurvePolygon, 1),
(ogr.wkbTriangle, ogr.wkbPolygon, 1),
(ogr.wkbMultiSurface, ogr.wkbGeometryCollection, 1),
(ogr.wkbMultiPolygon, ogr.wkbMultiSurface, 1),
(ogr.wkbMultiLineString, ogr.wkbMultiCurve, 1),
(ogr.wkbUnknown, ogr.wkbUnknown, 1),
(ogr.wkbUnknown, ogr.wkbPoint, 0),
(ogr.wkbTIN, ogr.wkbPolyhedralSurface, 1),
(ogr.wkbPolyhedralSurface, ogr.wkbTIN, 0),
]
for (gt, gt2, res) in tuples:
assert ogr.GT_IsSubClassOf(gt, gt2) == res
# GT_IsCurve
tuples = [
(ogr.wkbPoint, 0),
(ogr.wkbPoint25D, 0),
(ogr.wkbPointM, 0),
(ogr.wkbPointZM, 0),
(ogr.wkbCircularString, 1),
(ogr.wkbCircularStringZ, 1),
(ogr.wkbLineString, 1),
(ogr.wkbCompoundCurve, 1),
(ogr.wkbCompoundCurveZ, 1),
(ogr.wkbCompoundCurveM, 1),
(ogr.wkbCompoundCurveZM, 1),
(ogr.wkbCurvePolygon, 0),
(ogr.wkbTriangle, 0),
(ogr.wkbPolyhedralSurface, 0),
(ogr.wkbTIN, 0),
]
for (gt, res) in tuples:
assert ogr.GT_IsCurve(gt) == res
# GT_IsSurface
tuples = [
(ogr.wkbPoint, 0),
(ogr.wkbPoint25D, 0),
(ogr.wkbPointM, 0),
(ogr.wkbPointZM, 0),
(ogr.wkbCircularString, 0),
(ogr.wkbCurvePolygon, 1),
(ogr.wkbCurvePolygonZ, 1),
(ogr.wkbCurvePolygonM, 1),
(ogr.wkbCurvePolygonZM, 1),
(ogr.wkbPolygon, 1),
(ogr.wkbTriangle, 1),
(ogr.wkbPolyhedralSurface, 1),
(ogr.wkbTIN, 1),
]
for (gt, res) in tuples:
assert ogr.GT_IsSurface(gt) == res
# GT_GetCollection
tuples = [
(ogr.wkbPoint, ogr.wkbMultiPoint),
(ogr.wkbPoint25D, ogr.wkbMultiPoint25D),
(ogr.wkbPointM, ogr.wkbMultiPointM),
(ogr.wkbPointZM, ogr.wkbMultiPointZM),
(ogr.wkbCircularString, ogr.wkbMultiCurve),
(ogr.wkbCompoundCurve, ogr.wkbMultiCurve),
(ogr.wkbCurvePolygon, ogr.wkbMultiSurface),
(ogr.wkbLineString, ogr.wkbMultiLineString),
(ogr.wkbPolygon, ogr.wkbMultiPolygon),
]
for (gt, res) in tuples:
assert ogr.GT_GetCollection(gt) == res
# GT_IsNonLinear
tuples = [
(ogr.wkbPoint, 0),
(ogr.wkbPoint25D, 0),
(ogr.wkbPointM, 0),
(ogr.wkbPointZM, 0),
(ogr.wkbCircularString, 1),
(ogr.wkbCircularStringM, 1),
(ogr.wkbCircularStringZ, 1),
(ogr.wkbCircularStringZM, 1),
(ogr.wkbCompoundCurve, 1),
(ogr.wkbCurvePolygon, 1),
(ogr.wkbMultiCurve, 1),
(ogr.wkbMultiSurface, 1),
(ogr.wkbLineString, 0),
(ogr.wkbPolygon, 0),
(ogr.wkbTriangle, 0),
]
for (gt, res) in tuples:
assert ogr.GT_IsNonLinear(gt) == res
# GT_GetCurve
tuples = [
(ogr.wkbPoint, ogr.wkbPoint),
(ogr.wkbPoint25D, ogr.wkbPoint25D),
(ogr.wkbPointM, ogr.wkbPointM),
(ogr.wkbPointZM, ogr.wkbPointZM),
(ogr.wkbCircularString, ogr.wkbCircularString),
(ogr.wkbCircularStringZ, ogr.wkbCircularStringZ),
(ogr.wkbCircularStringM, ogr.wkbCircularStringM),
(ogr.wkbCircularStringZM, ogr.wkbCircularStringZM),
(ogr.wkbCompoundCurve, ogr.wkbCompoundCurve),
(ogr.wkbCurvePolygon, ogr.wkbCurvePolygon),
(ogr.wkbLineString, ogr.wkbCompoundCurve),
(ogr.wkbPolygon, ogr.wkbCurvePolygon),
(ogr.wkbMultiLineString, ogr.wkbMultiCurve),
(ogr.wkbMultiPolygon, ogr.wkbMultiSurface),
(ogr.wkbMultiCurve, ogr.wkbMultiCurve),
(ogr.wkbMultiSurface, ogr.wkbMultiSurface),
]
for (gt, res) in tuples:
assert ogr.GT_GetCurve(gt) == res
# GT_GetLinear
tuples = [
(ogr.wkbPoint, ogr.wkbPoint),
(ogr.wkbPoint25D, ogr.wkbPoint25D),
(ogr.wkbPointM, ogr.wkbPointM),
(ogr.wkbPointZM, ogr.wkbPointZM),
(ogr.wkbCircularString, ogr.wkbLineString),
(ogr.wkbCircularStringM, ogr.wkbLineStringM),
(ogr.wkbCircularStringZ, ogr.wkbLineString25D),
(ogr.wkbCircularStringZM, ogr.wkbLineStringZM),
(ogr.wkbCompoundCurve, ogr.wkbLineString),
(ogr.wkbCurvePolygon, ogr.wkbPolygon),
(ogr.wkbLineString, ogr.wkbLineString),
(ogr.wkbPolygon, ogr.wkbPolygon),
(ogr.wkbMultiLineString, ogr.wkbMultiLineString),
(ogr.wkbMultiPolygon, ogr.wkbMultiPolygon),
(ogr.wkbMultiCurve, ogr.wkbMultiLineString),
(ogr.wkbMultiSurface, ogr.wkbMultiPolygon),
]
for (gt, res) in tuples:
assert ogr.GT_GetLinear(gt) == res
###############################################################################
# Limit cases
def test_ogr_geom_api_limit_tests():
p = ogr.Geometry(ogr.wkbPoint)
lyr = ogr.Geometry(ogr.wkbLineString)
poly = ogr.Geometry(ogr.wkbPolygon)
with gdaltest.error_handler():
p.GetX(1)
p.GetY(1)
p.GetZ(1)
lyr.GetX(1)
lyr.GetY(1)
lyr.GetZ(1)
poly.GetX()
poly.GetY()
poly.GetZ()
poly.GetPoints()
p.GetPoint(1)
lyr.GetPoint(1)
poly.GetPoint(1)
p.SetPoint(1, 0, 0)
lyr.SetPoint(-1, 0, 0)
poly.SetPoint(0, 0, 0)
p.SetPoint_2D(1, 0, 0)
lyr.SetPoint_2D(-1, 0, 0)
poly.SetPoint_2D(0, 0, 0)
poly.AddPoint(0, 0)
poly.AddPoint_2D(0, 0)
p.GetGeometryRef(1)
p.AddGeometry(p)
p.AddGeometryDirectly(p)
###############################################################################
# Test Equals
def test_ogr_geom_equals():
p_empty = ogr.Geometry(ogr.wkbPoint)
p_0 = ogr.CreateGeometryFromWkt("POINT (0 0)")
p_1 = ogr.CreateGeometryFromWkt("POINT (1 1)")
assert p_empty.Equals(p_empty)
assert p_0.Equals(p_0)
assert p_0.Equals(p_0.Clone())
assert not p_empty.Equals(p_0)
assert not p_0.Equals(p_empty)
assert not p_0.Equals(p_1)
l_empty = ogr.Geometry(ogr.wkbLineString)
l_0_1 = ogr.CreateGeometryFromWkt("LINESTRING (0 0,1 1)")
l_0_1_2 = ogr.CreateGeometryFromWkt("LINESTRING (0 0,1 1,2 2)")
assert l_0_1.Equals(l_0_1)
assert l_0_1.Equals(l_0_1.Clone())
assert not l_empty.Equals(l_0_1)
assert not l_0_1.Equals(l_empty)
assert not l_0_1.Equals(l_0_1_2)
gc_empty = ogr.Geometry(ogr.wkbGeometryCollection)
gc_p_0 = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION (POINT (0 0))")
gc_p_1 = ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION (POINT (1 1))")
assert gc_empty.Equals(gc_empty)
assert gc_p_0.Equals(gc_p_0)
assert gc_p_0.Equals(gc_p_0.Clone())
assert not gc_empty.Equals(gc_p_0)
assert not gc_p_0.Equals(gc_empty)
assert not gc_p_0.Equals(gc_p_1)
###############################################################################
# Test FlattenTo2D(), SetCoordinateDimension(2) and SetCoordinateDimension(3) with Measured geometries
def test_ogr_geom_measured_geometries_to_2D_or_3D():
list_wkt = [
["POINT M (1 2 3)", "POINT (1 2)", "POINT Z (1 2 0)"],
["POINT ZM (1 2 3 4)", "POINT (1 2)", "POINT Z (1 2 3)"],
["LINESTRING M (1 2 3)", "LINESTRING (1 2)", "LINESTRING Z (1 2 0)"],
["LINESTRING ZM (1 2 3 4)", "LINESTRING (1 2)", "LINESTRING Z (1 2 3)"],
["POLYGON M ((1 2 3))", "POLYGON ((1 2))", "POLYGON Z ((1 2 0))"],
["POLYGON ZM ((1 2 3 4))", "POLYGON ((1 2))", "POLYGON Z ((1 2 3))"],
[
"CIRCULARSTRING M (1 2 3,4 5 6,7 8 9)",
"CIRCULARSTRING (1 2,4 5,7 8)",
"CIRCULARSTRING Z (1 2 0,4 5 0,7 8 0)",
],
[
"CIRCULARSTRING ZM (1 2 3 0,4 5 6 0,7 8 9 0)",
"CIRCULARSTRING (1 2,4 5,7 8)",
"CIRCULARSTRING Z (1 2 3,4 5 6,7 8 9)",
],
[
"COMPOUNDCURVE M ((1 2 3,4 5 6))",
"COMPOUNDCURVE ((1 2,4 5))",
"COMPOUNDCURVE Z ((1 2 0,4 5 0))",
],
[
"COMPOUNDCURVE ZM ((1 2 3 4,5 6 7 8))",
"COMPOUNDCURVE ((1 2,5 6))",
"COMPOUNDCURVE Z ((1 2 3,5 6 7))",
],
["MULTIPOINT M ((1 2 3))", "MULTIPOINT ((1 2))", "MULTIPOINT Z ((1 2 0))"],
["MULTIPOINT ZM ((1 2 3 4))", "MULTIPOINT ((1 2))", "MULTIPOINT Z ((1 2 3))"],
[
"MULTILINESTRING M ((1 2 3))",
"MULTILINESTRING ((1 2))",
"MULTILINESTRING Z ((1 2 0))",
],
[
"MULTILINESTRING ZM ((1 2 3 4))",
"MULTILINESTRING ((1 2))",
"MULTILINESTRING Z ((1 2 3))",
],
["MULTICURVE M ((1 2 3))", "MULTICURVE ((1 2))", "MULTICURVE Z ((1 2 0))"],
["MULTICURVE ZM ((1 2 3 4))", "MULTICURVE ((1 2))", "MULTICURVE Z ((1 2 3))"],
[
"MULTIPOLYGON M (((1 2 3)))",
"MULTIPOLYGON (((1 2)))",
"MULTIPOLYGON Z (((1 2 0)))",
],
[
"MULTIPOLYGON ZM (((1 2 3 4)))",
"MULTIPOLYGON (((1 2)))",
"MULTIPOLYGON Z (((1 2 3)))",
],
[
"MULTISURFACE M (((1 2 3)))",
"MULTISURFACE (((1 2)))",
"MULTISURFACE Z (((1 2 0)))",
],
[
"MULTISURFACE ZM (((1 2 3 4)))",
"MULTISURFACE (((1 2)))",
"MULTISURFACE Z (((1 2 3)))",
],
[
"GEOMETRYCOLLECTION M (POINT M (1 2 3))",
"GEOMETRYCOLLECTION (POINT (1 2))",
"GEOMETRYCOLLECTION Z (POINT Z (1 2 0))",
],
[
"GEOMETRYCOLLECTION ZM (POINT ZM (1 2 3 4))",
"GEOMETRYCOLLECTION (POINT (1 2))",
"GEOMETRYCOLLECTION Z (POINT Z (1 2 3))",
],
[
"TRIANGLE M ((0 0 3,0 1 3,1 1 3,0 0 3))",
"TRIANGLE ((0 0,0 1,1 1,0 0))",
"TRIANGLE Z ((0 0 0,0 1 0,1 1 0,0 0 0))",
],
[
"TRIANGLE ZM ((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4))",
"TRIANGLE ((0 0,0 1,1 1,0 0))",
"TRIANGLE Z ((0 0 3,0 1 3,1 1 3,0 0 3))",
],
[
"POLYHEDRALSURFACE M (((0 0 3,0 1 3,1 1 3,0 0 3)))",
"POLYHEDRALSURFACE (((0 0,0 1,1 1,0 0)))",
"POLYHEDRALSURFACE Z (((0 0 0,0 1 0,1 1 0,0 0 0)))",
],
[
"POLYHEDRALSURFACE ZM (((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4)))",
"POLYHEDRALSURFACE (((0 0,0 1,1 1,0 0)))",
"POLYHEDRALSURFACE Z (((0 0 3,0 1 3,1 1 3,0 0 3)))",
],
[
"TIN M (((0 0 3,0 1 3,1 1 3,0 0 3)))",
"TIN (((0 0,0 1,1 1,0 0)))",
"TIN Z (((0 0 0,0 1 0,1 1 0,0 0 0)))",
],
[
"TIN ZM (((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4)))",
"TIN (((0 0,0 1,1 1,0 0)))",
"TIN Z (((0 0 3,0 1 3,1 1 3,0 0 3)))",
],
]
for (before, after_2D, after_3D) in list_wkt:
geom = ogr.CreateGeometryFromWkt(before)
wkb = geom.ExportToIsoWkb()
geom2 = ogr.CreateGeometryFromWkb(wkb)
if not geom.Equals(geom2):
print(before)
pytest.fail(geom2.ExportToIsoWkt())
geom = ogr.CreateGeometryFromWkt(before)
geom.FlattenTo2D()
assert geom.ExportToIsoWkt() == after_2D, before
geom = ogr.CreateGeometryFromWkt(before)
geom.SetCoordinateDimension(2)
assert geom.ExportToIsoWkt() == after_2D, before
geom = ogr.CreateGeometryFromWkt(before)
geom.SetCoordinateDimension(3)
assert geom.ExportToIsoWkt() == after_3D, before
# Test no-op
geom = ogr.CreateGeometryFromWkt(before)
geom.Set3D(geom.Is3D())
geom.SetMeasured(geom.IsMeasured())
assert geom.ExportToIsoWkt() == before
assert ogr.CreateGeometryFromWkt("POINT (1 2)").CoordinateDimension() == 2
assert ogr.CreateGeometryFromWkt("POINT M (1 2 3)").CoordinateDimension() == 3
assert ogr.CreateGeometryFromWkt("POINT Z (1 2 3)").CoordinateDimension() == 3
assert ogr.CreateGeometryFromWkt("POINT ZM (1 2 3 4)").CoordinateDimension() == 4
# Unrelated test. Test old-style unqualified non-bracketted ZM import
g = ogr.CreateGeometryFromWkt("MULTIPOINT (1 2 3 4)")
assert g.ExportToIsoWkt() == "MULTIPOINT ZM ((1 2 3 4))"
###############################################################################
# Test PostGIS EWKT with XYM
def test_ogr_geom_postgis_ewkt_xym():
list_wkt = [
["POINTM(1 2 3)", "POINT M (1 2 3)"],
[
"GEOMETRYCOLLECTIONM(POINTM(1 2 3))",
"GEOMETRYCOLLECTION M (POINT M (1 2 3))",
],
]
for (before, after) in list_wkt:
geom = ogr.CreateGeometryFromWkt(before)
assert geom.ExportToIsoWkt() == after, before
###############################################################################
# Test ogr.wkbCurve / ogr.wkbSurface
def test_ogr_geom_curve_surface():
tests = [
[ogr.wkbCurve, "Curve"],
[ogr.wkbCurveZ, "3D Curve"],
[ogr.wkbCurveM, "Measured Curve"],
[ogr.wkbCurveZM, "3D Measured Curve"],
[ogr.wkbSurface, "Surface"],
[ogr.wkbSurfaceZ, "3D Surface"],
[ogr.wkbSurfaceM, "Measured Surface"],
[ogr.wkbSurfaceZM, "3D Measured Surface"],
]
for (wkb_type, name) in tests:
assert ogr.GeometryTypeToName(wkb_type) == name
###############################################################################
# Test importing corrupted WKB
def test_ogr_geom_import_corrupted_wkb():
list_wkt = [
"POINT ZM (1 2 3 4)"
"LINESTRING ZM (1 2 3 4)"
"POLYGON ZM ((1 2 3 4))"
"CIRCULARSTRING ZM (1 2 3 0,4 5 6 0,7 8 9 0)",
"COMPOUNDCURVE ZM ((1 2 3 4,5 6 7 8))",
"MULTIPOINT ZM ((1 2 3 4))",
"MULTILINESTRING ZM ((1 2 3 4))",
"MULTICURVE ZM ((1 2 3 4))",
"MULTIPOLYGON ZM (((1 2 3 4)))",
"MULTISURFACE ZM (((1 2 3 4)))",
"GEOMETRYCOLLECTION ZM (POINT ZM (1 2 3 4))",
"TRIANGLE ZM ((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4))",
"POLYHEDRALSURFACE ZM (((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4)),((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4)))",
"TIN ZM (((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4)),((0 0 3 4,0 1 3 4,1 1 3 4,0 0 3 4)))",
]
for wkt in list_wkt:
g = ogr.CreateGeometryFromWkt(wkt)
wkb = bytearray(g.ExportToWkb())
# Test altering the WKB
for i, _ in enumerate(wkb):
for method in range(4 + 4 + 4 + 1):
init_val = wkb[i]
if method < 4:
wkb[i] = method
elif method < 8:
wkb[i] = 255 - (method - 4)
elif method < 12:
wkb[i] = 127 + 2 - (method - 8)
else:
wkb[i] = 255 - wkb[i]
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkb(bytes(wkb))
if g:
g2 = ogr.CreateGeometryFromWkb(g.ExportToIsoWkb())
assert g.Equals(g2), (wkt, i, method)
wkb[i] = init_val
# Test truncation of the WKB
for i in range(len(wkb)):
with gdaltest.error_handler():
g = ogr.CreateGeometryFromWkb(bytes(wkb[0:i]))
assert g is None, (wkt, i)
###############################################################################
# Test conversions from/into triangle, TIN, PS
def test_ogr_geom_triangle_ps_tin_conversion():
wkts = [
"TRIANGLE ((0 0,0 1,1 1,0 0))",
"POLYGON ((0 0,0 1,1 1,0 0))",
"CURVEPOLYGON ((0 0,0 1,1 1,0 0))",
"MULTIPOLYGON (((0 0,0 1,1 1,0 0)))",
"MULTISURFACE (((0 0,0 1,1 1,0 0)))",
"TIN (((0 0,0 1,1 1,0 0)))",
"POLYHEDRALSURFACE (((0 0,0 1,1 1,0 0)))",
]
for wkt in wkts:
for wkt_target in wkts:
# print(wkt, wkt_target)
g = ogr.CreateGeometryFromWkt(wkt)
g2 = ogr.CreateGeometryFromWkt(wkt_target)
got_wkt = ogr.ForceTo(g, g2.GetGeometryType()).ExportToWkt()
if not (
g.GetGeometryType()
in [ogr.wkbTriangle, ogr.wkbTIN, ogr.wkbPolyhedralSurface]
or g2.GetGeometryType()
in [ogr.wkbTriangle, ogr.wkbTIN, ogr.wkbPolyhedralSurface]
):
continue
wkt_expected = wkt_target
if (
g.GetGeometryType() == ogr.wkbTIN
or g.GetGeometryType() == ogr.wkbPolyhedralSurface
) and g2.GetGeometryType() == ogr.wkbCurvePolygon:
wkt_expected = wkt
assert got_wkt == wkt_expected, (wkt, wkt_target, got_wkt, wkt_expected)
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("POLYGON ((0 0,0 1,1 1,1 0,0 0))"), ogr.wkbTriangle
)
assert g.GetGeometryType() == ogr.wkbPolygon, g.ExportToWkt()
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("POLYHEDRALSURFACE (((0 0,0 1,1 1,1 0,0 0)))"),
ogr.wkbTIN,
)
assert g.GetGeometryType() == ogr.wkbPolyhedralSurface, g.ExportToWkt()
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION (POLYHEDRALSURFACE (((0 0,0 1,1 1,1 0,0 0))))"
),
ogr.wkbMultiPolygon,
)
assert g.ExportToWkt() == "MULTIPOLYGON (((0 0,0 1,1 1,1 0,0 0)))"
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("GEOMETRYCOLLECTION (TRIANGLE ((0 0,0 1,1 1,0 0)))"),
ogr.wkbMultiPolygon,
)
assert g.ExportToWkt() == "MULTIPOLYGON (((0 0,0 1,1 1,0 0)))"
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("MULTIPOLYGON (((0 0,0 1,1 1,0 0)))"),
ogr.wkbGeometryCollection,
)
assert g.ExportToWkt() == "GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)))"
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("TRIANGLE ((0 0,0 1,1 1,0 0))"),
ogr.wkbGeometryCollection,
)
assert g.ExportToWkt() == "GEOMETRYCOLLECTION (TRIANGLE ((0 0,0 1,1 1,0 0)))"
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("TIN (((0 0,0 1,1 1,0 0)))"),
ogr.wkbGeometryCollection,
)
assert g.ExportToWkt() == "GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)))"
g = ogr.ForceTo(
ogr.CreateGeometryFromWkt("POLYHEDRALSURFACE (((0 0,0 1,1 1,0 0)))"),
ogr.wkbGeometryCollection,
)
assert g.ExportToWkt() == "GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)))"
###############################################################################
def test_ogr_geom_multipoint_envelope_bug():
g = ogr.CreateGeometryFromWkt("MULTIPOINT(0 0,1 1)")
minx, maxx, miny, maxy = g.GetEnvelope()
assert (minx, maxx, miny, maxy) == (0, 1, 0, 1)
g = ogr.CreateGeometryFromWkt("MULTIPOINT(0 0 0,1 1 1)")
minx, maxx, miny, maxy, minz, maxz = g.GetEnvelope3D()
assert (minx, maxx, miny, maxy, minz, maxz) == (0, 1, 0, 1, 0, 1)
###############################################################################
def test_ogr_geom_polygon_empty_ring():
g = ogr.Geometry(ogr.wkbPolygon)
g2 = ogr.Geometry(ogr.wkbLinearRing)
g.AddGeometryDirectly(g2)
assert g.IsEmpty()
###############################################################################
@pytest.mark.require_geos
def test_ogr_geom_polygon_intersects_point():
poly = ogr.CreateGeometryFromWkt("POLYGON((0 0,5 5,10 0,0 0))")
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(10, 0)
assert poly.Intersects(point) == 1
assert poly.Contains(point) == 0
###############################################################################
# Test fix for #7128
def test_ogr_geom_geometrycollection():
wkt_list = [
"GEOMETRYCOLLECTION (POINT EMPTY)",
"GEOMETRYCOLLECTION (LINESTRING EMPTY)",
"GEOMETRYCOLLECTION (POLYGON EMPTY)",
"GEOMETRYCOLLECTION (MULTIPOINT EMPTY)",
"GEOMETRYCOLLECTION (MULTILINESTRING EMPTY)",
"GEOMETRYCOLLECTION (MULTIPOLYGON EMPTY)",
"GEOMETRYCOLLECTION (GEOMETRYCOLLECTION EMPTY)",
"GEOMETRYCOLLECTION (CIRCULARSTRING EMPTY)",
"GEOMETRYCOLLECTION (COMPOUNDCURVE EMPTY)",
"GEOMETRYCOLLECTION (CURVEPOLYGON EMPTY)",
"GEOMETRYCOLLECTION (MULTICURVE EMPTY)",
"GEOMETRYCOLLECTION (MULTISURFACE EMPTY)",
"GEOMETRYCOLLECTION (TRIANGLE EMPTY)",
"GEOMETRYCOLLECTION (POLYHEDRALSURFACE EMPTY)",
"GEOMETRYCOLLECTION (TIN EMPTY)",
]
for wkt in wkt_list:
g = ogr.CreateGeometryFromWkt(wkt)
assert g.ExportToWkt() == wkt
###############################################################################
# Test fix for #7126
def test_ogr_geom_assignspatialref():
g = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION(POLYGON((0 0,0 1,1 1,0 0)),COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,2 0)),POLYHEDRALSURFACE(((0 0,0 1,1 1,0 0))))"
)
sr = osr.SpatialReference()
sr.ImportFromEPSG(4326)
g.AssignSpatialReference(sr)
assert g.GetGeometryRef(0).GetSpatialReference().ExportToWkt() == sr.ExportToWkt()
assert (
g.GetGeometryRef(0).GetGeometryRef(0).GetSpatialReference().ExportToWkt()
== sr.ExportToWkt()
)
assert g.GetGeometryRef(1).GetSpatialReference().ExportToWkt() == sr.ExportToWkt()
assert (
g.GetGeometryRef(1).GetGeometryRef(0).GetSpatialReference().ExportToWkt()
== sr.ExportToWkt()
)
assert g.GetGeometryRef(2).GetSpatialReference().ExportToWkt() == sr.ExportToWkt()
assert (
g.GetGeometryRef(2).GetGeometryRef(0).GetSpatialReference().ExportToWkt()
== sr.ExportToWkt()
)
###############################################################################
def test_ogr_geom_swapxy():
g = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(1 2,2 3),POLYGON((0 0,0 1,1 1,0 0)),COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,2 0)),POLYHEDRALSURFACE(((0 0,0 1,1 1,0 0))))"
)
g.SwapXY()
assert (
g.ExportToWkt()
== "GEOMETRYCOLLECTION (POINT (2 1),LINESTRING (2 1,3 2),POLYGON ((0 0,1 0,1 1,0 0)),COMPOUNDCURVE (CIRCULARSTRING (0 0,1 1,0 2)),POLYHEDRALSURFACE (((0 0,1 0,1 1,0 0))))"
)
###############################################################################
def test_ogr_geom_remove_geometry():
# With GEOMETRYCOLLECTION
g = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION (POINT (1 2),LINESTRING (1 2,2 3),POINT (3 4))"
)
assert not (g.RemoveGeometry(3) == 0 or g.RemoveGeometry(-2) == 0)
assert g.RemoveGeometry(1) == 0
assert g.ExportToWkt() == "GEOMETRYCOLLECTION (POINT (1 2),POINT (3 4))"
assert g.RemoveGeometry(1) == 0
assert g.ExportToWkt() == "GEOMETRYCOLLECTION (POINT (1 2))"
assert g.RemoveGeometry(0) == 0
assert g.ExportToWkt() == "GEOMETRYCOLLECTION EMPTY"
g = ogr.CreateGeometryFromWkt(
"GEOMETRYCOLLECTION (POINT (1 2),LINESTRING (1 2,2 3),POINT (3 4))"
)
assert g.RemoveGeometry(-1) == 0
assert g.ExportToWkt() == "GEOMETRYCOLLECTION EMPTY"
# With POLYHEDRALSURFACE/TIN
g = ogr.CreateGeometryFromWkt("TIN (((0 0,0 1,1 1,0 0)),((0 0,1 0,1 1,0 0)))")
assert not (g.RemoveGeometry(2) == 0 or g.RemoveGeometry(-2) == 0)
assert g.RemoveGeometry(1) == 0
assert g.ExportToWkt() == "TIN (((0 0,0 1,1 1,0 0)))"
assert g.RemoveGeometry(0) == 0
assert g.ExportToWkt() == "TIN EMPTY"
g = ogr.CreateGeometryFromWkt("TIN (((0 0,0 1,1 1,0 0)),((0 0,1 0,1 1,0 0)))")
assert g.RemoveGeometry(-1) == 0
assert g.ExportToWkt() == "TIN EMPTY"
# With POLYGON
g = ogr.CreateGeometryFromWkt(
"POLYGON ((0 0,0 10,10 10,10 0,0 0),(1 1,1 9,9 9,1 1))"
)
assert not (g.RemoveGeometry(2) == 0 or g.RemoveGeometry(-2) == 0)
assert g.RemoveGeometry(1) == 0
assert g.ExportToWkt() == "POLYGON ((0 0,0 10,10 10,10 0,0 0))"
assert g.RemoveGeometry(0) == 0
assert g.ExportToWkt() == "POLYGON EMPTY"
g = ogr.CreateGeometryFromWkt(
"POLYGON ((0 0,0 10,10 10,10 0,0 0),(1 1,1 9,9 9,1 1))"
)
assert g.RemoveGeometry(-1) == 0
assert g.ExportToWkt() == "POLYGON EMPTY"
# Unsupported type
g = ogr.CreateGeometryFromWkt("POINT (0 0)")
assert g.RemoveGeometry(0) != 0
###############################################################################
def test_ogr_geom_sfcgal():
if not ogrtest.have_sfcgal():
pytest.skip("SFCGAL is not available")
g1 = ogr.CreateGeometryFromWkt("TIN EMPTY")
g2_poly = ogr.CreateGeometryFromWkt("POLYGON((0 0,0 1,1 1,0 0))")
g2 = g2_poly.GetGeometryRef(0)
g1.Distance(g2)
g2 = ogr.CreateGeometryFromWkt("CIRCULARSTRING EMPTY")
g1.Distance(g2)
g2 = ogr.CreateGeometryFromWkt("CURVEPOLYGON EMPTY")
g1.Distance(g2)
###############################################################################
def test_ogr_geom_cannot_add_triangle_to_multisurface():
g = ogr.Geometry(ogr.wkbMultiSurface)
assert g.AddGeometry(ogr.Geometry(ogr.wkbTriangle)) != 0
###############################################################################
def test_ogr_geom_force_polygonzm_to_linestring():
g = ogr.CreateGeometryFromWkt(
"POLYGON ZM ((0 0 10 20,0 1 30 40,1 1 50 60,0 0 10 70))"
)
wkt = ogr.ForceToLineString(g).ExportToIsoWkt()
assert wkt == "LINESTRING ZM (0 0 10 20,0 1 30 40,1 1 50 60,0 0 10 70)"
###############################################################################
def test_ogr_geom_force_polygonzm_to_multilinestring():
g = ogr.CreateGeometryFromWkt(
"POLYGON ZM ((0 0 10 20,0 1 30 40,1 1 50 60,0 0 10 70))"
)
wkt = ogr.ForceToMultiLineString(g).ExportToIsoWkt()
assert wkt == "MULTILINESTRING ZM ((0 0 10 20,0 1 30 40,1 1 50 60,0 0 10 70))"
###############################################################################
def test_ogr_geom_create_from_wkt_polyhedrasurface():
g = ogr.CreateGeometryFromWkt(
"POLYHEDRALSURFACE (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)))"
)
assert g.ExportToWkt() == "POLYHEDRALSURFACE Z (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)))"
###############################################################################
@pytest.mark.require_geos(3, 8)
def test_ogr_geom_makevalid():
g = ogr.CreateGeometryFromWkt("POINT (0 0)")
g = g.MakeValid()
assert g is None or g.ExportToWkt() == "POINT (0 0)"
g = ogr.CreateGeometryFromWkt("POINT EMPTY")
g = g.MakeValid()
assert g is None or g.ExportToWkt() == "POINT EMPTY"
g = ogr.CreateGeometryFromWkt("LINESTRING (0 0)")
with gdaltest.error_handler():
g = g.MakeValid()
assert not g
g = ogr.CreateGeometryFromWkt("CURVEPOLYGON ((0 0,0 1,1 0,0 0))")
g = g.MakeValid()
assert g is None or g.ExportToWkt() == "CURVEPOLYGON ((0 0,0 1,1 0,0 0))"
# Invalid
g = ogr.CreateGeometryFromWkt("POLYGON ((0 0,10 10,0 10,10 0,0 0))")
g = g.MakeValid()
assert (
g is None
or ogrtest.check_feature_geometry(
g, "MULTIPOLYGON (((0 0,5 5,10 0,0 0)),((5 5,0 10,10 10,5 5)))"
)
== 0
), g.ExportToWkt()
# Invalid
g = ogr.CreateGeometryFromWkt("CURVEPOLYGON ((0 0,10 10,0 10,10 0,0 0))")
g = g.MakeValid()
assert (
g is None
or ogrtest.check_feature_geometry(
g, "MULTIPOLYGON (((0 0,5 5,10 0,0 0)),((5 5,0 10,10 10,5 5)))"
)
== 0
), g.ExportToWkt()
if (
ogr.GetGEOSVersionMajor() * 10000
+ ogr.GetGEOSVersionMinor() * 100
+ ogr.GetGEOSVersionMicro()
>= 31000
):
g = ogr.CreateGeometryFromWkt(
"POLYGON ((0 0,0 10,10 10,10 0,0 0),(5 5,15 10,15 0,5 5))"
)
# Only since GEOS 3.10
g = g.MakeValid(["METHOD=STRUCTURE"])
assert (
g is None
or ogrtest.check_feature_geometry(
g, "POLYGON ((0 10,10 10,10.0 7.5,5 5,10.0 2.5,10 0,0 0,0 10))"
)
== 0
), g.ExportToWkt()
###############################################################################
@pytest.mark.require_geos
def test_ogr_geom_normalize():
g = ogr.CreateGeometryFromWkt("POLYGON ((0 1,1 1,1 0,0 0,0 1))")
g = g.Normalize()
assert g is None or g.ExportToWkt() == "POLYGON ((0 0,0 1,1 1,1 0,0 0))"
###############################################################################
def test_ogr_geom_force_multipolygon_z_to_compound_curve():
g = ogr.CreateGeometryFromWkt("MULTIPOLYGON Z (((0 0 0,0 1 0,1 1 0,0 0 0)))")
g = ogr.ForceTo(g, ogr.wkbCompoundCurve)
assert g.ExportToIsoWkt() == "COMPOUNDCURVE Z ((0 0 0,0 1 0,1 1 0,0 0 0))"
###############################################################################
@pytest.mark.parametrize(
"input_wkt,expected_wkt",
[
("POINT EMPTY", "POINT EMPTY"),
("POINT (1 2)", "POINT (1 2)"),
("POINT Z (1 2 3)", "POINT Z (1 2 3)"),
("LINESTRING (1 2,3 4)", "LINESTRING (1 2,3 4)"),
("POLYGON ((0 0,0 1,1 1,0 0))", "POLYGON ((0 0,0 1,1 1,0 0))"),
("GEOMETRYCOLLECTION EMPTY", "GEOMETRYCOLLECTION EMPTY"),
("GEOMETRYCOLLECTION Z (POINT Z (1 2 3))", "POINT Z (1 2 3)"),
("GEOMETRYCOLLECTION (LINESTRING (1 2,3 4))", "LINESTRING (1 2,3 4)"),
(
"GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)))",
"POLYGON ((0 0,0 1,1 1,0 0))",
),
(
"GEOMETRYCOLLECTION (LINESTRING (1 2,3 4),POINT (1 2))",
"LINESTRING (1 2,3 4)",
),
(
"GEOMETRYCOLLECTION (POINT (1 2),LINESTRING (1 2,3 4))",
"LINESTRING (1 2,3 4)",
),
(
"GEOMETRYCOLLECTION (LINESTRING (1 2,3 4),LINESTRING (5 6,7 8))",
"MULTILINESTRING ((1 2,3 4),(5 6,7 8))",
),
(
"GEOMETRYCOLLECTION (POINT (1 2),POLYGON ((0 0,0 1,1 1,0 0)))",
"POLYGON ((0 0,0 1,1 1,0 0))",
),
(
"GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)),POLYGON ((10 0,10 1,11 1,10 0)))",
"MULTIPOLYGON (((0 0,0 1,1 1,0 0)),((10 0,10 1,11 1,10 0)))",
),
(
"GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)),MULTIPOLYGON (((10 0,10 1,11 1,10 0))))",
"MULTIPOLYGON (((0 0,0 1,1 1,0 0)),((10 0,10 1,11 1,10 0)))",
),
(
"GEOMETRYCOLLECTION (CIRCULARSTRING (0 0,1 1,2 0),LINESTRING(3 4,5 6))",
"MULTICURVE (CIRCULARSTRING (0 0,1 1,2 0),(3 4,5 6))",
),
(
"GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,0 0)),CURVEPOLYGON ((10 0,10 1,11 1,10 0)))",
"MULTISURFACE (((0 0,0 1,1 1,0 0)),CURVEPOLYGON ((10 0,10 1,11 1,10 0)))",
),
(
"GEOMETRYCOLLECTION (MULTIPOLYGON (((0 0,0 1,1 1,0 0)),((10 0,10 1,11 1,10 0))),POINT (1 2))",
"MULTIPOLYGON (((0 0,0 1,1 1,0 0)),((10 0,10 1,11 1,10 0)))",
),
],
)
def test_ogr_geom_removeLowerDimensionSubGeoms(input_wkt, expected_wkt):
g = ogr.CreateGeometryFromWkt(input_wkt)
g = g.RemoveLowerDimensionSubGeoms()
assert g.ExportToIsoWkt() == expected_wkt
###############################################################################
def test_ogr_geom_copy():
g = ogr.CreateGeometryFromWkt("POINT (0 1)")
sr = osr.SpatialReference()
sr.ImportFromEPSG(4326)
g.AssignSpatialReference(sr)
g2 = copy.copy(g)
assert g2.ExportToWkt() == g.ExportToWkt()
assert g2.GetSpatialReference().IsSame(sr)
sr.ImportFromEPSG(32631)
assert g2.GetSpatialReference().IsSame(sr)
###############################################################################
def test_ogr_geom_deepcopy():
g = ogr.CreateGeometryFromWkt("POINT (0 1)")
sr = osr.SpatialReference()
sr.ImportFromEPSG(4326)
g.AssignSpatialReference(sr)
g2 = copy.deepcopy(g)
assert g2.ExportToWkt() == g.ExportToWkt()
assert g2.GetSpatialReference().IsSame(sr)
sr.ImportFromEPSG(32631)
assert not g2.GetSpatialReference().IsSame(sr)
###############################################################################
# Test that setting a Point with NaN is like setting a POINT EMPTY
def test_ogr_geom_point_nan():
geom = ogr.Geometry(type=ogr.wkbPoint)
geom.AddPoint_2D(float("nan"), float("nan"))
assert geom.IsEmpty()
###############################################################################
@pytest.mark.parametrize(
"geom_type",
[
ogr.wkbPoint,
ogr.wkbPoint25D,
ogr.wkbPointM,
ogr.wkbPointZM,
ogr.wkbLineString,
ogr.wkbPolygon,
ogr.wkbMultiPoint,
ogr.wkbMultiLineString,
ogr.wkbMultiPolygon,
ogr.wkbGeometryCollection,
ogr.wkbCircularString,
ogr.wkbCompoundCurve,
ogr.wkbCurvePolygon,
ogr.wkbMultiCurve,
ogr.wkbMultiSurface,
ogr.wkbPolyhedralSurface,
ogr.wkbTIN,
],
)
def test_ogr_geom_CreateGeometry(geom_type):
geom = ogr.Geometry(geom_type)
assert geom.GetGeometryType() == geom_type
assert geom.IsEmpty()