📄 binaryparser.java
字号:
/* * BinaryParser.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 Public 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 Public License for more * details. * * You should have received a copy of the GNU Lesser General Public 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: BinaryParser.java 1622 2005-04-15 14:04:34Z mschaber $ */package org.postgis.binary;import org.postgis.Geometry;import org.postgis.GeometryCollection;import org.postgis.LineString;import org.postgis.LinearRing;import org.postgis.MultiLineString;import org.postgis.MultiPoint;import org.postgis.MultiPolygon;import org.postgis.Point;import org.postgis.Polygon;import org.postgis.binary.ByteGetter.BinaryByteGetter;import org.postgis.binary.ByteGetter.StringByteGetter;/** * Parse binary representation of geometries. * * It should be easy to add char[] and CharSequence ByteGetter instances, * although the latter one is not compatible with older jdks. * * I did not implement real unsigned 32-bit integers or emulate them with long, * as both java Arrays and Strings currently can have only 2^31-1 elements * (bytes), so we cannot even get or build Geometries with more than approx. * 2^28 coordinates (8 bytes each). * * @author Markus Schaber <markus.schaber@logix-tt.com> * */public class BinaryParser { /** * Get the appropriate ValueGetter for my endianness * * @param bytes The appropriate Byte Getter * * @return the ValueGetter */ public static ValueGetter valueGetterForEndian(ByteGetter bytes) { if (bytes.get(0) == ValueGetter.XDR.NUMBER) { // XDR return new ValueGetter.XDR(bytes); } else if (bytes.get(0) == ValueGetter.NDR.NUMBER) { return new ValueGetter.NDR(bytes); } else { throw new IllegalArgumentException("Unknown Endian type:" + bytes.get(0)); } } /** * Parse a hex encoded geometry * * Is synchronized to protect offset counter. (Unfortunately, Java does not * have neither call by reference nor multiple return values.) */ public synchronized Geometry parse(String value) { StringByteGetter bytes = new ByteGetter.StringByteGetter(value); return parseGeometry(valueGetterForEndian(bytes)); } /** * Parse a binary encoded geometry. * * Is synchronized to protect offset counter. (Unfortunately, Java does not * have neither call by reference nor multiple return values.) */ public synchronized Geometry parse(byte[] value) { BinaryByteGetter bytes = new ByteGetter.BinaryByteGetter(value); return parseGeometry(valueGetterForEndian(bytes)); } /** Parse a geometry starting at offset. */ protected Geometry parseGeometry(ValueGetter data) { 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 = -1; if (haveS) { srid = data.getInt(); } Geometry result1; switch (realtype) { case Geometry.POINT : result1 = parsePoint(data, haveZ, haveM); break; case Geometry.LINESTRING : result1 = parseLineString(data, haveZ, haveM); break; case Geometry.POLYGON : result1 = parsePolygon(data, haveZ, haveM); break; case Geometry.MULTIPOINT : result1 = parseMultiPoint(data); break; case Geometry.MULTILINESTRING : result1 = parseMultiLineString(data); break; case Geometry.MULTIPOLYGON : result1 = parseMultiPolygon(data); break; case Geometry.GEOMETRYCOLLECTION : result1 = parseCollection(data); break; default : throw new IllegalArgumentException("Unknown Geometry Type: " + realtype); } Geometry result = result1; if (haveS) { result.setSrid(srid); } return result; } private Point parsePoint(ValueGetter data, boolean haveZ, boolean haveM) { double X = data.getDouble(); double Y = data.getDouble(); Point result; if (haveZ) { double Z = data.getDouble(); result = new Point(X, Y, Z); } else { result = new Point(X, Y); } if (haveM) { result.setM(data.getDouble()); } return result; } /** Parse an Array of "full" Geometries */ private void parseGeometryArray(ValueGetter data, Geometry[] container) { for (int i = 0; i < container.length; i++) { container[i] = parseGeometry(data); } } /** * Parse an Array of "slim" Points (without endianness and type, part of * LinearRing and Linestring, but not MultiPoint! * * @param haveZ * @param haveM */ private Point[] parsePointArray(ValueGetter data, boolean haveZ, boolean haveM) { int count = data.getInt(); Point[] result = new Point[count]; for (int i = 0; i < count; i++) { result[i] = parsePoint(data, haveZ, haveM); } return result; } private MultiPoint parseMultiPoint(ValueGetter data) { Point[] points = new Point[data.getInt()]; parseGeometryArray(data, points); return new MultiPoint(points); } private LineString parseLineString(ValueGetter data, boolean haveZ, boolean haveM) { Point[] points = parsePointArray(data, haveZ, haveM); return new LineString(points); } private LinearRing parseLinearRing(ValueGetter data, boolean haveZ, boolean haveM) { Point[] points = parsePointArray(data, haveZ, haveM); return new LinearRing(points); } private Polygon parsePolygon(ValueGetter data, boolean haveZ, boolean haveM) { int count = data.getInt(); LinearRing[] rings = new LinearRing[count]; for (int i = 0; i < count; i++) { rings[i] = parseLinearRing(data, haveZ, haveM); } return new Polygon(rings); } private MultiLineString parseMultiLineString(ValueGetter data) { int count = data.getInt(); LineString[] strings = new LineString[count]; parseGeometryArray(data, strings); return new MultiLineString(strings); } private MultiPolygon parseMultiPolygon(ValueGetter data) { int count = data.getInt(); Polygon[] polys = new Polygon[count]; parseGeometryArray(data, polys); return new MultiPolygon(polys); } private GeometryCollection parseCollection(ValueGetter data) { int count = data.getInt(); Geometry[] geoms = new Geometry[count]; parseGeometryArray(data, geoms); return new GeometryCollection(geoms); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -