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

com.datastax.dse.driver.shaded.esri.core.geometry.OperatorConvexHullCursor Maven / Gradle / Ivy

/*
 Copyright 1995-2015 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.datastax.dse.driver.shaded.esri.core.geometry;

class OperatorConvexHullCursor extends GeometryCursor {
	private ProgressTracker m_progress_tracker;
	private boolean m_b_merge;
	private boolean m_b_done;
	private GeometryCursor m_inputGeometryCursor;
	private int m_index;
	ConvexHull m_hull = new ConvexHull();
	
	OperatorConvexHullCursor(boolean b_merge, GeometryCursor geoms,
			ProgressTracker progress_tracker) {
		m_index = -1;
		if (geoms == null)
			throw new IllegalArgumentException();

		m_b_merge = b_merge;
		m_b_done = false;
		m_inputGeometryCursor = geoms;
		m_progress_tracker = progress_tracker;
	}

	@Override
	public Geometry next() {
		if (m_b_merge) {
			if (!m_b_done) {
				Geometry result = calculateConvexHullMerging_(
						m_inputGeometryCursor, m_progress_tracker);
				m_b_done = true;
				return result;
			}

			return null;
		}

		if (!m_b_done) {
			Geometry geometry = m_inputGeometryCursor.next();
			if (geometry != null) {
				m_index = m_inputGeometryCursor.getGeometryID();
				return calculateConvexHull_(geometry, m_progress_tracker);
			}

			m_b_done = true;
		}

		return null;
	}

	@Override
	public int getGeometryID() {
		return m_index;
	}

	private Geometry calculateConvexHullMerging_(GeometryCursor geoms,
			ProgressTracker progress_tracker) {
		Geometry geometry;

		while ((geometry = geoms.next()) != null)
			m_hull.addGeometry(geometry);

		return m_hull.getBoundingGeometry();
	}
	
	@Override
	public boolean tock() {
		if (m_b_done)
			return true;
		
		if (!m_b_merge)
		{
			//Do not use tick/tock with the non-merging convex hull.
			//Call tick/next instead,
			//because tick pushes geometry into the cursor, and next performs a single convex hull on it. 
			throw new GeometryException("Invalid call for non merging convex hull.");
		}
		
		Geometry geometry = m_inputGeometryCursor.next();
		if (geometry != null) {
			m_hull.addGeometry(geometry);
			return true;
		} else {
			throw new GeometryException("Expects a non-null geometry.");
		}
	}

	static Geometry calculateConvexHull_(Geometry geom,
			ProgressTracker progress_tracker) {
		if (isConvex_(geom, progress_tracker))
			return geom;

		int type = geom.getType().value();

		if (MultiPath.isSegment(type)) {
			Polyline polyline = new Polyline(geom.getDescription());
			polyline.addSegment((Segment) geom, true);
			return polyline;
		}

		if (type == Geometry.GeometryType.MultiPoint) {
			MultiPoint multi_point = (MultiPoint) geom;
			if (multi_point.getPointCount() == 2) {
				Point pt = new Point();
				Polyline polyline = new Polyline(geom.getDescription());
				multi_point.getPointByVal(0, pt);
				polyline.startPath(pt);
				multi_point.getPointByVal(1, pt);
				polyline.lineTo(pt);
				return polyline;
			}
		}

		Polygon convex_hull = ConvexHull.construct((MultiVertexGeometry) geom);
		return convex_hull;
	}

	static boolean isConvex_(Geometry geom, ProgressTracker progress_tracker) {
		if (geom.isEmpty())
			return true; // vacuously true

		int type = geom.getType().value();

		if (type == Geometry.GeometryType.Point)
			return true; // vacuously true

		if (type == Geometry.GeometryType.Envelope)
			return true; // always convex

		if (MultiPath.isSegment(type))
			return false; // upgrade to polyline

		if (type == Geometry.GeometryType.MultiPoint) {
			MultiPoint multi_point = (MultiPoint) geom;

			if (multi_point.getPointCount() == 1)
				return true; // vacuously true

			return false; // upgrade to polyline if point count is 2, otherwise
							// create convex hull
		}

		if (type == Geometry.GeometryType.Polyline) {
			Polyline polyline = (Polyline) geom;

			if (polyline.getPathCount() == 1 && polyline.getPointCount() <= 2)
				return true; // vacuously true

			return false; // create convex hull
		}

		Polygon polygon = (Polygon) geom;

		if (polygon.getPathCount() != 1)
			return false;

		if (polygon.getPointCount() <= 2)
			return true; // vacuously true

		return ConvexHull.isPathConvex(polygon, 0, progress_tracker);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy