update CMA Radar base data reading function

This commit is contained in:
wyq 2023-08-20 17:17:11 +08:00
parent 2d72e5f30b
commit 3717f61ea5
41 changed files with 867 additions and 107 deletions

5
.idea/compiler.xml generated
View File

@ -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
View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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);

View File

@ -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};
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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__

View File

@ -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):
"""

View File

@ -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])

View 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

View File

@ -0,0 +1,4 @@
import ncutil
import RadarUtil
__all__ = ['ncutil', 'RadarUtil']

View File

@ -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")

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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
*

View File

@ -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>

View File

@ -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;
}
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>