241 lines
7.4 KiB
Java
241 lines
7.4 KiB
Java
/*
|
|
* Copyright 2013 Hannes Janetzek
|
|
*
|
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under the
|
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License along with
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package org.oscim.web.client;
|
|
|
|
import org.oscim.core.GeometryBuffer;
|
|
|
|
public class WKTReader {
|
|
private final static String POINT = "POINT";
|
|
private final static String LINE = "LINESTRING";
|
|
private final static String POLY = "POLYGON";
|
|
private final static String MULTI = "MULTI";
|
|
|
|
private final static int SKIP_POINT = POINT.length();
|
|
private final static int SKIP_LINE = LINE.length();
|
|
private final static int SKIP_POLY = POLY.length();
|
|
private final static int SKIP_MULTI = MULTI.length();
|
|
|
|
public void parse(String wkt, GeometryBuffer geom) throws Exception {
|
|
// return position.
|
|
int[] pos = new int[]{0};
|
|
|
|
int len = wkt.length();
|
|
|
|
if (wkt.startsWith(POINT, pos[0])) {
|
|
pos[0] += SKIP_POINT;
|
|
geom.startPoints();
|
|
ensure(wkt, pos, '(');
|
|
parsePoint(geom, wkt, len, pos);
|
|
ensure(wkt, pos, ')');
|
|
} else if (wkt.startsWith(LINE, pos[0])) {
|
|
pos[0] += SKIP_LINE;
|
|
geom.startLine();
|
|
|
|
parseLine(geom, wkt, len, pos);
|
|
|
|
} else if (wkt.startsWith(POLY, pos[0])) {
|
|
pos[0] += SKIP_POLY;
|
|
geom.startPolygon();
|
|
|
|
parsePoly(geom, wkt, len, pos);
|
|
|
|
} else if (wkt.startsWith(MULTI, pos[0])) {
|
|
pos[0] += SKIP_MULTI;
|
|
|
|
if (wkt.startsWith(POINT, pos[0])) {
|
|
pos[0] += SKIP_POINT;
|
|
geom.startPoints();
|
|
ensure(wkt, pos, '(');
|
|
parsePoint(geom, wkt, len, pos);
|
|
while (wkt.charAt(pos[0]) == ',') {
|
|
pos[0]++;
|
|
parsePoint(geom, wkt, len, pos);
|
|
}
|
|
ensure(wkt, pos, ')');
|
|
|
|
} else if (wkt.startsWith(LINE, pos[0])) {
|
|
pos[0] += SKIP_LINE;
|
|
geom.startLine();
|
|
ensure(wkt, pos, '(');
|
|
parseLine(geom, wkt, len, pos);
|
|
while (wkt.charAt(pos[0]) == ',') {
|
|
pos[0]++;
|
|
geom.startLine();
|
|
parseLine(geom, wkt, len, pos);
|
|
}
|
|
ensure(wkt, pos, ')');
|
|
|
|
} else if (wkt.startsWith(POLY, pos[0])) {
|
|
pos[0] += SKIP_POLY;
|
|
geom.startPolygon();
|
|
ensure(wkt, pos, '(');
|
|
parsePoly(geom, wkt, len, pos);
|
|
while (wkt.charAt(pos[0]) == ',') {
|
|
pos[0]++;
|
|
geom.startPolygon();
|
|
parsePoly(geom, wkt, len, pos);
|
|
}
|
|
ensure(wkt, pos, ')');
|
|
} else
|
|
throw new Exception("usupported geometry ");
|
|
} else
|
|
throw new Exception("usupported geometry ");
|
|
}
|
|
|
|
private static void ensure(String wkt, int[] pos, char c) throws Exception {
|
|
if (wkt.charAt(pos[0]) != c)
|
|
throw new Exception();
|
|
|
|
pos[0]++;
|
|
}
|
|
|
|
private static void parsePoly(GeometryBuffer geom, String wkt, int len, int[] adv)
|
|
throws Exception {
|
|
// outer ring
|
|
ensure(wkt, adv, '(');
|
|
parseLine(geom, wkt, len, adv);
|
|
|
|
while (wkt.charAt(adv[0]) == ',') {
|
|
adv[0]++;
|
|
geom.startHole();
|
|
parseLine(geom, wkt, len, adv);
|
|
}
|
|
ensure(wkt, adv, ')');
|
|
}
|
|
|
|
private static void parseLine(GeometryBuffer geom, String wkt, int len, int[] adv)
|
|
throws Exception {
|
|
ensure(wkt, adv, '(');
|
|
|
|
parsePoint(geom, wkt, len, adv);
|
|
while (wkt.charAt(adv[0]) == ',') {
|
|
adv[0]++;
|
|
parsePoint(geom, wkt, len, adv);
|
|
}
|
|
ensure(wkt, adv, ')');
|
|
}
|
|
|
|
private static void parsePoint(GeometryBuffer geom, String wkt, int len, int[] adv) {
|
|
float x = parseNumber(wkt, len, adv);
|
|
|
|
// skip ' '
|
|
adv[0]++;
|
|
|
|
float y = parseNumber(wkt, len, adv);
|
|
|
|
geom.addPoint(x, y);
|
|
}
|
|
|
|
static float parseNumber(String wkt, int len, int[] adv) {
|
|
int pos = adv[0];
|
|
|
|
boolean neg = false;
|
|
if (wkt.charAt(pos) == '-') {
|
|
neg = true;
|
|
pos++;
|
|
}
|
|
|
|
float val = 0;
|
|
int pre = 0;
|
|
char c = 0;
|
|
|
|
for (; pos < len; pos++, pre++) {
|
|
c = wkt.charAt(pos);
|
|
if (c < '0' || c > '9') {
|
|
if (pre == 0)
|
|
throw new NumberFormatException("s " + c);
|
|
|
|
break;
|
|
}
|
|
val = val * 10 + (int) (c - '0');
|
|
}
|
|
|
|
if (pre == 0)
|
|
throw new NumberFormatException();
|
|
|
|
if (c == '.') {
|
|
float div = 10;
|
|
for (pos++; pos < len; pos++) {
|
|
c = wkt.charAt(pos);
|
|
if (c < '0' || c > '9')
|
|
break;
|
|
val = val + ((int) (c - '0')) / div;
|
|
div *= 10;
|
|
}
|
|
}
|
|
|
|
if (c == 'e' || c == 'E') {
|
|
// advance 'e'
|
|
pos++;
|
|
|
|
// check direction
|
|
int dir = 1;
|
|
if (wkt.charAt(pos) == '-') {
|
|
dir = -1;
|
|
pos++;
|
|
}
|
|
// skip leading zeros
|
|
for (; pos < len; pos++)
|
|
if (wkt.charAt(pos) != '0')
|
|
break;
|
|
|
|
int shift = 0;
|
|
for (pre = 0; pos < len; pos++, pre++) {
|
|
c = wkt.charAt(pos);
|
|
if (c < '0' || c > '9') {
|
|
// nothing after 'e'
|
|
if (pre == 0)
|
|
throw new NumberFormatException("e " + c);
|
|
break;
|
|
}
|
|
shift = shift * 10 + (int) (c - '0');
|
|
}
|
|
|
|
// guess it's ok for sane values of E
|
|
if (dir > 0) {
|
|
while (shift-- > 0)
|
|
val *= 10;
|
|
} else {
|
|
while (shift-- > 0)
|
|
val /= 10;
|
|
}
|
|
}
|
|
|
|
adv[0] = pos;
|
|
|
|
return neg ? -val : val;
|
|
}
|
|
|
|
// public static void main(String[] args) {
|
|
// WKTReader r = new WKTReader();
|
|
// GeometryBuffer geom = new GeometryBuffer(10, 10);
|
|
// try {
|
|
// String wkt = "MULTIPOINT(0 0,1 0)";
|
|
// r.parse(wkt, geom);
|
|
// for (int i = 0; i < geom.index.length; i++) {
|
|
// int len = geom.index[i];
|
|
// if (len < 0)
|
|
// break;
|
|
// for (int p = 0; p < len; p += 2)
|
|
// System.out.println(len + ": " + geom.points[p] + "," + geom.points[p + 1]);
|
|
// }
|
|
// } catch (Exception e) {
|
|
// e.printStackTrace();
|
|
// }
|
|
// }
|
|
}
|