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

com.esri.core.geometry.MultiVertexGeometryImpl Maven / Gradle / Ivy

Go to download

The Esri Geometry API for Java enables developers to write custom applications for analysis of spatial data.

There is a newer version: 2.2.4
Show newest version
/*
 Copyright 1995-2013 Esri

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 For additional information, contact:
 Environmental Systems Research Institute, Inc.
 Attn: Contracts Dept
 380 New York Street
 Redlands, California, USA 92373

 email: [email protected]
 */


package com.esri.core.geometry;

import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
import com.esri.core.geometry.VertexDescription.Semantics;

/**
 * This class is a base for geometries with many vertices.
 * 
 * The vertex attributes are stored in separate arrays of corresponding type.
 * There are as many arrays as there are attributes in the vertex. It uses lazy
 * allocation for the vertex attributes. This means, the actual AttributeStream
 * is allocated only when the users asks for it, or sets a non-default value.
 * 
 */
abstract class MultiVertexGeometryImpl extends MultiVertexGeometry {

	// HEADER DEFINED
	public interface GeometryXSimple {
		final int Unknown = -1; // not know if simple or not
		final int Not = 0; // not simple
		final int Weak = 1; // weak simple (no self intersections, ring
							// orientation is correct, but ring order is not)
		final int Strong = 2; // same as weak simple + OGC ring order.
	}

	// TODO Remove?
	/**
	 * \internal CHildren implement this method to copy additional information
	 */
	abstract void _copyToImpl(MultiVertexGeometryImpl mvg);

	protected abstract void _notifyModifiedAllImpl();

	/**
	 * \internal Called inside of the VerifyAllStreams to get a child class a
	 * chance to do additional verify.
	 */
	protected abstract void _verifyStreamsImpl();

	public interface DirtyFlags {
		public static final int DirtyIsKnownSimple = 1; // !<0 when IsWeakSimple
														// flag is valid
		public static final int IsWeakSimple = 2; // != m_pointCount)
			// TODO
			throw new GeometryException("index out of bounds");

		// _ASSERT(!IsEmpty());
		// _ASSERT(m_vertexAttributes != null);

		_verifyAllStreams();

		Point outPoint = dst;
		outPoint.assignVertexDescription(m_description);
		if (outPoint.isEmpty())
			outPoint._setToDefault();

		for (int attributeIndex = 0; attributeIndex < m_description
				.getAttributeCount(); attributeIndex++) {
			// fix semantics
			int semantics = m_description._getSemanticsImpl(attributeIndex);

			// VertexDescription.getComponentCount(semantics);
			for (int icomp = 0, ncomp = VertexDescription
					.getComponentCount(semantics); icomp < ncomp; icomp++) {
				double v = m_vertexAttributes[attributeIndex].readAsDbl(ncomp
						* index + icomp);
				outPoint.setAttribute(semantics, icomp, v);
			}
		}
	}

	// Checked vs. Jan 11, 2011
	@Override
	protected void setPointByVal(int index, Point src) {
		if (index < 0 || index >= m_pointCount)
			throw new GeometryException("index out of bounds");

		Point point = src;

		if (src.isEmpty())// can not assign an empty point to a multipoint
							// vertex
			throw new IllegalArgumentException();

		_verifyAllStreams();// verify all allocated streams are of necessary
							// size.
		VertexDescription vdin = point.getDescription();
		for (int attributeIndex = 0; attributeIndex < vdin.getAttributeCount(); attributeIndex++) {
			int semantics = vdin._getSemanticsImpl(attributeIndex);
			int ncomp = VertexDescription.getComponentCount(semantics);
			for (int icomp = 0; icomp < ncomp; icomp++) {
				double v = point.getAttributeAsDbl(semantics, icomp);
				setAttribute(semantics, index, icomp, v);
			}
		}
	}

	// Checked vs. Jan 11, 2011
	@Override
	public Point2D getXY(int index) {
		Point2D pt = new Point2D();
		getXY(index, pt);
		return pt;
	}

