提交 16536c94 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Simplify handling of SRID

上级 d3b2588b
......@@ -43,7 +43,7 @@ public final class EWKBUtils {
private int type;
private int level;
private int srid;
/**
* Creates a new EWKB output target.
......@@ -59,19 +59,24 @@ public final class EWKBUtils {
}
@Override
protected void startPoint(int srid) {
writeHeader(POINT, srid);
protected void init(int srid) {
this.srid = srid;
}
@Override
protected void startLineString(int srid, int numPoints) {
writeHeader(LINE_STRING, srid);
protected void startPoint() {
writeHeader(POINT);
}
@Override
protected void startLineString(int numPoints) {
writeHeader(LINE_STRING);
writeInt(numPoints);
}
@Override
protected void startPolygon(int srid, int numInner, int numPoints) {
writeHeader(POLYGON, srid);
protected void startPolygon(int numInner, int numPoints) {
writeHeader(POLYGON);
writeInt(numInner + 1);
writeInt(numPoints);
}
......@@ -82,12 +87,12 @@ public final class EWKBUtils {
}
@Override
protected void startCollection(int type, int srid, int numItems) {
writeHeader(type, srid);
protected void startCollection(int type, int numItems) {
writeHeader(type);
writeInt(numItems);
}
private void writeHeader(int type, int srid) {
private void writeHeader(int type) {
this.type = type;
switch (dimensionSystem) {
case DIMENSION_SYSTEM_XYZ:
......@@ -99,30 +104,23 @@ public final class EWKBUtils {
case DIMENSION_SYSTEM_XYM:
type |= EWKB_M;
}
// Never write SRID in inner objects
if (level > 0) {
srid = 0;
} else if (srid != 0) {
if (srid != 0) {
type |= EWKB_SRID;
}
output.write(0);
writeInt(type);
if (srid != 0) {
writeInt(srid);
// Newer write SRID in inner objects
srid = 0;
}
}
@Override
protected Target startCollectionItem(int index, int total) {
level++;
return this;
}
@Override
protected void endCollectionItem(Target target, int index, int total) {
level--;
}
@Override
protected void addCoordinate(double x, double y, double z, double m, int index, int total) {
boolean check = type != POINT || !Double.isNaN(x) || !Double.isNaN(y) || !Double.isNaN(z)
......@@ -281,7 +279,7 @@ public final class EWKBUtils {
*/
public static void parseEWKB(byte[] ewkb, Target target) {
try {
parseEWKB(new EWKBSource(ewkb), target, 0, 0);
parseEWKB(new EWKBSource(ewkb), target, 0);
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException();
}
......@@ -296,11 +294,8 @@ public final class EWKBUtils {
* output target
* @param parentType
* type of parent geometry collection, or 0 for the root geometry
* @param parentSrid
* SRID of a parent geometry collection, or any value for the
* root geometry (will be determined from the EWKB instead)
*/
private static void parseEWKB(EWKBSource source, Target target, int parentType, int parentSrid) {
private static void parseEWKB(EWKBSource source, Target target, int parentType) {
// Read byte order of a next geometry
switch (source.readByte()) {
case 0:
......@@ -318,9 +313,9 @@ public final class EWKBUtils {
boolean useZ = (type & EWKB_Z) != 0;
boolean useM = (type & EWKB_M) != 0;
int srid = (type & EWKB_SRID) != 0 ? source.readInt() : 0;
// Preserve parent SRID unconditionally
if (parentType != 0) {
srid = parentSrid;
// Use only top-level SRID
if (parentType == 0) {
target.init(srid);
}
// OGC 06-103r4
type &= 0xffff;
......@@ -340,7 +335,7 @@ public final class EWKBUtils {
if (parentType != 0 && parentType != MULTI_POINT && parentType != GEOMETRY_COLLECTION) {
throw new IllegalArgumentException();
}
target.startPoint(srid);
target.startPoint();
addCoordinate(source, target, useZ, useM, 0, 1);
break;
case LINE_STRING: {
......@@ -351,7 +346,7 @@ public final class EWKBUtils {
if (numPoints < 0 || numPoints == 1) {
throw new IllegalArgumentException();
}
target.startLineString(srid, numPoints);
target.startLineString(numPoints);
for (int i = 0; i < numPoints; i++) {
addCoordinate(source, target, useZ, useM, i, numPoints);
}
......@@ -373,7 +368,7 @@ public final class EWKBUtils {
if (size == 0 && numInner > 0) {
throw new IllegalArgumentException();
}
target.startPolygon(srid, numInner, size);
target.startPolygon(numInner, size);
if (size > 0) {
addRing(source, target, useZ, useM, size);
for (int i = 0; i < numInner; i++) {
......@@ -400,10 +395,10 @@ public final class EWKBUtils {
if (numItems < 0) {
throw new IllegalArgumentException();
}
target.startCollection(type, srid, numItems);
target.startCollection(type, numItems);
for (int i = 0; i < numItems; i++) {
Target innerTarget = target.startCollectionItem(i, numItems);
parseEWKB(source, innerTarget, type, srid);
parseEWKB(source, innerTarget, type);
target.endCollectionItem(innerTarget, i, numItems);
}
target.endCollection(type);
......
......@@ -42,8 +42,6 @@ public final class EWKTUtils {
private final int dimensionSystem;
private int level;
private int type;
private boolean inMulti;
......@@ -62,21 +60,28 @@ public final class EWKTUtils {
}
@Override
protected void startPoint(int srid) {
writeHeader(POINT, srid);
protected void init(int srid) {
if (srid != 0) {
output.append("SRID=").append(srid).append(';');
}
}
@Override
protected void startPoint() {
writeHeader(POINT);
}
@Override
protected void startLineString(int srid, int numPoints) {
writeHeader(LINE_STRING, srid);
protected void startLineString(int numPoints) {
writeHeader(LINE_STRING);
if (numPoints == 0) {
output.append("EMPTY");
}
}
@Override
protected void startPolygon(int srid, int numInner, int numPoints) {
writeHeader(POLYGON, srid);
protected void startPolygon(int numInner, int numPoints) {
writeHeader(POLYGON);
if (numPoints == 0) {
output.append("EMPTY");
} else {
......@@ -95,8 +100,8 @@ public final class EWKTUtils {
}
@Override
protected void startCollection(int type, int srid, int numItems) {
writeHeader(type, srid);
protected void startCollection(int type, int numItems) {
writeHeader(type);
if (numItems == 0) {
output.append("EMPTY");
}
......@@ -105,12 +110,8 @@ public final class EWKTUtils {
}
}
private void writeHeader(int type, int srid) {
private void writeHeader(int type) {
this.type = type;
// Never write SRID in inner objects
if (level == 0 && srid != 0) {
output.append("SRID=").append(srid).append(';');
}
if (inMulti) {
return;
}
......@@ -154,7 +155,6 @@ public final class EWKTUtils {
@Override
protected Target startCollectionItem(int index, int total) {
level++;
if (index == 0) {
output.append('(');
} else {
......@@ -168,7 +168,6 @@ public final class EWKTUtils {
if (index + 1 == total) {
output.append(')');
}
level--;
}
@Override
......@@ -229,10 +228,12 @@ public final class EWKTUtils {
private int offset;
int srid;
EWKTSource(String ewkt) {
this.ewkt = ewkt;
}
int readSRID() {
int srid;
if (ewkt.startsWith("SRID=")) {
int idx = ewkt.indexOf(';', 5);
srid = Integer.parseInt(ewkt.substring(5, idx));
......@@ -240,6 +241,7 @@ public final class EWKTUtils {
} else {
srid = 0;
}
return srid;
}
void read(char symbol) {
......@@ -522,6 +524,9 @@ public final class EWKTUtils {
* parent geometry uses dimension M
*/
private static void parseEWKT(EWKTSource source, Target target, int parentType, boolean useZ, boolean useM) {
if (parentType == 0) {
target.init(source.readSRID());
}
String type;
boolean empty = false;
switch (parentType) {
......@@ -577,7 +582,7 @@ public final class EWKTUtils {
throw new IllegalArgumentException();
}
empty = source.readEmpty(empty);
target.startPoint(source.srid);
target.startPoint();
if (empty) {
target.addCoordinate(Double.NaN, Double.NaN, Double.NaN, Double.NaN, 0, 1);
} else {
......@@ -591,7 +596,7 @@ public final class EWKTUtils {
}
empty = source.readEmpty(empty);
if (empty) {
target.startLineString(source.srid, 0);
target.startLineString(0);
} else {
ArrayList<double[]> coordinates = new ArrayList<>();
do {
......@@ -601,7 +606,7 @@ public final class EWKTUtils {
if (numPoints < 0 || numPoints == 1) {
throw new IllegalArgumentException();
}
target.startLineString(source.srid, numPoints);
target.startLineString(numPoints);
for (int i = 0; i < numPoints; i++) {
double[] c = coordinates.get(i);
target.addCoordinate(c[X], c[Y], c[Z], c[M], i, numPoints);
......@@ -615,7 +620,7 @@ public final class EWKTUtils {
}
empty = source.readEmpty(empty);
if (empty) {
target.startPolygon(source.srid, 0, 0);
target.startPolygon(0, 0);
} else {
ArrayList<double[]> outer = readRing(source, useZ, useM);
ArrayList<ArrayList<double[]>> inner = new ArrayList<>();
......@@ -631,7 +636,7 @@ public final class EWKTUtils {
if (size == 0 && numInner > 0) {
throw new IllegalArgumentException();
}
target.startPolygon(source.srid, numInner, size);
target.startPolygon(numInner, size);
if (size > 0) {
addRing(outer, target, useZ, useM);
for (int i = 0; i < numInner; i++) {
......@@ -675,13 +680,13 @@ public final class EWKTUtils {
throw new IllegalArgumentException();
}
if (source.readEmpty(empty)) {
target.startCollection(type, source.srid, 0);
target.startCollection(type, 0);
} else {
if (type == MULTI_POINT && source.hasCoordinate()) {
parseMultiPointAlternative(source, target, useZ, useM);
} else {
int numItems = source.getItemCount();
target.startCollection(type, source.srid, numItems);
target.startCollection(type, numItems);
for (int i = 0; i < numItems; i++) {
if (i > 0) {
source.read(',');
......@@ -703,10 +708,10 @@ public final class EWKTUtils {
points.add(readCoordinate(source, useZ, useM));
} while (source.hasMoreCoordinates());
int numItems = points.size();
target.startCollection(MULTI_POINT, source.srid, numItems);
target.startCollection(MULTI_POINT, numItems);
for (int i = 0; i < points.size(); i++) {
Target innerTarget = target.startCollectionItem(i, numItems);
target.startPoint(source.srid);
target.startPoint();
double[] c = points.get(i);
target.addCoordinate(c[X], c[Y], c[Z], c[M], 0, 1);
target.endCollectionItem(innerTarget, i, numItems);
......
......@@ -21,36 +21,38 @@ public final class GeometryUtils {
}
/**
* Invoked before writing a POINT.
* Initializes top-level target.
*
* @param srid
* SRID
*/
protected void startPoint(int srid) {
protected void init(int srid) {
}
/**
* Invoked before writing a POINT.
*/
protected void startPoint() {
}
/**
* Invoked before writing a LINESTRING.
*
* @param srid
* SRID
* @param numPoints
* number of points in line string
*/
protected void startLineString(int srid, int numPoints) {
protected void startLineString(int numPoints) {
}
/**
* Invoked before writing a POLYGON.
*
* @param srid
* SRID
* @param numInner
* number of inner polygons
* @param numPoints
* number of points in outer polygon
*/
protected void startPolygon(int srid, int numInner, int numPoints) {
protected void startPolygon(int numInner, int numPoints) {
}
/**
......@@ -77,12 +79,10 @@ public final class GeometryUtils {
* {@link GeometryUtils#MULTI_LINE_STRING},
* {@link GeometryUtils#MULTI_POLYGON},
* {@link GeometryUtils#GEOMETRY_COLLECTION}
* @param srid
* SRID
* @param numItems
* number of items in this collection
*/
protected void startCollection(int type, int srid, int numItems) {
protected void startCollection(int type, int numItems) {
}
/**
......@@ -120,7 +120,7 @@ public final class GeometryUtils {
*
* @param type
* type of collection, see
* {@link #startCollection(int, int, int)}
* {@link #startCollection(int, int)}
*/
protected void endCollection(int type) {
}
......@@ -170,17 +170,17 @@ public final class GeometryUtils {
}
@Override
protected void startPoint(int srid) {
protected void startPoint() {
enabled = true;
}
@Override
protected void startLineString(int srid, int numPoints) {
protected void startLineString(int numPoints) {
enabled = true;
}
@Override
protected void startPolygon(int srid, int numInner, int numPoints) {
protected void startPolygon(int numInner, int numPoints) {
enabled = true;
}
......@@ -292,17 +292,17 @@ public final class GeometryUtils {
}
@Override
protected void startPoint(int srid) {
protected void startPoint() {
enabled = true;
}
@Override
protected void startLineString(int srid, int numPoints) {
protected void startLineString(int numPoints) {
enabled = true;
}
@Override
protected void startPolygon(int srid, int numInner, int numPoints) {
protected void startPolygon(int numInner, int numPoints) {
enabled = true;
}
......
......@@ -81,22 +81,29 @@ public final class JTSUtils {
}
@Override
protected void startPoint(int srid) {
init(POINT, srid);
protected void init(int srid) {
factory = new GeometryFactory(new PrecisionModel(), srid,
(dimensionSystem & DIMENSION_SYSTEM_XYM) != 0 ? PackedCoordinateSequenceFactory.DOUBLE_FACTORY
: CoordinateArraySequenceFactory.instance());
}
@Override
protected void startPoint() {
type = POINT;
initCoordinates(1);
innerOffset = -1;
}
@Override
protected void startLineString(int srid, int numPoints) {
init(LINE_STRING, srid);
protected void startLineString(int numPoints) {
type = LINE_STRING;
initCoordinates(numPoints);
innerOffset = -1;
}
@Override
protected void startPolygon(int srid, int numInner, int numPoints) {
init(POLYGON, srid);
protected void startPolygon(int numInner, int numPoints) {
type = POLYGON;
initCoordinates(numPoints);
innerCoordinates = new CoordinateSequence[numInner];
innerOffset = -1;
......@@ -108,8 +115,8 @@ public final class JTSUtils {
}
@Override
protected void startCollection(int type, int srid, int numItems) {
init(type, srid);
protected void startCollection(int type, int numItems) {
this.type = type;
switch (type) {
case MULTI_POINT:
subgeometries = new Point[numItems];
......@@ -138,15 +145,6 @@ public final class JTSUtils {
subgeometries[index] = ((GeometryTarget) target).getGeometry();
}
private void init(int type, int srid) {
if (factory == null) {
factory = new GeometryFactory(new PrecisionModel(), srid,
(dimensionSystem & DIMENSION_SYSTEM_XYM) != 0 ? PackedCoordinateSequenceFactory.DOUBLE_FACTORY
: CoordinateArraySequenceFactory.instance());
}
this.type = type;
}
private void initCoordinates(int numPoints) {
coordinates = createCoordinates(numPoints);
}
......@@ -273,7 +271,7 @@ public final class JTSUtils {
* output target
*/
public static void parseGeometry(Geometry geometry, Target target) {
parseGeometry(geometry, target, 0, 0);
parseGeometry(geometry, target, 0);
}
/**
......@@ -285,21 +283,16 @@ public final class JTSUtils {
* output target
* @param parentType
* type of parent geometry collection, or 0 for the root geometry
* @param parentSrid
* SRID of a parent geometry collection, or any value for the
* root geometry (will be determined from the EWKB instead)
*/
private static void parseGeometry(Geometry geometry, Target target, int parentType, int parentSrid) {
int srid = geometry.getSRID();
// Preserve parent SRID unconditionally
if (parentType != 0) {
srid = parentSrid;
private static void parseGeometry(Geometry geometry, Target target, int parentType) {
if (parentType == 0) {
target.init(geometry.getSRID());
}
if (geometry instanceof Point) {
if (parentType != 0 && parentType != MULTI_POINT && parentType != GEOMETRY_COLLECTION) {
throw new IllegalArgumentException();
}
target.startPoint(srid);
target.startPoint();
Point p = (Point) geometry;
if (p.isEmpty()) {
target.addCoordinate(Double.NaN, Double.NaN, Double.NaN, Double.NaN, 0, 1);
......@@ -316,7 +309,7 @@ public final class JTSUtils {
if (numPoints < 0 || numPoints == 1) {
throw new IllegalArgumentException();
}
target.startLineString(srid, numPoints);
target.startLineString(numPoints);
for (int i = 0; i < numPoints; i++) {
addCoordinate(cs, target, i, numPoints);
}
......@@ -338,7 +331,7 @@ public final class JTSUtils {
if (size == 0 && numInner > 0) {
throw new IllegalArgumentException();
}
target.startPolygon(srid, numInner, size);
target.startPolygon(numInner, size);
if (size > 0) {
addRing(cs, target, size);
for (int i = 0; i < numInner; i++) {
......@@ -372,10 +365,10 @@ public final class JTSUtils {
if (numItems < 0) {
throw new IllegalArgumentException();
}
target.startCollection(type, srid, numItems);
target.startCollection(type, numItems);
for (int i = 0; i < numItems; i++) {
Target innerTarget = target.startCollectionItem(i, numItems);
parseGeometry(gc.getGeometryN(i), innerTarget, type, srid);
parseGeometry(gc.getGeometryN(i), innerTarget, type);
target.endCollectionItem(innerTarget, i, numItems);
}
target.endCollection(type);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论