地物分类项目代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.3KB

  1. """
  2. rdp
  3. ~~~
  4. Pure Python implementation of the Ramer-Douglas-Peucker algorithm.
  5. :copyright: (c) 2014 Fabian Hirschmann <fabian@hirschmann.email>
  6. :license: MIT, see LICENSE.txt for more details.
  7. """
  8. import numpy as np
  9. def pldist(x0, x1, x2):
  10. """
  11. Calculates the distance from the point ``x0`` to the line given
  12. by the points ``x1`` and ``x2``.
  13. :param x0: a point
  14. :type x0: a 2x1 numpy array
  15. :param x1: a point of the line
  16. :type x1: 2x1 numpy array
  17. :param x2: another point of the line
  18. :type x2: 2x1 numpy array
  19. """
  20. x0, x1, x2 = x0[:2], x1[:2], x2[:2] # discard timestamp
  21. if x1[0] == x2[0]:
  22. return np.abs(x0[0] - x1[0])
  23. return np.divide(np.linalg.norm(np.linalg.det([x2 - x1, x1 - x0])),
  24. np.linalg.norm(x2 - x1)) # 输入矩阵,除数矩阵
  25. def _rdp(M, epsilon, dist):
  26. """
  27. Simplifies a given array of points.
  28. :param M: an array
  29. :type M: Nx2 numpy array
  30. :param epsilon: epsilon in the rdp algorithm
  31. :type epsilon: float
  32. :param dist: distance function
  33. :type dist: function with signature ``f(x1, x2, x3)``
  34. """
  35. dmax = 0.0
  36. index = -1
  37. for i in range(1, M.shape[0]):
  38. d = dist(M[i], M[0], M[-1])
  39. if d > dmax:
  40. index = i
  41. dmax = d
  42. if dmax > epsilon:
  43. r1 = _rdp(M[:index + 1], epsilon, dist)
  44. r2 = _rdp(M[index:], epsilon, dist)
  45. return np.vstack((r1[:-1], r2))
  46. else:
  47. return np.vstack((M[0], M[-1]))
  48. def _rdp_nn(seq, epsilon, dist):
  49. """
  50. Simplifies a given array of points.
  51. :param seq: a series of points
  52. :type seq: sequence of 2-tuples
  53. :param epsilon: epsilon in the rdp algorithm
  54. :type epsilon: float
  55. :param dist: distance function
  56. :type dist: function with signature ``f(x1, x2, x3)``
  57. """
  58. return _rdp(np.array(seq), epsilon, dist).tolist()
  59. def rdp(M, epsilon=0, dist=pldist):
  60. """
  61. Simplifies a given array of points.
  62. :param M: a series of points
  63. :type M: either a Nx2 numpy array or sequence of 2-tuples
  64. :param epsilon: epsilon in the rdp algorithm
  65. :type epsilon: float
  66. :param dist: distance function
  67. :type dist: function with signature ``f(x1, x2, x3)``
  68. """
  69. if "numpy" in str(type(M)):
  70. return _rdp(M, epsilon, dist)
  71. return _rdp_nn(M, epsilon, dist)