	@Override
	public void getXY(int index, Point2D pt) {
		if (index < 0 || index >= getPointCount())
			throw new IndexOutOfBoundsException();

		_verifyAllStreams();
		// AttributeStreamOfDbl v = (AttributeStreamOfDbl)
		// m_vertexAttributes[0];
		AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
		v.read(index * 2, pt);
	}

	// Checked vs. Jan 11, 2011
	@Override
	public void setXY(int index, Point2D pt) {
		if (index < 0 || index >= m_pointCount)
			// TODO exception
			throw new IndexOutOfBoundsException();

		_verifyAllStreams();
		// AttributeStreamOfDbl v = (AttributeStreamOfDbl)
		// m_vertexAttributes[0];
		AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
		v.write(index * 2, pt);
		notifyModified(DirtyFlags.DirtyCoordinates);
	}

	// Checked vs. Jan 11, 2011
	public void setXY(int index, double x, double y) {
		if (index < 0 || index >= m_pointCount)
			// TODO exc
			throw new IndexOutOfBoundsException();

		_verifyAllStreams();
		// AttributeStreamOfDbl v = (AttributeStreamOfDbl)
		// m_vertexAttributes[0];
		// TODO ask sergey about casts
		AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
		v.write(index * 2, x);
		v.write(index * 2 + 1, y);
		notifyModified(DirtyFlags.DirtyCoordinates);
	}

	// Checked vs. Jan 11, 2011
	@Override
	public Point3D getXYZ(int index) {
		if (index < 0 || index >= getPointCount())
			// FIXME exc
			throw new IndexOutOfBoundsException();

		_verifyAllStreams();
		// AttributeStreamOfDbl v = (AttributeStreamOfDbl)
		// m_vertexAttributes[0];
		AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
		Point3D pt = new Point3D();
		pt.x = v.read(index * 2);
		pt.y = v.read(index * 2 + 1);

		// TODO check excluded if statement componenet
		if (hasAttribute(Semantics.Z))// && (m_vertexAttributes[1] != null))
			pt.z = m_vertexAttributes[1].readAsDbl(index);
		else
			pt.z = VertexDescription.getDefaultValue(Semantics.Z);

		return pt;
	}

	// Checked vs. Jan 11, 2011
	@Override
	public void setXYZ(int index, Point3D pt) {
		if (index < 0 || index >= getPointCount())
			// FIXME exc
			throw new IndexOutOfBoundsException();

		addAttribute(Semantics.Z);

		_verifyAllStreams();
		notifyModified(DirtyFlags.DirtyCoordinates);
		// AttributeStreamOfDbl v = (AttributeStreamOfDbl)
		// m_vertexAttributes[0];
		AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
		v.write(index * 2, pt.x);
		v.write(index * 2 + 1, pt.y);
		m_vertexAttributes[1].writeAsDbl(index, pt.z);
	}

	// Checked vs. Jan 11, 2011
	@Override
	public double getAttributeAsDbl(int semantics, int offset, int ordinate) {
		if (offset < 0 || offset >= m_pointCount)
			// FIXME exc
			throw new IndexOutOfBoundsException();

		int ncomps = VertexDescription.getComponentCount(semantics);
		if (ordinate >= ncomps)
			// FIXME exc
			throw new IndexOutOfBoundsException();

		_verifyAllStreams();
		int attributeIndex = m_description.getAttributeIndex(semantics);
		// TODO check if statement
		if (attributeIndex >= 0)// && m_vertexAttributes[attributeIndex] !=
								// null) {
		{
			return m_vertexAttributes[attributeIndex].readAsDbl(offset * ncomps
					+ ordinate);
		}
		return VertexDescription.getDefaultValue(semantics);
	}

	// Checked vs. Jan 11, 2011
	@Override
	public int getAttributeAsInt(int semantics, int offset, int ordinate) {
		return (int) getAttributeAsDbl(semantics, offset, ordinate);
	}

	// Checked vs. Jan 11, 2011
	@Override
	public void setAttribute(int semantics, int offset, int ordinate,
			double value) {
		if (offset < 0 || offset >= m_pointCount)
			// FIXME exc
			throw new IndexOutOfBoundsException();

		int ncomps = VertexDescription.getComponentCount(semantics);
		if (ordinate >= ncomps)
			// FIXME exc
			throw new IndexOutOfBoundsException();

		addAttribute(semantics);
		_verifyAllStreams();
		int attributeIndex = m_description.getAttributeIndex(semantics);
		notifyModified(DirtyFlags.DirtyCoordinates);
		m_vertexAttributes[attributeIndex].writeAsDbl(offset * ncomps
				+ ordinate, value);
	}

