mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
bugfix for saving shape dbf file
This commit is contained in:
parent
854e480362
commit
46c5fc079c
@ -10,7 +10,6 @@ import org.meteoinfo.data.meteodata.Variable;
|
||||
import org.meteoinfo.ndarray.Array;
|
||||
import org.meteoinfo.ndarray.InvalidRangeException;
|
||||
import org.meteoinfo.ndarray.io.npy.Npy;
|
||||
import org.meteoinfo.ndarray.io.npy.NpyArray;
|
||||
import org.meteoinfo.ndarray.io.npy.NpyUtil;
|
||||
|
||||
import java.io.*;
|
||||
@ -25,15 +24,14 @@ public class NumpyDataInfo extends DataInfo implements IGridDataInfo {
|
||||
public void readDataInfo(String fileName) {
|
||||
this.setFileName(fileName);
|
||||
File file = new File(fileName);
|
||||
NpyArray npyArray = Npy.read(file);
|
||||
Array array = NpyUtil.toMIArray(npyArray);
|
||||
Array array = Npy.load(file);
|
||||
|
||||
this.addAttribute(new Attribute("File type", "Numpy"));
|
||||
int[] shape = npyArray.shape();
|
||||
int[] shape = array.getShape();
|
||||
String name = "a";
|
||||
Variable variable = new Variable();
|
||||
variable.setName(name);
|
||||
variable.setDataType(NpyUtil.toMIDataType(npyArray.dataType()));
|
||||
variable.setDataType(array.getDataType());
|
||||
variable.setCachedData(array);
|
||||
for (int i = 0; i < shape.length; i++) {
|
||||
Dimension dim = new Dimension();
|
||||
|
||||
@ -1175,15 +1175,15 @@ public class VectorLayer extends MapLayer {
|
||||
/**
|
||||
* Edit: Add a field
|
||||
*
|
||||
* @param aField The field
|
||||
* @param field The field
|
||||
*/
|
||||
public void editAddField(Field aField) {
|
||||
public void editAddField(Field field) {
|
||||
for (int i = 0; i < this.getFieldNumber(); i++) {
|
||||
if (aField.getColumnName().equals(_attributeTable.getTable().getColumns().get(i).getColumnName())) {
|
||||
aField.setColumnName(aField.getColumnName() + "_1");
|
||||
if (field.getColumnName().equals(_attributeTable.getTable().getColumns().get(i).getColumnName())) {
|
||||
field.setColumnName(field.getColumnName() + "_1");
|
||||
}
|
||||
}
|
||||
_attributeTable.getTable().addColumn(aField);
|
||||
_attributeTable.addField(field);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,32 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\matlab">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\test">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\city"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\burf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj\calculate"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW\airship"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\text"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\numpy"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\numpy"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\matlab"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\test"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_npz_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\matlab\loadmat_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\test\test_class_inherit.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_npz_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\matlab\loadmat_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\test\test_class_inherit.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="config.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Temp\test"/>
|
||||
<Path OpenPath="D:\Temp\traj\Sample"/>
|
||||
<Font>
|
||||
<TextFont FontName="YaHei Consolas Hybrid" FontSize="14"/>
|
||||
<LegendFont FontName="宋体" FontSize="12"/>
|
||||
@ -8,5 +8,5 @@
|
||||
<ScriptLanguage Language="Jython"/>
|
||||
<LookFeel LafDecorated="true" Name="FlatLightLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-5,1" MainFormSize="1293,685" ShowMeteoDataDlg="true"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685" ShowMeteoDataDlg="true"/>
|
||||
</MeteoInfo>
|
||||
|
||||
@ -40,9 +40,9 @@ import org.meteoinfo.geometry.shape.Shape;
|
||||
*/
|
||||
public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
|
||||
private List<VectorLayer> _mapLayers = new ArrayList<>();
|
||||
private VectorLayer _currentLayer;
|
||||
private FrmMain _parent;
|
||||
private List<VectorLayer> mapLayers = new ArrayList<>();
|
||||
private VectorLayer currentLayer;
|
||||
private FrmMain parent;
|
||||
|
||||
/**
|
||||
* Creates new form FrmOutputMapData
|
||||
@ -53,7 +53,7 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
|
||||
_parent = (FrmMain) parent;
|
||||
this.parent = (FrmMain) parent;
|
||||
initialize();
|
||||
}
|
||||
|
||||
@ -62,17 +62,17 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
|
||||
//Get map layer list
|
||||
int i;
|
||||
for (i = 0; i < _parent.getMapDocument().getActiveMapFrame().getMapView().getLayerNum(); i++) {
|
||||
if (_parent.getMapDocument().getActiveMapFrame().getMapView().getLayers().get(i).getLayerType() == LayerTypes.VECTOR_LAYER) {
|
||||
VectorLayer aLayer = (VectorLayer) _parent.getMapDocument().getActiveMapFrame().getMapView().getLayers().get(i);
|
||||
_mapLayers.add(aLayer);
|
||||
for (i = 0; i < parent.getMapDocument().getActiveMapFrame().getMapView().getLayerNum(); i++) {
|
||||
if (parent.getMapDocument().getActiveMapFrame().getMapView().getLayers().get(i).getLayerType() == LayerTypes.VECTOR_LAYER) {
|
||||
VectorLayer aLayer = (VectorLayer) parent.getMapDocument().getActiveMapFrame().getMapView().getLayers().get(i);
|
||||
mapLayers.add(aLayer);
|
||||
}
|
||||
}
|
||||
|
||||
this.jComboBox_MapLayer.removeAllItems();
|
||||
if (_mapLayers.size() > 0) {
|
||||
for (i = 0; i < _mapLayers.size(); i++) {
|
||||
this.jComboBox_MapLayer.addItem(_mapLayers.get(i).getLayerName());
|
||||
if (mapLayers.size() > 0) {
|
||||
for (i = 0; i < mapLayers.size(); i++) {
|
||||
this.jComboBox_MapLayer.addItem(mapLayers.get(i).getLayerName());
|
||||
}
|
||||
this.jComboBox_MapLayer.setSelectedIndex(0);
|
||||
}
|
||||
@ -175,7 +175,7 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
private void jComboBox_MapLayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox_MapLayerActionPerformed
|
||||
// TODO add your handling code here:
|
||||
if (this.jComboBox_MapLayer.getItemCount() > 0) {
|
||||
_currentLayer = _mapLayers.get(this.jComboBox_MapLayer.getSelectedIndex());
|
||||
currentLayer = mapLayers.get(this.jComboBox_MapLayer.getSelectedIndex());
|
||||
|
||||
int i;
|
||||
String str = this.jComboBox_OutputFormat.getSelectedItem().toString();
|
||||
@ -183,7 +183,7 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
this.jComboBox_OutputFormat.addItem("ASCII wmp File");
|
||||
this.jComboBox_OutputFormat.addItem("Shape File");
|
||||
this.jComboBox_OutputFormat.addItem("KML File");
|
||||
switch (_currentLayer.getShapeType()) {
|
||||
switch (currentLayer.getShapeType()) {
|
||||
case POLYGON:
|
||||
case POLYGON_M:
|
||||
case POLYGON_Z:
|
||||
@ -268,14 +268,14 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
}
|
||||
|
||||
BufferedWriter sw = new BufferedWriter(new FileWriter(file));
|
||||
List<Integer> selIndexes = _currentLayer.getSelectedShapeIndexes();
|
||||
boolean hasSelShape = _currentLayer.hasSelectedShapes();
|
||||
int shpNum = _currentLayer.getShapeNum();
|
||||
List<Integer> selIndexes = currentLayer.getSelectedShapeIndexes();
|
||||
boolean hasSelShape = currentLayer.hasSelectedShapes();
|
||||
int shpNum = currentLayer.getShapeNum();
|
||||
if (hasSelShape) {
|
||||
shpNum = selIndexes.size();
|
||||
}
|
||||
int i;
|
||||
switch (_currentLayer.getShapeType()) {
|
||||
switch (currentLayer.getShapeType()) {
|
||||
case POINT:
|
||||
sw.write("Point");
|
||||
sw.newLine();
|
||||
@ -283,20 +283,20 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
sw.newLine();
|
||||
PointShape aPS;
|
||||
if (hasSelShape) {
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPS = (PointShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPS = (PointShape) currentLayer.getShapes().get(i);
|
||||
if (aPS.isSelected()) {
|
||||
sw.write(String.valueOf(aPS.getPoint().X) + "," + String.valueOf(aPS.getPoint().Y));
|
||||
sw.newLine();
|
||||
}
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / _currentLayer.getShapeNum());
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / currentLayer.getShapeNum());
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPS = (PointShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPS = (PointShape) currentLayer.getShapes().get(i);
|
||||
sw.write(String.valueOf(aPS.getPoint().X) + "," + String.valueOf(aPS.getPoint().Y));
|
||||
sw.newLine();
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / _currentLayer.getShapeNum());
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / currentLayer.getShapeNum());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -306,8 +306,8 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
sw.newLine();
|
||||
int shapeNum = 0;
|
||||
PolylineShape aPLS;
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPLS = (PolylineShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPLS = (PolylineShape) currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPLS.isSelected()) {
|
||||
continue;
|
||||
@ -318,8 +318,8 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
sw.write(String.valueOf(shpNum));
|
||||
sw.newLine();
|
||||
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPLS = (PolylineShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPLS = (PolylineShape) currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPLS.isSelected()) {
|
||||
continue;
|
||||
@ -347,7 +347,7 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
shapeNum += 1;
|
||||
}
|
||||
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / _currentLayer.getShapeNum());
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / currentLayer.getShapeNum());
|
||||
}
|
||||
break;
|
||||
case POLYGON:
|
||||
@ -355,8 +355,8 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
sw.newLine();
|
||||
shapeNum = 0;
|
||||
PolygonShape aPGS;
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPGS = (PolygonShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPGS = (PolygonShape) currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPGS.isSelected()) {
|
||||
continue;
|
||||
@ -367,8 +367,8 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
sw.write(String.valueOf(shapeNum));
|
||||
sw.newLine();
|
||||
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPGS = (PolygonShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPGS = (PolygonShape) currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPGS.isSelected()) {
|
||||
continue;
|
||||
@ -397,7 +397,7 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
shapeNum += 1;
|
||||
}
|
||||
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / _currentLayer.getShapeNum());
|
||||
this.jProgressBar1.setValue((i + 1) * 100 / currentLayer.getShapeNum());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -436,14 +436,14 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
}
|
||||
|
||||
int i;
|
||||
boolean hasSelShape = _currentLayer.hasSelectedShapes();
|
||||
boolean hasSelShape = currentLayer.hasSelectedShapes();
|
||||
|
||||
//Get grid set
|
||||
PolygonShape aPGS;
|
||||
Extent aExtent = new Extent();
|
||||
int n = 0;
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
aPGS = (PolygonShape) _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
aPGS = (PolygonShape) currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPGS.isSelected()) {
|
||||
continue;
|
||||
@ -490,8 +490,8 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
for (j = 0; j < aGDP.xNum; j++) {
|
||||
aPoint.X = aGDP.dataExtent.minX + j * xSize;
|
||||
isIn = false;
|
||||
for (p = 0; p < _currentLayer.getShapeNum(); p++) {
|
||||
aPGS = (PolygonShape) _currentLayer.getShapes().get(p);
|
||||
for (p = 0; p < currentLayer.getShapeNum(); p++) {
|
||||
aPGS = (PolygonShape) currentLayer.getShapes().get(p);
|
||||
if (hasSelShape) {
|
||||
if (!aPGS.isSelected()) {
|
||||
continue;
|
||||
@ -586,14 +586,14 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
|
||||
//Create a VectorLayer with selected shapes
|
||||
int i, j;
|
||||
VectorLayer aLayer = new VectorLayer(_currentLayer.getShapeType());
|
||||
for (i = 0; i < _currentLayer.getFieldNumber(); i++) {
|
||||
aLayer.editAddField(_currentLayer.getField(i).getColumnName(), _currentLayer.getField(i).getDataType());
|
||||
VectorLayer aLayer = new VectorLayer(currentLayer.getShapeType());
|
||||
for (i = 0; i < currentLayer.getFieldNumber(); i++) {
|
||||
aLayer.editAddField(currentLayer.getField(i).getColumnName(), currentLayer.getField(i).getDataType());
|
||||
}
|
||||
boolean hasSelShape = _currentLayer.hasSelectedShapes();
|
||||
boolean hasSelShape = currentLayer.hasSelectedShapes();
|
||||
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
Shape aPS = _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
Shape aPS = currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPS.isSelected()) {
|
||||
continue;
|
||||
@ -603,15 +603,15 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
try {
|
||||
if (aLayer.editInsertShape(aPS, sNum)) {
|
||||
for (j = 0; j < aLayer.getFieldNumber(); j++) {
|
||||
aLayer.editCellValue(j, sNum, _currentLayer.getCellValue(j, i));
|
||||
aLayer.editCellValue(j, sNum, currentLayer.getCellValue(j, i));
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(FrmOutputMapData.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
FrmOutputMapData.this.jProgressBar1.setValue((int) ((double) i / _currentLayer.getShapeNum() * 100));
|
||||
FrmOutputMapData.this.jProgressBar1.setValue((int) ((double) i / currentLayer.getShapeNum() * 100));
|
||||
}
|
||||
aLayer.setProjInfo(_currentLayer.getProjInfo());
|
||||
aLayer.setProjInfo(currentLayer.getProjInfo());
|
||||
aLayer.saveFile(fileName);
|
||||
|
||||
return "";
|
||||
@ -634,14 +634,14 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
|
||||
//Create a VectorLayer with selected shapes
|
||||
int i, j;
|
||||
VectorLayer aLayer = new VectorLayer(_currentLayer.getShapeType());
|
||||
for (i = 0; i < _currentLayer.getFieldNumber(); i++) {
|
||||
aLayer.editAddField(_currentLayer.getField(i).getColumnName(), _currentLayer.getField(i).getDataType());
|
||||
VectorLayer aLayer = new VectorLayer(currentLayer.getShapeType());
|
||||
for (i = 0; i < currentLayer.getFieldNumber(); i++) {
|
||||
aLayer.editAddField(currentLayer.getField(i));
|
||||
}
|
||||
boolean hasSelShape = _currentLayer.hasSelectedShapes();
|
||||
boolean hasSelShape = currentLayer.hasSelectedShapes();
|
||||
|
||||
for (i = 0; i < _currentLayer.getShapeNum(); i++) {
|
||||
Shape aPS = _currentLayer.getShapes().get(i);
|
||||
for (i = 0; i < currentLayer.getShapeNum(); i++) {
|
||||
Shape aPS = currentLayer.getShapes().get(i);
|
||||
if (hasSelShape) {
|
||||
if (!aPS.isSelected()) {
|
||||
continue;
|
||||
@ -651,15 +651,15 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
try {
|
||||
if (aLayer.editInsertShape(aPS, sNum)) {
|
||||
for (j = 0; j < aLayer.getFieldNumber(); j++) {
|
||||
aLayer.editCellValue(j, sNum, _currentLayer.getCellValue(j, i));
|
||||
aLayer.editCellValue(j, sNum, currentLayer.getCellValue(j, i));
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(FrmOutputMapData.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
FrmOutputMapData.this.jProgressBar1.setValue((int) ((double) i / _currentLayer.getShapeNum() * 100));
|
||||
FrmOutputMapData.this.jProgressBar1.setValue((int) ((double) i / currentLayer.getShapeNum() * 100));
|
||||
}
|
||||
aLayer.setProjInfo(_currentLayer.getProjInfo());
|
||||
aLayer.setProjInfo(currentLayer.getProjInfo());
|
||||
aLayer.saveFile(fileName);
|
||||
|
||||
FrmOutputMapData.this.setCursor(Cursor.getDefaultCursor());
|
||||
@ -689,7 +689,7 @@ public class FrmOutputMapData extends javax.swing.JDialog {
|
||||
if (!fileName.substring(fileName.length() - extent.length()).equals(extent)) {
|
||||
fileName = fileName + "." + extent;
|
||||
}
|
||||
_currentLayer.saveAsKMLFile(fileName);
|
||||
currentLayer.saveAsKMLFile(fileName);
|
||||
|
||||
this.setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ public class MatLabUtil {
|
||||
case INT:
|
||||
case UINT:
|
||||
for (int i = 0; i < array.getSize(); i++) {
|
||||
array.setInt(index, matArray.getInt(i));
|
||||
current = index.getCurrentCounter();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (current[j] < shape[j] - 1) {
|
||||
@ -64,12 +65,12 @@ public class MatLabUtil {
|
||||
}
|
||||
}
|
||||
index.set(current);
|
||||
array.setInt(index, matArray.getInt(i));
|
||||
}
|
||||
break;
|
||||
case LONG:
|
||||
case ULONG:
|
||||
for (int i = 0; i < array.getSize(); i++) {
|
||||
array.setLong(index, matArray.getLong(i));
|
||||
current = index.getCurrentCounter();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (current[j] < shape[j] - 1) {
|
||||
@ -80,11 +81,11 @@ public class MatLabUtil {
|
||||
}
|
||||
}
|
||||
index.set(current);
|
||||
array.setLong(index, matArray.getLong(i));
|
||||
}
|
||||
break;
|
||||
case FLOAT:
|
||||
for (int i = 0; i < array.getSize(); i++) {
|
||||
array.setFloat(index, matArray.getFloat(i));
|
||||
current = index.getCurrentCounter();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (current[j] < shape[j] - 1) {
|
||||
@ -95,11 +96,11 @@ public class MatLabUtil {
|
||||
}
|
||||
}
|
||||
index.set(current);
|
||||
array.setFloat(index, matArray.getFloat(i));
|
||||
}
|
||||
break;
|
||||
case DOUBLE:
|
||||
for (int i = 0; i < array.getSize(); i++) {
|
||||
array.setDouble(index, matArray.getDouble(i));
|
||||
current = index.getCurrentCounter();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (current[j] < shape[j] - 1) {
|
||||
@ -110,11 +111,22 @@ public class MatLabUtil {
|
||||
}
|
||||
}
|
||||
index.set(current);
|
||||
array.setDouble(index, matArray.getDouble(i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ndim >= 3) {
|
||||
int[] shapeIdx = new int[ndim];
|
||||
int idx = 0;
|
||||
for (int i = ndim - 1; i > 1; i--) {
|
||||
shapeIdx[idx] = i;
|
||||
idx += 1;
|
||||
}
|
||||
shapeIdx[idx] = 0;
|
||||
shapeIdx[idx + 1] = 1;
|
||||
array = array.permute(shapeIdx);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
abstract class AbstractNpyArray<T> implements NpyArray<T> {
|
||||
|
||||
protected final int[] shape;
|
||||
protected final T data;
|
||||
protected final boolean fortranOrder;
|
||||
|
||||
protected AbstractNpyArray(int[] shape, T data, boolean fortranOrder) {
|
||||
this.shape = Objects.requireNonNull(shape);
|
||||
this.data = Objects.requireNonNull(data);
|
||||
this.fortranOrder = fortranOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int[] shape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasColumnOrder() {
|
||||
return fortranOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
protected final int[] copyShape() {
|
||||
return Arrays.copyOf(shape, shape.length);
|
||||
}
|
||||
}
|
||||
@ -1,416 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import org.meteoinfo.ndarray.io.npy.dict.NpyHeaderDict;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class Array2d {
|
||||
|
||||
private Array2d() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given array is a valid 2-dimensional array. We do not check
|
||||
* this in the other utility methods of this class. So if you are not sure
|
||||
* if an array is a 2D array you should call this method to check this before
|
||||
* calling the other methods of this class.
|
||||
*
|
||||
* @param array the NPY array to check
|
||||
* @return {@code true} if the array has 2 dimensions and each dimensions is
|
||||
* {@code > 1}.
|
||||
*/
|
||||
public static boolean isValid(NpyArray<?> array) {
|
||||
if (array == null || array.shape() == null)
|
||||
return false;
|
||||
int[] shape = array.shape();
|
||||
int rowCount = shape[0];
|
||||
int colCount = shape[1];
|
||||
return rowCount > 0
|
||||
&& colCount > 0
|
||||
&& rowCount * colCount == array.size();
|
||||
}
|
||||
|
||||
public static int rowCountOf(NpyArray<?> array) {
|
||||
return array.shape()[0];
|
||||
}
|
||||
|
||||
public static int columnCountOf(NpyArray<?> array) {
|
||||
return array.shape()[1];
|
||||
}
|
||||
|
||||
public static int indexOf(NpyArray<?> array, int row, int col) {
|
||||
if (array.hasColumnOrder()) {
|
||||
int rows = array.shape()[0];
|
||||
return col * rows + row;
|
||||
} else {
|
||||
int cols = array.shape()[1];
|
||||
return row * cols + col;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean get(NpyBooleanArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static boolean[] getRow(NpyBooleanArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
boolean[] values = new boolean[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static boolean[] getColumn(NpyBooleanArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
boolean[] values = new boolean[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static byte get(NpyByteArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static byte[] getRow(NpyByteArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
byte[] values = new byte[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static byte[] getColumn(NpyByteArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
byte[] values = new byte[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static double get(NpyDoubleArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static double[] getRow(NpyDoubleArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
double[] values = new double[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static double[] getColumn(NpyDoubleArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
double[] values = new double[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static float get(NpyFloatArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static float[] getRow(NpyFloatArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
float[] values = new float[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static float[] getColumn(NpyFloatArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
float[] values = new float[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static int get(NpyIntArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static int[] getRow(NpyIntArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
int[] values = new int[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static int[] getColumn(NpyIntArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
int[] values = new int[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static long get(NpyLongArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static long[] getRow(NpyLongArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
long[] values = new long[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static long[] getColumn(NpyLongArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
long[] values = new long[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static short get(NpyShortArray array, int row, int col) {
|
||||
int i = indexOf(array, row, col);
|
||||
return array.data[i];
|
||||
}
|
||||
|
||||
public static short[] getRow(NpyShortArray array, int row) {
|
||||
int cols = array.shape[1];
|
||||
if (!array.hasColumnOrder()) {
|
||||
int offset = row * cols;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + cols);
|
||||
}
|
||||
int rows = array.shape[0];
|
||||
short[] values = new short[cols];
|
||||
int offset = 0;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
values[col] = array.data[offset + row];
|
||||
offset += rows;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static short[] getColumn(NpyShortArray array, int col) {
|
||||
int rows = array.shape[0];
|
||||
if (array.hasColumnOrder()) {
|
||||
int offset = col * rows;
|
||||
return Arrays.copyOfRange(array.data, offset, offset + rows);
|
||||
}
|
||||
int cols = array.shape[1];
|
||||
short[] values = new short[rows];
|
||||
int offset = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
values[row] = array.data[offset + col];
|
||||
offset += cols;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static NpyArray<?> readRow(File file, int row) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
java.nio.channels.FileChannel channel = raf.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return readRow(raf, header, row);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read a row " + row + " from NPY file " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static NpyArray<?> readRow(
|
||||
RandomAccessFile file, NpyHeader header, int row) {
|
||||
NpyHeaderDict dict = header.dict();
|
||||
int rows = dict.sizeOfDimension(0);
|
||||
int columns = dict.sizeOfDimension(1);
|
||||
return dict.hasFortranOrder()
|
||||
? Npy.readElements(file, header, columns, row, rows)
|
||||
: Npy.readRange(file, header, columns, row * columns);
|
||||
}
|
||||
|
||||
public static NpyArray<?> readColumn(File file, int column) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
java.nio.channels.FileChannel channel = raf.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return readColumn(raf, header, column);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read a column " + column + " from NPY file " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static NpyArray<?> readColumn(
|
||||
RandomAccessFile file, NpyHeader header, int column) {
|
||||
NpyHeaderDict dict = header.dict();
|
||||
int rows = dict.sizeOfDimension(0);
|
||||
int columns = dict.sizeOfDimension(1);
|
||||
return dict.hasFortranOrder()
|
||||
? Npy.readRange(file, header, rows, column * rows)
|
||||
: Npy.readElements(file, header, rows, column, columns);
|
||||
}
|
||||
|
||||
public static <T extends NpyArray<?>> T switchOrder(T array) {
|
||||
return OrderSwitch2d.of(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the diagonal of the 2d-array (matrix) stored in the given NPY file.
|
||||
*
|
||||
* @param file the NPY file
|
||||
* @return the diagonal of the matrix
|
||||
*/
|
||||
public static NpyArray<?> readDiag(File file) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
java.nio.channels.FileChannel channel = raf.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return readDiag(raf, header);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read diagonal from NPY file " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static NpyArray<?> readDiag(RandomAccessFile file, NpyHeader header) {
|
||||
NpyHeaderDict dict = header.dict();
|
||||
int elemSize = dict.dataType() == NpyDataType.U
|
||||
? 4
|
||||
: Math.max(dict.dataType().size(), 1);
|
||||
|
||||
int rows = dict.sizeOfDimension(0);
|
||||
int cols = dict.sizeOfDimension(1);
|
||||
int n = Math.min(rows, cols);
|
||||
if (n < 1)
|
||||
throw new IndexOutOfBoundsException(String.valueOf(n));
|
||||
|
||||
try {
|
||||
NpyArrayReader reader = NpyArrayReader.of(Npy.shape1d(dict, n));
|
||||
ByteBuffer buffer = ByteBuffer.allocate(elemSize);
|
||||
buffer.order(header.byteOrder());
|
||||
java.nio.channels.FileChannel channel = file.getChannel();
|
||||
|
||||
long pos = header.dataOffset();
|
||||
long seekDist = dict.hasFortranOrder()
|
||||
? (long) (rows + 1) * elemSize
|
||||
: (long) (cols + 1) * elemSize;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
file.seek(pos);
|
||||
channel.read(buffer);
|
||||
buffer.flip();
|
||||
reader.readNextFrom(buffer);
|
||||
pos += seekDist;
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
return reader.finish();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read diagonal from NPY file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
|
||||
class ChannelReader {
|
||||
|
||||
private static final int MAX_BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
private final ReadableByteChannel channel;
|
||||
private final NpyHeader header;
|
||||
|
||||
private ChannelReader(ReadableByteChannel channel, NpyHeader header) {
|
||||
this.channel = channel;
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
static NpyArray<?> read(ReadableByteChannel channel, NpyHeader header)
|
||||
throws IOException, NpyFormatException {
|
||||
return new ChannelReader(channel, header).read();
|
||||
}
|
||||
|
||||
private NpyArray<?> read() throws IOException, NpyFormatException {
|
||||
long totalBytes = header.dict().dataSize();
|
||||
int bufferSize = totalBytes > 0 && totalBytes < ((long) MAX_BUFFER_SIZE)
|
||||
? (int) totalBytes
|
||||
: MAX_BUFFER_SIZE;
|
||||
|
||||
NpyArrayReader builder = NpyArrayReader.of(header.dict());
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
|
||||
buffer.order(header.byteOrder());
|
||||
long readBytes = 0;
|
||||
while (readBytes < totalBytes) {
|
||||
int n = channel.read(buffer);
|
||||
if (n <= 0)
|
||||
break;
|
||||
buffer.flip();
|
||||
builder.readAllFrom(buffer);
|
||||
buffer.clear();
|
||||
readBytes += n;
|
||||
}
|
||||
return builder.finish();
|
||||
}
|
||||
}
|
||||
@ -30,24 +30,6 @@ public class Npy {
|
||||
return load(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the content of the given file into NPY array instance.
|
||||
*
|
||||
* @param file the NPY file to read
|
||||
* @return the mapped NPY array
|
||||
* @throws NpyFormatException if the NPY format is invalid or unsupported
|
||||
* @throws RuntimeException IO exceptions are wrapped in runtime exceptions
|
||||
*/
|
||||
public static NpyArray<?> read(File file) {
|
||||
try (RandomAccessFile f = new RandomAccessFile(file, "r");
|
||||
FileChannel channel = f.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return ChannelReader.read(channel, header);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to read file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the content of the given file into NPY array instance.
|
||||
*
|
||||
@ -83,15 +65,6 @@ public class Npy {
|
||||
}
|
||||
}
|
||||
|
||||
public static NpyArray<?> read(ReadableByteChannel channel) {
|
||||
try {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return ChannelReader.read(channel, header);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to read NPY array from channel", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given file as a random access file and reads the NPY header. It
|
||||
* calls the given consumer with the opened file and header and closes the
|
||||
@ -111,128 +84,6 @@ public class Npy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a range of {@code n} elements from an array in an NPY file. Say you
|
||||
* have an NPY file with an array {@code [1, 2, 3, 4]}, then
|
||||
* {@code readRange(file, 2, 1)} would read {@code 2} elements starting from
|
||||
* an offset of {@code 1} and thus would return {@code [2, 3]}.
|
||||
*
|
||||
* @param file a NPY file
|
||||
* @param n the number of elements that should be read from the file
|
||||
* @param offset the 0-based position of the first element of the range
|
||||
* @return a one-dimensional array with {@code n} elements
|
||||
*/
|
||||
public static NpyArray<?> readRange(File file, int n, int offset) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
FileChannel channel = raf.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return readRange(raf, header, n, offset);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read a range of " +
|
||||
n + " elements from NPY file " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #readRange(File, int, int)} but with an opened NPY file.
|
||||
*
|
||||
* @param file the opened NPY file
|
||||
* @param header the NPY header of the file
|
||||
* @param n the number of elements that should be read from the file
|
||||
* @param offset the 0-based position of the first element of the range
|
||||
* @return a one-dimensional array with {@code n} elements
|
||||
*/
|
||||
public static NpyArray<?> readRange(
|
||||
RandomAccessFile file, NpyHeader header, int n, int offset) {
|
||||
|
||||
NpyHeaderDict dict = header.dict();
|
||||
int elemSize = dict.dataType() == NpyDataType.U
|
||||
? 4
|
||||
: Math.max(dict.dataType().size(), 1);
|
||||
|
||||
try {
|
||||
|
||||
// seek to the reading position and read the data
|
||||
long start = header.dataOffset();
|
||||
if (offset > 0) {
|
||||
start += (long) elemSize * (long) offset;
|
||||
}
|
||||
file.seek(start);
|
||||
int byteCount = n * elemSize;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(byteCount)
|
||||
.order(dict.byteOrder().toJava());
|
||||
if (file.getChannel().read(buffer) < byteCount) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"failed to read " + n + " elements from file");
|
||||
}
|
||||
buffer.flip();
|
||||
|
||||
// read the range into an array
|
||||
NpyHeaderDict rangeDict = shape1d(dict, n);
|
||||
NpyArrayReader reader = NpyArrayReader.of(rangeDict);
|
||||
reader.readAllFrom(buffer);
|
||||
return reader.finish();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read range from NPY file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static NpyArray<?> readElements(File file, int n, int offset, int inc) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
FileChannel channel = raf.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
return readElements(raf, header, n, offset, inc);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read " + n + " elements from NPY file " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static NpyArray<?> readElements(
|
||||
RandomAccessFile file, NpyHeader header, int n, int offset, int inc) {
|
||||
|
||||
if (inc == 1)
|
||||
return readRange(file, header, n, offset);
|
||||
|
||||
NpyHeaderDict dict = header.dict();
|
||||
int elemSize = dict.dataType() == NpyDataType.U
|
||||
? 4
|
||||
: Math.max(dict.dataType().size(), 1);
|
||||
|
||||
try {
|
||||
|
||||
// read the data
|
||||
ByteBuffer buffer = ByteBuffer.allocate(n * elemSize)
|
||||
.order(dict.byteOrder().toJava());
|
||||
long fileOffset = header.dataOffset();
|
||||
if (offset > 0) {
|
||||
fileOffset += (long) elemSize * (long) offset;
|
||||
}
|
||||
FileChannel channel = file.getChannel();
|
||||
for (int i = 0; i < n; i++) {
|
||||
file.seek(fileOffset + (long) i * inc * elemSize);
|
||||
buffer.limit(buffer.position() + elemSize);
|
||||
if (channel.read(buffer) < elemSize) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"failed to read " + n + " elements from file");
|
||||
}
|
||||
}
|
||||
buffer.flip();
|
||||
|
||||
// read the range into an array
|
||||
NpyHeaderDict rangeDict = shape1d(dict, n);
|
||||
NpyArrayReader reader = NpyArrayReader.of(rangeDict);
|
||||
reader.readAllFrom(buffer);
|
||||
return reader.finish();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"failed to read elements from NPY file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
static NpyHeaderDict shape1d(NpyHeaderDict dict, int n) {
|
||||
return NpyHeaderDict.of(dict.dataType())
|
||||
.withTypeSize(dict.typeSize())
|
||||
@ -319,101 +170,4 @@ public class Npy {
|
||||
throw new RuntimeException("failed to write npy data", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(File file, NpyArray<?> array) {
|
||||
try (RandomAccessFile f = new RandomAccessFile(file, "rw");
|
||||
FileChannel channel = f.getChannel()) {
|
||||
write(channel, array);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to write array to file " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(WritableByteChannel channel, NpyArray<?> array) {
|
||||
try {
|
||||
|
||||
NpyDataType dataType = array.dataType();
|
||||
|
||||
// handle strings
|
||||
if (array.isCharArray()) {
|
||||
NpyCharArray charArray = array.asCharArray();
|
||||
NpyHeaderDict dict = NpyHeaderDict.of(dataType)
|
||||
.withByteOrder(dataType == NpyDataType.S
|
||||
? NpyByteOrder.NOT_APPLICABLE
|
||||
: NpyByteOrder.LITTLE_ENDIAN)
|
||||
.withTypeSize(charArray.size())
|
||||
.create();
|
||||
byte[] bytes = charArray.asByteArray().data();
|
||||
Npy.write(channel, dict, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
// write the header
|
||||
NpyHeaderDict dict = NpyHeaderDict.of(dataType)
|
||||
.withShape(array.shape())
|
||||
.withFortranOrder(array.hasColumnOrder())
|
||||
.withByteOrder(NpyByteOrder.LITTLE_ENDIAN)
|
||||
.create();
|
||||
channel.write(ByteBuffer.wrap(dict.toNpyHeader()));
|
||||
|
||||
// allocate a buffer
|
||||
long totalBytes = dict.dataSize();
|
||||
int maxBufferSize = 8 * 1024;
|
||||
int bufferSize = totalBytes < maxBufferSize
|
||||
? (int) totalBytes
|
||||
: maxBufferSize;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(bufferSize)
|
||||
.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// write data to the channel
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
array.writeElementTo(i, buffer);
|
||||
if (!buffer.hasRemaining()) {
|
||||
buffer.flip();
|
||||
channel.write(buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
}
|
||||
if (buffer.position() > 0) {
|
||||
buffer.flip();
|
||||
channel.write(buffer);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to write NPY array to channel", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(OutputStream stream, NpyArray<?> array) {
|
||||
// do not close the channel here because it would
|
||||
// close the underlying output stream which is
|
||||
// not the idea of this function.
|
||||
WritableByteChannel channel = Channels.newChannel(stream);
|
||||
write(channel, array);
|
||||
}
|
||||
|
||||
public static NpyArray<?> memmap(File file) {
|
||||
try (RandomAccessFile f = new RandomAccessFile(file, "r");
|
||||
FileChannel channel = f.getChannel()) {
|
||||
NpyHeader header = NpyHeader.read(channel);
|
||||
long dataSize = header.dict().dataSize();
|
||||
|
||||
// only a buffer of size < Integer.MAX_VALUE can be mapped
|
||||
// into memory. if the size of the stored array is larger
|
||||
// we take the normal reader currently
|
||||
long max = Integer.MAX_VALUE;
|
||||
if (dataSize >= max)
|
||||
return ChannelReader.read(channel, header);
|
||||
|
||||
java.nio.MappedByteBuffer buffer = channel.map(
|
||||
FileChannel.MapMode.READ_ONLY, header.dataOffset(), dataSize);
|
||||
buffer.order(header.byteOrder());
|
||||
NpyArrayReader builder = NpyArrayReader.of(header.dict());
|
||||
builder.readAllFrom(buffer);
|
||||
return builder.finish();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to memmap NPY file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public interface NpyArray<T> {
|
||||
|
||||
T data();
|
||||
|
||||
int[] shape();
|
||||
|
||||
/**
|
||||
* Returns {@code true} when this array is stored in column-major order
|
||||
* (Fortran order).
|
||||
*/
|
||||
boolean hasColumnOrder();
|
||||
|
||||
/**
|
||||
* Returns {@code true} when this array is stored in row-major order (C order).
|
||||
*/
|
||||
default boolean hasRowOrder() {
|
||||
return !hasColumnOrder();
|
||||
}
|
||||
|
||||
NpyDataType dataType();
|
||||
|
||||
/**
|
||||
* Get the element by index.
|
||||
*
|
||||
* @param i Index
|
||||
*
|
||||
* @return The element
|
||||
*/
|
||||
Object getElement(int i);
|
||||
|
||||
/**
|
||||
* Writes the element {@code i} of this array to the given buffer.
|
||||
*
|
||||
* @param i the 0-based position of the element in this array that should
|
||||
* be written to the buffer; must have a value between {@code 0}
|
||||
* inclusively and {@link #size()} exclusively.
|
||||
* @param buffer the byte buffer to which the element should be written
|
||||
*/
|
||||
void writeElementTo(int i, ByteBuffer buffer);
|
||||
|
||||
/**
|
||||
* Returns the size of this array. That is the number of elements of this
|
||||
* array.
|
||||
*
|
||||
* @return the number of elements of this array
|
||||
*/
|
||||
int size();
|
||||
|
||||
default boolean isBigIntegerArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isBooleanArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
NpyBooleanArray asBooleanArray();
|
||||
|
||||
/**
|
||||
* Returns true if this array is an instance of {@link NpyByteArray}.
|
||||
*/
|
||||
default boolean isByteArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this array into an instance of {@link NpyByteArray}. If this
|
||||
* array is already such an instance it is directly returned without copying.
|
||||
* Otherwise the values of this array are casted into a new
|
||||
* {@link NpyByteArray}. Note that such casting can result in data loss.
|
||||
*
|
||||
* @return this array as an instance of {@link NpyByteArray}
|
||||
*/
|
||||
NpyByteArray asByteArray();
|
||||
|
||||
default boolean isDoubleArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this array into a double array. If this array is already a double
|
||||
* array it is directly returned without making a copy of it.
|
||||
*
|
||||
* @return this array if it is a double array, otherwise a converted array
|
||||
*/
|
||||
NpyDoubleArray asDoubleArray();
|
||||
|
||||
default boolean isFloatArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
NpyFloatArray asFloatArray();
|
||||
|
||||
default boolean isIntArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
NpyIntArray asIntArray();
|
||||
|
||||
default boolean isLongArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
NpyLongArray asLongArray();
|
||||
|
||||
default boolean isShortArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
NpyShortArray asShortArray();
|
||||
|
||||
default boolean isCharArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default NpyCharArray asCharArray() {
|
||||
return asIntArray().asCharArray();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,306 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import org.meteoinfo.ndarray.io.npy.dict.NpyHeaderDict;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
|
||||
abstract class NpyArrayReader {
|
||||
|
||||
protected final NpyHeaderDict dict;
|
||||
protected final int elementCount;
|
||||
private final int elementSize;
|
||||
private int pos;
|
||||
|
||||
private NpyArrayReader(NpyHeaderDict dict) {
|
||||
this.dict = dict;
|
||||
NpyDataType type = dict.dataType();
|
||||
this.elementCount = type == NpyDataType.S || type == NpyDataType.U
|
||||
? dict.typeSize()
|
||||
: dict.numberOfElements();
|
||||
this.elementSize = type == NpyDataType.S ? 1
|
||||
: type == NpyDataType.U ? 4 : type.size();
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
static NpyArrayReader of(NpyHeaderDict dict) throws NpyFormatException {
|
||||
switch (dict.dataType()) {
|
||||
case bool:
|
||||
return new BooleanBuilder(dict);
|
||||
case f2:
|
||||
return new FloatBuilder(dict, NpyUtil::f2ToFloat);
|
||||
case f4:
|
||||
return new FloatBuilder(dict, ByteBuffer::getFloat);
|
||||
case f8:
|
||||
return new DoubleBuilder(dict);
|
||||
case i1:
|
||||
return new ByteBuilder(dict);
|
||||
case i2:
|
||||
return new ShortBuilder(dict, ByteBuffer::getShort);
|
||||
case i4:
|
||||
return new IntBuilder(dict, ByteBuffer::getInt);
|
||||
case i8:
|
||||
return new LongBuilder(dict, ByteBuffer::getLong);
|
||||
case u1:
|
||||
return new ShortBuilder(dict, NpyUtil::u1ToShort);
|
||||
case u2:
|
||||
return new IntBuilder(dict, NpyUtil::u2ToInt);
|
||||
case u4:
|
||||
return new LongBuilder(dict, NpyUtil::u4ToLong);
|
||||
case u8:
|
||||
return new BigIntBuilder(dict);
|
||||
case S:
|
||||
return new AsciiBuilder(dict);
|
||||
case U:
|
||||
return new UnicodeBuilder(dict);
|
||||
default:
|
||||
throw new NpyFormatException(
|
||||
"unsupported data type: " + dict.dataType());
|
||||
}
|
||||
}
|
||||
|
||||
final void readAllFrom(ByteBuffer buffer) {
|
||||
while (pos != elementCount && buffer.remaining() >= elementSize) {
|
||||
nextInto(buffer, pos);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
final void readNextFrom(ByteBuffer buffer) {
|
||||
nextInto(buffer, pos);
|
||||
pos++;
|
||||
}
|
||||
|
||||
abstract void nextInto(ByteBuffer buffer, int pos);
|
||||
|
||||
abstract NpyArray<?> finish();
|
||||
|
||||
private static final class BooleanBuilder extends NpyArrayReader {
|
||||
|
||||
private final boolean[] data;
|
||||
|
||||
private BooleanBuilder(NpyHeaderDict dict) {
|
||||
super(dict);
|
||||
this.data = new boolean[elementCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = buffer.get() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyBooleanArray finish() {
|
||||
return new NpyBooleanArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ByteBuilder extends NpyArrayReader {
|
||||
|
||||
private final byte[] data;
|
||||
|
||||
private ByteBuilder(NpyHeaderDict dict) {
|
||||
super(dict);
|
||||
this.data = new byte[elementCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = buffer.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyByteArray finish() {
|
||||
return new NpyByteArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DoubleBuilder extends NpyArrayReader {
|
||||
|
||||
private final double[] data;
|
||||
|
||||
private DoubleBuilder(NpyHeaderDict dict) {
|
||||
super(dict);
|
||||
this.data = new double[elementCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = buffer.getDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyDoubleArray finish() {
|
||||
return new NpyDoubleArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FloatBuilder extends NpyArrayReader {
|
||||
|
||||
private final float[] data;
|
||||
private final ToFloatFunction<ByteBuffer> fn;
|
||||
|
||||
private FloatBuilder(NpyHeaderDict dict, ToFloatFunction<ByteBuffer> fn) {
|
||||
super(dict);
|
||||
this.data = new float[elementCount];
|
||||
this.fn = fn;
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = fn.applyAsFloat(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyFloatArray finish() {
|
||||
return new NpyFloatArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class IntBuilder extends NpyArrayReader {
|
||||
|
||||
private final int[] data;
|
||||
private final ToIntFunction<ByteBuffer> fn;
|
||||
|
||||
private IntBuilder(NpyHeaderDict dict, ToIntFunction<ByteBuffer> fn) {
|
||||
super(dict);
|
||||
this.data = new int[elementCount];
|
||||
this.fn = fn;
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = fn.applyAsInt(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyIntArray finish() {
|
||||
return new NpyIntArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ShortBuilder extends NpyArrayReader {
|
||||
|
||||
private final short[] data;
|
||||
private final ToShortFunction<ByteBuffer> fn;
|
||||
|
||||
private ShortBuilder(NpyHeaderDict dict, ToShortFunction<ByteBuffer> fn) {
|
||||
super(dict);
|
||||
this.data = new short[elementCount];
|
||||
this.fn = fn;
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = fn.applyAsShort(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyShortArray finish() {
|
||||
return new NpyShortArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LongBuilder extends NpyArrayReader {
|
||||
|
||||
private final long[] data;
|
||||
private final ToLongFunction<ByteBuffer> fn;
|
||||
|
||||
private LongBuilder(NpyHeaderDict dict, ToLongFunction<ByteBuffer> fn) {
|
||||
super(dict);
|
||||
this.data = new long[elementCount];
|
||||
this.fn = fn;
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = fn.applyAsLong(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyLongArray finish() {
|
||||
return new NpyLongArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class BigIntBuilder extends NpyArrayReader {
|
||||
|
||||
private final BigInteger[] data;
|
||||
|
||||
private BigIntBuilder(NpyHeaderDict dict) {
|
||||
super(dict);
|
||||
this.data = new BigInteger[elementCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = NpyUtil.u8ToBigInteger(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyBigIntArray finish() {
|
||||
return new NpyBigIntArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class AsciiBuilder extends NpyArrayReader {
|
||||
|
||||
private final CharBuffer chars;
|
||||
private boolean terminated = false;
|
||||
|
||||
private AsciiBuilder(NpyHeaderDict dict) {
|
||||
super(dict);
|
||||
this.chars = CharBuffer.allocate(elementCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
if (terminated)
|
||||
return;
|
||||
char next = (char)buffer.get();
|
||||
if (next == 0) {
|
||||
terminated = true;
|
||||
return;
|
||||
}
|
||||
chars.put(next);
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyCharArray finish() {
|
||||
char[] data;
|
||||
if (chars.remaining() == 0) {
|
||||
data = chars.array();
|
||||
} else {
|
||||
chars.flip();
|
||||
data = new char[chars.limit()];
|
||||
chars.get(data, 0, chars.limit());
|
||||
}
|
||||
|
||||
return new NpyCharArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UnicodeBuilder extends NpyArrayReader {
|
||||
|
||||
private final int[] data;
|
||||
|
||||
private UnicodeBuilder(NpyHeaderDict dict) {
|
||||
super(dict);
|
||||
this.data = new int[elementCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
void nextInto(ByteBuffer buffer, int pos) {
|
||||
data[pos] = buffer.getInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
NpyCharArray finish() {
|
||||
NpyIntArray ints = new NpyIntArray(dict.shape(), data, dict.hasFortranOrder());
|
||||
return ints.asCharArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,154 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyBigIntArray extends AbstractNpyArray<BigInteger[]> {
|
||||
|
||||
public NpyBigIntArray(int[] shape, BigInteger[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyBigIntArray vectorOf(BigInteger[] data) {
|
||||
return new NpyBigIntArray(new int[] {data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyBigIntArray rowOrderOf(BigInteger[] data, int rows, int cols) {
|
||||
return new NpyBigIntArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyBigIntArray columnOrderOf(BigInteger[] data, int rows, int cols) {
|
||||
return new NpyBigIntArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.u8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
BigInteger value = data[i];
|
||||
if (value == null) {
|
||||
buffer.putLong(0);
|
||||
} else {
|
||||
buffer.putLong(value.longValueExact());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBigIntegerArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
booleans[i] = val.longValueExact() != 0;
|
||||
}
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
bytes[i] = (byte) val.intValueExact();
|
||||
}
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
doubles[i] = val.doubleValue();
|
||||
}
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
floats[i] = (float) val.doubleValue();
|
||||
}
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
ints[i] = val.intValueExact();
|
||||
}
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
longs[i] = val.longValueExact();
|
||||
}
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
BigInteger val = data[i];
|
||||
if (val != null) {
|
||||
shorts[i] = (short) val.intValueExact();
|
||||
}
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
}
|
||||
@ -1,138 +0,0 @@
|
||||
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyBooleanArray extends AbstractNpyArray<boolean[]> {
|
||||
|
||||
public NpyBooleanArray(int[] shape, boolean[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyBooleanArray vectorOf(boolean[] data) {
|
||||
return new NpyBooleanArray(new int[] {data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyBooleanArray rowOrderOf(boolean[] data, int rows, int cols) {
|
||||
return new NpyBooleanArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyBooleanArray columnOrderOf(boolean[] data, int rows, int cols) {
|
||||
return new NpyBooleanArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.bool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
byte b = data[i] ? (byte) 1 : (byte) 0;
|
||||
buffer.put(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBooleanArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
bytes[i] = 1;
|
||||
}
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
doubles[i] = 1d;
|
||||
}
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
floats[i] = 1f;
|
||||
}
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
ints[i] = 1;
|
||||
}
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
longs[i] = 1L;
|
||||
}
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
shorts[i] = 1;
|
||||
}
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyByteArray extends AbstractNpyArray<byte[]> {
|
||||
|
||||
public NpyByteArray(int[] shape, byte[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyByteArray vectorOf(byte[] data) {
|
||||
return new NpyByteArray(new int[] {data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyByteArray rowOrderOf(byte[] data, int rows, int cols) {
|
||||
return new NpyByteArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyByteArray columnOrderOf(byte[] data, int rows, int cols) {
|
||||
return new NpyByteArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.i1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
buffer.put(data[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isByteArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = i != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
doubles[i] = data[i];
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
floats[i] = data[i];
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
ints[i] = data[i];
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
longs[i] = data[i];
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
shorts[i] = data[i];
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,152 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class NpyCharArray extends AbstractNpyArray<char[]> {
|
||||
|
||||
private NpyDataType type;
|
||||
|
||||
public NpyCharArray(int[] shape, char[] data) {
|
||||
super(shape, data, false);
|
||||
}
|
||||
|
||||
public NpyCharArray(int[] shape, char[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyCharArray of(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
return new NpyCharArray(new int[0], chars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
if (type != null)
|
||||
return type;
|
||||
boolean isAscii = StandardCharsets.US_ASCII
|
||||
.newEncoder()
|
||||
.canEncode(CharBuffer.wrap(data));
|
||||
type = isAscii
|
||||
? NpyDataType.S
|
||||
: NpyDataType.U;
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
if (dataType() == NpyDataType.S) {
|
||||
buffer.put((byte) data[i]);
|
||||
} else {
|
||||
buffer.putInt(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCharArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = data[i] != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this character array into a byte array. If the characters in this
|
||||
* array can be encoded in ASCII, a NULL-terminated byte array will be
|
||||
* returned. Otherwise, an array with the 4-byte unicode code-points encoded
|
||||
* in little-endian order will be returned.
|
||||
*
|
||||
* @return the NPY byte-array representation of this character array
|
||||
*/
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
NpyDataType type = dataType();
|
||||
if (type == NpyDataType.S) {
|
||||
// write as NULL terminated string
|
||||
byte[] bytes = new byte[data.length + 1];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
bytes[i] = (byte) data[i];
|
||||
}
|
||||
return NpyByteArray.vectorOf(bytes);
|
||||
}
|
||||
|
||||
// write unicode code points
|
||||
byte[] bytes = new byte[data.length * 4];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
for (char datum : data) {
|
||||
buffer.putInt(datum);
|
||||
}
|
||||
return NpyByteArray.vectorOf(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyCharArray asCharArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
return asIntArray().asDoubleArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
return asIntArray().asFloatArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
IntBuffer buffer = IntBuffer.allocate(data.length);
|
||||
int pos = 0;
|
||||
while (pos < data.length) {
|
||||
int codePoint = Character.codePointAt(data, pos);
|
||||
buffer.put(codePoint);
|
||||
pos += Character.charCount(codePoint);
|
||||
}
|
||||
|
||||
int[] ints;
|
||||
if (buffer.remaining() == 0) {
|
||||
ints = buffer.array();
|
||||
} else {
|
||||
buffer.flip();
|
||||
ints = new int[buffer.limit()];
|
||||
buffer.get(ints, 0, buffer.limit());
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
return asIntArray().asLongArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
return asIntArray().asShortArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(data);
|
||||
}
|
||||
}
|
||||
@ -1,123 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyDoubleArray extends AbstractNpyArray<double[]> {
|
||||
|
||||
public NpyDoubleArray(int[] shape, double[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyDoubleArray vectorOf(double[] data) {
|
||||
return new NpyDoubleArray(new int[]{data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyDoubleArray rowOrderOf(double[] data, int rows, int cols) {
|
||||
return new NpyDoubleArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyDoubleArray columnOrderOf(double[] data, int rows, int cols) {
|
||||
return new NpyDoubleArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.f8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
buffer.putDouble(data[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDoubleArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = data[i] != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
bytes[i] = (byte) data[i];
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
floats[i] = (float) data[i];
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
ints[i] = (int) data[i];
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
longs[i] = (long) data[i];
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
shorts[i] = (short) data[i];
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
}
|
||||
@ -1,123 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyFloatArray extends AbstractNpyArray<float[]> {
|
||||
|
||||
public NpyFloatArray(int[] shape, float[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyFloatArray vectorOf(float[] data) {
|
||||
return new NpyFloatArray(new int[]{data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyFloatArray rowOrderOf(float[] data, int rows, int cols) {
|
||||
return new NpyFloatArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyFloatArray columnOrderOf(float[] data, int rows, int cols) {
|
||||
return new NpyFloatArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.f4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
buffer.putFloat(data[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFloatArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = i != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
bytes[i] = (byte) data[i];
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
doubles[i] = data[i];
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
ints[i] = (int) data[i];
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
longs[i] = (long) data[i];
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
shorts[i] = (short) data[i];
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
}
|
||||
@ -1,167 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
public final class NpyIntArray extends AbstractNpyArray<int[]> {
|
||||
|
||||
public NpyIntArray(int[] shape, int[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyIntArray vectorOf(int[] data) {
|
||||
return new NpyIntArray(new int[] {data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyIntArray rowOrderOf(int[] data, int rows, int cols) {
|
||||
return new NpyIntArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyIntArray columnOrderOf(int[] data, int rows, int cols) {
|
||||
return new NpyIntArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.i4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
buffer.putInt(data[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIntArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = data[i] != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
bytes[i] = (byte) data[i];
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyCharArray asCharArray() {
|
||||
int bufferSize = Math.max(data.length, 10);
|
||||
CharBuffer buffer = CharBuffer.allocate(bufferSize);
|
||||
for (int i : data) {
|
||||
char[] next = Character.toChars(i);
|
||||
|
||||
// because a code point can result in multiple
|
||||
// characters, we may need to allocate a larger
|
||||
// buffer here
|
||||
if (buffer.remaining() < next.length) {
|
||||
bufferSize = Math.max(
|
||||
bufferSize + next.length,
|
||||
bufferSize + (bufferSize >> 1));
|
||||
if (bufferSize < 0)
|
||||
throw new OutOfMemoryError();
|
||||
char[] chars = new char[bufferSize];
|
||||
buffer.flip();
|
||||
int nextPos = buffer.limit();
|
||||
buffer.get(chars, 0, nextPos);
|
||||
buffer = CharBuffer.wrap(chars);
|
||||
buffer.position(nextPos);
|
||||
}
|
||||
|
||||
for (char c : next) {
|
||||
buffer.put(c);
|
||||
}
|
||||
}
|
||||
|
||||
char[] chars;
|
||||
if (buffer.remaining() == 0) {
|
||||
chars = buffer.array();
|
||||
} else {
|
||||
buffer.flip();
|
||||
chars = new char[buffer.limit()];
|
||||
buffer.get(chars, 0, buffer.limit());
|
||||
}
|
||||
|
||||
return new NpyCharArray(copyShape(), chars, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
doubles[i] = data[i];
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
floats[i] = (float) data[i];
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
longs[i] = data[i];
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
shorts[i] = (short) data[i];
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyLongArray extends AbstractNpyArray<long[]> {
|
||||
|
||||
public NpyLongArray(int[] shape, long[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyLongArray vectorOf(long[] data) {
|
||||
return new NpyLongArray(new int[] {data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyLongArray rowOrderOf(long[] data, int rows, int cols) {
|
||||
return new NpyLongArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyLongArray columnOrderOf(long[] data, int rows, int cols) {
|
||||
return new NpyLongArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.i8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
buffer.putLong(data[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLongArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = i != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
bytes[i] = (byte) data[i];
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
doubles[i] = data[i];
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
floats[i] = (float) data[i];
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
ints[i] = (int) data[i];
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
short[] shorts = new short[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
shorts[i] = (short) data[i];
|
||||
}
|
||||
return new NpyShortArray(copyShape(), shorts, fortranOrder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class NpyShortArray extends AbstractNpyArray<short[]> {
|
||||
|
||||
public NpyShortArray(int[] shape, short[] data, boolean fortranOrder) {
|
||||
super(shape, data, fortranOrder);
|
||||
}
|
||||
|
||||
public static NpyShortArray vectorOf(short[] data) {
|
||||
return new NpyShortArray(new int[] {data.length}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in row-major order (C order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyShortArray rowOrderOf(short[] data, int rows, int cols) {
|
||||
return new NpyShortArray(new int[]{rows, cols}, data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given data in a 2-dimensional array in column-major order (
|
||||
* Fortran order).
|
||||
*
|
||||
* @param data the data of the array
|
||||
* @param rows the number of rows of the array
|
||||
* @param cols the number of columns of the array
|
||||
* @return a 2d array of the given shape
|
||||
*/
|
||||
public static NpyShortArray columnOrderOf(short[] data, int rows, int cols) {
|
||||
return new NpyShortArray(new int[]{rows, cols}, data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDataType dataType() {
|
||||
return NpyDataType.i2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElement(int i) {
|
||||
return data[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeElementTo(int i, ByteBuffer buffer) {
|
||||
buffer.putShort(data[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShortArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyShortArray asShortArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyBooleanArray asBooleanArray() {
|
||||
boolean[] booleans = new boolean[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
booleans[i] = i != 0;
|
||||
}
|
||||
return new NpyBooleanArray(copyShape(), booleans, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyByteArray asByteArray() {
|
||||
byte[] bytes = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
bytes[i] = (byte) data[i];
|
||||
}
|
||||
return new NpyByteArray(copyShape(), bytes, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyDoubleArray asDoubleArray() {
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
doubles[i] = data[i];
|
||||
}
|
||||
return new NpyDoubleArray(copyShape(), doubles, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyFloatArray asFloatArray() {
|
||||
float[] floats = new float[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
floats[i] = data[i];
|
||||
}
|
||||
return new NpyFloatArray(copyShape(), floats, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyIntArray asIntArray() {
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
ints[i] = data[i];
|
||||
}
|
||||
return new NpyIntArray(copyShape(), ints, fortranOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpyLongArray asLongArray() {
|
||||
long[] longs = new long[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
longs[i] = data[i];
|
||||
}
|
||||
return new NpyLongArray(copyShape(), longs, fortranOrder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,21 +161,4 @@ public class NpyUtil {
|
||||
throw new NpyFormatException("Unsupported data type: " + dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Npy array to MeteoInfo array
|
||||
*
|
||||
* @param npyArray Npy array
|
||||
* @return MeteoInfo array
|
||||
*/
|
||||
public static Array toMIArray(NpyArray npyArray) {
|
||||
DataType dataType = toMIDataType(npyArray.dataType());
|
||||
int[] shape = npyArray.shape();
|
||||
Array array = Array.factory(dataType, shape);
|
||||
for (int i = 0; i < array.getSize(); i++) {
|
||||
array.setObject(i, npyArray.getElement(i));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,38 +91,6 @@ public class Npz {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an array from an entry of a NPZ file.
|
||||
*
|
||||
* @param npz the NPZ file
|
||||
* @param entry the name of the entry in which the array is stored
|
||||
* @return the NPY array of the entry
|
||||
*/
|
||||
public static NpyArray<?> read(File npz, String entry) {
|
||||
try (ZipFile zip = new ZipFile(npz)) {
|
||||
return read(zip, entry);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to read zip file: " + npz, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an array from an entry of a NPZ file.
|
||||
*
|
||||
* @param npz the NPZ file
|
||||
* @param entry the name of the entry in which the array is stored
|
||||
* @return the NPY array of the entry
|
||||
*/
|
||||
public static NpyArray<?> read(ZipFile npz, String entry) {
|
||||
ZipEntry e = npz.getEntry(entry);
|
||||
try (java.io.InputStream stream = npz.getInputStream(e);
|
||||
java.nio.channels.ReadableByteChannel channel = Channels.newChannel(stream)) {
|
||||
return Npy.read(channel);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("failed to read entry " + entry, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the given file as an NPZ file. This function is useful when you want
|
||||
* to do multiple things with a NPZ file, e.g.
|
||||
@ -183,15 +151,4 @@ public class Npz {
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(ZipOutputStream npz, String entry, NpyArray<?> array) {
|
||||
ZipEntry e = new ZipEntry(entry);
|
||||
try {
|
||||
npz.putNextEntry(e);
|
||||
Npy.write(npz, array);
|
||||
npz.closeEntry();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("failed to write NPZ entry: " + entry, ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,197 +0,0 @@
|
||||
package org.meteoinfo.ndarray.io.npy;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
class OrderSwitch2d<T extends NpyArray<?>> {
|
||||
|
||||
private final T array;
|
||||
private final int rows;
|
||||
private final int cols;
|
||||
|
||||
private OrderSwitch2d(T array) {
|
||||
this.array = array;
|
||||
this.rows = Array2d.rowCountOf(array);
|
||||
this.cols = Array2d.columnCountOf(array);
|
||||
}
|
||||
|
||||
static <T extends NpyArray<?>> T of(T array) {
|
||||
return new OrderSwitch2d<T>(array).apply();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T apply() {
|
||||
if (array.isBigIntegerArray())
|
||||
return (T) switchBigInts((NpyBigIntArray) array);
|
||||
if (array.isBooleanArray())
|
||||
return (T) switchBooleans(array.asBooleanArray());
|
||||
if (array.isByteArray())
|
||||
return (T) switchBytes(array.asByteArray());
|
||||
if (array.isCharArray())
|
||||
return (T) switchChars(array.asCharArray());
|
||||
if (array.isDoubleArray())
|
||||
return (T) switchDoubles(array.asDoubleArray());
|
||||
if (array.isFloatArray())
|
||||
return (T) switchFloats(array.asFloatArray());
|
||||
if (array.isIntArray())
|
||||
return (T) switchInts(array.asIntArray());
|
||||
if (array.isLongArray())
|
||||
return (T) switchLongs(array.asLongArray());
|
||||
if (array.isShortArray())
|
||||
return (T) switchShorts(array.asShortArray());
|
||||
|
||||
throw new IllegalArgumentException("unsupported array type: " + array);
|
||||
}
|
||||
|
||||
private NpyBigIntArray switchBigInts(NpyBigIntArray a) {
|
||||
BigInteger[] data = a.data;
|
||||
BigInteger[] newData = new BigInteger[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
BigInteger value = data[pos];
|
||||
if (value == null)
|
||||
return;
|
||||
newData[newPos] = value; // BigInts are immutable; so this is fine
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyBigIntArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyBigIntArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyBooleanArray switchBooleans(NpyBooleanArray a) {
|
||||
boolean[] data = a.data;
|
||||
boolean[] newData = new boolean[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
boolean value = data[pos];
|
||||
if (!value)
|
||||
return;
|
||||
newData[newPos] = true;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyBooleanArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyBooleanArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyByteArray switchBytes(NpyByteArray a) {
|
||||
byte[] data = a.data;
|
||||
byte[] newData = new byte[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
byte value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyByteArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyByteArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyCharArray switchChars(NpyCharArray a) {
|
||||
char[] data = a.data;
|
||||
char[] newData = new char[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
char value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? new NpyCharArray(new int[]{rows, cols}, newData, false)
|
||||
: new NpyCharArray(new int[]{rows, cols}, newData, true);
|
||||
}
|
||||
|
||||
private NpyDoubleArray switchDoubles(NpyDoubleArray a) {
|
||||
double[] data = a.data;
|
||||
double[] newData = new double[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
double value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyDoubleArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyDoubleArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyFloatArray switchFloats(NpyFloatArray a) {
|
||||
float[] data = a.data;
|
||||
float[] newData = new float[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
float value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyFloatArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyFloatArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyIntArray switchInts(NpyIntArray a) {
|
||||
int[] data = a.data;
|
||||
int[] newData = new int[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
int value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyIntArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyIntArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyLongArray switchLongs(NpyLongArray a) {
|
||||
long[] data = a.data;
|
||||
long[] newData = new long[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
long value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyLongArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyLongArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private NpyShortArray switchShorts(NpyShortArray a) {
|
||||
short[] data = a.data;
|
||||
short[] newData = new short[data.length];
|
||||
iter((pos, newPos) -> {
|
||||
short value = data[pos];
|
||||
if (value == 0)
|
||||
return;
|
||||
newData[newPos] = value;
|
||||
});
|
||||
return a.hasColumnOrder()
|
||||
? NpyShortArray.rowOrderOf(newData, rows, cols)
|
||||
: NpyShortArray.columnOrderOf(newData, rows, cols);
|
||||
}
|
||||
|
||||
private void iter(IndexFn fn) {
|
||||
int pos = 0;
|
||||
if (array.hasColumnOrder()) {
|
||||
for (int col = 0; col < cols; col++) {
|
||||
for (int row = 0; row < rows; row++) {
|
||||
int newPos = row * cols + col;
|
||||
fn.accept(pos, newPos);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int row = 0; row < rows; row++) {
|
||||
for (int col = 0; col < cols; col++) {
|
||||
int newPos = col * rows + row;
|
||||
fn.accept(pos, newPos);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface IndexFn {
|
||||
void accept(int pos, int newPos);
|
||||
}
|
||||
|
||||
}
|
||||
@ -41,7 +41,7 @@ public final class AttributeTable implements Cloneable {
|
||||
private int _headerLength;
|
||||
private int _recordLength;
|
||||
private int _numFields;
|
||||
private List<Field> _columns;
|
||||
private List<Field> fields;
|
||||
private byte _fileType;
|
||||
private EndianDataOutputStream _writer;
|
||||
private File _file;
|
||||
@ -87,7 +87,7 @@ public final class AttributeTable implements Cloneable {
|
||||
private void configure() {
|
||||
_fileType = 0x03;
|
||||
_dataTable = new DataTable();
|
||||
_columns = new ArrayList<>();
|
||||
fields = new ArrayList<>();
|
||||
_attributesPopulated = true; // only turn this false during an "open" method
|
||||
_deletedRows = new ArrayList<>();
|
||||
_characterContent = new char[1];
|
||||
@ -263,7 +263,7 @@ public final class AttributeTable implements Cloneable {
|
||||
_numFields = (_headerLength - FileDescriptorSize - 1) / FileDescriptorSize;
|
||||
|
||||
// _numFields = (_headerLength - FileDescriptorSize) / FileDescriptorSize;
|
||||
_columns = new ArrayList<>();
|
||||
fields = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < _numFields; i++) {
|
||||
arr = new byte[18];
|
||||
@ -304,7 +304,7 @@ public final class AttributeTable implements Cloneable {
|
||||
Field myField = new Field(name, Code, tempLength, decimalcount);
|
||||
//myField.DataAddress = dataAddress; // not sure what this does yet
|
||||
|
||||
_columns.add(myField); // Store fields accessible by an index
|
||||
fields.add(myField); // Store fields accessible by an index
|
||||
_dataTable.getColumns().add(myField);
|
||||
}
|
||||
|
||||
@ -416,7 +416,7 @@ public final class AttributeTable implements Cloneable {
|
||||
|
||||
for (int col = 0; col < _dataTable.getColumns().size(); col++) {
|
||||
// find the length of the field.
|
||||
Field CurrentField = _columns.get(col);
|
||||
Field CurrentField = fields.get(col);
|
||||
|
||||
// find the field type
|
||||
char tempFieldType = CurrentField.getTypeCharacter();
|
||||
@ -494,6 +494,19 @@ public final class AttributeTable implements Cloneable {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a field
|
||||
*
|
||||
* @param field The field to be added
|
||||
*/
|
||||
public void addField(Field field) {
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<>();
|
||||
}
|
||||
fields.add(field);
|
||||
this._dataTable.addColumn(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the file
|
||||
*/
|
||||
@ -565,13 +578,13 @@ public final class AttributeTable implements Cloneable {
|
||||
_numRecords = this._dataTable.getRows().size();
|
||||
_updateDate = LocalDateTime.now();
|
||||
_headerLength = FileDescriptorSize + FileDescriptorSize * _dataTable.getColumns().size() + 1;
|
||||
if (_columns == null) {
|
||||
_columns = new ArrayList<>();
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<>();
|
||||
}
|
||||
// Delete any fields from the columns list that are no
|
||||
// longer in the data Table.
|
||||
List<Field> removeFields = new ArrayList<>();
|
||||
for (Field fld : _columns) {
|
||||
for (Field fld : fields) {
|
||||
if (!_dataTable.getColumnNames().contains(fld.getColumnName())) {
|
||||
removeFields.add(fld);
|
||||
} else {
|
||||
@ -579,7 +592,7 @@ public final class AttributeTable implements Cloneable {
|
||||
}
|
||||
}
|
||||
for (Field field : removeFields) {
|
||||
_columns.remove(field);
|
||||
fields.remove(field);
|
||||
}
|
||||
|
||||
// Add new columns that exist in the data Table, but don't have a matching field yet.
|
||||
@ -588,28 +601,23 @@ public final class AttributeTable implements Cloneable {
|
||||
if (columnNameExists(dc.getColumnName())) {
|
||||
continue;
|
||||
}
|
||||
// Field fld = (Field) dc;
|
||||
// if (fld == null) {
|
||||
// fld = new Field(dc);
|
||||
// }
|
||||
|
||||
Field fld = new Field(dc);
|
||||
|
||||
tempColumns.add(fld);
|
||||
}
|
||||
}
|
||||
|
||||
_columns = tempColumns;
|
||||
fields = tempColumns;
|
||||
|
||||
// Recalculate the recordlength
|
||||
for (Field fld : _columns) {
|
||||
for (Field fld : fields) {
|
||||
//_recordLength = _recordLength + fld.Length + 1;
|
||||
_recordLength = _recordLength + fld.getLength();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean columnNameExists(String name) {
|
||||
for (Field fld : _columns) {
|
||||
for (Field fld : fields) {
|
||||
if (fld.getColumnName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
@ -647,8 +655,8 @@ public final class AttributeTable implements Cloneable {
|
||||
|
||||
// write all of the header records
|
||||
Field currentField;
|
||||
for (int i = 0; i < _columns.size(); i++) {
|
||||
currentField = _columns.get(i);
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
currentField = fields.get(i);
|
||||
// write the field name
|
||||
byte[] bytes = currentField.getColumnName().getBytes(this.encoding);
|
||||
for (int j = 0; j < 11; j++) {
|
||||
@ -695,8 +703,8 @@ public final class AttributeTable implements Cloneable {
|
||||
//int len = _recordLength - 1;
|
||||
StringBuffer tmps;
|
||||
//String s;
|
||||
for (int fld = 0; fld < _columns.size(); fld++) {
|
||||
Field currentField = _columns.get(fld);
|
||||
for (int fld = 0; fld < fields.size(); fld++) {
|
||||
Field currentField = fields.get(fld);
|
||||
String name = currentField.getColumnName();
|
||||
|
||||
Object columnValue = _dataTable.getRows().get(row).getValue(name);
|
||||
@ -727,11 +735,15 @@ public final class AttributeTable implements Cloneable {
|
||||
case 'n':
|
||||
// int?
|
||||
String fs;
|
||||
if (currentField.getDataType() == DataType.INT) {
|
||||
fs = String.format("%1$" + String.valueOf(currentField.getLength()) + "d", columnValue);
|
||||
} else {
|
||||
fs = String.format("%1$" + String.valueOf(currentField.getLength()) + "."
|
||||
+ String.valueOf(currentField.getDecimalCount()) + "f", columnValue);
|
||||
switch (currentField.getDataType()) {
|
||||
case INT:
|
||||
case LONG:
|
||||
fs = String.format("%1$" + String.valueOf(currentField.getLength()) + "d", columnValue);
|
||||
break;
|
||||
default:
|
||||
fs = String.format("%1$" + String.valueOf(currentField.getLength()) + "."
|
||||
+ String.valueOf(currentField.getDecimalCount()) + "f", columnValue);
|
||||
break;
|
||||
}
|
||||
if (fs.length() > currentField.getLength()) {
|
||||
fs = fs.substring(0, currentField.getLength());
|
||||
|
||||
@ -254,6 +254,8 @@ public class DataColumn {
|
||||
switch (this.dataType) {
|
||||
case INT:
|
||||
return Integer.MIN_VALUE;
|
||||
case LONG:
|
||||
return Long.MIN_VALUE;
|
||||
case FLOAT:
|
||||
return Float.NaN;
|
||||
case DOUBLE:
|
||||
@ -275,6 +277,14 @@ public class DataColumn {
|
||||
return Integer.valueOf(vStr);
|
||||
}
|
||||
break;
|
||||
case LONG:
|
||||
if (!(value instanceof Long)) {
|
||||
String vStr = value.toString();
|
||||
if (vStr.isEmpty())
|
||||
return Long.MIN_VALUE;
|
||||
return Long.valueOf(vStr);
|
||||
}
|
||||
break;
|
||||
case DOUBLE:
|
||||
if (!(value instanceof Double)) {
|
||||
String vStr = value.toString();
|
||||
|
||||
@ -68,6 +68,7 @@ import org.meteoinfo.ndarray.DataType;
|
||||
fieldNumDec = 9;
|
||||
break;
|
||||
case INT:
|
||||
case LONG:
|
||||
fieldLen = 11;
|
||||
break;
|
||||
case BOOLEAN:
|
||||
@ -183,6 +184,7 @@ import org.meteoinfo.ndarray.DataType;
|
||||
return 'F';
|
||||
case DOUBLE:
|
||||
case INT:
|
||||
case LONG:
|
||||
return 'N';
|
||||
default:
|
||||
return 'C';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user