Skip to content

Commit 5ffc05a

Browse files
committed
Add documentation about visvalingam and a correction about point removed
1 parent 872f65a commit 5ffc05a

File tree

2 files changed

+60
-52
lines changed

2 files changed

+60
-52
lines changed

src/py_eddy_tracker/observations/network.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
empty,
1616
in1d,
1717
ones,
18-
uint32,
1918
uint16,
19+
uint32,
2020
unique,
2121
where,
2222
zeros,
@@ -490,7 +490,9 @@ def relatives(self, obs, order=2):
490490
"""
491491
Extract the segments at a certain order from multiple observations.
492492
493-
:param iterable,int obs: indices of observation for relatives computation. Can be one observation (int) or collection of observations (iterable(int))
493+
:param iterable,int obs:
494+
indices of observation for relatives computation. Can be one observation (int)
495+
or collection of observations (iterable(int))
494496
:param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ...
495497
496498
:return: all segments relatives
@@ -532,7 +534,6 @@ def relatives(self, obs, order=2):
532534
segments_connexion[n_seg][1].append(seg)
533535

534536
i_obs = [obs] if not hasattr(obs, "__iter__") else obs
535-
536537
distance = zeros(segment.size, dtype=uint16) - 1
537538

538539
def loop(seg, dist=1):

src/py_eddy_tracker/poly.py

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -716,50 +716,85 @@ def tri_area2(x, y, i0, i1, i2):
716716
def visvalingam(x, y, fixed_size=18):
717717
"""Polygon simplification with visvalingam algorithm
718718
719+
X, Y are considered like a polygon, the next point after the last one is the first one
719720
:param array x:
720721
:param array y:
721722
:param int fixed_size: array size of out
722-
:return: New (x, y) array
723+
:return:
724+
New (x, y) array, last position will be equal to first one, if array size is 6,
725+
there is only 5 point.
723726
:rtype: array,array
727+
728+
.. plot::
729+
730+
import matplotlib.pyplot as plt
731+
import numpy as np
732+
from py_eddy_tracker.poly import visvalingam
733+
734+
x = np.array([1, 2, 3, 4, 5, 6.75, 6, 1])
735+
y = np.array([-0.5, -1.5, -1, -1.75, -1, -1, -0.5, -0.5])
736+
ax = plt.subplot(111)
737+
ax.set_aspect("equal")
738+
ax.grid(True), ax.set_ylim(-2, -.2)
739+
ax.plot(x, y, "r", lw=5)
740+
ax.plot(*visvalingam(x,y,6), "b", lw=2)
741+
plt.show()
724742
"""
743+
# TODO : in case of original size lesser than fixed size, jump at the end
725744
nb = x.shape[0]
726-
i0, i1 = nb - 3, nb - 2
745+
nb_ori = nb
746+
# Get indice of first triangle
747+
i0, i1 = nb - 2, nb - 1
748+
# Init heap with first area and tiangle
727749
h = [(tri_area2(x, y, i0, i1, 0), (i0, i1, 0))]
750+
# Roll index for next one
728751
i0 = i1
729752
i1 = 0
730-
i_previous = empty(nb - 1, dtype=numba_types.int32)
731-
i_next = empty(nb - 1, dtype=numba_types.int32)
753+
# Index of previous valid point
754+
i_previous = empty(nb, dtype=numba_types.int64)
755+
# Index of next valid point
756+
i_next = empty(nb, dtype=numba_types.int64)
757+
# Mask of removed
758+
removed = zeros(nb, dtype=numba_types.bool_)
732759
i_previous[0] = -1
733760
i_next[0] = -1
734-
for i in range(1, nb - 1):
761+
for i in range(1, nb):
735762
i_previous[i] = -1
736763
i_next[i] = -1
764+
# We add triangle area for all triangle
737765
heapq.heappush(h, (tri_area2(x, y, i0, i1, i), (i0, i1, i)))
738766
i0 = i1
739767
i1 = i
740768
# we continue until we are equal to nb_pt
741-
while len(h) >= fixed_size:
769+
while nb >= fixed_size:
742770
# We pop lower area
743771
_, (i0, i1, i2) = heapq.heappop(h)
744772
# We check if triangle is valid(i0 or i2 not removed)
745-
i_p, i_n = i_previous[i0], i_next[i2]
746-
if i_p == -1 and i_n == -1:
747-
# We store reference of delete point
748-
i_previous[i1] = i0
749-
i_next[i1] = i2
773+
if removed[i0] or removed[i2]:
774+
# In this cas nothing to do
750775
continue
751-
elif i_p == -1:
752-
i2 = i_n
753-
elif i_n == -1:
754-
i0 = i_p
755-
else:
756-
# in this case we replace two point
757-
i0, i2 = i_p, i_n
758-
heapq.heappush(h, (tri_area2(x, y, i0, i1, i2), (i0, i1, i2)))
776+
# Flag obs like removed
777+
removed[i1] = True
778+
# We count point still valid
779+
nb -= 1
780+
# Modify index for the next and previous, we jump over i1
781+
i_previous[i2] = i0
782+
i_next[i0] = i2
783+
# We insert 2 triangles which are modified by the deleted point
784+
# Previous triangle
785+
i_1 = i_previous[i0]
786+
if i_1 == -1:
787+
i_1 = (i0 - 1) % nb_ori
788+
heapq.heappush(h, (tri_area2(x, y, i_1, i0, i2), (i_1, i0, i2)))
789+
# Previous triangle
790+
i3 = i_next[i2]
791+
if i3 == -1:
792+
i3 = (i2 + 1) % nb_ori
793+
heapq.heappush(h, (tri_area2(x, y, i0, i2, i3), (i0, i2, i3)))
759794
x_new, y_new = empty(fixed_size, dtype=x.dtype), empty(fixed_size, dtype=y.dtype)
760795
j = 0
761-
for i, i_n in enumerate(i_next):
762-
if i_n == -1:
796+
for i, flag in enumerate(removed):
797+
if not flag:
763798
x_new[j] = x[i]
764799
y_new[j] = y[i]
765800
j += 1
@@ -872,34 +907,6 @@ def poly_indexs(x_p, y_p, x_c, y_c):
872907
return indexs
873908

874909

875-
@njit(cache=True)
876-
def poly_indexs_old(x_p, y_p, x_c, y_c):
877-
"""
878-
index of contour for each postion inside a contour, -1 in case of no contour
879-
880-
:param array x_p: longitude to test
881-
:param array y_p: latitude to test
882-
:param array x_c: longitude of contours
883-
:param array y_c: latitude of contours
884-
"""
885-
nb_p = x_p.shape[0]
886-
nb_c = x_c.shape[0]
887-
indexs = -ones(nb_p, dtype=numba_types.int32)
888-
for i in range(nb_c):
889-
x_, y_ = reduce_size(x_c[i], y_c[i])
890-
x_c_min, y_c_min = x_.min(), y_.min()
891-
x_c_max, y_c_max = x_.max(), y_.max()
892-
v = create_vertice(x_, y_)
893-
for j in range(nb_p):
894-
if indexs[j] != -1:
895-
continue
896-
x, y = x_p[j], y_p[j]
897-
if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max:
898-
if winding_number_poly(x, y, v) != 0:
899-
indexs[j] = i
900-
return indexs
901-
902-
903910
@njit(cache=True)
904911
def insidepoly(x_p, y_p, x_c, y_c):
905912
"""

0 commit comments

Comments
 (0)