org.fudaa.dodico.telemac.io.MatisseReader Maven / Gradle / Ivy
/**
* @creation 2002-11-20
* @modification $Date: 2007-05-04 13:47:27 $
* @license GNU General Public License 2
* @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne
* @mail [email protected]
*/
package org.fudaa.dodico.telemac.io;
import gnu.trove.TDoubleArrayList;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import org.fudaa.ctulu.CtuluActivity;
import org.fudaa.ctulu.CtuluAnalyze;
import org.fudaa.ctulu.CtuluLibMessage;
import org.fudaa.ctulu.fileformat.FileReadOperationAbstract;
import org.fudaa.ctulu.fileformat.FortranInterface;
import org.fudaa.ctulu.gis.GISCoordinateSequence;
import org.fudaa.ctulu.gis.GISGeometryFactory;
import org.fudaa.ctulu.gis.GISPoint;
import org.fudaa.ctulu.gis.GISPolygone;
import org.fudaa.ctulu.gis.GISPolyligne;
import org.fudaa.ctulu.gis.GISZone;
import org.fudaa.ctulu.gis.GISZoneCollectionPoint;
import org.fudaa.dodico.commun.DodicoLib;
import org.fudaa.dodico.fichiers.NativeBinarySystem;
import org.fudaa.dodico.fortran.FortranBinaryInputStream;
import org.fudaa.dodico.h2d.resource.H2dResource;
/**
* lecture d'un fichier serafin. Les donnees sont enregistrees en tant que double par simplicite. Les donnees de la
* deuxieme discretisation sont ignorees. Attention : la numerotation des tableaux commencent a 0 (java!!!).
*
* @version $Id: MatisseReader.java,v 1.24 2007-05-04 13:47:27 deniger Exp $
* @author Fred Deniger
*/
public class MatisseReader extends FileReadOperationAbstract implements CtuluActivity {
private ByteOrder byteOrder_;
BufferedInputStream in_;
boolean stop_;
long totalSize_;
public MatisseReader() {
byteOrder_ = NativeBinarySystem.getNativeByteOrder();
}
/**
* @param _idx l'index a tester
* @param _maxIdx l'index max
* @return true si invalide
*/
private boolean formatInvalid(final int _idx, final int _maxIdx) {
if ((_idx < 0) || (_idx >= _maxIdx)) {
analyze_.addFatalError(DodicoLib.getS("invalid data"));
return true;
}
return false;
}
/**
* Lecture du flux entrant ( utilise un BufferedInputStream). Les erreur graves (bloquantes) sont renvoyees sous forme
* d' IOException. Les erreurs non bloquantes sont renvoy�es par la methode. Le flux est ferme a la fin.
*
* @return Description des erreurs non bloquantes rencontrees ( null si aucune erreur).
*/
private synchronized GISZone readMatisse() {
final GISZone r = new GISZone();
try {
FortranBinaryInputStream in = new FortranBinaryInputStream(in_, false, byteOrder_);
// TITRE
// Lecture du titre
// je ne sais pas a quoi sert les 5 premier bytes
// in.skipBytes(5);
// System.out.println(in.readCharacter(5));
// System.out.println(in.readFloat32());
in_.mark(5);
/* int v1 = */in.readInt8();
int v2 = in.readInteger();
if (v2 > 2) {
// System.out.println("changement de format binaire");
if (byteOrder_.equals(ByteOrder.LITTLE_ENDIAN)) {
byteOrder_ = ByteOrder.BIG_ENDIAN;
} else {
byteOrder_ = ByteOrder.LITTLE_ENDIAN;
}
in_.reset();
in = new FortranBinaryInputStream(in_, false, byteOrder_);
/* v1 = */in.readInt8();
v2 = in.readInteger();
if (v2 > 2) {
analyze_.addFatalError(H2dResource.getS("Version de matisse inconnue"));
}
}
// in.skipBytes(1);
//
final int nbPoint = in.readInteger();
final int nbLigne = in.readInteger();
// A decommenter des que l'on sait comment g�rer les zones
// final int nbZone = v1 > 1 ? in.readInteger() : 0;
if (v2 > 1) {
in.readInteger();
}
final int nbSemis = in.readInteger();
final int nbDonnees = in.readInteger();
int temp, idx;
for (int i = nbDonnees - 1; i >= 0; i--) {
temp = in.readInteger();
in.readCharacter(temp);
// marqueur
in.readUInt16();
// couleur
in.readInteger();
if (stop_) {
return null;
}
}
updateProg(in.positionCourante());
final GISPoint[] pts = new GISPoint[nbPoint];
for (int i = 0; i < nbPoint; i++) {
pts[i] = new GISPoint(in.readDoublePrecision(), in.readDoublePrecision(), in.readDoublePrecision());
updateProg(in.positionCourante());
if (stop_) {
return null;
}
}
for (int i = 0; i < nbSemis; i++) {
if (stop_) {
return null;
}
// Le nombre de point
// MNTSemis semis = z.getSemis();
// a quoi correspond cet entier ?
in.readInteger();
final int nbPt = in.readInteger();
final List l = new ArrayList(nbPt);
for (int j = 0; j < nbPt; j++) {
if (stop_) {
return null;
}
idx = in.readInteger();
if (!formatInvalid(idx, nbPoint)) {
l.add(pts[idx]);
}
updateProg(in.positionCourante());
}
final GISZoneCollectionPoint zpt = r.createPointContainer(l.size());
zpt.addAll((GISPoint[]) l.toArray(new GISPoint[l.size()]), null, null);
}
if (nbLigne > 0) {
readLines(in, r, nbPoint, nbLigne, pts);
if (stop_) {
return null;
}
}
} catch (final IOException _e) {
analyze_.manageException(_e);
return null;
}
return r;
}
private void readLines(final FortranBinaryInputStream _in, final GISZone _r, final int _nbPoint, final int _nbLigne,
final GISPoint[] _pts) throws IOException {
final List polyg = new ArrayList();
final List polyl = new ArrayList();
for (int i = 0; i < _nbLigne; i++) {
if (stop_) {
return;
}
// inutile pour l'instant
/* int id = */_in.readInteger();
final int nature = _in.readInteger();
// inutile pour l'instant
/* int type = */_in.readInteger();
/* int contour = */_in.readInteger();
final int ferme = _in.readInteger();
if (nature != 0) {
_in.readDoublePrecision();
_in.readDoublePrecision();
_in.readInteger();
_in.readDoublePrecision();
_in.readDoublePrecision();
_in.readDoublePrecision();
}
final boolean isPolygone = (ferme == 1);
final int temp = _in.readInteger();
if (temp > 0) {
final TDoubleArrayList xyz = new TDoubleArrayList(temp * 3);
for (int j = 0; j < temp; j++) {
if (stop_) {
return;
}
if (nature == 0) {
_in.readInteger();
}
final int idx = _in.readInteger();
if (!formatInvalid(idx, _nbPoint)) {
final GISPoint pt = _pts[idx];
xyz.add(pt.getX());
xyz.add(pt.getY());
xyz.add(pt.getZ());
}
updateProg(_in.positionCourante());
}
if (xyz.size() >= 6) {
if (isPolygone) {
final double x = xyz.get(0);
final double y = xyz.get(1);
final double z = xyz.get(2);
xyz.add(x);
xyz.add(y);
xyz.add(z);
polyg.add(GISGeometryFactory.INSTANCE.createLinearRing(new GISCoordinateSequence(xyz)));
} else {
polyl.add(GISGeometryFactory.INSTANCE.createLineString(new GISCoordinateSequence(xyz)));
}
}
}
updateProg(_in.positionCourante());
}
if (polyg.size() > 0) {
_r.createPolygoneContainer(polyg.size()).addAllPolygones(
(GISPolygone[]) polyg.toArray(new GISPolygone[polyg.size()]), null);
}
if (polyl.size() > 0) {
_r.createPolyligneContainer(polyl.size()).addAllPolylignes(
(GISPolyligne[]) polyl.toArray(new GISPolyligne[polyl.size()]), null);
}
}
private void setFile(final BufferedInputStream _in) {
in_ = _in;
}
private void setFile(final InputStream _in) {
setFile(new BufferedInputStream(_in));
}
@Override
protected FortranInterface getFortranInterface() {
return new FortranInterface() {
@Override
public void close() throws IOException {
if (in_ != null) {
in_.close();
}
}
};
}
@Override
protected Object internalRead() {
return readMatisse();
}
protected void updateProg(final long _pos) {
if (progress_ == null || totalSize_ <= 0) {
return;
}
progress_.setProgression((int) (_pos * 100L / totalSize_));
}
@Override
public void setFile(final File _f) {
analyze_ = new CtuluAnalyze();
analyze_.setResource(_f.getAbsolutePath());
FileInputStream in = null;
try {
in = new FileInputStream(_f);
totalSize_ = _f.length();
} catch (final FileNotFoundException _e) {
if (CtuluLibMessage.DEBUG) {
_e.printStackTrace();
// analyze_.addFatalError(DodicoLib.geti18n("Fichier non trouv�"));
}
}
if (in != null) {
setFile(in);
}
}
/**
* @param _fs seul f[0] est recupere
*/
public void setFile(final File[] _fs) {
setFile(_fs[0]);
}
@Override
public void stop() {
stop_ = true;
}
}