// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.io.ozi;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import org.openstreetmap.josm.data.SystemOfMeasurement;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.gpx.GpxConstants;
import org.openstreetmap.josm.data.gpx.GpxData;
import org.openstreetmap.josm.data.gpx.GpxTrack;
import org.openstreetmap.josm.data.gpx.WayPoint;
import org.openstreetmap.josm.io.IGpxReader;
import org.openstreetmap.josm.tools.Logging;
import org.xml.sax.SAXException;
/**
* Reads an OziExplorer Waypoint file. Based on information from
* https://www.oziexplorer4.com.
* @since 18179
*/
public class OziWptReader implements IGpxReader {
private static final int IDX_NAME = 1;
private static final int IDX_LAT = 2;
private static final int IDX_LON = 3;
private static final int IDX_DESC = 10;
private static final int IDX_ELE = 14;
private static final int INVALID_ELE = -777;
private final InputStream source;
private GpxData data;
private int success; // number of successfully parsed lines
/**
* Constructs a new {@code OziWptReader}
* @param source Ozi wpt file input stream
* @throws IOException if an I/O error occurs
*/
public OziWptReader(InputStream source) throws IOException {
this.source = Objects.requireNonNull(source);
}
@Override
public boolean parse(boolean tryToFinish) throws SAXException, IOException {
data = new GpxData();
Collection> currentTrack = new ArrayList<>();
Collection waypoints = new ArrayList<>();
try (BufferedReader rd = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
int linecount = 0;
String line;
do {
line = rd.readLine();
if (line != null) {
linecount++;
if (linecount == 1) {
if (!line.startsWith("OziExplorer Waypoint File")) {
throw new UnsupportedOperationException("Unsupported format: " + line);
}
} else if (linecount == 2) {
if (!"WGS 84".equals(line)) {
throw new UnsupportedOperationException("Unsupported datum: " + line);
}
} else if (linecount == 3 || linecount == 4) {
Logging.trace(line);
} else {
try {
String[] fields = line.split(",");
WayPoint currentwp = new WayPoint(new LatLon(
Double.parseDouble(fields[IDX_LAT]),
Double.parseDouble(fields[IDX_LON])));
currentwp.put(GpxConstants.GPX_NAME, fields[IDX_NAME]);
currentwp.put(GpxConstants.GPX_DESC, fields[IDX_DESC]);
String ele = fields[IDX_ELE];
if (!ele.isEmpty()) {
int eleInFeet = Integer.parseInt(ele);
if (eleInFeet != 0 && eleInFeet != INVALID_ELE) {
currentwp.put(GpxConstants.PT_ELE, eleInFeet * SystemOfMeasurement.IMPERIAL.aValue);
}
}
waypoints.add(currentwp);
success++;
} catch (IllegalArgumentException e) {
Logging.error(e);
}
}
}
} while (line != null);
}
currentTrack.add(waypoints);
data.tracks.add(new GpxTrack(currentTrack, Collections.emptyMap()));
return true;
}
@Override
public GpxData getGpxData() {
return data;
}
@Override
public int getNumberOfCoordinates() {
return success;
}
}