44import numpy
55import json
66import os
7+ import math
78import meshfill
89from vtk .util import numpy_support as VN
910import cdms2
1011import warnings
1112from projection import round_projections , no_over_proj4_parameter_projections
1213from vcsvtk import fillareautils
14+ import sys
1315import numbers
1416
1517f = open (os .path .join (vcs .prefix , "share" , "vcs" , "wmo_symbols.json" ))
@@ -220,6 +222,34 @@ def getBoundsList(axis, hasCellData, dualGrid):
220222 return None
221223
222224
225+ def setInfToValid (geoPoints , ghost ):
226+ '''
227+ Set infinity points to a point that already exists in the list.
228+ If a ghost array is passed, we also hide infinity points.
229+ We return true if any points are infinity
230+ '''
231+ anyInfinity = False
232+ validPoint = [0 , 0 , 0 ]
233+ for i in range (geoPoints .GetNumberOfPoints ()):
234+ point = geoPoints .GetPoint (i )
235+ if (not math .isinf (point [0 ]) and not math .isinf (point [1 ])):
236+ validPoint [0 ] = point [0 ]
237+ validPoint [1 ] = point [1 ]
238+ break
239+ for i in range (geoPoints .GetNumberOfPoints ()):
240+ point = geoPoints .GetPoint (i )
241+ if (math .isinf (point [0 ]) or math .isinf (point [1 ])):
242+ anyInfinity = True
243+ newPoint = list (point )
244+ if (math .isinf (point [0 ])):
245+ newPoint [0 ] = validPoint [0 ]
246+ if (math .isinf (point [1 ])):
247+ newPoint [1 ] = validPoint [1 ]
248+ geoPoints .SetPoint (i , newPoint )
249+ ghost .SetValue (i , vtk .vtkDataSetAttributes .HIDDENPOINT )
250+ return anyInfinity
251+
252+
223253def genGrid (data1 , data2 , gm , deep = True , grid = None , geo = None , genVectors = False ,
224254 dualGrid = False ):
225255 continents = False
@@ -444,6 +474,25 @@ def genGrid(data1, data2, gm, deep=True, grid=None, geo=None, genVectors=False,
444474 data1 .getAxis (- 2 ))
445475 geo , geopts = project (pts , projection , getWrappedBounds (
446476 wc , [xm , xM , ym , yM ], wrap ))
477+ # proj4 returns inf for points that are not visible. Set those to a valid point
478+ # and hide them.
479+ ghost = vg .AllocatePointGhostArray ()
480+ if (setInfToValid (geopts , ghost )):
481+ # if there are hidden points, we recompute the bounds
482+ xm = ym = sys .float_info .max
483+ xM = yM = - sys .float_info .max
484+ for i in range (pts .GetNumberOfPoints ()):
485+ if (ghost .GetValue (i ) & vtk .vtkDataSetAttributes .HIDDENPOINT == 0 ):
486+ # point not hidden
487+ p = pts .GetPoint (i )
488+ if (p [0 ] < xm ):
489+ xm = p [0 ]
490+ if (p [0 ] > xM ):
491+ xM = p [0 ]
492+ if (p [1 ] < ym ):
493+ ym = p [1 ]
494+ if (p [1 ] > yM ):
495+ yM = p [1 ]
447496 # Sets the vertics into the grid
448497 vg .SetPoints (geopts )
449498 else :
@@ -557,24 +606,42 @@ def apply_proj_parameters(pd, projection, x1, x2, y1, y2):
557606 else :
558607 pd .SetOptionalParameter ("over" , "false" )
559608 setProjectionParameters (pd , projection )
560- if (hasattr (projection , 'centralmeridian' ) and
561- numpy .allclose (projection .centralmeridian , 1e+20 )):
562- pd .SetCentralMeridian (float (x1 + x2 ) / 2.0 )
563- if (hasattr (projection , 'centerlongitude' ) and
564- numpy .allclose (projection .centerlongitude , 1e+20 )):
565- pd .SetOptionalParameter ("lon_0" , str (float (x1 + x2 ) / 2.0 ))
566- if (hasattr (projection , 'originlatitude' ) and
567- numpy .allclose (projection .originlatitude , 1e+20 )):
568- pd .SetOptionalParameter ("lat_0" , str (float (y1 + y2 ) / 2.0 ))
569- if (hasattr (projection , 'centerlatitude' ) and
570- numpy .allclose (projection .centerlatitude , 1e+20 )):
571- pd .SetOptionalParameter ("lat_0" , str (float (y1 + y2 ) / 2.0 ))
572- if (hasattr (projection , 'standardparallel1' ) and
573- numpy .allclose (projection .standardparallel1 , 1.e20 )):
574- pd .SetOptionalParameter ('lat_1' , str (min (y1 , y2 )))
575- if (hasattr (projection , 'standardparallel2' ) and
576- numpy .allclose (projection .standardparallel2 , 1.e20 )):
577- pd .SetOptionalParameter ('lat_2' , str (max (y1 , y2 )))
609+ if (hasattr (projection , 'centralmeridian' )):
610+ if (numpy .allclose (projection .centralmeridian , 1e+20 )):
611+ centralmeridian = float (x1 + x2 ) / 2.0
612+ else :
613+ centralmeridian = projection .centralmeridian
614+ pd .SetCentralMeridian (centralmeridian )
615+ if (hasattr (projection , 'centerlongitude' )):
616+ if (numpy .allclose (projection .centerlongitude , 1e+20 )):
617+ centerlongitude = float (x1 + x2 ) / 2.0
618+ else :
619+ centerlongitude = projection .centerlongitude
620+ pd .SetOptionalParameter ("lon_0" , str (centerlongitude ))
621+ if (hasattr (projection , 'originlatitude' )):
622+ if (numpy .allclose (projection .originlatitude , 1e+20 )):
623+ originlatitude = float (y1 + y2 ) / 2.0
624+ else :
625+ originlatitude = projection .originlatitude
626+ pd .SetOptionalParameter ("lat_0" , str (originlatitude ))
627+ if (hasattr (projection , 'centerlatitude' )):
628+ if (numpy .allclose (projection .centerlatitude , 1e+20 )):
629+ centerlatitude = float (y1 + y2 ) / 2.0
630+ else :
631+ centerlatitude = projection .centerlatitude
632+ pd .SetOptionalParameter ("lat_0" , str (centerlatitude ))
633+ if (hasattr (projection , 'standardparallel1' )):
634+ if (numpy .allclose (projection .standardparallel1 , 1.e20 )):
635+ standardparallel1 = min (y1 , y2 )
636+ else :
637+ standardparallel1 = projection .standardparallel1
638+ pd .SetOptionalParameter ('lat_1' , str (standardparallel1 ))
639+ if (hasattr (projection , 'standardparallel2' )):
640+ if (numpy .allclose (projection .standardparallel2 , 1.e20 )):
641+ standardparallel2 = max (y1 , y2 )
642+ else :
643+ standardparallel2 = projection .standardparallel2
644+ pd .SetOptionalParameter ('lat_2' , str (standardparallel2 ))
578645
579646
580647def projectArray (w , projection , wc , geo = None ):
@@ -1072,7 +1139,7 @@ def prepTextProperty(p, winSize, to="default", tt="default", cmap=None,
10721139
10731140
10741141def genTextActor (renderer , string = None , x = None , y = None ,
1075- to = 'default' , tt = 'default' , cmap = None ):
1142+ to = 'default' , tt = 'default' , cmap = None , geoBounds = None , geo = None ):
10761143 if isinstance (to , str ):
10771144 to = vcs .elements ["textorientation" ][to ]
10781145 if isinstance (tt , str ):
@@ -1096,21 +1163,8 @@ def genTextActor(renderer, string=None, x=None, y=None,
10961163 sz = renderer .GetRenderWindow ().GetSize ()
10971164 actors = []
10981165 pts = vtk .vtkPoints ()
1099- geo = None
11001166 if vcs .elements ["projection" ][tt .projection ].type != "linear" :
1101- # Need to figure out new WC
1102- Npts = 20
1103- for i in range (Npts + 1 ):
1104- X = tt .worldcoordinate [
1105- 0 ] + float (i ) / Npts * (tt .worldcoordinate [1 ] -
1106- tt .worldcoordinate [0 ])
1107- for j in range (Npts + 1 ):
1108- Y = tt .worldcoordinate [
1109- 2 ] + float (j ) / Npts * (tt .worldcoordinate [3 ] -
1110- tt .worldcoordinate [2 ])
1111- pts .InsertNextPoint (X , Y , 0. )
1112- geo , pts = project (pts , tt .projection , tt .worldcoordinate , geo = None )
1113- wc = pts .GetBounds ()[:4 ]
1167+ wc = geoBounds [:4 ]
11141168 # renderer.SetViewport(tt.viewport[0],tt.viewport[2],tt.viewport[1],tt.viewport[3])
11151169 renderer .SetWorldPoint (wc )
11161170
@@ -1120,8 +1174,8 @@ def genTextActor(renderer, string=None, x=None, y=None,
11201174 prepTextProperty (p , sz , to , tt , cmap )
11211175 pts = vtk .vtkPoints ()
11221176 pts .InsertNextPoint (x [i ], y [i ], 0. )
1123- if geo is not None :
1124- geo , pts = project (pts , tt .projection , tt .worldcoordinate , geo = geo )
1177+ if vcs . elements [ "projection" ][ tt . projection ]. type != "linear" :
1178+ _ , pts = project (pts , tt .projection , tt .worldcoordinate , geo = geo )
11251179 X , Y , tz = pts .GetPoint (0 )
11261180 X , Y = world2Renderer (renderer , X , Y , tt .viewport , wc )
11271181 else :
0 commit comments