119 lines
3.2 KiB
Java
119 lines
3.2 KiB
Java
package geography;
|
|
|
|
import java.awt.geom.Rectangle2D;
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
|
|
import gui.CartographyDocument;
|
|
|
|
/**
|
|
* A class for reading geographic shapes from an input stream and creating a CartographyDocument
|
|
* containing those shapes.
|
|
*/
|
|
public class GeographicShapesReader
|
|
{
|
|
private BufferedReader in;
|
|
private MapProjection proj;
|
|
|
|
/**
|
|
* @param is
|
|
* The input stream to read the shapes from
|
|
* @param proj
|
|
* The map projection to use when converting geographic coordinates to Cartesian
|
|
* coordinates
|
|
*/
|
|
public GeographicShapesReader(final InputStream is, final MapProjection proj)
|
|
{
|
|
this.in = new BufferedReader(new InputStreamReader(is));
|
|
this.proj = proj;
|
|
}
|
|
|
|
/**
|
|
* @return A CartographyDocument containing the shapes read from the input stream.
|
|
*/
|
|
public CartographyDocument<GeographicShape> read()
|
|
{
|
|
double maxX = Double.NEGATIVE_INFINITY;
|
|
double maxY = Double.NEGATIVE_INFINITY;
|
|
double minX = Double.POSITIVE_INFINITY;
|
|
double minY = Double.POSITIVE_INFINITY;
|
|
|
|
Map<String, GeographicShape> shapes = new HashMap<>();
|
|
|
|
String currentLine;
|
|
try
|
|
{
|
|
while ((currentLine = in.readLine()) != null)
|
|
{
|
|
Map<String, String> parsed = new LinkedHashMap<>();
|
|
String[] tokens = currentLine.trim().split("(?=Type:|ID:|Code:)");
|
|
|
|
for (String token : tokens)
|
|
{
|
|
if (token.isBlank())
|
|
continue;
|
|
int colonIdx = token.indexOf(':');
|
|
String key = token.substring(0, colonIdx).trim();
|
|
String value = token.substring(colonIdx + 1).trim();
|
|
parsed.put(key, value);
|
|
}
|
|
|
|
String type = parsed.get("Type");
|
|
String id = parsed.get("ID");
|
|
|
|
PiecewiseLinearCurve shape;
|
|
|
|
switch (type)
|
|
{
|
|
case "PiecewiseLinearCurve":
|
|
shape = new PiecewiseLinearCurve(id);
|
|
break;
|
|
case "Polygon":
|
|
shape = new Polygon(id);
|
|
break;
|
|
case "Comment":
|
|
in.readLine(); // skip the END
|
|
continue;
|
|
default:
|
|
return null;
|
|
}
|
|
|
|
while ((currentLine = in.readLine()) != null)
|
|
{
|
|
currentLine = currentLine.trim();
|
|
|
|
if (currentLine.equals("END"))
|
|
{
|
|
break;
|
|
}
|
|
|
|
String[] strCoords = currentLine.trim().split("\\s+");
|
|
double[] coords = new double[] {Double.parseDouble(strCoords[0]),
|
|
Double.parseDouble(strCoords[1])};
|
|
|
|
double[] projCoords = proj.forward(coords);
|
|
shape.add(projCoords);
|
|
|
|
maxX = Math.max(maxX, projCoords[0]);
|
|
maxY = Math.max(maxY, projCoords[1]);
|
|
minX = Math.min(minX, projCoords[0]);
|
|
minY = Math.min(minY, projCoords[1]);
|
|
}
|
|
shapes.put(id, shape);
|
|
}
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
|
|
Rectangle2D.Double bounds = new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
|
|
return new CartographyDocument<>(shapes, bounds);
|
|
}
|
|
}
|