/**
* Copyright (c) 2009-2011, chunquedong(YangJiandong)
*
* This file is part of ChunMap project
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
*
* History:
* 2010-05-05 Jed Young Creation
*/
package chunmap.model.geom;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import chunmap.model.coord.Coordinate2D;
import chunmap.model.coord.CPoint;
import chunmap.model.coord.PrecisionModel;
import chunmap.model.elem.Envelope;
import chunmap.util.Logger;
import chunmap.util.LoggerTest;
/**
* 读取WKT字符串表示的几何体
*
* @author chunquedong
*
*/
public class WktReader {
private static final Logger Log = new Logger(Logger.Info,LoggerTest.class.getName());
private final PrecisionModel precision;
public WktReader() {
precision = PrecisionModel.getDoubleFloatModel();
}
public WktReader(PrecisionModel precision) {
this.precision = precision;
}
public PrecisionModel getPrecision() {
return precision;
}
public Geometry read(String text) {
try {
int tIndex = text.indexOf('(');
String type = text.substring(0, tIndex);
text = text.substring(tIndex);
if (type.equalsIgnoreCase("POINT"))
return new GeoPoint(getPoint(text));
else if (type.equalsIgnoreCase("LINESTRING"))
return getLineString(text);
else if (type.equalsIgnoreCase("POLYGON"))
return getPolygon(text);
else if (type.equalsIgnoreCase("MULTIPOINT"))
return getMultiPoint(text);
else if (type.equalsIgnoreCase("MULTILINESTRING"))
return getMultiPath(text);
else if (type.equalsIgnoreCase("MULTIPOLYGON"))
return getMultiPolygon(text);
else if (type.equalsIgnoreCase("GEOMETRYCOLLECTION"))
return getMultiGeometry(text);
else
throw new IllegalArgumentException("Unknow geometry");
} catch (Exception ex) {
WktParseException ex2 = new WktParseException();
ex2.initCause(ex);
throw ex2;
}
}
public Envelope readEnvelop(String text) {
try {
int tIndex = text.indexOf('(');
String type = text.substring(0, tIndex);
text = text.substring(tIndex);
if (type.equalsIgnoreCase("BOX")) {
String[] str = text.split(",");
CPoint p1 = getPoint(str[0]);
CPoint p2 = getPoint(str[1]);
return new Envelope(p1, p2);
} else
throw new IllegalArgumentException("Unknow geometry");
} catch (Exception ex) {
WktParseException ex2 = new WktParseException();
ex2.initCause(ex);
throw ex2;
}
}
// ------------------------------------------------------------
private CPoint getPoint(String text) {
text = text.trim();
text = removeBrackets(text);
return readPoint(text);
}
private CPoint readPoint(String text) {
text = text.trim();
int xIndex = text.indexOf(' ');
double x = Double.parseDouble(text.substring(0, xIndex));
double y = Double.parseDouble(text.substring(xIndex));
CPoint p = new Coordinate2D(x, y);
return p;
}
private LineString getLineString(String text) {
text = text.trim();
List<CPoint> points = readPointList(text);
return new LineString(points);
}
private List<CPoint> readPointList(String text) {
text = text.trim();
List<CPoint> points = new ArrayList<CPoint>();
String[] str = text.split(",");
for (String s : str) {
CPoint p = getPoint(s);
points.add(p);
}
return points;
}
private MultiGeometry<Geometry> getMultiGeometry(String text) {
text = text.trim();
text = text.substring(1, text.length() - 1);
List<Geometry> geos = new ArrayList<Geometry>();
String regEx = ",[A-Z]";
Pattern pat = Pattern.compile(regEx);
Matcher mat = pat.matcher(text);
int i = 0;
int j = 0;
while (mat.find()) {
j = mat.start();
String s = text.substring(i, j);
i = j + 1;
Log.log(Logger.Debug, s);
Geometry g = read(s);
geos.add(g);
}
Log.log(Logger.Debug, text.substring(i, text.length()));
Geometry g = read(text.substring(i, text.length()));
geos.add(g);
return new MultiGeometry<Geometry>(geos);
}
private Polygon getPolygon(String text) {
text = text.trim();
String[] str = text.split("\\),\\(");
List<Ring> rings = new ArrayList<Ring>();
for (String s : str) {
Ring r = getLineString(s).toLinearRing();
rings.add(r);
}
return new Polygon(rings.get(0), rings.subList(1, rings.size()));
}
private MultiPoint getMultiPoint(String text) {
text = text.trim();
List<CPoint> points = readPointList(text);
List<GeoPoint> geoPointList=new ArrayList<GeoPoint>();
for(CPoint p:points){
geoPointList.add(new GeoPoint(p));
}
return new MultiPoint(geoPointList);
}
private MultiLineString getMultiPath(String text) {
text = text.trim();
String[] str = text.split("\\),\\(");
List<LineString> lines = new ArrayList<LineString>();
for (String s : str) {
LineString ls = getLineString(s);
lines.add(ls);
}
return new MultiLineString(lines);
}
private MultiPolygon getMultiPolygon(String text) {
text = text.trim();
String[] str = text.split("\\)\\),\\(\\(");
List<Polygon> polygons = new ArrayList<Polygon>();
for (String s : str) {
Polygon pg = getPolygon(s);
polygons.add(pg);
}
return new MultiPolygon(polygons);
}
private String removeBrackets(String text) {
text = text.replace('(', ' ');
text = text.replace(')', ' ');
return text.trim();
}
}