All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fudaa.dodico.telemac.io.MatisseReader Maven / Gradle / Ivy

The newest version!
/**
 * @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;

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy