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

com.vividsolutions.jts.io.sde.SdeReader Maven / Gradle / Ivy

The newest version!
/*
 * The JTS Topology Suite is a collection of Java classes that
 * implement the fundamental operations required to validate a given
 * geo-spatial data set to a known topological specification.
 *
 * Copyright (C) 2001 Vivid Solutions
 *
 * 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, or (at your option) any later version.
 *
 * 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
 *
 * For more information, contact:
 *
 *     Vivid Solutions
 *     Suite #1A
 *     2328 Government Street
 *     Victoria BC  V8T 5G5
 *     Canada
 *
 *     (250)385-6040
 *     www.vividsolutions.com
 */
package com.vividsolutions.jts.io.sde;

import com.vividsolutions.jts.geom.*;
import com.esri.sde.sdk.client.*;

/**
 * Reads a {@link Geometry} from an ESRI SDE Shape.
 * 

* The SDE geometry model differs from the OGC model used by JTS. * In particular: *

    *
  • Simple lines are read as {@link LineString}s *
  • Inverted Polygons and Exverted Holes are read as is. * These create invalid JTS polygons, and must be * rectified if further operations are to be performed on them. *
*

* This class allows specifying the maximum number of coordinate dimensions to read. * If dimensions higher than 2 are not required, it may be more efficient to not read them. *

* To use this class the ESRI SDE Java libraries must be present. *

* Currently reading measure (M) ordinates is not supported. * * @author Martin Davis * */ public class SdeReader { private GeometryFactory geometryFactory; private PrecisionModel precisionModel; private CoordinateSequenceFactory coordSeqFact; private int maxDimensionToRead = 2; /** * Creates a reader that creates geometries using the default {@link GeometryFactory}. */ public SdeReader() { this(new GeometryFactory()); } /** * Creates a reader that creates geometries using the given {@link GeometryFactory}. * @param geometryFactory */ public SdeReader(GeometryFactory geometryFactory) { this.geometryFactory = geometryFactory; precisionModel = geometryFactory.getPrecisionModel(); coordSeqFact = geometryFactory.getCoordinateSequenceFactory(); } /** * Gets the maximum number of coordinate dimensions which will be read. * * @return the dimension which will be read */ public int getDimension() { return maxDimensionToRead; } /** * Sets the maximum number of coordinate dimensions to read. * If this is larger than the number of dimensions actually * present in the input geometry, the higher ordinates will not * be read, and NaN will be returned as their value. *

* The default is to read only the X and Y ordinates (dimension = 2). * * @param dimension the dimension to read */ public void setDimension(int dimension) { this.maxDimensionToRead = dimension; } /** * Reads a {@link Geometry} from a given SDE shape. * * @param shape the shape to read * @return the geometry which represents the input shape * * @throws SeException */ public Geometry read(SeShape shape) throws SeException { switch (shape.getType()) { case SeShape.TYPE_POINT: return readPoint(shape); case SeShape.TYPE_MULTI_POINT: return readMultiPoint(shape); case SeShape.TYPE_LINE: case SeShape.TYPE_SIMPLE_LINE: return readLine(shape); case SeShape.TYPE_MULTI_LINE: case SeShape.TYPE_MULTI_SIMPLE_LINE: return readMultiLine(shape); case SeShape.TYPE_POLYGON: return readPolygon(shape); case SeShape.TYPE_MULTI_POLYGON: return readMultiPolygon(shape); } throw new IllegalArgumentException("Shapes of type " + shape.getType() + " are not supported"); } private Point readPoint(SeShape shape) throws SeException { java.util.List list = shape.getAllPoints(SeShape.TURN_RIGHT, false); // get points and offsets SDEPoint[] sePts = (SDEPoint[]) list.get(0); return geometryFactory.createPoint(toCoordinates(sePts, 0, 1)); } private MultiPoint readMultiPoint(SeShape shape) throws SeException { java.util.List list = shape.getAllPoints(SeShape.TURN_RIGHT, false); // get points and offsets SDEPoint[] sePts = (SDEPoint[]) list.get(0); return geometryFactory.createMultiPoint(toCoordinates(sePts, 0, sePts.length)); } private LineString readLine(SeShape shape) throws SeException { java.util.List list = shape.getAllPoints(SeShape.TURN_RIGHT, false); // get points and offsets SDEPoint[] sePts = (SDEPoint[]) list.get(0); return geometryFactory.createLineString(toCoordinates(sePts, 0, sePts.length)); } private MultiLineString readMultiLine(SeShape shape) throws SeException { java.util.List list = shape.getAllPoints(SeShape.TURN_RIGHT, false); // get points and offsets SDEPoint[] sePts = (SDEPoint[]) list.get(0); int[] partOffset = (int[]) list.get(1); LineString[] lines = new LineString[partOffset.length]; for (int i = 0; i < partOffset.length; i++) { int end = sePts.length; if (i < partOffset.length - 1) end = partOffset[i + 1]; lines[i] = geometryFactory.createLineString(toCoordinates(sePts, partOffset[i], end)); } return geometryFactory.createMultiLineString(lines); } private Polygon readPolygon(SeShape shape) throws SeException { java.util.List list = shape.getAllPoints(SeShape.TURN_RIGHT, true); // get points and offsets SDEPoint[] sePts = (SDEPoint[]) list.get(0); // a polygon has only one part int[] subPartOffset = (int[]) list.get(2); return readPolygon(sePts, subPartOffset, 0, subPartOffset.length); } private Polygon readPolygon(SDEPoint[] sePts, int[] subPartOffset, int subPartStart, int subPartEnd) throws SeException { int numSubParts = subPartEnd - subPartStart; int nHoles = numSubParts - 1; if (nHoles < 0) nHoles = 0; LinearRing shell = null; LinearRing[] holes = new LinearRing[nHoles]; int holeIndex = 0; for (int i = subPartStart; i < subPartEnd; i++) { int end = sePts.length; if (i < subPartEnd - 1) end = subPartOffset[i + 1]; LinearRing ring = geometryFactory.createLinearRing(toCoordinates(sePts, subPartOffset[i], end)); if (shell == null) { shell = ring; } else { holes[holeIndex++] = ring; } } return geometryFactory.createPolygon(shell, holes); } private MultiPolygon readMultiPolygon(SeShape shape) throws SeException { java.util.List list = shape.getAllPoints(SeShape.TURN_RIGHT, true); // get points and offsets SDEPoint[] sePts = (SDEPoint[]) list.get(0); int[] partOffset = (int[]) list.get(1); int[] subPartOffset = (int[]) list.get(2); Polygon[] polys = new Polygon[partOffset.length]; for (int i = 0; i < partOffset.length; i++) { int subPartEnd = subPartOffset.length; if (i + 1 < partOffset.length) { subPartEnd = partOffset[i + 1]; } polys[i] = readPolygon(sePts, subPartOffset, partOffset[i], subPartEnd); } return geometryFactory.createMultiPolygon(polys); } private void readCoordinate(SDEPoint p, CoordinateSequence seq, int index) throws SeException { seq.setOrdinate(index, 0, precisionModel.makePrecise(p.getX())); seq.setOrdinate(index, 1, precisionModel.makePrecise(p.getY())); // only read the Z dim if requested and present if (maxDimensionToRead >= 3 && p.is3D()) { seq.setOrdinate(index, 2, p.getZ()); } } private CoordinateSequence toCoordinates(SDEPoint[] sePts, int start, int end) throws SeException { int size = end - start; CoordinateSequence seq = coordSeqFact.create(size, maxDimensionToRead); int index = 0; for (int i = start; i < end; i++) { readCoordinate(sePts[i], seq, index); index++; } return seq; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy