start WKB2GeomBuffer reader
This commit is contained in:
parent
5222609025
commit
cccd053925
384
src/org/oscim/utils/wkb/Geometry.java
Normal file
384
src/org/oscim/utils/wkb/Geometry.java
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
/*
|
||||||
|
* Geometry.java
|
||||||
|
*
|
||||||
|
* PostGIS extension for PostgreSQL JDBC driver - geometry model
|
||||||
|
*
|
||||||
|
* (C) 2004 Paul Ramsey, pramsey@refractions.net
|
||||||
|
*
|
||||||
|
* (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Lesser General License as published by the Free
|
||||||
|
* Software Foundation, either version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* This library 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 License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General License
|
||||||
|
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
|
||||||
|
* http://www.gnu.org.
|
||||||
|
*
|
||||||
|
* $Id: Geometry.java 9324 2012-02-27 22:08:12Z pramsey $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.oscim.utils.wkb;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/** The base class of all geometries */
|
||||||
|
abstract class Geometry implements Serializable {
|
||||||
|
/* JDK 1.5 Serialization */
|
||||||
|
private static final long serialVersionUID = 0x100;
|
||||||
|
|
||||||
|
// OpenGIS Geometry types as defined in the OGC WKB Spec
|
||||||
|
// (May we replace this with an ENUM as soon as JDK 1.5
|
||||||
|
// has gained widespread usage?)
|
||||||
|
|
||||||
|
/** Fake type for linear ring */
|
||||||
|
static final int LINEARRING = 0;
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for points.
|
||||||
|
*/
|
||||||
|
static final int POINT = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for lines.
|
||||||
|
*/
|
||||||
|
static final int LINESTRING = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for polygons.
|
||||||
|
*/
|
||||||
|
static final int POLYGON = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for aggregate points.
|
||||||
|
*/
|
||||||
|
static final int MULTIPOINT = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for aggregate lines.
|
||||||
|
*/
|
||||||
|
static final int MULTILINESTRING = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for aggregate polygons.
|
||||||
|
*/
|
||||||
|
static final int MULTIPOLYGON = 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number for feature collections.
|
||||||
|
*/
|
||||||
|
static final int GEOMETRYCOLLECTION = 7;
|
||||||
|
|
||||||
|
static final String[] ALLTYPES = new String[] {
|
||||||
|
"", // internally used LinearRing does not have any text in front of
|
||||||
|
// it
|
||||||
|
"POINT", "LINESTRING", "POLYGON", "MULTIPOINT", "MULTILINESTRING",
|
||||||
|
"MULTIPOLYGON", "GEOMETRYCOLLECTION" };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Text representations of the geometry types
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
static String getTypeString(int type) {
|
||||||
|
if (type >= 0 && type <= 7)
|
||||||
|
return ALLTYPES[type];
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Unknown Geometry type" + type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Properties common to all geometries
|
||||||
|
/**
|
||||||
|
* The dimensionality of this feature (2,3)
|
||||||
|
*/
|
||||||
|
int dimension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we have a measure (4th dimension)
|
||||||
|
*/
|
||||||
|
boolean haveMeasure = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type of this feature. this is final as it never
|
||||||
|
* changes, it is bound to the subclass of the
|
||||||
|
* instance.
|
||||||
|
*/
|
||||||
|
final int type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Official UNKNOWN srid value
|
||||||
|
*/
|
||||||
|
final static int UNKNOWN_SRID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The spacial reference system id of this geometry, default is no srid
|
||||||
|
*/
|
||||||
|
int srid = UNKNOWN_SRID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a SRID value, anything <= 0 is unknown
|
||||||
|
*
|
||||||
|
* @param srid
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
static int parseSRID(int srid) {
|
||||||
|
if (srid < 0) {
|
||||||
|
/* TODO: raise a warning ? */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return srid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for subclasses
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* has to be given by all subclasses.
|
||||||
|
*/
|
||||||
|
protected Geometry(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* java.lang.Object hashCode implementation
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return dimension | (type * 4) | (srid * 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* java.lang.Object equals implementation
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
return (other != null) && (other instanceof Geometry)
|
||||||
|
&& equals((Geometry) other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* geometry specific equals implementation - only defined for non-null
|
||||||
|
* values
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean equals(Geometry other) {
|
||||||
|
return (other != null) && (this.dimension == other.dimension)
|
||||||
|
&& (this.type == other.type) && (this.srid == other.srid)
|
||||||
|
&& (this.haveMeasure == other.haveMeasure)
|
||||||
|
&& other.getClass().equals(this.getClass())
|
||||||
|
&& this.equalsintern(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether test coordinates for geometry - subclass specific code
|
||||||
|
* Implementors can assume that dimensin, type, srid
|
||||||
|
* and haveMeasure are equal, other != null and other is the same subclass.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
protected abstract boolean equalsintern(Geometry other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of Points of the geometry
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
abstract int numPoints();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the nth Point of the geometry
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* the index of the point, from 0 to numPoints()-1;
|
||||||
|
* @throws ArrayIndexOutOfBoundsException
|
||||||
|
* in case of an emtpy geometry or bad index.
|
||||||
|
*/
|
||||||
|
// abstract Point getPoint(int n);
|
||||||
|
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Same as getPoint(0);
|
||||||
|
// */
|
||||||
|
// abstract Point getFirstPoint();
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Same as getPoint(numPoints()-1);
|
||||||
|
// */
|
||||||
|
// abstract Point getLastPoint();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number of this geometry.
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
int getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Type as String
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
String getTypeString() {
|
||||||
|
return getTypeString(this.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether we have a measure
|
||||||
|
*
|
||||||
|
* @return ....
|
||||||
|
*/
|
||||||
|
boolean isMeasured() {
|
||||||
|
return haveMeasure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the number of geometric dimensions of this geometry. This does
|
||||||
|
* not include measures, as opposed to the
|
||||||
|
* server.
|
||||||
|
*
|
||||||
|
* @return The dimensionality (eg, 2D or 3D) of this geometry.
|
||||||
|
*/
|
||||||
|
int getDimension() {
|
||||||
|
return this.dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OGIS geometry type number of this geometry.
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
int getSrid() {
|
||||||
|
return this.srid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively sets the srid on this geometry and all contained
|
||||||
|
* subgeometries
|
||||||
|
*
|
||||||
|
* @param srid
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
void setSrid(int srid) {
|
||||||
|
this.srid = srid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
if (srid != UNKNOWN_SRID) {
|
||||||
|
sb.append("SRID=");
|
||||||
|
sb.append(srid);
|
||||||
|
sb.append(';');
|
||||||
|
}
|
||||||
|
outerWKT(sb, true);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the WKT version of this Geometry (without SRID) into the given
|
||||||
|
* StringBuffer.
|
||||||
|
*
|
||||||
|
* @param sb
|
||||||
|
* ...
|
||||||
|
* @param putM
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
void outerWKT(StringBuffer sb, boolean putM) {
|
||||||
|
sb.append(getTypeString());
|
||||||
|
if (putM && haveMeasure && dimension == 2) {
|
||||||
|
sb.append('M');
|
||||||
|
}
|
||||||
|
mediumWKT(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
final void outerWKT(StringBuffer sb) {
|
||||||
|
outerWKT(sb, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the WKT without the type name, but including the brackets into the
|
||||||
|
* StringBuffer
|
||||||
|
*
|
||||||
|
* @param sb
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
protected void mediumWKT(StringBuffer sb) {
|
||||||
|
sb.append('(');
|
||||||
|
innerWKT(sb);
|
||||||
|
sb.append(')');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the "inner" part of the WKT (inside the brackets) into the
|
||||||
|
* StringBuffer.
|
||||||
|
*
|
||||||
|
* @param SB
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
protected abstract void innerWKT(StringBuffer SB);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* backwards compatibility method
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
String getValue() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
mediumWKT(sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do some internal consistency checks on the geometry. Currently, all
|
||||||
|
* Geometries must have a valid dimension (2 or
|
||||||
|
* 3) and a valid type. 2-dimensional Points must have Z=0.0, as well as
|
||||||
|
* non-measured Points must have m=0.0.
|
||||||
|
* Composed geometries must have all equal SRID, dimensionality and
|
||||||
|
* measures, as well as that they do not contain
|
||||||
|
* NULL or inconsistent subgeometries. BinaryParser and WKTParser should
|
||||||
|
* only generate consistent geometries.
|
||||||
|
* BinaryWriter may produce invalid results on inconsistent geometries.
|
||||||
|
*
|
||||||
|
* @return true if all checks are passed.
|
||||||
|
*/
|
||||||
|
boolean checkConsistency() {
|
||||||
|
return (dimension >= 2 && dimension <= 3) && (type >= 0 && type <= 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits the SRID=4711; part of a EWKT rep if present and sets the srid.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* ...
|
||||||
|
* @return value without the SRID=4711; part
|
||||||
|
*/
|
||||||
|
protected String initSRID(String value) {
|
||||||
|
String v = value.trim();
|
||||||
|
if (v.startsWith("SRID=")) {
|
||||||
|
int index = v.indexOf(';', 5); // sridprefix length is 5
|
||||||
|
if (index == -1) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Error parsing Geometry - SRID not delimited with ';' ");
|
||||||
|
}
|
||||||
|
this.srid = Integer.parseInt(v.substring(5, index));
|
||||||
|
return v.substring(index + 1).trim();
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
139
src/org/oscim/utils/wkb/ValueGetter.java
Normal file
139
src/org/oscim/utils/wkb/ValueGetter.java
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* ValueGetter.java
|
||||||
|
*
|
||||||
|
* PostGIS extension for PostgreSQL JDBC driver - Binary Parser
|
||||||
|
*
|
||||||
|
* (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Lesser General License as published by the Free
|
||||||
|
* Software Foundation, either version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* This library 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 License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General License
|
||||||
|
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
|
||||||
|
* http://www.gnu.org.
|
||||||
|
*
|
||||||
|
* $Id: ValueGetter.java 9324 2012-02-27 22:08:12Z pramsey $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.oscim.utils.wkb;
|
||||||
|
|
||||||
|
abstract class ValueGetter {
|
||||||
|
byte[] data;
|
||||||
|
int position;
|
||||||
|
final byte endian;
|
||||||
|
|
||||||
|
ValueGetter(byte[] data, byte endian) {
|
||||||
|
this.data = data;
|
||||||
|
|
||||||
|
this.endian = endian;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a byte, should be equal for all endians
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
byte getByte() {
|
||||||
|
return data[position++];
|
||||||
|
}
|
||||||
|
|
||||||
|
int getInt() {
|
||||||
|
int res = getInt(position);
|
||||||
|
position += 4;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
long getLong() {
|
||||||
|
long res = getLong(position);
|
||||||
|
position += 8;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a 32-Bit integer
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
protected abstract int getInt(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a long value. This is not needed directly, but as a nice side-effect
|
||||||
|
* from GetDouble.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
protected abstract long getLong(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a double.
|
||||||
|
*
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
double getDouble() {
|
||||||
|
long bitrep = getLong();
|
||||||
|
return Double.longBitsToDouble(bitrep);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class XDR extends ValueGetter {
|
||||||
|
static final byte NUMBER = 0;
|
||||||
|
|
||||||
|
XDR(byte[] data) {
|
||||||
|
super(data, NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getInt(int index) {
|
||||||
|
return ((data[index] & 0xFF) << 24) + ((data[index + 1] & 0xFF) << 16)
|
||||||
|
+ ((data[index + 2] & 0xFF) << 8) + (data[index + 3] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long getLong(int index) {
|
||||||
|
|
||||||
|
return ((long) (data[index] & 0xFF) << 56) | ((long) (data[index + 1] & 0xFF) << 48)
|
||||||
|
| ((long) (data[index + 2] & 0xFF) << 40)
|
||||||
|
| ((long) (data[index + 3] & 0xFF) << 32)
|
||||||
|
| ((long) (data[index + 4] & 0xFF) << 24)
|
||||||
|
| ((long) (data[index + 5] & 0xFF) << 16)
|
||||||
|
| ((long) (data[index + 6] & 0xFF) << 8)
|
||||||
|
| ((long) (data[index + 7] & 0xFF) << 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class NDR extends ValueGetter {
|
||||||
|
static final byte NUMBER = 1;
|
||||||
|
|
||||||
|
NDR(byte[] data) {
|
||||||
|
super(data, NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getInt(int index) {
|
||||||
|
return ((data[index + 3] & 0xFF) << 24) + ((data[index + 2] & 0xFF) << 16)
|
||||||
|
+ ((data[index + 1] & 0xFF) << 8) + (data[index] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long getLong(int index) {
|
||||||
|
return ((long) (data[index + 7] & 0xFF) << 56)
|
||||||
|
| ((long) (data[index + 6] & 0xFF) << 48)
|
||||||
|
| ((long) (data[index + 5] & 0xFF) << 40)
|
||||||
|
| ((long) (data[index + 4] & 0xFF) << 32)
|
||||||
|
| ((long) (data[index + 3] & 0xFF) << 24)
|
||||||
|
| ((long) (data[index + 2] & 0xFF) << 16)
|
||||||
|
| ((long) (data[index + 1] & 0xFF) << 8) | ((long) (data[index] & 0xFF) << 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
208
src/org/oscim/utils/wkb/WKBReader.java
Normal file
208
src/org/oscim/utils/wkb/WKBReader.java
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* 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.utils.wkb;
|
||||||
|
|
||||||
|
import org.oscim.core.GeometryBuffer;
|
||||||
|
|
||||||
|
public class WKBReader {
|
||||||
|
interface Callback {
|
||||||
|
public void process(GeometryBuffer geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from postgis-java
|
||||||
|
|
||||||
|
private GeometryBuffer mGeom;
|
||||||
|
private final double mScale = 1;
|
||||||
|
private final double mOffsetX = 0;
|
||||||
|
private final double mOffsetY = 0;
|
||||||
|
|
||||||
|
private WKBReader.Callback mCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a binary encoded geometry.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
boolean parse(byte[] value) {
|
||||||
|
return parseGeometry(valueGetterForEndian(value), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean parseGeometry(ValueGetter data, int count) {
|
||||||
|
byte endian = data.getByte(); // skip and test endian flag
|
||||||
|
if (endian != data.endian) {
|
||||||
|
throw new IllegalArgumentException("Endian inconsistency!");
|
||||||
|
}
|
||||||
|
int typeword = data.getInt();
|
||||||
|
|
||||||
|
int realtype = typeword & 0x1FFFFFFF; // cut off high flag bits
|
||||||
|
|
||||||
|
boolean haveZ = (typeword & 0x80000000) != 0;
|
||||||
|
boolean haveM = (typeword & 0x40000000) != 0;
|
||||||
|
boolean haveS = (typeword & 0x20000000) != 0;
|
||||||
|
|
||||||
|
// int srid = Geometry.UNKNOWN_SRID;
|
||||||
|
boolean polygon = false;
|
||||||
|
if (haveS) {
|
||||||
|
// srid = Geometry.parseSRID(data.getInt());
|
||||||
|
data.getInt();
|
||||||
|
}
|
||||||
|
switch (realtype) {
|
||||||
|
case Geometry.POINT:
|
||||||
|
mGeom.startPoints();
|
||||||
|
parsePoint(data, haveZ, haveM);
|
||||||
|
break;
|
||||||
|
case Geometry.LINESTRING:
|
||||||
|
mGeom.startLine();
|
||||||
|
parseLineString(data, haveZ, haveM);
|
||||||
|
break;
|
||||||
|
case Geometry.POLYGON:
|
||||||
|
mGeom.startPolygon();
|
||||||
|
parsePolygon(data, haveZ, haveM);
|
||||||
|
polygon = true;
|
||||||
|
break;
|
||||||
|
case Geometry.MULTIPOINT:
|
||||||
|
mGeom.startPoints();
|
||||||
|
parseMultiPoint(data);
|
||||||
|
break;
|
||||||
|
case Geometry.MULTILINESTRING:
|
||||||
|
mGeom.startLine();
|
||||||
|
parseMultiLineString(data);
|
||||||
|
break;
|
||||||
|
case Geometry.MULTIPOLYGON:
|
||||||
|
mGeom.startPolygon();
|
||||||
|
parseMultiPolygon(data);
|
||||||
|
polygon = true;
|
||||||
|
break;
|
||||||
|
case Geometry.GEOMETRYCOLLECTION:
|
||||||
|
parseCollection(data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown Geometry Type: " + realtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
mCallback.process(mGeom);
|
||||||
|
mGeom.clear();
|
||||||
|
}
|
||||||
|
// if (srid != Geometry.UNKNOWN_SRID) {
|
||||||
|
// result.setSrid(srid);
|
||||||
|
// }
|
||||||
|
return polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parsePoint(ValueGetter data, boolean haveZ, boolean haveM) {
|
||||||
|
|
||||||
|
float x = (float) ((data.getDouble() + mOffsetX) * mScale);
|
||||||
|
float y = (float) ((data.getDouble() + mOffsetY) * mScale);
|
||||||
|
mGeom.addPoint(x, y);
|
||||||
|
|
||||||
|
if (haveZ)
|
||||||
|
data.getDouble();
|
||||||
|
|
||||||
|
if (haveM)
|
||||||
|
data.getDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse an Array of "full" Geometries
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* ...
|
||||||
|
* @param count
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
private void parseGeometryArray(ValueGetter data, int count) {
|
||||||
|
mGeom.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
parseGeometry(data, count);
|
||||||
|
mGeom.index[mGeom.indexPos++] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCallback.process(mGeom);
|
||||||
|
mGeom.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseMultiPoint(ValueGetter data) {
|
||||||
|
parseGeometryArray(data, data.getInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseLineString(ValueGetter data, boolean haveZ, boolean haveM) {
|
||||||
|
|
||||||
|
int count = data.getInt();
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
float x = (float) ((data.getDouble() + mOffsetX) * mScale);
|
||||||
|
float y = (float) ((data.getDouble() + mOffsetY) * mScale);
|
||||||
|
mGeom.addPoint(x, y);
|
||||||
|
|
||||||
|
// ignore
|
||||||
|
if (haveZ)
|
||||||
|
data.getDouble();
|
||||||
|
if (haveM)
|
||||||
|
data.getDouble();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parsePolygon(ValueGetter data, boolean haveZ, boolean haveM) {
|
||||||
|
int count = data.getInt();
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
mGeom.startHole();
|
||||||
|
|
||||||
|
parseLineString(data, haveZ, haveM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseMultiLineString(ValueGetter data) {
|
||||||
|
|
||||||
|
int count = data.getInt();
|
||||||
|
if (count <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parseGeometryArray(data, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseMultiPolygon(ValueGetter data) {
|
||||||
|
int count = data.getInt();
|
||||||
|
if (count <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parseGeometryArray(data, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseCollection(ValueGetter data) {
|
||||||
|
int count = data.getInt();
|
||||||
|
parseGeometryArray(data, count);
|
||||||
|
|
||||||
|
mCallback.process(mGeom);
|
||||||
|
mGeom.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ValueGetter valueGetterForEndian(byte[] bytes) {
|
||||||
|
if (bytes[0] == ValueGetter.XDR.NUMBER) { // XDR
|
||||||
|
return new ValueGetter.XDR(bytes);
|
||||||
|
} else if (bytes[0] == ValueGetter.NDR.NUMBER) {
|
||||||
|
return new ValueGetter.NDR(bytes);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unknown Endian type:" + bytes[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user