@@ -80,7 +80,7 @@ def nearest(lon_pt, lat_pt, lon2d, lat2d):
80
80
return i , j
81
81
82
82
83
- def uniform_resample (x , y , num_fac = 4 , kind = 'linear' ):
83
+ def uniform_resample (x , y , num_fac = 2 , kind = 'linear' ):
84
84
'''
85
85
Resample contours to have (nearly) equal spacing
86
86
'''
@@ -89,6 +89,7 @@ def uniform_resample(x, y, num_fac=4, kind='linear'):
89
89
##x = ndimage.zoom(x.copy(), 2)
90
90
##y = ndimage.zoom(y.copy(), 2)
91
91
#plt.plot(x, y, '.-r', lw=2)
92
+
92
93
# Get distances
93
94
d = np .r_ [0 , np .cumsum (haversine_distance_vector (x [:- 1 ],y [:- 1 ], x [1 :],y [1 :]))]
94
95
# Get uniform distances
@@ -98,7 +99,15 @@ def uniform_resample(x, y, num_fac=4, kind='linear'):
98
99
yfunc = interpolate .interp1d (d , y , kind = kind )
99
100
xnew = xfunc (d_uniform )
100
101
ynew = yfunc (d_uniform )
101
- #plt.plot(xnew, ynew, '.-r', lw=2)
102
+
103
+ # Akima is slightly slower, but may be more accurate
104
+ #xfunc = interpolate.Akima1DInterpolator(d, x)
105
+ #yfunc = interpolate.Akima1DInterpolator(d, y)
106
+ #xxnew = xfunc(d_uniform)
107
+ #yynew = yfunc(d_uniform)
108
+
109
+ #plt.plot(xnew, ynew, '.-r', lw=1.5)
110
+ #plt.plot(xxnew, yynew, '+-b', lw=1.)
102
111
#plt.axis('image')
103
112
#plt.show()
104
113
return xnew , ynew
@@ -107,7 +116,104 @@ def uniform_resample(x, y, num_fac=4, kind='linear'):
107
116
def strcompare (str1 , str2 ):
108
117
return str1 in str2 and str2 in str1
109
118
110
-
119
+
120
+
121
+
122
+
123
+
124
+
125
+ def _find_closest_point_on_leg (p1 , p2 , p0 ):
126
+ """find closest point to p0 on line segment connecting p1 and p2"""
127
+
128
+ # handle degenerate case
129
+ if np .all (p2 == p1 ):
130
+ d = p0 - p1
131
+ d **= 2
132
+ return d .sum ()
133
+
134
+ d21 = p2 - p1
135
+ d01 = p0 - p1
136
+
137
+ # project on to line segment to find closest point
138
+ proj = np .dot (d01 , d21 )
139
+ proj /= np .dot (d21 , d21 )
140
+ if proj < 0 :
141
+ proj = 0
142
+ elif proj > 1 :
143
+ proj = 1
144
+ pc = p1 + proj * d21
145
+
146
+ # find squared distance
147
+ d = pc - p0
148
+ d **= 2
149
+
150
+ return d .sum ()#, pc
151
+
152
+
153
+ def _find_closest_point_on_path (lc , point ):
154
+ """
155
+ lc: coordinates of vertices
156
+ point: coordinates of test point
157
+ """
158
+ # Find index of closest vertex for this segment
159
+ ds = np .sum ((lc - point [None , :])** 2 , 1 )
160
+ imin = ds .argmin ()
161
+
162
+ dmin = np .inf
163
+ closed = np .alltrue ([lc [0 ,0 ] == lc [- 1 ,0 ], lc [0 ,1 ] == y [- 1 ,1 ]])
164
+
165
+ # Build list of legs before and after this vertex
166
+ legs = []
167
+ if imin > 0 or closed :
168
+ legs .append (((imin - 1 ) % len (lc ), imin ))
169
+ if imin < len (lc ) - 1 or closed :
170
+ legs .append ((imin , (imin + 1 ) % len (lc )))
171
+
172
+ for leg in legs :
173
+ #d, xc = _find_closest_point_on_leg(lc[leg[0]], lc[leg[1]], point)
174
+ d = _find_closest_point_on_leg (lc [leg [0 ]], lc [leg [1 ]], point )
175
+ if d < dmin :
176
+ dmin = d
177
+
178
+ return dmin
179
+
180
+
181
+ def find_nearest_contour (cont_coll , x , y , indices ):
182
+ """
183
+ Finds contour that is closest to a point.
184
+
185
+ Returns a tuple containing the contour, segment of minimum point.
186
+
187
+ Call signature::
188
+
189
+ conmin, segmin = find_nearest_contour(cont_coll, x, y, indices)
190
+ """
191
+ dmin = np .inf
192
+ conmin = None
193
+ segmin = None
194
+
195
+ point = np .array ([x , y ])
196
+
197
+ for icon in indices :
198
+ con = cont_coll .collections [icon ]
199
+ paths = con .get_paths ()
200
+
201
+ for segNum , linepath in enumerate (paths ):
202
+ lc = linepath .vertices
203
+ d = _find_closest_point_on_path (lc , point )
204
+
205
+ if d < dmin :
206
+ dmin = d
207
+ conmin = icon
208
+ segmin = segNum
209
+
210
+ return conmin , segmin
211
+
212
+
213
+
214
+
215
+
216
+
111
217
112
218
113
219
@@ -1087,7 +1193,7 @@ def _set_global_ellipse(self):
1087
1193
ew_x = np .hstack ((e_verts [:e_size ,0 ], w_verts [w_size :,0 ]))
1088
1194
ew_y = np .hstack ((e_verts [:e_size ,1 ], w_verts [w_size :,1 ]))
1089
1195
self .ellipse_path = path .Path (np .array ([ew_x , ew_y ]).T )
1090
- return self .ellipse_path
1196
+ return self # .ellipse_path
1091
1197
1092
1198
def _set_black_sea_ellipse (self ):
1093
1199
'''
@@ -1097,13 +1203,14 @@ def _set_black_sea_ellipse(self):
1097
1203
verts = self .black_sea_ellipse .get_verts ()
1098
1204
self .ellipse_path = path .Path (np .array ([verts [:,0 ],
1099
1205
verts [:,1 ]]).T )
1100
-
1206
+ return self
1101
1207
1102
1208
def get_search_ellipse (self , x , y ):
1103
1209
'''
1104
1210
'''
1105
1211
self .x = x
1106
1212
self .y = y
1213
+
1107
1214
if self .domain in ('Global' , 'ROMS' ):
1108
1215
self .rw_d [:] = self .rwv .get_rwdistance (x , y , self .days_btwn_recs )
1109
1216
self .rw_d_mod [:] = 1.75
@@ -1118,8 +1225,10 @@ def get_search_ellipse(self, x, y):
1118
1225
self .rw_d_mod *= self .rw_d
1119
1226
self ._set_black_sea_ellipse ()
1120
1227
1121
- else : Exception
1122
-
1228
+ else :
1229
+ Exception
1230
+
1231
+ return self
1123
1232
1124
1233
def view_search_ellipse (self , Eddy ):
1125
1234
'''
0 commit comments