test_format.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import pytest
  2. from shapely import Point, Polygon, geos_version
  3. def test_format_invalid():
  4. # check invalid spec formats
  5. pt = Point(1, 2)
  6. test_list = [
  7. ("5G", ValueError, "invalid format specifier"),
  8. (".f", ValueError, "invalid format specifier"),
  9. ("0.2e", ValueError, "invalid format specifier"),
  10. (".1x", ValueError, "hex representation does not specify precision"),
  11. ]
  12. for format_spec, err, match in test_list:
  13. with pytest.raises(err, match=match):
  14. format(pt, format_spec)
  15. def get_tst_format_point_params():
  16. xy1 = (0.12345678901234567, 1.2345678901234567e10)
  17. xy2 = (-169.910918, -18.997564)
  18. xyz3 = (630084, 4833438, 76)
  19. test_list = [
  20. (".0f", xy1, "POINT (0 12345678901)", True),
  21. (".1f", xy1, "POINT (0.1 12345678901.2)", True),
  22. ("0.2f", xy2, "POINT (-169.91 -19.00)", True),
  23. (".3F", (float("inf"), -float("inf")), "POINT (INF -INF)", True),
  24. ]
  25. if geos_version < (3, 10, 0):
  26. # 'g' format varies depending on GEOS version
  27. test_list += [
  28. (".1g", xy1, "POINT (0.1 1e+10)", True),
  29. (".6G", xy1, "POINT (0.123457 1.23457E+10)", True),
  30. ("0.12g", xy1, "POINT (0.123456789012 12345678901.2)", True),
  31. ("0.4g", xy2, "POINT (-169.9 -19)", True),
  32. ]
  33. else:
  34. test_list += [
  35. (".1g", xy1, "POINT (0.1 12345678901.2)", False),
  36. (".6G", xy1, "POINT (0.123457 12345678901.234568)", False),
  37. ("0.12g", xy1, "POINT (0.123456789012 12345678901.234568)", False),
  38. ("g", xy2, "POINT (-169.910918 -18.997564)", False),
  39. ("0.2g", xy2, "POINT (-169.91 -19)", False),
  40. ]
  41. # without precisions test GEOS rounding_precision=-1; different than Python
  42. test_list += [
  43. ("f", (1, 2), f"POINT ({1:.16f} {2:.16f})", False),
  44. ("F", xyz3, "POINT Z ({:.16f} {:.16f} {:.16f})".format(*xyz3), False),
  45. ("g", xyz3, "POINT Z (630084 4833438 76)", False),
  46. ]
  47. return test_list
  48. @pytest.mark.parametrize(
  49. "format_spec, coords, expt_wkt, same_python_float", get_tst_format_point_params()
  50. )
  51. def test_format_point(format_spec, coords, expt_wkt, same_python_float):
  52. pt = Point(*coords)
  53. # basic checks
  54. assert f"{pt}" == pt.wkt
  55. assert format(pt, "") == pt.wkt
  56. assert format(pt, "x") == pt.wkb_hex.lower()
  57. assert format(pt, "X") == pt.wkb_hex
  58. # check formatted WKT to expected
  59. assert format(pt, format_spec) == expt_wkt, format_spec
  60. # check Python's format consistency
  61. text_coords = expt_wkt[expt_wkt.index("(") + 1 : expt_wkt.index(")")]
  62. is_same = []
  63. for coord, expt_coord in zip(coords, text_coords.split()):
  64. py_fmt_float = format(float(coord), format_spec)
  65. if same_python_float:
  66. assert py_fmt_float == expt_coord, format_spec
  67. else:
  68. is_same.append(py_fmt_float == expt_coord)
  69. if not same_python_float:
  70. assert not all(is_same), f"{format_spec!r} with {expt_wkt}"
  71. def test_format_polygon():
  72. # check basic cases
  73. poly = Point(0, 0).buffer(10, quad_segs=2)
  74. assert f"{poly}" == poly.wkt
  75. assert format(poly, "") == poly.wkt
  76. assert format(poly, "x") == poly.wkb_hex.lower()
  77. assert format(poly, "X") == poly.wkb_hex
  78. # Use f-strings with extra characters and rounding precision
  79. if geos_version < (3, 13, 0):
  80. assert f"<{poly:.2f}>" == (
  81. "<POLYGON ((10.00 0.00, 7.07 -7.07, 0.00 -10.00, -7.07 -7.07, "
  82. "-10.00 -0.00, -7.07 7.07, -0.00 10.00, 7.07 7.07, 10.00 0.00))>"
  83. )
  84. else:
  85. assert f"<{poly:.2f}>" == (
  86. "<POLYGON ((10.00 0.00, 7.07 -7.07, 0.00 -10.00, -7.07 -7.07, "
  87. "-10.00 0.00, -7.07 7.07, 0.00 10.00, 7.07 7.07, 10.00 0.00))>"
  88. )
  89. # 'g' format varies depending on GEOS version
  90. if geos_version < (3, 10, 0):
  91. assert f"{poly:.2G}" == (
  92. "POLYGON ((10 0, 7.1 -7.1, 1.6E-14 -10, -7.1 -7.1, "
  93. "-10 -3.2E-14, -7.1 7.1, -4.6E-14 10, 7.1 7.1, 10 0))"
  94. )
  95. else:
  96. assert f"{poly:.2G}" == (
  97. "POLYGON ((10 0, 7.07 -7.07, 0 -10, -7.07 -7.07, "
  98. "-10 0, -7.07 7.07, 0 10, 7.07 7.07, 10 0))"
  99. )
  100. # check empty
  101. empty = Polygon()
  102. assert f"{empty}" == "POLYGON EMPTY"
  103. assert format(empty, "") == empty.wkt
  104. assert format(empty, ".2G") == empty.wkt
  105. assert format(empty, "x") == empty.wkb_hex.lower()
  106. assert format(empty, "X") == empty.wkb_hex