Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
MUG
visad
Commits
066f29ae
Unverified
Commit
066f29ae
authored
Oct 15, 2018
by
tomrink
Committed by
GitHub
Oct 15, 2018
Browse files
Merge pull request #152 from tomrink/GriddedLatLonSet
Gridded lat lon set
parents
ec8aced4
65081b43
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
core/src/visad/FixGeomSizeAppearance.java
View file @
066f29ae
...
...
@@ -7,7 +7,6 @@ package visad;
import
java.util.ArrayList
;
import
java.rmi.RemoteException
;
import
javax.media.j3d.*
;
public
class
FixGeomSizeAppearance
implements
ControlListener
{
...
...
core/src/visad/GriddedLatLonSet.java
View file @
066f29ae
...
...
@@ -29,8 +29,13 @@ package visad;
import
java.io.*
;
/**
GriddedLatLonSet represents a finite set of samples of R^2.<P>
*/
*
* @author rink
*
* GriddedLatLonSet represents a finite set of samples with a 2D grid topology on the surface
* of the Earth mapped to R^2: (Longitude, Latitude) or (Latitude, Longitude). This class
* exists primarily to override valueToGrid and gridToValue.
*/
public
class
GriddedLatLonSet
extends
Gridded2DSet
{
int
LengthX
,
LengthY
,
TrackLen
,
latI
,
lonI
;
...
...
@@ -46,7 +51,7 @@ public class GriddedLatLonSet extends Gridded2DSet {
null errors, CoordinateSystem and Units are defaults from type */
public
GriddedLatLonSet
(
MathType
type
,
float
[][]
samples
,
int
lengthX
,
int
lengthY
)
throws
VisADException
{
this
(
type
,
samples
,
lengthX
,
lengthY
,
null
,
null
,
null
,
false
,
false
);
this
(
type
,
samples
,
lengthX
,
lengthY
,
null
,
null
,
null
,
false
);
}
/** a 2-D set whose topology is a lengthX x lengthY grid;
...
...
@@ -59,23 +64,14 @@ public class GriddedLatLonSet extends Gridded2DSet {
public
GriddedLatLonSet
(
MathType
type
,
float
[][]
samples
,
int
lengthX
,
int
lengthY
,
CoordinateSystem
coord_sys
,
Unit
[]
units
,
ErrorEstimate
[]
errors
)
throws
VisADException
{
this
(
type
,
samples
,
lengthX
,
lengthY
,
coord_sys
,
units
,
errors
,
true
,
true
);
this
(
type
,
samples
,
lengthX
,
lengthY
,
coord_sys
,
units
,
errors
,
false
);
}
public
GriddedLatLonSet
(
MathType
type
,
float
[][]
samples
,
int
lengthX
,
int
lengthY
,
CoordinateSystem
coord_sys
,
Unit
[]
units
,
ErrorEstimate
[]
errors
,
boolean
copy
)
throws
VisADException
{
this
(
type
,
samples
,
lengthX
,
lengthY
,
coord_sys
,
units
,
errors
,
copy
,
true
);
}
public
GriddedLatLonSet
(
MathType
type
,
float
[][]
samples
,
int
lengthX
,
int
lengthY
,
CoordinateSystem
coord_sys
,
Unit
[]
units
,
ErrorEstimate
[]
errors
,
boolean
copy
,
boolean
test
)
throws
VisADException
{
super
(
type
,
samples
,
lengthX
,
lengthY
,
coord_sys
,
units
,
errors
,
copy
,
test
);
super
(
type
,
samples
,
lengthX
,
lengthY
,
coord_sys
,
units
,
errors
,
copy
,
false
);
LowX
=
Low
[
0
];
HiX
=
Hi
[
0
];
...
...
@@ -136,15 +132,17 @@ public class GriddedLatLonSet extends Gridded2DSet {
System
.
arraycopy
(
lons
,
lons0
.
length
,
lons1
,
0
,
lons1
.
length
);
System
.
arraycopy
(
lats
,
lats0
.
length
,
lats1
,
0
,
lats1
.
length
);
granules
[
0
]
=
new
GriddedLatLonSet
(
type
,
new
float
[][]
{
lons0
,
lats0
},
LengthX
,
TrackLen0
,
coord_sys
,
units
,
errors
,
copy
,
test
);
granules
[
1
]
=
new
GriddedLatLonSet
(
type
,
new
float
[][]
{
lons1
,
lats1
},
LengthX
,
TrackLen1
,
coord_sys
,
units
,
errors
,
copy
,
test
);
granules
[
0
]
=
new
GriddedLatLonSet
(
type
,
new
float
[][]
{
lons0
,
lats0
},
LengthX
,
TrackLen0
,
coord_sys
,
units
,
errors
,
copy
);
granules
[
1
]
=
new
GriddedLatLonSet
(
type
,
new
float
[][]
{
lons1
,
lats1
},
LengthX
,
TrackLen1
,
coord_sys
,
units
,
errors
,
copy
);
}
}
/** transform an array of non-integer grid coordinates to an array
of values in R^DomainDimension */
/** transform an array of non-integer grid coordinates to an array of values in (Longitude, Latitude).
* Returns nearest neighbor if the cell which contains the grid coordinate straddles
* the dateline or prime meridian.
*/
public
float
[][]
gridToValue
(
float
[][]
grid
)
throws
VisADException
{
if
(
grid
.
length
!=
ManifoldDimension
)
{
throw
new
SetException
(
"Gridded2DSet.gridToValue: grid dimension "
+
...
...
@@ -258,6 +256,16 @@ public class GriddedLatLonSet extends Gridded2DSet {
return
valueToGrid
(
value
,
null
);
}
/** transform an array of values in R^2 (Longitude, Latitude) to an array
* of non-integer grid coordinates by walking the grid from guess to incoming
* target values by minimizing the angle between vectors from Earth center to the
* their respective Earth coordinates.
* @param value (Longitude, Latitude)
* @param guess Integer grid coordinate. Is replaced by last valid grid located
* by the search. If null, center point of domain is used as guess.
* @return Fractional grid coordinates for incoming values
* @throws visad.VisADException
*/
@Override
public
synchronized
float
[][]
valueToGrid
(
float
[][]
value
,
int
[]
guess
)
throws
VisADException
{
...
...
@@ -537,16 +545,16 @@ public class GriddedLatLonSet extends Gridded2DSet {
offGrid
=
!
insideTriangle
(
gg
,
CC
,
LL
,
DD
,
tt
);
}
else
if
(
gy
==
0
)
{
offGrid
=
!
insideTriangle
(
gg
,
LL
,
UU
,
RR
,
tt
);
offGrid
=
!
(
insideTriangle
(
gg
,
CC
,
UU
,
LL
,
tt
)
||
insideTriangle
(
gg
,
CC
,
RR
,
UU
,
tt
)
)
;
}
else
if
(
gy
==
TrackLen
-
1
)
{
offGrid
=
!
insideTriangle
(
gg
,
LL
,
DD
,
RR
,
tt
);
offGrid
=
!
(
insideTriangle
(
gg
,
CC
,
LL
,
DD
,
tt
)
||
insideTriangle
(
gg
,
CC
,
DD
,
RR
,
tt
)
)
;
}
else
if
(
gx
==
0
)
{
offGrid
=
!
insideTriangle
(
gg
,
UU
,
RR
,
DD
,
tt
);
offGrid
=
!
(
insideTriangle
(
gg
,
CC
,
UU
,
RR
,
tt
)
||
insideTriangle
(
gg
,
CC
,
DD
,
RR
,
tt
)
)
;
}
else
if
(
gx
==
LengthX
-
1
)
{
offGrid
=
!
insideTriangle
(
gg
,
UU
,
LL
,
DD
,
tt
);
offGrid
=
!
(
insideTriangle
(
gg
,
CC
,
UU
,
LL
,
tt
)
||
insideTriangle
(
gg
,
CC
,
DD
,
LL
,
tt
)
)
;
}
if
(!
offGrid
)
{
...
...
@@ -633,6 +641,13 @@ public class GriddedLatLonSet extends Gridded2DSet {
public
static
boolean
insideTriangle
(
float
[]
v0
,
float
[]
v1
,
float
[]
v2
,
float
[]
pt
)
{
/* Eventhough chance of this happening is small (that the incoming target would fall on a domain point)*/
if
((
pt
[
0
]
==
v0
[
0
]
&&
pt
[
1
]
==
v0
[
1
]
&&
pt
[
2
]
==
v0
[
2
])
||
(
pt
[
0
]
==
v1
[
0
]
&&
pt
[
1
]
==
v1
[
1
]
&&
pt
[
2
]
==
v1
[
2
])
||
(
pt
[
0
]
==
v2
[
0
]
&&
pt
[
1
]
==
v2
[
1
]
&&
pt
[
2
]
==
v2
[
2
]))
{
return
true
;
}
float
[]
triNorm
=
TrajectoryManager
.
AxB
(
new
float
[]
{
v1
[
0
]-
v0
[
0
],
v1
[
1
]-
v0
[
1
],
v1
[
2
]-
v0
[
2
]},
new
float
[]
{
v2
[
0
]-
v0
[
0
],
v2
[
1
]-
v0
[
1
],
v2
[
2
]-
v0
[
2
]},
true
);
double
[]
coeffs
=
TrajectoryManager
.
getPlaneCoeffsFromNormalAndPoint
(
new
double
[]
{(
float
)
triNorm
[
0
],
(
float
)
triNorm
[
1
],
(
float
)
triNorm
[
2
]},
new
double
[]{(
float
)
v0
[
0
],
(
float
)
v0
[
1
],
(
float
)
v0
[
2
]});
...
...
core/src/visad/GriddedSet.java
View file @
066f29ae
...
...
@@ -202,7 +202,7 @@ public class GriddedSet extends SampledSet implements GriddedSetIface {
if
(
type
.
equals
(
RealTupleType
.
LatitudeLongitudeTuple
)
||
type
.
equals
(
RealTupleType
.
SpatialEarth2DTuple
))
{
return
new
GriddedLatLonSet
(
type
,
samples
,
lengths
[
0
],
lengths
[
1
],
coord_sys
,
units
,
errors
,
copy
,
test
);
coord_sys
,
units
,
errors
,
copy
);
}
else
{
return
new
Gridded2DSet
(
type
,
samples
,
...
...
core/src/visad/Trajectory.java
View file @
066f29ae
...
...
@@ -173,20 +173,25 @@ public class Trajectory {
if
(
terrain
!=
null
)
{
adjustFlowAtTerrain
(
terrain
,
color_values
);
}
}
}
addPair
(
startPts
,
stopPts
,
startColor
,
stopColor
);
if
(
indices
[
0
]
==
null
)
{
offGrid
=
true
;
}
else
{
addPair
(
startPts
,
stopPts
,
startColor
,
stopColor
);
uVecPath
[
0
]
=
stopPts
[
0
]
-
startPts
[
0
];
uVecPath
[
1
]
=
stopPts
[
1
]
-
startPts
[
1
];
uVecPath
[
2
]
=
stopPts
[
2
]
-
startPts
[
2
];
uVecPath
[
0
]
=
stopPts
[
0
]
-
startPts
[
0
];
uVecPath
[
1
]
=
stopPts
[
1
]
-
startPts
[
1
];
uVecPath
[
2
]
=
stopPts
[
2
]
-
startPts
[
2
];
float
mag
=
(
float
)
Math
.
sqrt
(
uVecPath
[
0
]*
uVecPath
[
0
]
+
uVecPath
[
1
]*
uVecPath
[
1
]
+
uVecPath
[
2
]*
uVecPath
[
2
]);
uVecPath
[
0
]
/=
mag
;
uVecPath
[
1
]
/=
mag
;
uVecPath
[
2
]
/=
mag
;
update
();
float
mag
=
(
float
)
Math
.
sqrt
(
uVecPath
[
0
]*
uVecPath
[
0
]
+
uVecPath
[
1
]*
uVecPath
[
1
]
+
uVecPath
[
2
]*
uVecPath
[
2
]);
uVecPath
[
0
]
/=
mag
;
uVecPath
[
1
]
/=
mag
;
uVecPath
[
2
]
/=
mag
;
update
();
}
}
}
...
...
@@ -400,23 +405,30 @@ public class Trajectory {
}
}
addPair
(
startPts
,
stopPts
,
startColor
,
stopColor
);
if
(
indices
[
0
]
==
null
)
{
offGrid
=
true
;
}
else
{
addPair
(
startPts
,
stopPts
,
startColor
,
stopColor
);
uVecPath
[
0
]
=
stopPts
[
0
]
-
startPts
[
0
];
uVecPath
[
1
]
=
stopPts
[
1
]
-
startPts
[
1
];
uVecPath
[
2
]
=
stopPts
[
2
]
-
startPts
[
2
];
uVecPath
[
0
]
=
stopPts
[
0
]
-
startPts
[
0
];
uVecPath
[
1
]
=
stopPts
[
1
]
-
startPts
[
1
];
uVecPath
[
2
]
=
stopPts
[
2
]
-
startPts
[
2
];
float
mag
=
(
float
)
Math
.
sqrt
(
uVecPath
[
0
]*
uVecPath
[
0
]
+
uVecPath
[
1
]*
uVecPath
[
1
]
+
uVecPath
[
2
]*
uVecPath
[
2
]);
uVecPath
[
0
]
/=
mag
;
uVecPath
[
1
]
/=
mag
;
uVecPath
[
2
]
/=
mag
;
update
();
float
mag
=
(
float
)
Math
.
sqrt
(
uVecPath
[
0
]*
uVecPath
[
0
]
+
uVecPath
[
1
]*
uVecPath
[
1
]
+
uVecPath
[
2
]*
uVecPath
[
2
]);
uVecPath
[
0
]
/=
mag
;
uVecPath
[
1
]
/=
mag
;
uVecPath
[
2
]
/=
mag
;
update
();
}
}
}
/*
Add start/stop pair segment to the TrajectoryManager.
*/
private
void
addPair
(
float
[]
startPt
,
float
[]
stopPt
,
byte
[]
startColor
,
byte
[]
stopColor
)
{
indexes
[
npairs
]
=
trajMan
.
getCoordinateCount
();
...
...
@@ -435,6 +447,9 @@ public class Trajectory {
}
}
/*
Advance forecast (stop) point location, color and intrp info to the start for the next displacement interval.
*/
private
void
update
()
throws
VisADException
{
startPts
[
0
]
=
stopPts
[
0
];
...
...
core/src/visad/TrajectoryManager.java
View file @
066f29ae
This diff is collapsed.
Click to expand it.
core/src/visad/TrajectoryParams.java
View file @
066f29ae
...
...
@@ -54,11 +54,19 @@ public class TrajectoryParams {
Euler
;
}
public
static
enum
InterpolationMethod
{
Cubic
,
Linear
,
None
;
}
public
static
final
int
LINE
=
0
;
public
static
final
int
RIBBON
=
1
;
public
static
final
int
CYLINDER
=
2
;
public
static
final
int
DEFORM_RIBBON
=
3
;
public
static
final
int
POINT
=
4
;
public
static
final
int
TRACER
=
5
;
public
static
final
int
TRACER_POINT
=
6
;
double
trajVisibilityTimeWindow
=
86400.0
;
double
trajRefreshInterval
=
86400.0
;
...
...
@@ -67,13 +75,16 @@ public class TrajectoryParams {
SmoothParams
smoothParams
=
SmoothParams
.
LIGHT
;
boolean
forward
=
true
;
int
direction
=
1
;
//1: forward, -1: backward
boolean
doIntrp
=
true
;
//
boolean doIntrp = true;
float
markerSize
=
1
f
;
boolean
markerEnabled
=
false
;
boolean
manualIntrpPts
=
false
;
boolean
autoSizeMarker
=
true
;
boolean
cachingEnabled
=
true
;
boolean
terrainFollowEnabled
=
true
;
boolean
trcrStreamingEnabled
=
false
;
boolean
saveTracerLocations
=
false
;
boolean
trajDoIntrp
=
true
;
int
trajForm
=
LINE
;
float
cylWidth
=
0.00014f
;
...
...
@@ -89,6 +100,9 @@ public class TrajectoryParams {
FlatField
terrain
=
null
;
Method
method
=
Method
.
HySplit
;
//Default
InterpolationMethod
interpMethod
=
InterpolationMethod
.
Cubic
;
double
timeStepScaleFactor
=
1
;
public
TrajectoryParams
()
{
}
...
...
@@ -101,7 +115,6 @@ public class TrajectoryParams {
this
.
smoothParams
=
params
.
getSmoothParams
();
this
.
forward
=
params
.
getDirectionFlag
();
this
.
direction
=
params
.
getDirection
();
this
.
doIntrp
=
params
.
getDoIntrp
();
this
.
markerSize
=
params
.
getMarkerSize
();
this
.
markerEnabled
=
params
.
getMarkerEnabled
();
this
.
manualIntrpPts
=
params
.
getManualIntrpPts
();
...
...
@@ -117,6 +130,11 @@ public class TrajectoryParams {
this
.
terrain
=
params
.
getTerrain
();
this
.
terrainFollowEnabled
=
params
.
getTerrainFollowing
();
this
.
method
=
params
.
getMethod
();
this
.
interpMethod
=
params
.
getInterpolationMethod
();
this
.
trcrStreamingEnabled
=
params
.
getTracerStreamingEnabled
();
this
.
saveTracerLocations
=
params
.
getSaveTracerLocations
();
this
.
timeStepScaleFactor
=
params
.
getTimeStepScaleFactor
();
this
.
trajDoIntrp
=
params
.
getTrajDoIntrp
();
}
public
TrajectoryParams
(
double
trajVisibilityTimeWindow
,
double
trajRefreshInterval
,
int
numIntrpPts
,
int
startSkip
,
SmoothParams
smoothParams
)
{
...
...
@@ -183,10 +201,6 @@ public class TrajectoryParams {
return
forward
;
}
public
void
setDoIntrp
(
boolean
yesno
)
{
this
.
doIntrp
=
yesno
;
}
public
void
setNumIntrpPts
(
int
numIntrpPts
)
{
this
.
numIntrpPts
=
numIntrpPts
;
this
.
manualIntrpPts
=
true
;
...
...
@@ -224,6 +238,10 @@ public class TrajectoryParams {
this
.
method
=
method
;
}
public
void
setInterpolationMethod
(
InterpolationMethod
m
)
{
this
.
interpMethod
=
m
;
}
public
void
setCachingEnabled
(
boolean
yesno
)
{
this
.
cachingEnabled
=
yesno
;
}
...
...
@@ -288,10 +306,6 @@ public class TrajectoryParams {
return
direction
;
}
public
boolean
getDoIntrp
()
{
return
this
.
doIntrp
;
}
public
float
getMarkerSize
()
{
return
this
.
markerSize
;
}
...
...
@@ -308,6 +322,10 @@ public class TrajectoryParams {
return
method
;
}
public
InterpolationMethod
getInterpolationMethod
()
{
return
interpMethod
;
}
public
void
setStartPoints
(
float
[][]
startPts
)
{
this
.
startPoints
=
startPts
;
this
.
startType
=
Display
.
DisplaySpatialCartesianTuple
;
...
...
@@ -346,6 +364,38 @@ public class TrajectoryParams {
return
this
.
cachingEnabled
;
}
public
boolean
getTracerStreamingEnabled
()
{
return
this
.
trcrStreamingEnabled
;
}
public
void
setTracerStreamingEnabled
(
boolean
yesno
)
{
this
.
trcrStreamingEnabled
=
yesno
;
}
public
boolean
getSaveTracerLocations
()
{
return
this
.
saveTracerLocations
;
}
public
void
setSaveTracerLocations
(
boolean
yesno
)
{
this
.
saveTracerLocations
=
yesno
;
}
public
double
getTimeStepScaleFactor
()
{
return
this
.
timeStepScaleFactor
;
}
public
void
setTimeStepScaleFactor
(
double
fac
)
{
this
.
timeStepScaleFactor
=
fac
;
}
public
boolean
getTrajDoIntrp
()
{
return
this
.
trajDoIntrp
;
}
public
void
setTrajDoIntrp
(
boolean
yesno
)
{
this
.
trajDoIntrp
=
yesno
;
}
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
||
!(
obj
instanceof
TrajectoryParams
))
{
return
false
;
...
...
@@ -376,9 +426,6 @@ public class TrajectoryParams {
else
if
(
this
.
trajForm
!=
trajParams
.
trajForm
)
{
return
false
;
}
else
if
(
this
.
doIntrp
!=
trajParams
.
doIntrp
)
{
return
false
;
}
else
if
(
this
.
forward
!=
trajParams
.
forward
)
{
return
false
;
}
...
...
@@ -400,6 +447,18 @@ public class TrajectoryParams {
else
if
(
this
.
method
!=
trajParams
.
method
)
{
return
false
;
}
else
if
(
this
.
trcrStreamingEnabled
!=
trajParams
.
trcrStreamingEnabled
)
{
return
false
;
}
else
if
(
this
.
saveTracerLocations
!=
trajParams
.
saveTracerLocations
)
{
return
false
;
}
else
if
(
this
.
timeStepScaleFactor
!=
trajParams
.
timeStepScaleFactor
)
{
return
false
;
}
else
if
(
this
.
trajDoIntrp
!=
trajParams
.
trajDoIntrp
)
{
return
false
;
}
}
return
true
;
}
...
...
core/src/visad/XTrackScanLatLonSet.java
0 → 100644
View file @
066f29ae
//
// XTrackScanLatLonSet
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2018 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package
visad
;
/**
*
* @author rink
*
* Specialized extension to GriddedLatLonSet for a contiguous collection of spatially overlapping sets
* wherein it's trusted that samples of an individual set are spatially coherent (non-degenerative: no bow-ties).
* Examples are MODIS and VIIRS whose granules are comprised of multiple scans, each with a fixed number of
* detectors, and perpendicular to the polar orbit track, but may overlap when navigated to the Earth's surface.
* The primary purpose of this class is to override valueToGrid.
*
*/
public
class
XTrackScanLatLonSet
extends
GriddedLatLonSet
{
GriddedLatLonSet
[]
scanSets
;
int
numOfScans
;
int
linesPerScan
;
int
lastSetIdx
;
public
XTrackScanLatLonSet
(
MathType
type
,
float
[][]
samples
,
int
XTrackLen
,
int
TrackLen
,
int
linesPerScan
)
throws
VisADException
{
super
(
type
,
samples
,
XTrackLen
,
TrackLen
,
null
,
null
,
null
,
false
);
if
((
TrackLen
%
linesPerScan
)
!=
0
)
{
throw
new
VisADException
(
"There must be an intergral number of scans with detectorsPerScan: "
+
linesPerScan
+
" per "
+
"TrackLen: "
+
TrackLen
);
}
this
.
linesPerScan
=
linesPerScan
;
numOfScans
=
TrackLen
/
linesPerScan
;
scanSets
=
new
GriddedLatLonSet
[
numOfScans
];
int
scanLen
=
linesPerScan
*
XTrackLen
;
for
(
int
k
=
0
;
k
<
numOfScans
;
k
++)
{
float
[]
scanLonArray
=
new
float
[
linesPerScan
*
XTrackLen
];
float
[]
scanLatArray
=
new
float
[
linesPerScan
*
XTrackLen
];
System
.
arraycopy
(
lons
,
k
*
scanLen
,
scanLonArray
,
0
,
scanLen
);
System
.
arraycopy
(
lats
,
k
*
scanLen
,
scanLatArray
,
0
,
scanLen
);
scanSets
[
k
]
=
new
GriddedLatLonSet
(
RealTupleType
.
SpatialEarth2DTuple
,
new
float
[][]
{
scanLonArray
,
scanLatArray
},
XTrackLen
,
linesPerScan
);
}
}
public
float
[][]
valueToGrid
(
float
[][]
value
)
throws
VisADException
{
return
valueToGrid
(
value
,
null
);
}
public
float
[][]
valueToGrid
(
float
[][]
value
,
int
[]
guess
)
throws
VisADException
{
if
(
value
.
length
<
DomainDimension
)
{
throw
new
SetException
(
"Gridded2DSet.valueToGrid: value dimension "
+
value
.
length
+
" not equal to Domain dimension "
+
DomainDimension
);
}
if
(
ManifoldDimension
<
2
)
{
throw
new
SetException
(
"Gridded2DSet.valueToGrid: Manifold dimension "
+
"must be 2, not "
+
ManifoldDimension
);
}
if
(
Length
>
1
&&
(
Lengths
[
0
]
<
2
||
Lengths
[
1
]
<
2
))
{
throw
new
SetException
(
"Gridded2DSet.valueToGrid: requires all grid "
+
"dimensions to be > 1"
);
}
if
(
guess
!=
null
&&
guess
.
length
!=
2
)
{
throw
new
SetException
(
"Gridded2DSet.valueToGrid: guess length "
+
guess
.
length
+
" must equal 2"
);
}
int
length
=
Math
.
min
(
value
[
0
].
length
,
value
[
1
].
length
);
float
[][]
grid
=
new
float
[
ManifoldDimension
][
length
];
// (gx, gy) is the current grid box guess
int
gx
=
(
LengthX
-
1
)/
2
;
int
gy
=
(
TrackLen
-
1
)/
2
;
if
(
guess
!=
null
&&
guess
[
0
]
>=
0
&&
guess
[
1
]
>=
0
)
{
gx
=
guess
[
0
];
gy
=
guess
[
1
];
}
else
if
(
lgxy
[
0
]
!=
-
1
&&
lgxy
[
1
]
!=
-
1
)
{
gx
=
lgxy
[
0
];
gy
=
lgxy
[
1
];
}
int
setIdx
=
gy
/
linesPerScan
;
//int gy_set = gy % linesPerScan;
lastSetIdx
=
setIdx
;
int
idx
=
gy
*
LengthX
+
gx
;
if
(
Float
.
isNaN
(
lons
[
idx
])
||
Float
.
isNaN
(
lats
[
idx
])
||
(
Math
.
abs
(
lats
[
idx
])
>
90
))
{
throw
new
VisADException
(
"initial grid box guess cannot be invalid or missing"
);
}
float
[][]
lonlat
=
new
float
[
2
][
1
];
int
[]
guess_set
=
new
int
[
2
];
guess_set
[
0
]
=
gx
;
guess_set
[
1
]
=
linesPerScan
/
2
;
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
if
(
Length
==
1
)
{
if
(
Float
.
isNaN
(
value
[
0
][
i
])
||
Float
.
isNaN
(
value
[
1
][
i
]))
{
grid
[
0
][
i
]
=
grid
[
1
][
i
]
=
Float
.
NaN
;
}
else
{
grid
[
0
][
i
]
=
0
;
grid
[
1
][
i
]
=
0
;
}
continue
;
}
// test for missing
if
(
(
i
!=
0
)
&&
grid
[
0
][
i
-
1
]
!=
grid
[
0
][
i
-
1
]
)
{
// use last valid
if
(
lgxy
[
0
]
!=
-
1
&&
lgxy
[
1
]
!=
-
1
)
{
gx
=
lgxy
[
0
];
gy
=
lgxy
[
1
];
}
}
// if the loop doesn't find the answer, the result should be NaN
grid
[
0
][
i
]
=
grid
[
1
][
i
]
=
Float
.
NaN
;
float
targetLon
=
value
[
lonI
][
i
];
float
targetLat
=
value
[
latI
][
i
];
lonlat
[
lonI
][
0
]
=
targetLon
;
lonlat
[
latI
][
0
]
=
targetLat
;
float
[][]
gxgy
;
/* Should never exceed numOfScans */
int
cnt
=
0
;
/* Used to detect infinite stepping back and forth between consecutive scans.
This may happen if the target falls in a gap between two adjacent scans,
for example, near MODIS, VIIRS Nadir. In this situation, NaN is returned but
may consider other options in the future.
*/
int
dir
=
0
;
/* Beginnig with lastSetIdx start walking through the GriddedLatLonSet to find grid
cell which contains the target. If none found, use last test position (must be
on an edge) as guess position for the adjacent scan.
*/
while
((
lastSetIdx
>=
0
&&
lastSetIdx
<
numOfScans
)
&&
cnt
<
numOfScans
)
{
GriddedLatLonSet
scanSet
=
scanSets
[
lastSetIdx
];
gxgy
=
scanSet
.
valueToGrid
(
lonlat
,
guess_set
);
if
(
Float
.
isNaN
(
gxgy
[
0
][
0
])
||
Float
.
isNaN
(
gxgy
[
1
][
0
]))
{
int
gx_set
=
guess_set
[
0
];
int
gy_set
=
guess_set
[
1
];
if
(
gy_set
==
0
)
{
lastSetIdx
-=
1
;
guess_set
[
0
]
=
gx_set
;
guess_set
[
1
]
=
linesPerScan
-
1
;
if
(
dir
==
1
)
{
break
;
}
dir
=
-
1
;
}
else
if
(
gy_set
==
linesPerScan