mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
update CMA Radar base data reading function
This commit is contained in:
parent
2d72e5f30b
commit
3717f61ea5
5
.idea/compiler.xml
generated
5
.idea/compiler.xml
generated
@ -25,9 +25,6 @@
|
||||
<module name="meteoinfo-common" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="meteoinfo-legend" target="11" />
|
||||
<module name="MeteoInfoLib" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -13,7 +13,7 @@
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/classes" />
|
||||
</component>
|
||||
</project>
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-chart</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<freehep.version>2.4</freehep.version>
|
||||
<jogl.version>2.4.0</jogl.version>
|
||||
</properties>
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
@ -67,7 +67,7 @@ import java.util.zip.ZipInputStream;
|
||||
public static String getVersion(){
|
||||
String version = GlobalUtil.class.getPackage().getImplementationVersion();
|
||||
if (version == null || version.equals("")) {
|
||||
version = "3.6.4";
|
||||
version = "3.6.5";
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-console</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-data</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<netcdf.version>5.5.4-SNAPSHOT</netcdf.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ public class Variable {
|
||||
private double fill_value = -9999.0;
|
||||
private double scale_factor = 1;
|
||||
private double add_offset = 0;
|
||||
private Array cachedData;
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Constructor">
|
||||
|
||||
@ -600,6 +601,30 @@ public class Variable {
|
||||
public void setAddOffset(double value) {
|
||||
this.add_offset = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached data array
|
||||
* @return Cached data array
|
||||
*/
|
||||
public Array getCachedData() {
|
||||
return this.cachedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cached data array
|
||||
* @param value Cached data array
|
||||
*/
|
||||
public void setCachedData(Array value) {
|
||||
this.cachedData = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check has cached data or not
|
||||
* @return Has cached data or not
|
||||
*/
|
||||
public boolean hasCachedData() {
|
||||
return this.cachedData != null;
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
|
||||
@ -219,10 +219,7 @@ public class AWXDataInfo extends DataInfo implements IGridDataInfo, IStationData
|
||||
br.read(bytes);
|
||||
_numHeadRecord = DataConvert.bytes2Int(bytes, byteOrder);
|
||||
br.read(bytes);
|
||||
_numDataRecord = DataConvert.bytes2Int(bytes, byteOrder);
|
||||
if (_numDataRecord < 0) {
|
||||
_numDataRecord = DataConvert.bytes2UShort(bytes, byteOrder);
|
||||
}
|
||||
_numDataRecord = DataConvert.bytes2UShort(bytes, byteOrder);
|
||||
br.read(bytes);
|
||||
_productType = DataConvert.bytes2Int(bytes, byteOrder);
|
||||
br.read(bytes);
|
||||
@ -745,7 +742,7 @@ public class AWXDataInfo extends DataInfo implements IGridDataInfo, IStationData
|
||||
Array a = Array.factory(DataType.FLOAT, new int[]{this._numDataRecord});
|
||||
RandomAccessFile br = new RandomAccessFile(this.getFileName(), "r");
|
||||
float t;
|
||||
br.seek(_lenRecord * _numHeadRecord);
|
||||
br.seek((long) _lenRecord * _numHeadRecord);
|
||||
long bP = br.getFilePointer();
|
||||
byte[] bytes = new byte[2];
|
||||
int varIdx = this.VarList.indexOf(varName);
|
||||
|
||||
@ -16,10 +16,7 @@ import java.io.*;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -38,6 +35,8 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
{30,"Flag"}, {31,"Flag"}, {32,"Zc"}, {33,"Vc"}, {34,"Wc"}, {35,"ZDRc"}, {0,"Flag"}
|
||||
}).collect(Collectors.toMap(data -> (Integer) data[0], data -> (String) data[1]));
|
||||
private final Map<String, RadialRecord> recordMap = new HashMap<>();
|
||||
private final List<String> velocityGroup = new ArrayList<>(Arrays.asList("V", "W"));
|
||||
private Dimension radialDim, scanDim, gateRDim, gateVDim;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -200,9 +199,11 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
RandomAccessFile raf = new RandomAccessFile(fileName, "r");
|
||||
readDataInfo(raf);
|
||||
} catch (FileNotFoundException e) {
|
||||
//RandomAccessFile raf = new RandomAccessFile(fileName, "r");
|
||||
//readDataInfo(raf);
|
||||
BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(Paths.get(fileName)));
|
||||
readDataInfo(inputStream);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ -220,6 +221,8 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
this.addAttribute(new Attribute("StationLongitude", siteConfig.longitude));
|
||||
this.addAttribute(new Attribute("AntennaHeight", siteConfig.antennaHeight));
|
||||
this.addAttribute(new Attribute("GroundHeight", siteConfig.groundHeight));
|
||||
this.addAttribute(new Attribute("featureType", "RADIAL"));
|
||||
this.addAttribute(new Attribute("DataType", "Radial"));
|
||||
|
||||
//Read radial data
|
||||
taskConfig = new TaskConfig(raf);
|
||||
@ -288,6 +291,8 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
this.addAttribute(new Attribute("AntennaHeight", siteConfig.antennaHeight));
|
||||
this.addAttribute(new Attribute("GroundHeight", siteConfig.groundHeight));
|
||||
this.addAttribute(new Attribute("RadarType", siteConfig.getRadarType()));
|
||||
this.addAttribute(new Attribute("featureType", "RADIAL"));
|
||||
this.addAttribute(new Attribute("DataType", "Radial"));
|
||||
|
||||
//Read radial data
|
||||
taskConfig = new TaskConfig(raf);
|
||||
@ -308,19 +313,22 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
} else {
|
||||
record = new RadialRecord(product);
|
||||
record.setBinLength(momentHeader.binLength);
|
||||
record.scale = momentHeader.scale;;
|
||||
record.scale = momentHeader.scale;
|
||||
record.offset = momentHeader.offset;
|
||||
this.recordMap.put(product, record);
|
||||
}
|
||||
if (radialHeader.radialNumber == 1) {
|
||||
record.fixedElevation.add(cutConfigs.get(radialHeader.elevationNumber - 1).elevation);
|
||||
record.elevation.add(new ArrayList<>());
|
||||
record.azimuth.add(new ArrayList<>());
|
||||
record.azimuthMinIndex.add(0);
|
||||
record.disResolution.add(cutConfigs.get(radialHeader.elevationNumber - 1).logResolution);
|
||||
record.distance.add(ArrayUtil.arrayRange1(0, momentHeader.dataLength / momentHeader.binLength,
|
||||
cutConfigs.get(0).logResolution));
|
||||
cutConfigs.get(radialHeader.elevationNumber - 1).logResolution));
|
||||
record.newScanData();
|
||||
}
|
||||
record.elevation.get(record.elevation.size() - 1).add(radialHeader.elevation);
|
||||
record.azimuth.get(record.azimuth.size() - 1).add(radialHeader.azimuth);
|
||||
record.addAzimuth(radialHeader.azimuth);
|
||||
byte[] bytes = new byte[momentHeader.dataLength];
|
||||
raf.read(bytes);
|
||||
record.addDataBytes(bytes);
|
||||
@ -330,13 +338,35 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
raf.close();
|
||||
|
||||
//Add dimensions and variables
|
||||
Dimension xyzDim = new Dimension(DimensionType.OTHER);
|
||||
RadialRecord refRadialRecord = this.recordMap.get("dBZ");
|
||||
radialDim = new Dimension();
|
||||
radialDim.setName("radial");
|
||||
radialDim.setLength(refRadialRecord.getMaxRadials());
|
||||
this.addDimension(radialDim);
|
||||
scanDim = new Dimension();
|
||||
scanDim.setName("scan");
|
||||
scanDim.setLength(refRadialRecord.getScanNumber());
|
||||
this.addDimension(scanDim);
|
||||
gateRDim = new Dimension();
|
||||
gateRDim.setName("gateR");
|
||||
gateRDim.setLength(refRadialRecord.getGateNumber(0));
|
||||
this.addDimension(gateRDim);
|
||||
makeRefVariables(refRadialRecord);
|
||||
|
||||
RadialRecord velRadialRecord = this.recordMap.get("V");
|
||||
gateVDim = new Dimension();
|
||||
gateVDim.setName("gateV");
|
||||
gateVDim.setLength(velRadialRecord.getGateNumber(0));
|
||||
this.addDimension(gateVDim);
|
||||
makeVelVariables(velRadialRecord);
|
||||
|
||||
/*Dimension xyzDim = new Dimension(DimensionType.OTHER);
|
||||
xyzDim.setShortName("xyz");
|
||||
xyzDim.setDimValue(Array.factory(DataType.INT, new int[]{3}, new int[]{1,2,3}));
|
||||
this.addDimension(xyzDim);
|
||||
for (String product : this.recordMap.keySet()) {
|
||||
this.recordMap.get(product).makeVariables(this, xyzDim);
|
||||
}
|
||||
}*/
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
@ -344,6 +374,168 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
}
|
||||
}
|
||||
|
||||
private void makeRefVariables(RadialRecord refRadialRecord) {
|
||||
Dimension[] dimensions = new Dimension[]{scanDim, radialDim, gateRDim};
|
||||
for (RadialRecord radialRecord : this.recordMap.values()) {
|
||||
if (!radialRecord.isVelocityGroup())
|
||||
radialRecord.makeVariable(this, dimensions);
|
||||
}
|
||||
|
||||
//coordinate variables
|
||||
Variable elevation = new Variable();
|
||||
elevation.setName("elevationR");
|
||||
elevation.setDataType(DataType.FLOAT);
|
||||
elevation.addDimension(scanDim);
|
||||
elevation.addDimension(radialDim);
|
||||
elevation.addAttribute(new Attribute("units", "degree"));
|
||||
elevation.addAttribute(new Attribute("long_name", "elevation angle in degrees"));
|
||||
this.addVariable(elevation);
|
||||
|
||||
Variable azimuth = new Variable();
|
||||
azimuth.setName("azimuthR");
|
||||
azimuth.setDataType(DataType.FLOAT);
|
||||
azimuth.addDimension(scanDim);
|
||||
azimuth.addDimension(radialDim);
|
||||
azimuth.addAttribute(new Attribute("units", "degree"));
|
||||
azimuth.addAttribute(new Attribute("long_name", "azimuth angle in degrees"));
|
||||
this.addVariable(azimuth);
|
||||
|
||||
Variable distance = new Variable();
|
||||
distance.setName("distanceR");
|
||||
distance.setDataType(DataType.FLOAT);
|
||||
distance.addDimension(gateRDim);
|
||||
distance.addAttribute(new Attribute("units", "m"));
|
||||
distance.addAttribute(new Attribute("long_name", "radial distance to start of gate"));
|
||||
this.addVariable(distance);
|
||||
|
||||
Variable nRadials = new Variable();
|
||||
nRadials.setName("numRadialsR");
|
||||
nRadials.setDataType(DataType.INT);
|
||||
nRadials.addDimension(scanDim);
|
||||
nRadials.addAttribute(new Attribute("long_name", "number of valid radials in this scan"));
|
||||
this.addVariable(nRadials);
|
||||
|
||||
Variable nGates = new Variable();
|
||||
nGates.setName("numGatesR");
|
||||
nGates.setDataType(DataType.INT);
|
||||
nGates.addDimension(scanDim);
|
||||
nGates.addAttribute(new Attribute("long_name", "number of valid gates in this scan"));
|
||||
this.addVariable(nGates);
|
||||
|
||||
int nScan = scanDim.getLength();
|
||||
int nRadial = radialDim.getLength();
|
||||
int nGate = gateRDim.getLength();
|
||||
Array elevData = Array.factory(DataType.FLOAT, new int[]{nScan, nRadial});
|
||||
Array aziData = Array.factory(DataType.FLOAT, new int[]{nScan, nRadial});
|
||||
Array nRData = Array.factory(DataType.INT, new int[]{nScan});
|
||||
Array nGData = Array.factory(DataType.INT, new int[]{nScan});
|
||||
Index elevIndex = elevData.getIndex();
|
||||
Index aziIndex = aziData.getIndex();
|
||||
for (int i = 0; i < nScan; i++) {
|
||||
List<Float> elevList = refRadialRecord.elevation.get(i);
|
||||
List<Float> aziList = refRadialRecord.azimuth.get(i);
|
||||
nRData.setInt(i, aziList.size());
|
||||
nGData.setInt(i, (int) refRadialRecord.distance.get(i).getSize());
|
||||
for (int j = 0; j < nRadial; j++) {
|
||||
if (j < elevList.size()) {
|
||||
elevData.setFloat(elevIndex.set(i, j), elevList.get(j));
|
||||
aziData.setFloat(aziIndex.set(i, j), aziList.get(j));
|
||||
} else {
|
||||
elevData.setFloat(elevIndex.set(i, j), Float.NaN);
|
||||
aziData.setFloat(aziIndex.set(i, j), Float.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
Array disData = refRadialRecord.distance.get(0);
|
||||
|
||||
elevation.setCachedData(elevData);
|
||||
azimuth.setCachedData(aziData);
|
||||
distance.setCachedData(disData);
|
||||
nRadials.setCachedData(nRData);
|
||||
nGates.setCachedData(nGData);
|
||||
}
|
||||
|
||||
private void makeVelVariables(RadialRecord velRadialRecord) {
|
||||
Dimension[] dimensions = new Dimension[]{scanDim, radialDim, gateVDim};
|
||||
for (RadialRecord radialRecord : this.recordMap.values()) {
|
||||
if (radialRecord.isVelocityGroup())
|
||||
radialRecord.makeVariable(this, dimensions);
|
||||
}
|
||||
|
||||
//coordinate variables
|
||||
Variable elevation = new Variable();
|
||||
elevation.setName("elevationV");
|
||||
elevation.setDataType(DataType.FLOAT);
|
||||
elevation.addDimension(scanDim);
|
||||
elevation.addDimension(radialDim);
|
||||
elevation.addAttribute(new Attribute("units", "degree"));
|
||||
elevation.addAttribute(new Attribute("long_name", "elevation angle in degrees"));
|
||||
this.addVariable(elevation);
|
||||
|
||||
Variable azimuth = new Variable();
|
||||
azimuth.setName("azimuthV");
|
||||
azimuth.setDataType(DataType.FLOAT);
|
||||
azimuth.addDimension(scanDim);
|
||||
azimuth.addDimension(radialDim);
|
||||
azimuth.addAttribute(new Attribute("units", "degree"));
|
||||
azimuth.addAttribute(new Attribute("long_name", "azimuth angle in degrees"));
|
||||
this.addVariable(azimuth);
|
||||
|
||||
Variable distance = new Variable();
|
||||
distance.setName("distanceV");
|
||||
distance.setDataType(DataType.FLOAT);
|
||||
distance.addDimension(gateVDim);
|
||||
distance.addAttribute(new Attribute("units", "m"));
|
||||
distance.addAttribute(new Attribute("long_name", "radial distance to start of gate"));
|
||||
this.addVariable(distance);
|
||||
|
||||
Variable nRadials = new Variable();
|
||||
nRadials.setName("numRadialsR");
|
||||
nRadials.setDataType(DataType.INT);
|
||||
nRadials.addDimension(scanDim);
|
||||
nRadials.addAttribute(new Attribute("long_name", "number of valid radials in this scan"));
|
||||
this.addVariable(nRadials);
|
||||
|
||||
Variable nGates = new Variable();
|
||||
nGates.setName("numGatesR");
|
||||
nGates.setDataType(DataType.INT);
|
||||
nGates.addDimension(scanDim);
|
||||
nGates.addAttribute(new Attribute("long_name", "number of valid gates in this scan"));
|
||||
this.addVariable(nGates);
|
||||
|
||||
int nScan = scanDim.getLength();
|
||||
int nRadial = radialDim.getLength();
|
||||
int nGate = gateVDim.getLength();
|
||||
Array elevData = Array.factory(DataType.FLOAT, new int[]{nScan, nRadial});
|
||||
Array aziData = Array.factory(DataType.FLOAT, new int[]{nScan, nRadial});
|
||||
Array nRData = Array.factory(DataType.INT, new int[]{nScan});
|
||||
Array nGData = Array.factory(DataType.INT, new int[]{nScan});
|
||||
Index elevIndex = elevData.getIndex();
|
||||
Index aziIndex = aziData.getIndex();
|
||||
for (int i = 0; i < nScan; i++) {
|
||||
List<Float> elevList = velRadialRecord.elevation.get(i);
|
||||
List<Float> aziList = velRadialRecord.azimuth.get(i);
|
||||
nRData.setInt(i, aziList.size());
|
||||
nGData.setInt(i, (int) velRadialRecord.distance.get(i).getSize());
|
||||
for (int j = 0; j < nRadial; j++) {
|
||||
if (j < elevList.size()) {
|
||||
elevData.setFloat(elevIndex.set(i, j), elevList.get(j));
|
||||
aziData.setFloat(aziIndex.set(i, j), aziList.get(j));
|
||||
} else {
|
||||
elevData.setFloat(elevIndex.set(i, j), Float.NaN);
|
||||
aziData.setFloat(aziIndex.set(i, j), Float.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
Array disData = velRadialRecord.distance.get(0);
|
||||
|
||||
elevation.setCachedData(elevData);
|
||||
azimuth.setCachedData(aziData);
|
||||
distance.setCachedData(disData);
|
||||
nRadials.setCachedData(nRData);
|
||||
nGates.setCachedData(nGData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product names
|
||||
* @return product names
|
||||
@ -377,12 +569,8 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
*/
|
||||
public List<Float> getElevations(String product) {
|
||||
RadialRecord radialRecord = this.recordMap.get(product);
|
||||
List<Float> elevations = new ArrayList<>();
|
||||
for (List<Float> elist : radialRecord.elevation) {
|
||||
elevations.add(elist.get(0));
|
||||
}
|
||||
|
||||
return elevations;
|
||||
return radialRecord.fixedElevation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -405,6 +593,75 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
|
||||
@Override
|
||||
public Array read(String varName, int[] origin, int[] size, int[] stride) {
|
||||
try {
|
||||
Variable variable = this.getVariable(varName);
|
||||
if (variable.hasCachedData()) {
|
||||
return variable.getCachedData().section(origin, size, stride).copy();
|
||||
}
|
||||
|
||||
Section section = new Section(origin, size, stride);
|
||||
RadialRecord record = this.recordMap.get(varName);
|
||||
Array dataArray = Array.factory(record.getDataType(), section.getShape());
|
||||
Range zRange = section.getRange(0);
|
||||
Range yRange = section.getRange(1);
|
||||
Range xRange = section.getRange(2);
|
||||
IndexIterator iter = dataArray.getIndexIterator();
|
||||
for (int s = zRange.first(); s <= zRange.last(); s += zRange.stride()) {
|
||||
List<Array> arrays = record.getDataArray(s);
|
||||
for (int i = yRange.first(); i <= yRange.last(); i += yRange.stride()) {
|
||||
if (i < arrays.size()) {
|
||||
Array array = arrays.get(i);
|
||||
for (int j = xRange.first(); j <= xRange.last(); j += xRange.stride()) {
|
||||
if (j < array.getSize())
|
||||
iter.setObjectNext(array.getObject(j));
|
||||
else
|
||||
iter.setObjectNext(Float.NaN);
|
||||
}
|
||||
} else {
|
||||
for (int j = xRange.first(); j <= xRange.last(); j += xRange.stride()) {
|
||||
iter.setObjectNext(Float.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Attribute aoAttr = variable.findAttribute("add_offset");
|
||||
Attribute sfAttr = variable.findAttribute("scale_factor");
|
||||
if (aoAttr != null || sfAttr != null) {
|
||||
Number add_offset = 0.f;
|
||||
Number scale_factor = 1.f;
|
||||
if (aoAttr != null) {
|
||||
switch (aoAttr.getDataType()) {
|
||||
case DOUBLE:
|
||||
add_offset = aoAttr.getValues().getDouble(0);
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
add_offset = aoAttr.getValues().getFloat(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sfAttr != null) {
|
||||
switch (sfAttr.getDataType()) {
|
||||
case DOUBLE:
|
||||
scale_factor = sfAttr.getValues().getDouble(0);
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
scale_factor = sfAttr.getValues().getFloat(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataArray = ArrayMath.div(ArrayMath.sub(dataArray, add_offset), scale_factor);
|
||||
}
|
||||
}
|
||||
|
||||
return dataArray;
|
||||
} catch (InvalidRangeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Array read_bak(String varName, int[] origin, int[] size, int[] stride) {
|
||||
try {
|
||||
int idx = varName.lastIndexOf("_s");
|
||||
int scanIdx = Integer.parseInt(varName.substring(idx + 2)) - 1;
|
||||
@ -426,9 +683,18 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
Range xRange = section.getRange(1);
|
||||
IndexIterator iter = dataArray.getIndexIterator();
|
||||
for (int i = yRange.first(); i <= yRange.last(); i += yRange.stride()) {
|
||||
Array array = arrays.get(i);
|
||||
for (int j = xRange.first(); j <= xRange.last(); j += xRange.stride()) {
|
||||
iter.setObjectNext(array.getObject(j));
|
||||
if (i < arrays.size()) {
|
||||
Array array = arrays.get(i);
|
||||
for (int j = xRange.first(); j <= xRange.last(); j += xRange.stride()) {
|
||||
if (j < array.getSize())
|
||||
iter.setObjectNext(array.getObject(j));
|
||||
else
|
||||
iter.setObjectNext(Float.NaN);
|
||||
}
|
||||
} else {
|
||||
for (int j = xRange.first(); j <= xRange.last(); j += xRange.stride()) {
|
||||
iter.setObjectNext(Float.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,4 +740,54 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
public List<Attribute> getGlobalAttributes() {
|
||||
return this.attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get VCS data
|
||||
* @param varName Variable name
|
||||
* @param startX Start x, km
|
||||
* @param startY Start y, km
|
||||
* @param endX End x, km
|
||||
* @param endY End y, km
|
||||
* @return VCS data
|
||||
*/
|
||||
public Array[] getVCSData(String varName, float startX, float startY, float endX, float endY) {
|
||||
RadialRecord record = this.recordMap.get(varName);
|
||||
int nScan = record.getScanNumber();
|
||||
float halfBeamWidth = this.siteConfig.beamWidthVert / 2;
|
||||
float binRes = this.cutConfigs.get(0).logResolution;
|
||||
float height = this.siteConfig.antennaHeight / 1000.f;
|
||||
float startEndDistance = (float) Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
|
||||
int nPoints = (int) (startEndDistance * 1000 / binRes + 1);
|
||||
Array xa = ArrayUtil.lineSpace(startX, endX, nPoints);
|
||||
Array ya = ArrayUtil.lineSpace(startY, endY, nPoints);
|
||||
Array aa = Transform.xyToAzimuth(xa, ya);
|
||||
int[] shape = new int[]{nScan, 2, nPoints};
|
||||
Array data = Array.factory(DataType.FLOAT, shape);
|
||||
Array meshXY = Array.factory(DataType.FLOAT, shape);
|
||||
Array meshZ = Array.factory(DataType.FLOAT, shape);
|
||||
Index dataIndex = data.getIndex();
|
||||
Index meshXYIndex = meshXY.getIndex();
|
||||
Index meshZIndex = meshZ.getIndex();
|
||||
float x, y, z1, z2, dis, azi, v, ele;
|
||||
for (int i = 0; i < nScan; i++) {
|
||||
ele = record.fixedElevation.get(i);
|
||||
for (int j = 0; j < nPoints; j++) {
|
||||
x = xa.getFloat(j);
|
||||
y = ya.getFloat(j);
|
||||
dis = (float) Math.sqrt(x * x + y * y);
|
||||
azi = aa.getFloat(j);
|
||||
v = record.getValue(i, azi, dis * 1000);
|
||||
z1 = (float) (dis * Math.sin(Math.toRadians(ele - halfBeamWidth))) + height;
|
||||
z2 = (float) (dis * Math.sin(Math.toRadians(ele + halfBeamWidth))) + height;
|
||||
for (int k = 0; k < 2; k++) {
|
||||
data.setFloat(dataIndex.set(i, k, j), v);
|
||||
meshXY.setFloat(meshXYIndex.set(i, k, j), dis);
|
||||
}
|
||||
meshZ.setFloat(meshZIndex.set(i, 0, j), z1);
|
||||
meshZ.setFloat(meshZIndex.set(i, 1, j), z2);
|
||||
}
|
||||
}
|
||||
|
||||
return new Array[]{data, meshXY, meshZ};
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,9 +20,12 @@ public class RadialRecord {
|
||||
private DataType dataType;
|
||||
public int scale;
|
||||
public int offset;
|
||||
public List<Float> fixedElevation = new ArrayList<>();
|
||||
public List<List<Float>> elevation = new ArrayList<>();
|
||||
public List<List<Float>> azimuth = new ArrayList<>();
|
||||
public List<Integer> azimuthMinIndex = new ArrayList<>();
|
||||
public List<Array> distance = new ArrayList<>();
|
||||
public List<Integer> disResolution = new ArrayList<>();
|
||||
private final List<List<Array>> data = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@ -40,6 +43,7 @@ public class RadialRecord {
|
||||
public void setBinLength(int value) {
|
||||
this.binLength = value;
|
||||
this.dataType = this.binLength == 1 ? DataType.UBYTE : DataType.USHORT;
|
||||
//this.dataType = DataType.FLOAT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,6 +54,31 @@ public class RadialRecord {
|
||||
return this.dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an azimuth value
|
||||
* @param a Azimuth value
|
||||
*/
|
||||
public void addAzimuth(float a) {
|
||||
int n = getScanNumber();
|
||||
List<Float> azi = this.azimuth.get(n - 1);
|
||||
azi.add(a);
|
||||
if (this.azimuthMinIndex.get(n - 1) == 0) {
|
||||
if (azi.size() > 1) {
|
||||
if (a < azi.get(azi.size() - 2)) {
|
||||
this.azimuthMinIndex.set(n - 1, azi.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is velocity group or not
|
||||
* @return Velocity group or not
|
||||
*/
|
||||
public boolean isVelocityGroup() {
|
||||
return this.product.equals("V") || this.product.equals("W");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scan number
|
||||
* @return Scan number
|
||||
@ -105,6 +134,38 @@ public class RadialRecord {
|
||||
this.data.get(this.data.size() - 1).add(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a data bytes
|
||||
* @param bytes Data bytes
|
||||
* @param offset Offset
|
||||
* @param scale Scale
|
||||
*/
|
||||
public void addDataBytes(byte[] bytes, int offset, int scale) {
|
||||
if (this.data.isEmpty()) {
|
||||
this.data.add(new ArrayList<>());
|
||||
}
|
||||
Array array;
|
||||
float v;
|
||||
if (this.binLength == 1) {
|
||||
array = Array.factory(this.dataType, new int[]{bytes.length});
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
v = (float) DataType.unsignedByteToShort(bytes[i]);
|
||||
v = (v - offset) / scale;
|
||||
array.setFloat(i, v);
|
||||
}
|
||||
} else {
|
||||
int n = bytes.length / 2;
|
||||
array = Array.factory(this.dataType, new int[]{n});
|
||||
for (int i = 0; i < n; i++) {
|
||||
short s = DataConvert.bytes2Short(new byte[]{bytes[i*2], bytes[i*2+1]}, ByteOrder.LITTLE_ENDIAN);
|
||||
v = (float) DataType.unsignedShortToInt(s);
|
||||
v = (v - offset) / scale;
|
||||
array.setFloat(i, v);
|
||||
}
|
||||
}
|
||||
this.data.get(this.data.size() - 1).add(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data array
|
||||
* @param scanIdx The scan index
|
||||
@ -114,6 +175,36 @@ public class RadialRecord {
|
||||
return this.data.get(scanIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get maximum radials number
|
||||
* @return Maximum radials number
|
||||
*/
|
||||
public int getMaxRadials() {
|
||||
int maxRadials = 0;
|
||||
for (List a : this.azimuth) {
|
||||
if (maxRadials < a.size()) {
|
||||
maxRadials = a.size();
|
||||
}
|
||||
}
|
||||
|
||||
return maxRadials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimum radials number
|
||||
* @return Minimum radials number
|
||||
*/
|
||||
public int getMinRadials() {
|
||||
int minRadials = Integer.MAX_VALUE;
|
||||
for (List a : this.azimuth) {
|
||||
if (minRadials > a.size()) {
|
||||
minRadials = a.size();
|
||||
}
|
||||
}
|
||||
|
||||
return minRadials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XYZ data array
|
||||
* @param scanIdx The scan index
|
||||
@ -147,6 +238,23 @@ public class RadialRecord {
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make variable
|
||||
* @param dataInfo The data info
|
||||
* @param dimensions Dimensions
|
||||
*/
|
||||
public void makeVariable(CMARadarBaseDataInfo dataInfo, Dimension[] dimensions) {
|
||||
Variable variable = new Variable();
|
||||
variable.setName(this.product);
|
||||
variable.setDataType(this.dataType);
|
||||
for (Dimension dimension : dimensions) {
|
||||
variable.addDimension(dimension);
|
||||
}
|
||||
variable.addAttribute(new Attribute("scale_factor", this.scale));
|
||||
variable.addAttribute(new Attribute("add_offset", this.offset));
|
||||
dataInfo.addVariable(variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make variables
|
||||
* @param dataInfo The data info
|
||||
@ -191,4 +299,80 @@ public class RadialRecord {
|
||||
dataInfo.addVariable(variable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get azimuth value index
|
||||
* @param ei Scan index
|
||||
* @param a Azimuth value
|
||||
* @return Azimuth value index
|
||||
*/
|
||||
public int getAzimuthIndex(int ei, float a) {
|
||||
List<Float> azs = this.azimuth.get(ei);
|
||||
int n = azs.size();
|
||||
int sIdx = this.azimuthMinIndex.get(ei);
|
||||
int eIdx = sIdx - 1;
|
||||
if (eIdx < 0) {
|
||||
eIdx = n - 1;
|
||||
}
|
||||
|
||||
int i1 = -1, i2 = -1;
|
||||
if (a < azs.get(sIdx) || a > azs.get(eIdx)) {
|
||||
i1 = eIdx;
|
||||
i2 = sIdx;
|
||||
} else {
|
||||
for (int i = sIdx + 1; i < n; i++) {
|
||||
if (a == azs.get(i)) {
|
||||
return i;
|
||||
} else if (a < azs.get(i)) {
|
||||
i1 = i - 1;
|
||||
i2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i1 < 0) {
|
||||
for (int i = 0; i <= eIdx; i++) {
|
||||
if (a == azs.get(i)) {
|
||||
return i;
|
||||
} else if (a < azs.get(i)) {
|
||||
i1 = i - 1;
|
||||
i2 = i;
|
||||
if (i1 < 0) {
|
||||
i1 = n - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (azs.get(i2) - a < a - azs.get(i1)) {
|
||||
return i2;
|
||||
} else {
|
||||
return i1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by elevation, azimuth and distance
|
||||
* @param ei Elevation index
|
||||
* @param a Azimuth value
|
||||
* @param r Distance value
|
||||
* @return Data value
|
||||
*/
|
||||
public float getValue(int ei, float a, float r) {
|
||||
List<Array> sData = this.data.get(ei);
|
||||
int aziIdx = getAzimuthIndex(ei, a);
|
||||
int disRes = this.disResolution.get(ei);
|
||||
int disIdx = (int) (r / disRes);
|
||||
Array rData = this.data.get(ei).get(aziIdx);
|
||||
float v;
|
||||
if (disIdx < rData.getSize()) {
|
||||
v = rData.getFloat(disIdx);
|
||||
v = (v - this.offset) / this.scale;
|
||||
} else {
|
||||
v = Float.NaN;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ public class Transform {
|
||||
|
||||
/**
|
||||
* Convert antenna coordinate to cartesian coordinate
|
||||
*
|
||||
* @param r Distances to the center of the radar gates (bins) in meters
|
||||
* @param a Azimuth angle of the radar in radians
|
||||
* @param e Elevation angle of the radar in radians
|
||||
@ -33,8 +34,6 @@ public class Transform {
|
||||
* @return Cartesian coordinate in meters from the radar
|
||||
*/
|
||||
public static double[] antennaToCartesian(float r, float a, float e, float h) {
|
||||
double R = 6371.0 * 1000.0 * 4.0 / 3.0; // effective radius of earth in meters.
|
||||
|
||||
double z = Math.pow(Math.pow(r * Math.cos(e), 2) + Math.pow(R + h + r * Math.sin(e), 2), 0.5) - R;
|
||||
double s = R * Math.asin(r * Math.cos(e) / (R + z)); // arc length in m.
|
||||
double x = s * Math.sin(a);
|
||||
@ -43,14 +42,160 @@ public class Transform {
|
||||
return new double[]{x, y, z};
|
||||
}
|
||||
|
||||
private static double xyToAzimuth(float x, float y) {
|
||||
double az = Math.PI / 2 - Math.atan2(x + y, 1);
|
||||
/**
|
||||
* Convert antenna coordinate to cartesian coordinate
|
||||
*
|
||||
* @param r Distances to the center of the radar gates (bins) in meters
|
||||
* @param a Azimuth angle of the radar in radians
|
||||
* @param e Elevation angle of the radar in radians
|
||||
* @return Cartesian coordinate in meters from the radar
|
||||
*/
|
||||
public static Array[] antennaToCartesian(Array ra, Array aa, Array ea) {
|
||||
ra = ra.copyIfView();
|
||||
aa = aa.copyIfView();
|
||||
ea = ea.copyIfView();
|
||||
|
||||
Array xa = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array ya = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array za = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
float r, a, e;
|
||||
|
||||
for (int i = 0; i < ra.getSize(); i++) {
|
||||
r = ra.getFloat(i);
|
||||
a = aa.getFloat(i);
|
||||
e = ea.getFloat(i);
|
||||
double[] xyz = antennaToCartesian(r, a, e);
|
||||
xa.setDouble(i, xyz[0]);
|
||||
ya.setDouble(i, xyz[1]);
|
||||
za.setDouble(i, xyz[2]);
|
||||
}
|
||||
|
||||
return new Array[]{xa, ya, za};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert antenna coordinate to cartesian coordinate
|
||||
*
|
||||
* @param r Distances to the center of the radar gates (bins) in meters
|
||||
* @param a Azimuth angle of the radar in radians
|
||||
* @param e Elevation angle of the radar in radians
|
||||
* @return Cartesian coordinate in meters from the radar
|
||||
*/
|
||||
public static Array[] antennaToCartesian(Array ra, Array aa, float e) {
|
||||
ra = ra.copyIfView();
|
||||
aa = aa.copyIfView();
|
||||
|
||||
Array xa = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array ya = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array za = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
float r, a;
|
||||
|
||||
for (int i = 0; i < ra.getSize(); i++) {
|
||||
r = ra.getFloat(i);
|
||||
a = aa.getFloat(i);
|
||||
double[] xyz = antennaToCartesian(r, a, e);
|
||||
xa.setDouble(i, xyz[0]);
|
||||
ya.setDouble(i, xyz[1]);
|
||||
za.setDouble(i, xyz[2]);
|
||||
}
|
||||
|
||||
return new Array[]{xa, ya, za};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert antenna coordinate to cartesian coordinate
|
||||
*
|
||||
* @param r Distances to the center of the radar gates (bins) in meters
|
||||
* @param a Azimuth angle of the radar in radians
|
||||
* @param e Elevation angle of the radar in radians
|
||||
* @param h Altitude of the instrument, above sea level, units:m
|
||||
* @return Cartesian coordinate in meters from the radar
|
||||
*/
|
||||
public static Array[] antennaToCartesian(Array ra, Array aa, Array ea, float h) {
|
||||
ra = ra.copyIfView();
|
||||
aa = aa.copyIfView();
|
||||
ea = ea.copyIfView();
|
||||
|
||||
Array xa = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array ya = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array za = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
float r, a, e;
|
||||
|
||||
for (int i = 0; i < ra.getSize(); i++) {
|
||||
r = ra.getFloat(i);
|
||||
a = aa.getFloat(i);
|
||||
e = ea.getFloat(i);
|
||||
double[] xyz = antennaToCartesian(r, a, e, h);
|
||||
xa.setDouble(i, xyz[0]);
|
||||
ya.setDouble(i, xyz[1]);
|
||||
za.setDouble(i, xyz[2]);
|
||||
}
|
||||
|
||||
return new Array[]{xa, ya, za};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert antenna coordinate to cartesian coordinate
|
||||
*
|
||||
* @param r Distances to the center of the radar gates (bins) in meters
|
||||
* @param a Azimuth angle of the radar in radians
|
||||
* @param e Elevation angle of the radar in radians
|
||||
* @param h Altitude of the instrument, above sea level, units:m
|
||||
* @return Cartesian coordinate in meters from the radar
|
||||
*/
|
||||
public static Array[] antennaToCartesian(Array ra, Array aa, float e, float h) {
|
||||
ra = ra.copyIfView();
|
||||
aa = aa.copyIfView();
|
||||
|
||||
Array xa = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array ya = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
Array za = Array.factory(DataType.DOUBLE, ra.getShape());
|
||||
float r, a;
|
||||
|
||||
for (int i = 0; i < ra.getSize(); i++) {
|
||||
r = ra.getFloat(i);
|
||||
a = aa.getFloat(i);
|
||||
double[] xyz = antennaToCartesian(r, a, e, h);
|
||||
xa.setDouble(i, xyz[0]);
|
||||
ya.setDouble(i, xyz[1]);
|
||||
za.setDouble(i, xyz[2]);
|
||||
}
|
||||
|
||||
return new Array[]{xa, ya, za};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get antenna azimuth from cartesian x, y coordinate
|
||||
* @param x X value
|
||||
* @param y Y value
|
||||
* @return Azimuth value
|
||||
*/
|
||||
public static double xyToAzimuth(float x, float y) {
|
||||
double az = Math.PI / 2 - Math.atan2(y, x);
|
||||
if (az < 0) {
|
||||
az = 2 * Math.PI + az;
|
||||
}
|
||||
return Math.toDegrees(az);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get antenna azimuth from cartesian x, y coordinate
|
||||
* @param x X array value
|
||||
* @param y Y array value
|
||||
* @return Azimuth array value
|
||||
*/
|
||||
public static Array xyToAzimuth(Array xa, Array ya) {
|
||||
xa = xa.copyIfView();
|
||||
ya = ya.copyIfView();
|
||||
|
||||
Array aa = Array.factory(DataType.FLOAT, xa.getShape());
|
||||
for (int i = 0; i < aa.getSize(); i++) {
|
||||
aa.setFloat(i, (float) xyToAzimuth(xa.getFloat(i), ya.getFloat(i)));
|
||||
}
|
||||
|
||||
return aa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert cartesian coordinate to antenna coordinate
|
||||
* @param x x coordinate in meters
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-dataframe</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-geo</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<freehep.version>2.4</freehep.version>
|
||||
<flatlaf.version>3.1.1</flatlaf.version>
|
||||
</properties>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-geometry</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-image</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\burf">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\linalg"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\cloudsat"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\gpm"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\radar"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\radar">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\FY"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\awx"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\burf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\awx"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW\ZhengZhou"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\savefig"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\no_opengl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\radar"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bin_proj.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\burf\bufr_cma_upar.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_geo.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_3d.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bin_proj.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\burf\bufr_cma_upar.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_geo.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_3d.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -36,5 +36,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1347,775"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
|
||||
</MeteoInfo>
|
||||
|
||||
@ -36,8 +36,8 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,9 @@
|
||||
import midata
|
||||
from .midata import *
|
||||
import ncutil
|
||||
from .util import ncutil
|
||||
from .dimvariable import DimVariable
|
||||
from .util import *
|
||||
|
||||
__all__ = ['ncutil', 'DimVariable']
|
||||
__all__ += midata.__all__
|
||||
__all__ = ['DimVariable']
|
||||
__all__ += midata.__all__
|
||||
__all__ += util.__all__
|
||||
Binary file not shown.
@ -16,7 +16,7 @@ from mipylib.dataframe.dataframe import DataFrame
|
||||
import mipylib.miutil as miutil
|
||||
import mipylib.numeric as np
|
||||
from mipylib.numeric.core._dtype import DataType
|
||||
from .ncutil import to_dtype
|
||||
from .util.ncutil import to_dtype
|
||||
|
||||
import datetime
|
||||
|
||||
@ -46,12 +46,12 @@ class DimDataFile(object):
|
||||
if isinstance(key, basestring):
|
||||
var = self.dataset.getDataInfo().getVariable(key)
|
||||
if var is None:
|
||||
print key + ' is not a variable name'
|
||||
print(key + ' is not a variable name')
|
||||
raise ValueError()
|
||||
else:
|
||||
return DimVariable(self.dataset.getDataInfo().getVariable(key), self)
|
||||
else:
|
||||
print key + ' is not a variable name'
|
||||
print(key + ' is not a variable name')
|
||||
raise ValueError()
|
||||
|
||||
def __str__(self):
|
||||
@ -192,7 +192,7 @@ class DimDataFile(object):
|
||||
"""
|
||||
Print data file information
|
||||
"""
|
||||
print self.dataset.getInfoText()
|
||||
print(self.dataset.getInfoText())
|
||||
|
||||
def read_dataframe(self, tidx=None):
|
||||
"""
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
|
||||
from .dimdatafile import DimDataFile
|
||||
import mipylib.numeric as np
|
||||
|
||||
|
||||
class RadarDataFile(DimDataFile):
|
||||
@ -28,3 +29,18 @@ class RadarDataFile(DimDataFile):
|
||||
return list(self.datainfo.getElevations())
|
||||
else:
|
||||
return list(self.datainfo.getElevations(product))
|
||||
|
||||
def get_vcs_data(self, product, start_point, end_point):
|
||||
"""
|
||||
Get VCS data.
|
||||
|
||||
:param product: (*str*) Product name.
|
||||
:param start_point: (*tuple of float*) Start point x/y coordinates with km units.
|
||||
:param end_point: (*tuple of float*) End point x/y coordinates with km units.
|
||||
|
||||
:return: VCS data arrays: X/Y mesh, Z mesh, product data.
|
||||
"""
|
||||
r = self.datainfo.getVCSData(product, start_point[0], start_point[1], end_point[0],
|
||||
end_point[1])
|
||||
|
||||
return np.array(r[0]), np.array(r[1]), np.array(r[2])
|
||||
|
||||
53
meteoinfo-lab/pylib/mipylib/dataset/util/RadarUtil.py
Normal file
53
meteoinfo-lab/pylib/mipylib/dataset/util/RadarUtil.py
Normal file
@ -0,0 +1,53 @@
|
||||
from mipylib import geolib
|
||||
import mipylib.numeric as np
|
||||
from org.meteoinfo.data.meteodata.radar import Transform
|
||||
|
||||
|
||||
__all__ = ['antenna_to_cartesian','antenna_to_geographic']
|
||||
|
||||
|
||||
def antenna_to_cartesian(distance, azimuth, elevation, h=None):
|
||||
"""
|
||||
Convert antenna coordinate to cartesian coordinate.
|
||||
|
||||
:param distance: (*array*) Distances to the center of the radar gates (bins) in meters.
|
||||
:param azimuth: (*array*) Azimuth angle of the radar in degrees.
|
||||
:param elevation: (*array*) Elevation angle of the radar in degrees.
|
||||
:param h: (*float*) Altitude of the instrument, above sea level, units:m.
|
||||
|
||||
:return: Cartesian coordinate in meters from the radar (x, y, z).
|
||||
"""
|
||||
azimuth = np.deg2rad(azimuth)
|
||||
elevation = np.deg2rad(elevation)
|
||||
nd = distance.shape[0]
|
||||
na = azimuth.shape[0]
|
||||
distance, azimuth = np.meshgrid(distance, azimuth)
|
||||
if isinstance(elevation, np.NDArray):
|
||||
elevation = elevation.reshape(na, 1)
|
||||
elevation = elevation.repeat(nd, axis=1)
|
||||
elevation = elevation._array
|
||||
if h is None:
|
||||
r = Transform.antennaToCartesian(distance._array, azimuth._array, elevation)
|
||||
else:
|
||||
r = Transform.antennaToCartesian(distance._array, azimuth._array, elevation, h)
|
||||
|
||||
return np.array(r[0]), np.array(r[1]), np.array(r[2])
|
||||
|
||||
def antenna_to_geographic(lon, lat, distance, azimuth, elevation, h=None):
|
||||
"""
|
||||
Convert antenna coordinate to geographic (longitude/latitude) coordinate.
|
||||
|
||||
:param lon: (*float*) Longitude of the radar.
|
||||
:param lat: (*float*) Latitude of the radar.
|
||||
:param distance: (*array*) Distances to the center of the radar gates (bins) in meters.
|
||||
:param azimuth: (*array*) Azimuth angle of the radar in degrees.
|
||||
:param elevation: (*array*) Elevation angle of the radar in degrees.
|
||||
:param h: (*float*) Altitude of the instrument, above sea level, units:m.
|
||||
|
||||
:return: Geographic coordinate.
|
||||
"""
|
||||
x, y, z = antenna_to_cartesian(distance, azimuth, elevation, h)
|
||||
proj = geolib.projinfo(proj='aeqd', lon_0=lon, lat_0=lat)
|
||||
rlon, rlat = geolib.project(x, y, fromproj=proj)
|
||||
|
||||
return rlon, rlat, z
|
||||
4
meteoinfo-lab/pylib/mipylib/dataset/util/__init__.py
Normal file
4
meteoinfo-lab/pylib/mipylib/dataset/util/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
import ncutil
|
||||
import RadarUtil
|
||||
|
||||
__all__ = ['ncutil', 'RadarUtil']
|
||||
Binary file not shown.
@ -419,8 +419,11 @@ class GLFigure(GLChartPanel):
|
||||
ax = MapAxes(*args, **kwargs)
|
||||
# self.__set_axesm(ax, **kwargs)
|
||||
elif axestype == '3d':
|
||||
# ax = Axes3D(*args, **kwargs)
|
||||
ax = Axes3DGL(*args, **kwargs)
|
||||
opengl = kwargs.pop('opengl', True)
|
||||
if opengl:
|
||||
ax = Axes3DGL(*args, **kwargs)
|
||||
else:
|
||||
ax = Axes3D(*args, **kwargs)
|
||||
else:
|
||||
ax = Axes(*args, **kwargs)
|
||||
# self.__set_axes(ax, **kwargs)
|
||||
@ -479,7 +482,7 @@ class GLFigure(GLChartPanel):
|
||||
self.getChart().addPlot(ax._axes)
|
||||
self.getChart().setCurrentPlot(self.getChart().getPlots().size())
|
||||
if not GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadless():
|
||||
if isinstance(ax, Axes3DGL):
|
||||
if isinstance(ax, (Axes3DGL, Axes3D)):
|
||||
self.set_mousemode("rotate")
|
||||
else:
|
||||
self.set_mousemode("pan")
|
||||
|
||||
Binary file not shown.
@ -808,7 +808,7 @@ def axes(*args, **kwargs):
|
||||
:param rightaxis: (*boolean*) Optional, set right axis visible or not. Default is ``True`` .
|
||||
:param xaxistype: (*string*) Optional, set x axis type as 'normal', 'lon', 'lat' or 'time'.
|
||||
:param xreverse: (*boolean*) Optional, set x axis reverse or not. Default is ``False`` .
|
||||
:param yreverse: (*boolean*) Optional, set yaxis reverse or not. Default is ``False`` .
|
||||
:param yreverse: (*boolean*) Optional, set y axis reverse or not. Default is ``False`` .
|
||||
|
||||
:returns: The axes.
|
||||
"""
|
||||
@ -865,7 +865,7 @@ def axes3d(*args, **kwargs):
|
||||
:param projection: (*str or ProjectionInfo*) If ``earth``, 3D earth axes will be created. If a
|
||||
``ProjectionInfo``, 3D map axes will be created. Default is ``None`` with normal 3D axes.
|
||||
:param opengl: (*bool*) Using opengl backend or not. Default is ``True``.
|
||||
:param orthographic: (*bool*) Using orthographic orthographic or perspective view. Default is
|
||||
:param orthographic: (*bool*) Using orthographic or perspective view. Default is
|
||||
``True``.
|
||||
:param aspect: (*str*) ['equal' | 'xy_equal' | None]. Default is ``None``.
|
||||
:param bgcolor: (*color*) Background color. Default is white.
|
||||
@ -892,6 +892,7 @@ def axes3d(*args, **kwargs):
|
||||
return axes3d_map(*args, **kwargs)
|
||||
else:
|
||||
kwargs['axestype'] = '3d'
|
||||
kwargs['opengl'] = False
|
||||
return axes(*args, **kwargs)
|
||||
|
||||
|
||||
|
||||
@ -26,8 +26,8 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-math</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<ejml.version>0.41.1</ejml.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-mkl</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<commons-math.version>4.0-beta1</commons-math.version>
|
||||
<commons-numbers.version>1.1</commons-numbers.version>
|
||||
<commons-rng.version>1.5</commons-rng.version>
|
||||
|
||||
@ -897,6 +897,18 @@ public class ArrayUtil {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array line space - stop is included
|
||||
*
|
||||
* @param start Start value
|
||||
* @param stop Stop value
|
||||
* @param n Number value
|
||||
* @return Array
|
||||
*/
|
||||
public static Array lineSpace(Number start, Number stop, final int n) {
|
||||
return lineSpace(start, stop, n, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array line space
|
||||
*
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-projection</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -97,15 +97,20 @@ public class Reproject {
|
||||
if (i >= points.length) {
|
||||
break;
|
||||
}
|
||||
ProjCoordinate p1 = new ProjCoordinate(points[i][0], points[i][1]);
|
||||
ProjCoordinate p2 = new ProjCoordinate();
|
||||
try {
|
||||
trans.transform(p1, p2);
|
||||
points[i][0] = p2.x;
|
||||
points[i][1] = p2.y;
|
||||
} catch (ProjectionException e) {
|
||||
if (Double.isNaN(points[i][0]) || Double.isNaN(points[i][1])) {
|
||||
points[i][0] = Double.NaN;
|
||||
points[i][1] = Double.NaN;
|
||||
} else {
|
||||
ProjCoordinate p1 = new ProjCoordinate(points[i][0], points[i][1]);
|
||||
ProjCoordinate p2 = new ProjCoordinate();
|
||||
try {
|
||||
trans.transform(p1, p2);
|
||||
points[i][0] = p2.x;
|
||||
points[i][1] = p2.y;
|
||||
} catch (ProjectionException e) {
|
||||
points[i][0] = Double.NaN;
|
||||
points[i][1] = Double.NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-table</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<artifactId>meteoinfo-ui</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
6
pom.xml
6
pom.xml
@ -35,9 +35,9 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<revision>3.5-SNAPSHOT</revision>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.release>1.8</maven.compiler.release>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<maven.compiler.release>8</maven.compiler.release>
|
||||
</properties>
|
||||
<licenses>
|
||||
<license>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user