	// Checked vs. Jan 11, 2011
	@Override
	public void setAttribute(int semantics, int offset, int ordinate, int value) {
		setAttribute(semantics, offset, ordinate, (double) value);
	}

	// FIXME change semantics to an enum
	// Checked vs. Jan 11, 2011
	public AttributeStreamBase getAttributeStreamRef(int semantics) {
		throwIfEmpty();

		addAttribute(semantics);
		_verifyAllStreams();

		int attributeIndex = m_description.getAttributeIndex(semantics);
		return m_vertexAttributes[attributeIndex];
	}

	// FIXME change semantics to an enum
	// Checked vs. Jan 11, 2011
	/**
	 * Sets a reference to the given AttributeStream of the Geometry. Once the
	 * buffer has been obtained, the vertices of the Geometry can be manipulated
	 * directly. The AttributeStream parameters are not checked for the size. 
* If the attribute is missing, it will be added.
* Note, that this method does not change the vertex count in the Geometry.
* The stream can have more elements, than the Geometry point count, but * only necessary part will be saved when exporting to a ESRI shape or other * format. @param semantics Semantics of the attribute to assign the stream * to. @param stream The input AttributeStream that will be assigned by * reference. If one changes the stream later through the reference, one has * to call NotifyStreamChanged. \exception Throws invalid_argument exception * if the input stream type does not match that of the semantics * persistence. */ public void setAttributeStreamRef(int semantics, AttributeStreamBase stream) { // int test1 = VertexDescription.getPersistence(semantics); // int test2 = stream.getPersistence(); if ((stream != null) && VertexDescription.getPersistence(semantics) != stream .getPersistence())// input stream has wrong persistence // FIXME exc throw new IllegalArgumentException(); // Do not check for the stream size here to allow several streams to be // attached before the point count is changed. addAttribute(semantics); int attributeIndex = m_description.getAttributeIndex(semantics); if (m_vertexAttributes == null) m_vertexAttributes = new AttributeStreamBase[m_description .getAttributeCount()]; m_vertexAttributes[attributeIndex] = stream; notifyModified(DirtyFlags.DirtyAll); } // Checked vs. Jan 11, 2011 @Override void _beforeDropAttributeImpl(int semantics) { _touch(); int attributeIndex = m_description.getAttributeIndex(semantics); // _ASSERT(attributeIndex >= 0); AttributeStreamBase[] newAttributes = null; if (m_vertexAttributes != null) { newAttributes = new AttributeStreamBase[m_description .getAttributeCount() - 1]; for (int i = 0; i < attributeIndex; i++) newAttributes[i] = m_vertexAttributes[i]; for (int i = attributeIndex + 1; i < m_description .getAttributeCount(); i++) newAttributes[i - 1] = m_vertexAttributes[i]; } m_vertexAttributes = newAttributes; // late assignment to try to stay // valid if out-of memory happens. notifyModified(DirtyFlags.DirtyAll); } // Checked vs. Jan 11, 2011 @Override void _afterAddAttributeImpl(int semantics) { _touch(); int attributeIndex = m_description.getAttributeIndex(semantics); // _ASSERT(attributeIndex >= 0); AttributeStreamBase[] newAttributes = null; if (m_vertexAttributes != null) { newAttributes = new AttributeStreamBase[m_description .getAttributeCount()]; if (m_vertexAttributes != null) { // Do not create new stream The stream will be created when one // queries or sets a point to it. for (int i = 0; i < attributeIndex; i++) newAttributes[i] = m_vertexAttributes[i]; for (int i = attributeIndex + 1; i < m_description .getAttributeCount(); i++) newAttributes[i] = m_vertexAttributes[i - 1]; } } m_vertexAttributes = newAttributes; // late assignment to try to stay // valid if out-of memory happens. m_reservedPointCount = -1;// we need to recreate the new attribute then notifyModified(DirtyFlags.DirtyAll); } // Checked vs. Jan 11, 2011 protected void _updateEnvelope(Envelope2D env) { _updateAllDirtyIntervals(true); m_envelope.queryEnvelope2D(env); } // note: overload for polylines/polygons with curves // Checked vs. Jan 11, 2011 protected void _updateEnvelope(Envelope3D env) { _updateAllDirtyIntervals(true); m_envelope.queryEnvelope3D(env); } // note: overload for polylines/polygons with curves // Checked vs. Jan 11, 2011 protected void _updateLooseEnvelope(Envelope2D env) { // TODO ROHIT has this set to true? _updateAllDirtyIntervals(false); m_envelope.queryEnvelope2D(env); } // note: overload for polylines/polygons with curves // Checked vs. Jan 11, 2011 /** * \internal Calculates loose envelope. Returns True if the calculation * renders exact envelope. */ protected void _updateLooseEnvelope(Envelope3D env) { // TODO ROHIT has this set to true? _updateAllDirtyIntervals(false); m_envelope.queryEnvelope3D(env); } // note: overload for polylines/polygons with curves // Checked vs. Jan 11, 2011 @Override public void queryEnvelope(Envelope env) { _updateAllDirtyIntervals(true); m_envelope.copyTo(env); } // TODO rename to remove 2D // Checked vs. Jan 11, 2011 @Override public void queryEnvelope2D(Envelope2D env) { _updateEnvelope(env); } // Checked vs. Jan 11, 2011 // TODO rename to remove 3D @Override public void queryEnvelope3D(Envelope3D env) { _updateEnvelope(env); } // Checked vs. Jan 11, 2011 // TODO rename to remove 2D @Override public void queryLooseEnvelope2D(Envelope2D env) { _updateLooseEnvelope(env); } // Checked vs. Jan 11, 2011 // TODO rename to remove 3D @Override public void queryLooseEnvelope3D(Envelope3D env) { _updateLooseEnvelope(env); } // Checked vs. Jan 11, 2011 @Override public Envelope1D queryInterval(int semantics, int ordinate) { Envelope1D env = new Envelope1D(); if (isEmptyImpl()) { env.setEmpty(); return env; } _updateAllDirtyIntervals(true); return m_envelope.queryInterval(semantics, ordinate); } // Checked vs. Jan 11, 2011 // TODO Rename to getHashCode @Override public int hashCode() { int hashCode = m_description.hashCode(); if (!isEmptyImpl()) { int pointCount = getPointCount(); for (int i = 0, n = m_description.getAttributeCount(); i < n; i++) { int components = VertexDescription .getComponentCount(m_description._getSemanticsImpl(i)); AttributeStreamBase stream = m_vertexAttributes[i]; hashCode = stream.calculateHashImpl(hashCode, 0, pointCount * components); } } return hashCode; } // Checked vs. Jan 11, 2011 @Override public boolean equals(Object other) { // Java checks if (other == this) return true; if (!(other instanceof MultiVertexGeometryImpl)) return false; // Borg Implementation MultiVertexGeometryImpl otherMulti = (MultiVertexGeometryImpl) other; if (!(m_description.equals(otherMulti.m_description))) return false; if (isEmptyImpl() != otherMulti.isEmptyImpl()) return false; if (isEmptyImpl()) return true; // both geometries are empty int pointCount = getPointCount(); int pointCountOther = otherMulti.getPointCount(); if (pointCount != pointCountOther) return false; for (int i = 0; i < m_description.getAttributeCount(); i++) { int semantics = m_description.getSemantics(i); AttributeStreamBase stream = getAttributeStreamRef(semantics); AttributeStreamBase streamOther = otherMulti .getAttributeStreamRef(semantics); int components = VertexDescription.getComponentCount(semantics); if (!stream.equals(streamOther, 0, pointCount * components)) return false; } return true; } // Checked vs. Jan 11, 2011 /** * Sets the envelope of the Geometry. The Envelope description must match * that of the Geometry. */ public void setEnvelope(Envelope env) { if (!m_description.equals(env.getDescription())) // FIXME exc throw new IllegalArgumentException(); // m_envelope = (Envelope) env.clone(); m_envelope = (Envelope) env.createInstance(); env.copyTo(m_envelope); _setDirtyFlag(DirtyFlags.DirtyIntervals, false); } // Checked vs. Jan 11, 2011 @Override public void copyTo(Geometry dstGeom) { // Consider this: // Imagine if we produce 100 copies, each will have dirty envelope to // calculate - not good. // However, if the copied geometry is changed immediately, we do not // want to call _UpdateDirtyParams twice. // That is why this is commented out so far. // _UpdateDirtyParams(); MultiVertexGeometryImpl dst = (MultiVertexGeometryImpl) dstGeom; if (dst.getType() != getType()) // FIXME exc throw new IllegalArgumentException(); _verifyAllStreams(); dst.m_description = m_description; dst.m_vertexAttributes = null; int nattrib = m_description.getAttributeCount(); AttributeStreamBase[] cloneAttributes = null; if (m_vertexAttributes != null) { cloneAttributes = new AttributeStreamBase[nattrib]; for (int i = 0; i < nattrib; i++) { if (m_vertexAttributes[i] != null) { int ncomps = VertexDescription .getComponentCount(m_description ._getSemanticsImpl(i)); cloneAttributes[i] = m_vertexAttributes[i] .restrictedClone(getPointCount() * ncomps); } } } if (m_envelope != null) { dst.m_envelope = (Envelope) m_envelope.createInstance(); m_envelope.copyTo(dst.m_envelope); // dst.m_envelope = (Envelope) m_envelope.clone(); } else dst.m_envelope = null; dst.m_pointCount = m_pointCount; dst.m_flagsMask = m_flagsMask; dst.m_vertexAttributes = cloneAttributes; // FIXME accelerators // if(m_accelerators != null) // dst.m_accelerators = m_accelerators; try { _copyToImpl(dst); // copy child props } catch (Exception ex) { dst.setEmpty(); // TODO fix exception throw new RuntimeException(ex); } } // Checked vs. Jan 11, 2011 public boolean _attributeStreamIsAllocated(int semantics) { throwIfEmpty(); int attributeIndex = m_description.getAttributeIndex(semantics); if (attributeIndex >= 0 && m_vertexAttributes[attributeIndex] != null) return true; return false; } // Checked vs. Jan 11, 2011 void _setEmptyImpl() { m_pointCount = 0; m_reservedPointCount = -1; m_vertexAttributes = null;// release it all streams. notifyModified(DirtyFlags.DirtyAll); } // Checked vs. Jan 11, 2011 /** * Notifies the Geometry of changes made to the vertices so that it could * reset cached structures. */ public void notifyModified(int flags) { if (flags == DirtyFlags.DirtyAll) { m_reservedPointCount = -1;// forget the reserved point number _notifyModifiedAllImpl(); } m_flagsMask |= flags; // FIXME acceler _clearAccelerators(); _touch(); } // Checked vs. Jan 11, 2011 /** * @param bExact * True, when the exact envelope need to be calculated and false * for the loose one. */ protected void _updateAllDirtyIntervals(boolean bExact) { _verifyAllStreams(); if (_hasDirtyFlag(DirtyFlags.DirtyIntervals)) { if (null == m_envelope) m_envelope = new Envelope(m_description); else m_envelope.assignVertexDescription(m_description); if (isEmpty()) { m_envelope.setEmpty(); return; } _updateXYImpl(bExact);// efficient method for xy's // now go through other attribues. for (int attributeIndex = 1; attributeIndex < m_description .getAttributeCount(); attributeIndex++) { int semantics = m_description._getSemanticsImpl(attributeIndex); int ncomps = VertexDescription.getComponentCount(semantics); AttributeStreamBase stream = m_vertexAttributes[attributeIndex]; for (int iord = 0; iord < ncomps; iord++) { Envelope1D interval = new Envelope1D(); interval.setEmpty(); for (int i = 0; i < m_pointCount; i++) { double value = stream.readAsDbl(i * ncomps + iord);// some // optimization // is // possible // if // non-virtual // method // is // used interval.merge(value); } m_envelope.setInterval(semantics, iord, interval); } } if (bExact) _setDirtyFlag(DirtyFlags.DirtyIntervals, false); } } // Checked vs. Jan 11, 2011 /** * \internal Updates x, y intervals. */ public void _updateXYImpl(boolean bExact) { m_envelope.setEmpty(); AttributeStreamOfDbl stream = (AttributeStreamOfDbl) m_vertexAttributes[0]; Point2D pt = new Point2D(); for (int i = 0; i < m_pointCount; i++) { stream.read(2 * i, pt); m_envelope.merge(pt); } } void calculateEnvelope2D(Envelope2D env, boolean bExact) { env.setEmpty(); AttributeStreamOfDbl stream = (AttributeStreamOfDbl) m_vertexAttributes[0]; Point2D pt = new Point2D(); for (int i = 0; i < m_pointCount; i++) { stream.read(2 * i, pt); env.merge(pt); } } // Checked vs. Jan 11, 2011 lots of changes /** * \internal Verifies all streams (calls _VerifyStream for every attribute). */ protected void _verifyAllStreamsImpl() { // This method checks that the streams are of correct size. // It resizes the streams to ensure they are not shorter than // m_PointCount // _ASSERT(_HasDirtyFlag(enum_value1(DirtyFlags, // DirtyVerifiedStreams))); if (m_reservedPointCount < m_pointCount) // an optimization to skip this // expensive loop when // adding point by point { if (m_vertexAttributes == null) m_vertexAttributes = new AttributeStreamBase[m_description .getAttributeCount()]; m_reservedPointCount = NumberUtils.intMax(); for (int attributeIndex = 0; attributeIndex < m_description .getAttributeCount(); attributeIndex++) { int semantics = m_description._getSemanticsImpl(attributeIndex); if (m_vertexAttributes[attributeIndex] != null) { int ncomp = VertexDescription.getComponentCount(semantics); int size = m_vertexAttributes[attributeIndex].virtualSize() / ncomp; if (size < m_pointCount) { size = (m_reservedPointCount > m_pointCount + 5) ? (m_pointCount * 5 + 3) / 4 : m_pointCount;// reserve 25% more than user // asks m_vertexAttributes[attributeIndex].resize(size * ncomp, VertexDescription.getDefaultValue(semantics)); } if (size < m_reservedPointCount) m_reservedPointCount = size; } else { m_vertexAttributes[attributeIndex] = AttributeStreamBase .createAttributeStreamWithSemantics(semantics, m_pointCount); // FIXME when attribute stream is updated, update this code. // m_vertexAttributes[attributeIndex] = // AttributeStreamBase.createAttributeStream(semantics, // m_pointCount); m_reservedPointCount = m_pointCount; } } } _verifyStreamsImpl(); _setDirtyFlag(DirtyFlags.DirtyVerifiedStreams, false); } // Checked vs. Jan 11, 2011 void _resizeImpl(int pointCount) { if (pointCount < 0) throw new IllegalArgumentException(); if (pointCount == m_pointCount) return; m_pointCount = pointCount; notifyModified(DirtyFlags.DirtyAllInternal); } // Checked vs. Jan 11, 2011 int QueryCoordinates(Point2D[] dst, int dstSize, int beginIndex, int endIndex) { int endIndexC = endIndex < 0 ? m_pointCount : endIndex; endIndexC = Math.min(endIndexC, beginIndex + dstSize); if (beginIndex < 0 || beginIndex >= m_pointCount || endIndexC < beginIndex) throw new IllegalArgumentException(); AttributeStreamOfDbl xy = (AttributeStreamOfDbl) getAttributeStreamRef(VertexDescription.Semantics.POSITION); int j = 0; double[] dstArray = new double[dst.length * 2]; xy.readRange(2 * beginIndex, endIndexC - beginIndex, dstArray, j, true); for (int i = 0; i < dst.length; i++) { dst[i] = new Point2D(dstArray[i * 2], dstArray[i * 2 + 1]); } // for (int i = beginIndex; i < endIndexC; i++, j++) // { // xy.read(2 * i, dst[j]); // } return endIndexC; } // Checked vs. Jan 11, 2011 int QueryCoordinates(Point3D[] dst, int dstSize, int beginIndex, int endIndex) { int endIndexC = endIndex < 0 ? m_pointCount : endIndex; endIndexC = Math.min(endIndexC, beginIndex + dstSize); if (beginIndex < 0 || beginIndex >= m_pointCount || endIndexC < beginIndex) // TODO replace geometry exc throw new IllegalArgumentException(); AttributeStreamOfDbl xy = (AttributeStreamOfDbl) getAttributeStreamRef(VertexDescription.Semantics.POSITION); AttributeStreamOfDbl z = null; double v = VertexDescription .getDefaultValue(VertexDescription.Semantics.Z); boolean bHasZ = hasAttribute(VertexDescription.Semantics.Z); if (bHasZ) z = (AttributeStreamOfDbl) getAttributeStreamRef(VertexDescription.Semantics.Z); int j = 0; for (int i = beginIndex; i < endIndexC; i++, j++) { dst[j].x = xy.read(2 * i); dst[j].y = xy.read(2 * i + 1); dst[j].z = bHasZ ? z.read(i) : v; dst[j] = getXYZ(i); } return endIndexC; } // Checked vs. Jan 11, 2011 // -1 : DirtySimple is true (whether or not the MultiPath is Simple is // unknown) // 0 : DirtySimple is false and the MultiPath is not Weak Simple // 1 : DirtySimple is false and the MultiPath is Weak Simple but not ring // ordering may be invalid // 2 : DirtySimple is false and the MultiPath is Strong Simple (Weak Simple // and valid ring ordering) public int getIsSimple(double tolerance) { if (!_hasDirtyFlag(DirtyFlags.DirtyIsKnownSimple)) { if (!_hasDirtyFlag(DirtyFlags.IsWeakSimple)) { return 0; } if (m_simpleTolerance >= tolerance) { if (!_hasDirtyFlag(DirtyFlags.DirtyOGCFlags)) return 2; return 1; } return -1; } return -1; } void setIsSimple(int isSimpleRes, double tolerance, boolean ogc_known) { m_simpleTolerance = tolerance; if (isSimpleRes == GeometryXSimple.Unknown) { _setDirtyFlag(DirtyFlags.DirtyIsKnownSimple, true); _setDirtyFlag(DirtyFlags.DirtyOGCFlags, true); return; } _setDirtyFlag(DirtyFlags.DirtyIsKnownSimple, false); if (!ogc_known) _setDirtyFlag(DirtyFlags.DirtyOGCFlags, true); if (isSimpleRes == GeometryXSimple.Not) { _setDirtyFlag(DirtyFlags.IsWeakSimple, false); _setDirtyFlag(DirtyFlags.IsStrongSimple, false); } else if (isSimpleRes == GeometryXSimple.Weak) { _setDirtyFlag(DirtyFlags.IsWeakSimple, true); _setDirtyFlag(DirtyFlags.IsStrongSimple, false); } else if (isSimpleRes == GeometryXSimple.Strong) { _setDirtyFlag(DirtyFlags.IsWeakSimple, true); _setDirtyFlag(DirtyFlags.IsStrongSimple, true); } else throw new GeometryException("internal error");// what? } double _getSimpleTolerance() { return m_simpleTolerance; } public GeometryAccelerators _getAccelerators() { return m_accelerators; } void _clearAccelerators() { if (m_accelerators != null) m_accelerators = null; } void _interpolateTwoVertices(int vertex1, int vertex2, double f, Point outPoint) { if (vertex1 < 0 || vertex1 >= m_pointCount) throw new GeometryException("index out of bounds."); if (vertex2 < 0 || vertex2 >= m_pointCount) throw new GeometryException("index out of bounds."); // _ASSERT(!IsEmpty()); // _ASSERT(m_vertexAttributes != NULLPTR); _verifyAllStreams(); outPoint.assignVertexDescription(m_description); if (outPoint.isEmpty()) outPoint._setToDefault(); for (int attributeIndex = 0; attributeIndex < m_description .getAttributeCount(); attributeIndex++) { int semantics = m_description._getSemanticsImpl(attributeIndex); for (int icomp = 0, ncomp = VertexDescription .getComponentCount(semantics); icomp < ncomp; icomp++) { double v1 = m_vertexAttributes[attributeIndex].readAsDbl(ncomp * vertex1 + icomp); double v2 = m_vertexAttributes[attributeIndex].readAsDbl(ncomp * vertex2 + icomp); outPoint.setAttribute(semantics, icomp, v1 * (1.0 - f) + v2 * f); } } } double _getShortestDistance(int vertex1, int vertex2) { Point2D pt = getXY(vertex1); pt.sub(getXY(vertex2)); return pt.length(); } // FIXME Remove this method. It is not in the MultiVertexGeometryImpl... // /** // * Returns a reference to the given AttributeStream of the Geometry. Once // * the stream has been obtained, the vertices of the Geometry can be // * manipulated directly. Call notifyModified, when finished. The method // * allocates the stream if not present. // * // * @param semantics // * Semantics of the attribute to return stream for. // * @throws Throws // * empty_geometry for the empty geometry. // */ // public AttributeStreamBase getAttributeStream(int semantics) { // if (isEmpty()) // throw new GeometryException( // "This operation was performed on an Empty Geometry."); // // addAttribute(semantics); // _verifyAllStreams(); // // int attributeIndex = m_description.getAttributeIndex(semantics); // return m_vertexAttributes[attributeIndex]; // } // FIXME // ////////////////// METHODS To REMOVE /////////////////////// @Override public Point getPoint(int index) { if (index < 0 || index >= m_pointCount) throw new IndexOutOfBoundsException(); // _ASSERT(!IsEmpty()); // _ASSERT(m_vertexAttributes != null); _verifyAllStreams(); Point outPoint = new Point(); outPoint.assignVertexDescription(m_description); if (outPoint.isEmpty()) outPoint._setToDefault(); for (int attributeIndex = 0; attributeIndex < m_description .getAttributeCount(); attributeIndex++) { int semantics = m_description.getSemantics(attributeIndex); for (int icomp = 0, ncomp = VertexDescription .getComponentCount(semantics); icomp < ncomp; icomp++) { double v = m_vertexAttributes[attributeIndex].readAsDbl(ncomp * index + icomp); outPoint.setAttribute(semantics, icomp, v); } } return outPoint; } @Override public void setPoint(int index, Point src) { if (index < 0 || index >= m_pointCount) throw new IndexOutOfBoundsException(); Point point = src; if (src.isEmpty())// can not assign an empty point to a multipoint // vertex throw new IllegalArgumentException(); _verifyAllStreams();// verify all allocated streams are of necessary // size. VertexDescription vdin = point.getDescription(); for (int attributeIndex = 0; attributeIndex < vdin.getAttributeCount(); attributeIndex++) { int semantics = vdin.getSemantics(attributeIndex); int ncomp = VertexDescription.getComponentCount(semantics); for (int icomp = 0; icomp < ncomp; icomp++) { double v = point.getAttributeAsDbl(semantics, icomp); setAttribute(semantics, index, icomp, v); } } } @Override public void queryCoordinates(Point[] dst) { int sz = m_pointCount; if (dst.length < sz) throw new IllegalArgumentException(); // TODO: refactor to a better AttributeAray call (ReadRange?) for (int i = 0; i < sz; i++) { dst[i] = getPoint(i); } } @Override public void queryCoordinates(Point2D[] dst) { int sz = m_pointCount; if (dst.length < sz) throw new IllegalArgumentException(); // TODO: refactor to a better AttributeAray call (ReadRange?) for (int i = 0; i < sz; i++) { dst[i] = getXY(i); } } @Override public void queryCoordinates(Point3D[] dst) { int sz = m_pointCount; if (dst.length < sz) throw new IllegalArgumentException(); // TODO: refactor to a better AttributeAray call (ReadRange?) for (int i = 0; i < sz; i++) { dst[i] = getXYZ(i); } } // FIXME public abstract boolean _buildRasterizedGeometryAccelerator( double toleranceXY, GeometryAccelerationDegree accelDegree); public abstract boolean _buildQuadTreeAccelerator( GeometryAccelerationDegree d); // //////////////////METHODS To REMOVE /////////////////////// }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy