All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotools.data.hana.wkb.HanaWKBWriter Maven / Gradle / Ivy

The newest version!
/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2018, Open Source Geospatial Foundation (OSGeo)
 *
 *    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;
 *    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.
 */
package org.geotools.data.hana.wkb;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.MessageFormat;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateSequence;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;

/**
 * A well-known binary writer.
 *
 * 

The JTS WKB writer cannot be used as it rejects empty points. * * @author Stefan Uhrig, SAP SE */ public class HanaWKBWriter { public static byte[] write(Geometry geometry, int dimension) throws HanaWKBWriterException { if (geometry == null) { return null; } int size = computeSize(geometry, dimension); ByteBuffer buffer = ByteBuffer.allocate(size); buffer.order(ByteOrder.LITTLE_ENDIAN); write(geometry, dimension, buffer); return buffer.array(); } private static final int HEADER_SIZE = 5; private static final int COUNT_SIZE = 4; private static final int COORD_SIZE = 8; private static int computeSize(Geometry geometry, int dimension) throws HanaWKBWriterException { if (geometry instanceof Point) { return computeSize((Point) geometry, dimension); } else if (geometry instanceof LineString) { return computeSize((LineString) geometry, dimension); } else if (geometry instanceof Polygon) { return computeSize((Polygon) geometry, dimension); } else if (geometry instanceof MultiPoint) { return computeSize((MultiPoint) geometry, dimension); } else if (geometry instanceof MultiLineString) { return computeSize((MultiLineString) geometry, dimension); } else if (geometry instanceof MultiPolygon) { return computeSize((MultiPolygon) geometry, dimension); } else if (geometry instanceof GeometryCollection) { return computeSize((GeometryCollection) geometry, dimension); } else { throw new HanaWKBWriterException( MessageFormat.format( "Unsupported geometry type {0}", geometry.getGeometryType())); } } private static int computeSize(Point point, int dimension) { return HEADER_SIZE + dimension * COORD_SIZE; } private static int computeSize(LineString lineString, int dimension) { return HEADER_SIZE + COUNT_SIZE + lineString.getNumPoints() * dimension * COORD_SIZE; } private static int computeSize(Polygon polygon, int dimension) { int size = HEADER_SIZE + COUNT_SIZE; LineString shell = polygon.getExteriorRing(); if ((shell == null) || (shell.getNumPoints() == 0)) { return size; } int pointSize = dimension * COORD_SIZE; size += COUNT_SIZE + shell.getNumPoints() * pointSize; int numHoles = polygon.getNumInteriorRing(); for (int i = 0; i < numHoles; ++i) { size += COUNT_SIZE + polygon.getInteriorRingN(i).getNumPoints() * pointSize; } return size; } private static int computeSize(MultiPoint multiPoint, int dimension) { return HEADER_SIZE + COUNT_SIZE + multiPoint.getNumPoints() * (HEADER_SIZE + dimension * COORD_SIZE); } private static int computeSize(MultiLineString multiLineString, int dimension) { int size = HEADER_SIZE + COUNT_SIZE; for (int i = 0; i < multiLineString.getNumGeometries(); ++i) { size += computeSize((LineString) multiLineString.getGeometryN(i), dimension); } return size; } private static int computeSize(MultiPolygon multiPolygon, int dimension) { int size = HEADER_SIZE + COUNT_SIZE; for (int i = 0; i < multiPolygon.getNumGeometries(); ++i) { size += computeSize((Polygon) multiPolygon.getGeometryN(i), dimension); } return size; } private static int computeSize(GeometryCollection geometryCollection, int dimension) throws HanaWKBWriterException { int size = HEADER_SIZE + COUNT_SIZE; for (int i = 0; i < geometryCollection.getNumGeometries(); ++i) { size += computeSize(geometryCollection.getGeometryN(i), dimension); } return size; } private static final byte NDR = 1; private static final int DIM_OFFSET = 1000; private static void write(Geometry geometry, int dimension, ByteBuffer buffer) throws HanaWKBWriterException { if (geometry instanceof Point) { write((Point) geometry, dimension, buffer); } else if (geometry instanceof LineString) { write((LineString) geometry, dimension, buffer); } else if (geometry instanceof Polygon) { write((Polygon) geometry, dimension, buffer); } else if (geometry instanceof MultiPoint) { write((MultiPoint) geometry, dimension, buffer); } else if (geometry instanceof MultiLineString) { write((MultiLineString) geometry, dimension, buffer); } else if (geometry instanceof MultiPolygon) { write((MultiPolygon) geometry, dimension, buffer); } else if (geometry instanceof GeometryCollection) { write((GeometryCollection) geometry, dimension, buffer); } else { throw new HanaWKBWriterException( MessageFormat.format( "Unsupported geometry type {0}", geometry.getGeometryType())); } } private static void write(Point point, int dimension, ByteBuffer buffer) { writeHeader(GeometryType.POINT, dimension, buffer); Coordinate coord = point.getCoordinate(); if (coord != null) { buffer.putDouble(coord.x); buffer.putDouble(coord.y); if (dimension >= 3) { buffer.putDouble(coord.getZ()); } } else { for (int i = 0; i < dimension; ++i) { buffer.putDouble(Double.NaN); } } } private static void write(LineString lineString, int dimension, ByteBuffer buffer) { writeHeader(GeometryType.LINESTRING, dimension, buffer); write(lineString.getCoordinateSequence(), dimension, buffer); } private static void write(Polygon polygon, int dimension, ByteBuffer buffer) { writeHeader(GeometryType.POLYGON, dimension, buffer); LineString shell = polygon.getExteriorRing(); if ((shell == null) || (shell.getNumPoints() == 0)) { buffer.putInt(0); return; } int numHoles = polygon.getNumInteriorRing(); buffer.putInt(1 + numHoles); write(shell.getCoordinateSequence(), dimension, buffer); for (int i = 0; i < numHoles; ++i) { LineString hole = polygon.getInteriorRingN(i); write(hole.getCoordinateSequence(), dimension, buffer); } } private static void write(MultiPoint multiPoint, int dimension, ByteBuffer buffer) { writeHeader(GeometryType.MULTIPOINT, dimension, buffer); int numPoints = multiPoint.getNumPoints(); buffer.putInt(numPoints); for (int i = 0; i < numPoints; ++i) { write((Point) multiPoint.getGeometryN(i), dimension, buffer); } } private static void write(MultiLineString multiLineString, int dimension, ByteBuffer buffer) { writeHeader(GeometryType.MULTILINESTRING, dimension, buffer); int numLineStrings = multiLineString.getNumGeometries(); buffer.putInt(numLineStrings); for (int i = 0; i < numLineStrings; ++i) { write((LineString) multiLineString.getGeometryN(i), dimension, buffer); } } private static void write(MultiPolygon multiPolygon, int dimension, ByteBuffer buffer) { writeHeader(GeometryType.MULTIPOLYGON, dimension, buffer); int numPolygons = multiPolygon.getNumGeometries(); buffer.putInt(numPolygons); for (int i = 0; i < numPolygons; ++i) { write((Polygon) multiPolygon.getGeometryN(i), dimension, buffer); } } private static void write( GeometryCollection geometryCollection, int dimension, ByteBuffer buffer) throws HanaWKBWriterException { writeHeader(GeometryType.GEOMETRYCOLLECTION, dimension, buffer); int numGeometries = geometryCollection.getNumGeometries(); buffer.putInt(numGeometries); for (int i = 0; i < numGeometries; ++i) { write(geometryCollection.getGeometryN(i), dimension, buffer); } } private static void write(CoordinateSequence cs, int dimension, ByteBuffer buffer) { int numPoints = cs.size(); buffer.putInt(numPoints); for (int i = 0; i < numPoints; ++i) { for (int j = 0; j < dimension; ++j) { buffer.putDouble(cs.getOrdinate(i, j)); } } } private static void writeHeader(GeometryType geometryType, int dimension, ByteBuffer buffer) { buffer.put(NDR); int typeCode = geometryType.getTypeCode(); if (dimension == 3) { typeCode += DIM_OFFSET; } buffer.putInt(typeCode); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy