/** @file ParserVisualTopo.java
*
* @author marco corvi
* @date mar 2015
*
* @brief TopoDroid VisualTopo parser
*
* --------------------------------------------------------
* Copyright This sowftare is distributed under GPL-3.0 or later
* See the file COPYING.
* ----------------------------------------------------------
*/
package com.topodroid.DistoX;
import java.io.File;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.Stack;
import java.util.regex.Pattern;
import android.util.Log;
public class ParserVisualTopo extends ImportParser
{
public ParserVisualTopo( String filename, boolean apply_declination ) throws ParserException
{
super( apply_declination );
int pos = filename.lastIndexOf( '/' ); ++pos;
int ext = filename.lastIndexOf( '.' ); if ( ext < 0 ) ext = filename.length();
mName = filename.substring( pos, ext );
readFile( filename );
}
private boolean isDuplicate( String flag )
{
if ( flag == null ) return false;
if ( flag.indexOf('L') >= 0 ) return true;
return false;
}
private boolean isSurface( String flag )
{
if ( flag == null ) return false;
if ( flag.indexOf('X') >= 0 ) return true;
return false;
}
float angle( float value, float unit, boolean dm )
{
if ( dm ) {
int sign = 1;
if ( value < 0 ) { sign = -1; value = -value; }
int iv = (int)value;
return sign * ( iv + (value-iv)*0.6f ); // 0.6 = 60/100
}
return value * unit;
}
/** read input file
* @param filename name of the file to parse
*/
@Override
void readFile( BufferedReader br ) throws ParserException
{
float mLength, mBearing, mClino, mLeft, mUp, mDown, mRight;
String mFlag=null, mFrom=null, mTo=null;
boolean dmb = false; // whether bearing is DD.MM
boolean dmc = false;
float ul = 1; // units factor [m]
float ub = 1; // dec.deg
float uc = 1; // dec.deg
int dirw = 1; // width direction
int dirb = 1; // bearing direction
int dirc = 1; // clino direction
boolean splayAtFrom = true;
String comment = "";
int extend = 1;
int shot_extend = 1;
boolean duplicate = false;
boolean surface = false;
boolean backshot = false;
String line = null;
try {
line = nextLine( br );
while ( line != null ) {
line = line.trim();
// Log.v("DistoX", "LINE: " + line );
if ( line.startsWith("[Configuration]") ) break;
int pos = line.indexOf(";");
if ( pos >= 0 ) {
comment = (pos+1<line.length())? line.substring( pos+1 ) : "";
line = line.substring( 0, pos );
comment.trim();
} else {
comment = "";
}
if ( line.length() == 0 ) { // comment
} else {
String[] vals = splitLine(line); // line.split( "\\s+" );
if ( line.startsWith("Version") ) {
// IGNORE
} else if ( line.startsWith("Trou") ) {
String[] params = line.substring(5).split(",");
if ( params.length > 0 ) {
mName = params[0].replaceAll(" ","_");
// TODO coordinates
}
} else if ( vals[0].equals("Param") ) {
for ( int k = 1; k < vals.length; ++k ) {
if ( vals[k].equals("Deca") ) {
if ( ++k < vals.length ) {
ub = 1;
dmb = false;
if ( vals[k].equals("Deg") ) {
dmb = true;
} else if ( vals[k].equals("Gra" ) ) {
ub = 0.9f; // 360/400
} else { // if ( vals[k].equals("Degd" )
/* nothing */
}
}
} else if ( vals[k].equals("Clino") ) {
if ( ++k < vals.length ) {
uc = 1;
dmc = false;
if ( vals[k].equals("Deg") ) {
dmc = true;
} else if ( vals[k].equals("Gra" ) ) {
uc = 0.9f; // 360/400
} else { // if ( vals[k].equals("Degd" )
/* nothing */
}
}
} else if ( vals[k].startsWith("Dir") || vals[k].startsWith("Inv") ) {
String[] dirs = vals[k].split(",");
if ( dirs.length == 3 ) {
dirb = ( dirs[0].equals("Dir") )? 1 : -1;
dirc = ( dirs[1].equals("Dir") )? 1 : -1;
dirw = ( dirs[2].equals("Dir") )? 1 : -1;
}
} else if ( vals[k].equals("Inc") ) {
// FIXME splay at next station: Which ???
splayAtFrom = false;
} else if ( vals[k].equals("Dep") ) {
splayAtFrom = true;
} else if ( vals[k].equals("Arr") ) {
splayAtFrom = false;
} else if ( vals[k].equals("Std") ) {
// standard colors; ignore
} else if ( k == 5 ) {
try {
mDeclination = angle( Float.parseFloat( vals[k] ), 1, true );
} catch ( NumberFormatException e ) { }
} else {
// ignore colors
}
}
} else if ( vals[0].equals("Entree") ) {
} else if ( vals[0].equals("Club") ) {
mTeam = line.substring(5);
} else if ( vals[0].equals("Couleur") ) {
// IGNORE
} else if ( vals[0].equals("Surface") ) {
// IGNORE
} else { // survey data
if ( vals.length >= 5 && ! vals[0].equals( vals[1] ) ) {
int k = 0;
mFrom = vals[k]; ++k; // 0
mTo = vals[k]; ++k; // 1
try {
mLength = Float.parseFloat(vals[k]) * ul; ++k; // 2
mBearing = angle( Float.parseFloat(vals[k]), ub, dmb); ++k; // 3
mClino = angle( Float.parseFloat(vals[k]), uc, dmc); ++k; // 5
mLeft = mRight = mUp = mDown = 0;
if ( k < vals.length ) {
mLeft = vals[k].equals("*")? -1 : Float.parseFloat(vals[k]) * ul; ++k; // 5
}
if ( k < vals.length ) {
mRight = vals[k].equals("*")? -1 : Float.parseFloat(vals[k]) * ul; ++k; // 6
}
if ( k < vals.length ) {
mUp = vals[k].equals("*")? -1 : Float.parseFloat(vals[k]) * ul; ++k; // 7
}
if ( k < vals.length ) {
mDown = vals[k].equals("*")? -1 : Float.parseFloat(vals[k]) * ul; ++k; // 8
}
shot_extend = 1;
if ( k < vals.length ) {
shot_extend = vals[k].equals("N")? 1 : -1; ++k; // 'N' or 'I'
}
duplicate = false;
if ( k < vals.length ) {
duplicate = vals[k].equals("E"); ++k; // 'I' or 'E'
}
String station = ( splayAtFrom ? mFrom : mTo );
extend = 0;
if ( mLeft > 0 ) {
float ber = mBearing + 180 + 90 * dirw;
if ( TDSetting.mLRExtend ) {
extend = (int)TDAzimuth.computeSplayExtend( ber );
}
// FIXME splays
shots.add( new ParserShot( station, EMPTY, mLeft, ber, 0.0f, 0.0f, extend, false, false, false, "" ) );
}
if ( mRight > 0 ) {
float ber = mBearing + 180 - 90 * dirw;
if ( ber > 360 ) ber -= 360;
if ( TDSetting.mLRExtend ) {
extend = (int)TDAzimuth.computeSplayExtend( ber );
}
// FIXME splays
shots.add( new ParserShot( station, EMPTY, mRight, ber, 0.0f, 0.0f, -extend, false, false, false, "" ) );
}
if ( mUp > 0 ) {
// FIXME splays
shots.add( new ParserShot( station, EMPTY, mUp, 0.0f, 90.0f, 0.0f, 0, false, false, false, "" ) );
}
if ( mDown > 0 ) {
// FIXME splays
shots.add( new ParserShot( station, EMPTY, mDown, 0.0f, -90.0f, 0.0f, 0, false, false, false, "" ) );
}
extend = ( mBearing < 90 || mBearing > 270 )? 1 : -1;
shots.add( new ParserShot( mFrom, mTo, mLength, mBearing, mClino, 0.0f,
shot_extend, duplicate, surface, backshot, comment ) );
} catch ( NumberFormatException e ) {
TDLog.Error( "ERROR " + mLineCnt + ": " + line + " " + e.getMessage() );
}
}
}
}
line = nextLine( br );
}
} catch ( IOException e ) {
// TODO
TDLog.Error( "ERROR " + mLineCnt + ": " + line );
throw new ParserException();
}
TDLog.Log( TDLog.LOG_THERION, "ParserVisualTopo shots "+ shots.size() +" splays "+ splays.size() );
// Log.v( "DistoX", "ParserVisualTopo shots "+ shots.size() + " splays "+ splays.size() );
}
float parseAngleUnit( String unit )
{
// not handled "percent"
if ( unit.startsWith("Min") ) return 1/60.0f;
if ( unit.startsWith("Grad") ) return (float)TopoDroidUtil.GRAD2DEG;
if ( unit.startsWith("Mil") ) return (float)TopoDroidUtil.GRAD2DEG;
// if ( unit.startsWith("Deg") ) return 1.0f;
return 1.0f;
}
float parseLengthUnit( String unit )
{
if ( unit.startsWith("c") ) return 0.01f; // cm centimeter
if ( unit.startsWith("f") ) return (float)TopoDroidUtil.FT2M; // ft feet
if ( unit.startsWith("i") ) return (float)TopoDroidUtil.IN2M; // in inch
if ( unit.startsWith("milli") || unit.equals("mm") ) return 0.001f; // mm millimeter
if ( unit.startsWith("y") ) return (float)TopoDroidUtil.YD2M; // yd yard
// if ( unit.startsWith("m") ) return 1.0f;
return 1.0f;
}
}