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" ))
@@ -163,23 +165,6 @@ def putMaskOnVTKGrid(data, grid, actorColor=None, cellData=True, deep=True):
163165 return mapper
164166
165167
166- def handleProjectionEdgeCases (projection , data ):
167- # For mercator projection, latitude values of -90 or 90
168- # transformation result in infinity values. We chose -85, 85
169- # as that's the typical limit used by the community.
170- ptype = projDict .get (projection ._type , projection .type )
171- if (ptype .lower () == "merc" ):
172- lat = data .getLatitude ()
173- if isinstance (lat , cdms2 .axis .TransientAxis ):
174- lat = lat [:]
175- # Reverse the latitudes incase the starting latitude is greater
176- # than the ending one
177- if lat [- 1 ] < lat [0 ]:
178- lat = lat [::- 1 ]
179- data = data (latitude = (max (- 85 , lat .min ()), min (85 , lat .max ())))
180- return data
181-
182-
183168def getBoundsList (axis , hasCellData , dualGrid ):
184169 '''
185170 Returns the bounds list for 'axis'. If axis has n elements the
@@ -220,6 +205,34 @@ def getBoundsList(axis, hasCellData, dualGrid):
220205 return None
221206
222207
208+ def setInfToValid (geoPoints , ghost ):
209+ '''
210+ Set infinity points to a point that already exists in the list.
211+ If a ghost array is passed, we also hide infinity points.
212+ We return true if any points are infinity
213+ '''
214+ anyInfinity = False
215+ validPoint = [0 , 0 , 0 ]
216+ for i in range (geoPoints .GetNumberOfPoints ()):
217+ point = geoPoints .GetPoint (i )
218+ if (not math .isinf (point [0 ]) and not math .isinf (point [1 ])):
219+ validPoint [0 ] = point [0 ]
220+ validPoint [1 ] = point [1 ]
221+ break
222+ for i in range (geoPoints .GetNumberOfPoints ()):
223+ point = geoPoints .GetPoint (i )
224+ if (math .isinf (point [0 ]) or math .isinf (point [1 ])):
225+ anyInfinity = True
226+ newPoint = list (point )
227+ if (math .isinf (point [0 ])):
228+ newPoint [0 ] = validPoint [0 ]
229+ if (math .isinf (point [1 ])):
230+ newPoint [1 ] = validPoint [1 ]
231+ geoPoints .SetPoint (i , newPoint )
232+ ghost .SetValue (i , vtk .vtkDataSetAttributes .HIDDENPOINT )
233+ return anyInfinity
234+
235+
223236def genGrid (data1 , data2 , gm , deep = True , grid = None , geo = None , genVectors = False ,
224237 dualGrid = False ):
225238 continents = False
@@ -230,10 +243,6 @@ def genGrid(data1, data2, gm, deep=True, grid=None, geo=None, genVectors=False,
230243 xm , xM , ym , yM = None , None , None , None
231244 projection = vcs .elements ["projection" ][gm .projection ]
232245
233- data1 = handleProjectionEdgeCases (projection , data1 )
234- if data2 is not None :
235- data2 = handleProjectionEdgeCases (projection , data2 )
236-
237246 try : # First try to see if we can get a mesh out of this
238247 g = data1 .getGrid ()
239248 # Ok need unstructured grid
@@ -444,6 +453,25 @@ def genGrid(data1, data2, gm, deep=True, grid=None, geo=None, genVectors=False,
444453 data1 .getAxis (- 2 ))
445454 geo , geopts = project (pts , projection , getWrappedBounds (
446455 wc , [xm , xM , ym , yM ], wrap ))
456+ # proj4 returns inf for points that are not visible. Set those to a valid point
457+ # and hide them.
458+ ghost = vg .AllocatePointGhostArray ()
459+ if (setInfToValid (geopts , ghost )):
460+ # if there are hidden points, we recompute the bounds
461+ xm = ym = sys .float_info .max
462+ xM = yM = - sys .float_info .max
463+ for i in range (pts .GetNumberOfPoints ()):
464+ if (ghost .GetValue (i ) & vtk .vtkDataSetAttributes .HIDDENPOINT == 0 ):
465+ # point not hidden
466+ p = pts .GetPoint (i )
467+ if (p [0 ] < xm ):
468+ xm = p [0 ]
469+ if (p [0 ] > xM ):
470+ xM = p [0 ]
471+ if (p [1 ] < ym ):
472+ ym = p [1 ]
473+ if (p [1 ] > yM ):
474+ yM = p [1 ]
447475 # Sets the vertics into the grid
448476 vg .SetPoints (geopts )
449477 else :
@@ -557,24 +585,42 @@ def apply_proj_parameters(pd, projection, x1, x2, y1, y2):
557585 else :
558586 pd .SetOptionalParameter ("over" , "false" )
559587 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 )))
588+ if (hasattr (projection , 'centralmeridian' )):
589+ if (numpy .allclose (projection .centralmeridian , 1e+20 )):
590+ centralmeridian = float (x1 + x2 ) / 2.0
591+ else :
592+ centralmeridian = projection .centralmeridian
593+ pd .SetCentralMeridian (centralmeridian )
594+ if (hasattr (projection , 'centerlongitude' )):
595+ if (numpy .allclose (projection .centerlongitude , 1e+20 )):
596+ centerlongitude = float (x1 + x2 ) / 2.0
597+ else :
598+ centerlongitude = projection .centerlongitude
599+ pd .SetOptionalParameter ("lon_0" , str (centerlongitude ))
600+ if (hasattr (projection , 'originlatitude' )):
601+ if (numpy .allclose (projection .originlatitude , 1e+20 )):
602+ originlatitude = float (y1 + y2 ) / 2.0
603+ else :
604+ originlatitude = projection .originlatitude
605+ pd .SetOptionalParameter ("lat_0" , str (originlatitude ))
606+ if (hasattr (projection , 'centerlatitude' )):
607+ if (numpy .allclose (projection .centerlatitude , 1e+20 )):
608+ centerlatitude = float (y1 + y2 ) / 2.0
609+ else :
610+ centerlatitude = projection .centerlatitude
611+ pd .SetOptionalParameter ("lat_0" , str (centerlatitude ))
612+ if (hasattr (projection , 'standardparallel1' )):
613+ if (numpy .allclose (projection .standardparallel1 , 1.e20 )):
614+ standardparallel1 = min (y1 , y2 )
615+ else :
616+ standardparallel1 = projection .standardparallel1
617+ pd .SetOptionalParameter ('lat_1' , str (standardparallel1 ))
618+ if (hasattr (projection , 'standardparallel2' )):
619+ if (numpy .allclose (projection .standardparallel2 , 1.e20 )):
620+ standardparallel2 = max (y1 , y2 )
621+ else :
622+ standardparallel2 = projection .standardparallel2
623+ pd .SetOptionalParameter ('lat_2' , str (standardparallel2 ))
578624
579625
580626def projectArray (w , projection , wc , geo = None ):
@@ -1072,7 +1118,7 @@ def prepTextProperty(p, winSize, to="default", tt="default", cmap=None,
10721118
10731119
10741120def genTextActor (renderer , string = None , x = None , y = None ,
1075- to = 'default' , tt = 'default' , cmap = None ):
1121+ to = 'default' , tt = 'default' , cmap = None , geoBounds = None , geo = None ):
10761122 if isinstance (to , str ):
10771123 to = vcs .elements ["textorientation" ][to ]
10781124 if isinstance (tt , str ):
@@ -1096,21 +1142,8 @@ def genTextActor(renderer, string=None, x=None, y=None,
10961142 sz = renderer .GetRenderWindow ().GetSize ()
10971143 actors = []
10981144 pts = vtk .vtkPoints ()
1099- geo = None
11001145 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 ]
1146+ wc = geoBounds [:4 ]
11141147 # renderer.SetViewport(tt.viewport[0],tt.viewport[2],tt.viewport[1],tt.viewport[3])
11151148 renderer .SetWorldPoint (wc )
11161149
@@ -1120,8 +1153,8 @@ def genTextActor(renderer, string=None, x=None, y=None,
11201153 prepTextProperty (p , sz , to , tt , cmap )
11211154 pts = vtk .vtkPoints ()
11221155 pts .InsertNextPoint (x [i ], y [i ], 0. )
1123- if geo is not None :
1124- geo , pts = project (pts , tt .projection , tt .worldcoordinate , geo = geo )
1156+ if vcs . elements [ "projection" ][ tt . projection ]. type != "linear" :
1157+ _ , pts = project (pts , tt .projection , tt .worldcoordinate , geo = geo )
11251158 X , Y , tz = pts .GetPoint (0 )
11261159 X , Y = world2Renderer (renderer , X , Y , tt .viewport , wc )
11271160 else :
0 commit comments