Skip to content

Commit

Permalink
Expand parsing of text files and content display in viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
gwlucastrig committed Dec 12, 2023
1 parent 3143c7c commit 8e2ca74
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 21 deletions.
27 changes: 25 additions & 2 deletions core/src/main/java/org/tinfour/utils/loaders/VertexReaderText.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ public List<Vertex> read(IMonitorWithCancellation monitor) throws IOException {
List<Vertex> readDelimitedFile(File file, char delimiter)
throws IOException {

// The header logic includes special rules for columns giving z
// values including "depth" and "elevation". But "z" is preferred
// over depth and elevation. So the z-alternate flag values will be used
// only if z values are not set.
try (DelimitedReader dlim = new DelimitedReader(file, delimiter)) {
List<String> sList = dlim.readStrings();
List<Vertex> vList = new ArrayList<>();
Expand All @@ -200,16 +204,24 @@ List<Vertex> readDelimitedFile(File file, char delimiter)
int yColumn = 1;
int zColumn = 2;
int iColumn = -1;
int zAltColumn = -1;
int nColumnsRequired = 3;
boolean geoText = false;
boolean xFound = false;
boolean yFound = false;
boolean zFound = false;
boolean zAltFound = false;
int k = 0;
for (String s : sList) {
String sLower = s.toLowerCase();
char c = s.charAt(0);
if (Character.isAlphabetic(c) || c == '_') {
headerRow = true;
int n = k + 1;
if(sLower.contains("acc")||sLower.contains("err")||sLower.contains("certain")){
// skip columns that give "accuracy", "error", or "uncertainty"
continue;
}
if ("x".equalsIgnoreCase(s)) {
xFound = true;
xColumn = k;
Expand All @@ -223,17 +235,24 @@ List<Vertex> readDelimitedFile(File file, char delimiter)
nColumnsRequired = n;
}
} else if ("z".equalsIgnoreCase(s)) {
zFound=true;
zColumn = k;
if (n > nColumnsRequired) {
nColumnsRequired = n;
}
} else if (s.toLowerCase().startsWith("lon")) {
} else if (sLower.startsWith("depth")|| sLower.startsWith("elev")) {
zAltFound=true;
zAltColumn = k;
if (n > nColumnsRequired) {
nColumnsRequired = n;
}
} else if (sLower.startsWith("lon")) {
geoText = true;
xColumn = k;
if (n > nColumnsRequired) {
nColumnsRequired = n;
}
} else if (s.toLowerCase().startsWith("lat")) {
} else if (sLower.startsWith("lat")) {
geoText = true;
yColumn = k;
if (n > nColumnsRequired) {
Expand All @@ -246,6 +265,10 @@ List<Vertex> readDelimitedFile(File file, char delimiter)
k++;
}

if(!zFound && zAltFound){
zColumn = zAltColumn;
}

int iVertex = 0;
// The first row gets special processing. If there was a header
// row, we still haven't read any data (just the header)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ private boolean isDragAcceptable(DropTargetDragEvent dtde) {
return true;
} else if (".SHP".equalsIgnoreCase(ext)) {
return true;
} else if(".XYZ".equalsIgnoreCase(ext)){
return true;
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
package org.tinfour.demo.viewer.backplane;

import java.awt.geom.AffineTransform;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities;
import org.tinfour.common.IMonitorWithCancellation;
Expand Down Expand Up @@ -60,7 +63,7 @@ public BackplaneManager(DataViewingPanel viewingPanel, StatusPanel statusPanel)
renderPool = new BackplaneExecutor(0); // size determined by CPU
loaderQueue = new BackplaneExecutor(1);
}


public void postStatusMessage(int index, final String message) {
statusPanel.postMessage(index, message);
Expand Down Expand Up @@ -170,9 +173,14 @@ public IModel loadModel(File file, String option) {
model = new ModelFromText(file );
} else if ("SHP".equalsIgnoreCase(ext)) {
model = new ModelFromShapefile(file, option);
} else if (isTextFile(file)) {
// although the file does not hava a recognized extension,
// the program may still be able to process it because it is
// likely to be a text file.
model = new ModelFromText(file);
} else {
postStatusMessage(taskIndex, "Unrecognized file extension " + ext);
return null;
postStatusMessage(taskIndex, "Unrecognized file extension " + ext);
return null;
}

postStatusMessage(taskIndex, "Loading " + name);
Expand All @@ -181,6 +189,41 @@ public IModel loadModel(File file, String option) {
return model;
}

/**
* Performs an inspection of a file to see if it may be a text
* file. The acceptance criteria is limited to European character sets.
* Within that context, it accepts alphabetic and punctuation characters
* on the theory that these may be labels. This method does not support
* Unicode encodings of more than one byte because it is intended as
* a test of data that can be parsed by existing Tinfour classes.
* @param file a valid file object
* @return true if the file is likely to be a text file; otherwise, false
*/
private boolean isTextFile(File file) {
try (
FileInputStream fos = new FileInputStream(file);
BufferedInputStream bos = new BufferedInputStream(fos)) {
int c;
while ((c = bos.read()) >= 0) {
// the following will accept letters, digits, whitespace,
// and punctuation. It will also accept some other characters,
// but we'll allow that in support of text-based labels,
// particularly those not given in legacy ASCII.
if (!(Character.isWhitespace(c)
|| c >= 32 && c <= 127 // Traditional ASCII character set
|| c >= 0xA0 && c<=0xFF // ISO 8859-1 European character set
)) {
return false;
}
}
} catch (IOException ioex) {
return false;
}

return true;
}


public MvComposite queueConstraintLoadingTask(
IModel model, File file, CompositeImageScale ccs, String optionString) {
cancelRenderingTasks();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,25 +378,31 @@ public String getFormattedCoordinates(double x, double y) {
@Override
public String getFormattedX(double x) {
if (coordinateTransform instanceof SimpleGeographicTransform) {
// in the simple-geographic transform, x and y are independent.
// So supply an arbitrary value (zero) for unused coordinate.
CoordinatePair cPair = new CoordinatePair();
if (coordinateTransform.inverse(x, 0, cPair)) {
StringBuilder sb = new StringBuilder();
Formatter fmt = new Formatter(sb);
fmt.format("%11.2f ", x);
fmtGeo(fmt, cPair.x, false);
return sb.toString();
}
}
return String.format("%11.2f", x);
}


@Override
public String getFormattedY(double y) {
if (coordinateTransform instanceof SimpleGeographicTransform) {
// in the simple-geographic transform, x and y are independent.
// So supply an arbitrary value (zero) for unused coordinate.
CoordinatePair cPair = new CoordinatePair();
if (coordinateTransform.inverse(0, y, cPair)) {
StringBuilder sb = new StringBuilder();
Formatter fmt = new Formatter(sb);
fmt.format("%11.2f ", y);
fmtGeo(fmt, cPair.y, false);
return sb.toString();
}
Expand Down Expand Up @@ -618,8 +624,8 @@ public boolean hasConstraintsSource() {
public boolean areConstraintsLoaded() {
return hasConstraints(); // probably to be deprecated.
}


@Override
public ICoordinateTransform getCoordinateTransform(){
return coordinateTransform;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,21 @@
*/
public class ModelFromText extends ModelAdapter implements IModel {
final char delimiter;

/**
* Construct a model tied to the specified file.
* <p>
* <strong>Delimiters</strong>
* Specifications in text files depend on the presence of a delimiter
* character to separate data fields given on a single line.
* Typically delimiters are specified using a space, tab, comma,
* or pipe (vertical bar character). Files with the extension
* Typically delimiters are specified using a space, tab, comma,
* or pipe (vertical bar character). Files with the extension
* ".csv" (for comma-separated-value) are assumed to be comma-delimited.
* Otherwise, the constructor will attempt to inspect the content
* of the specified file and determine the delimiter based on internal
* clues. If a file includes a mix of potential delimiters,
* such as both spaces and commas, the delimiter will be determined
* on the basis of precedence (in increasing order, space, tab,
* on the basis of precedence (in increasing order, space, tab,
* comma, and pipe).
* <p>An application may also override the automatically determined
* delimiter through the setDelimiter() method.
Expand All @@ -83,8 +83,8 @@ public class ModelFromText extends ModelAdapter implements IModel {
*/
public ModelFromText(File file) {
super(file);
// TO DO: Right now, this constructur does not throw an IOException,

// TO DO: Right now, this constructor does not throw an IOException,
// but it should.
char test = 0;
try (VertexReaderText reader = new VertexReaderText(file)) {
Expand All @@ -108,17 +108,17 @@ public ModelFromText(File file) {
@Override
public void load(IMonitorWithCancellation monitor) throws IOException {


if (areVerticesLoaded) {
System.out.println("Internal error, multiple calls to load model");
return;
}
VertexReaderText reader = new VertexReaderText(file);
long time0 = System.currentTimeMillis();


List<Vertex>list =reader.read (monitor );

if (list.isEmpty()) {
monitor.reportDone(); // remove the progress bar
throw new IOException("Unable to read points from file");
Expand All @@ -133,7 +133,7 @@ public void load(IMonitorWithCancellation monitor) throws IOException {

geographicCoordinates = reader.isSourceInGeographicCoordinates();
if (geographicCoordinates) {

coordinateTransform = reader.getCoordinateTransform();
}

long time1 = System.currentTimeMillis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,7 @@ public MvQueryResult performQuery(double x, double y) {
double z = interpolator.interpolate(SurfaceModel.QuadraticWithCrossTerms,
BandwidthSelectionMethod.OptimalAICc, 1.0,
mx, my, null);
String q = model.getFormattedX(mx);
fmt.format("X: %s%n", model.getFormattedX(mx));
fmt.format("Y: %s%n", model.getFormattedY(my));
if (queryIsOutside) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ void read(BufferedRandomAccessReader brad, long recordFilePos) throws IOExceptio
// a non-whitespace character. at this time,
// the meaning of this is unknown.
value = Double.NaN;
builder.setLength(0);
return;
}
}

if(i==fieldLength){
value = Double.NaN;
builder.setLength(0);
return;
}

Expand Down
8 changes: 7 additions & 1 deletion gis/src/main/java/org/tinfour/gis/shapefile/DbfFieldInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,20 @@ void read(BufferedRandomAccessReader brad, long recordFilePos) throws IOExceptio
// a non-whitespace character. at this time,
// the meaning of this is unknown.
value = 0;
builder.setLength(0);
if(b=='*'){
return;
}
throw new IOException(
"Invalid integer value, unknown character "
+ ((char) b));
}
}

if (!foundDigit) {
throw new IOException("Invalid integer value, blank field");
value = 0;
builder.setLength(0);
return;
}

// process the non-fractional part
Expand Down
18 changes: 18 additions & 0 deletions svm/src/main/java/org/tinfour/svm/SvmMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ public boolean accept(File file, String name) {
}
}

private static void printLicenseAndDisclaimer(PrintStream ps){
try (
InputStream ins
= SvmMain.class.getResourceAsStream("LicenseAndDisclaimer.txt");) {
int c;
while ((c = ins.read()) >= 0) {
ps.append((char) c);
}
System.out.flush();
} catch (IOException ioex) {
System.err.println("Failed to load template " + ioex.getMessage());
}
}


private SvmMain() {
// constructor scoped to private to deter application code
// from creating instances of this class.
Expand All @@ -171,6 +186,7 @@ public static void main(String[] args) throws IOException {
checkForTemplate(args);
checkForInspection(args);

printLicenseAndDisclaimer(System.out);
Date dateOfAnalysis = new Date(); // set to clock time
writeIntroduction(System.out, dateOfAnalysis);
SvmProperties prop = SvmProperties.load(args);
Expand Down Expand Up @@ -236,6 +252,7 @@ public static void main(String[] args) throws IOException {
reportOutputStream = new FileOutputStream(reportFile);
BufferedOutputStream bos = new BufferedOutputStream(reportOutputStream);
reportPrintStream = new PrintStream(bos, true, StandardCharsets.UTF_8.name());
printLicenseAndDisclaimer(reportPrintStream);
writeIntroduction(reportPrintStream, dateOfAnalysis);
prop.writeSummary(reportPrintStream);
reportPrintStream.flush();
Expand All @@ -258,6 +275,7 @@ private static void writeIntroduction(PrintStream ps, Date date) {
Locale locale = Locale.getDefault();
SimpleDateFormat sdFormat = new SimpleDateFormat("dd MMM yyyy HH:mm", locale);
sdFormat.setTimeZone(new SimpleTimeZone(0, "UTC"));
ps.println("");
ps.println("Simple Volumetric Model (Version 1.0 beta)");
ps.println("");
ps.println("Date of analysis: " + sdFormat.format(date) + " UTC");
Expand Down

0 comments on commit 8e2ca74

Please sign in to comment.