GISObject.java [src/gisobjects] Revision: default  Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2017, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package gisobjects;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import gisobjects.db.GISEngine;
import java.io.IOException;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
public interface GISObject {

    public static final int INPUT_PRECISION = 15;
    public static final int OUTPUT_PRECISION = 6;
    public static final int DEFAULT_ASSUMED_SRID = 4326;
    
    public enum GISContourType {
        ESRI_inner, ESRI_outer, openGIS_inner, openGIS_outer, undefined, unknown
    };

    public enum GISObjectType {
        unknown, feature, featurecollection, geometrycollection, linestring, multilinestring, multipolygon, polygon, point, multipoint
    }

    public enum GISType{
        geometry_type, geography_type, all_types
    }
    
    public enum UsePurpose{
        sql_server_use, ogc_use, all_purposes
    }
    
    public abstract boolean hasChanged();

    public abstract void hasChanged(boolean value);

    public double areaInAcres() throws GISObjectException;

    /**
     *
     * @param radius
     * @return A GISObject representing the resulting buffer around the boundary
     * of the input GISObject, or null on SQL not returning any valid data.
     * Otherwise an exception is thrown on error.
     * @throws GISObjectException
     */
    public GISObject buffer(double radius) throws GISObjectException;

    /**
     *
     * @return A GISObject representing a buffer around the centroid of the
     * input GISObject, or null on SQL not returning any valid data. Otherwise
     * an exception is thrown on error.
     * @param radius radius is specified in meters.
     *
     *
     * @throws GISObjectException
     */
    public GISObject bufferFromCentroid(double radius) throws GISObjectException;

    public GISObject clippedUnion(GISObject object) throws GISObjectException;

    public boolean contains(GISObject object2) throws GISObjectException;

    public GISObject difference(GISObject object2) throws GISObjectException;

    public void dissolve(double percentage) throws GISObjectException;

    public double distanceTo(GISObject otherObject) throws GISObjectException;

    public GISEngine getEngine();

    public Geometry getGeometry();

    public GISObject[] getEndPoints() throws GISObjectException;

    public default double getLatitude() throws GISObjectException {
        double ret_val = Double.NaN;
        Geometry tGeometry = getGeometry();
        if (null != tGeometry) {
            Point point = tGeometry.getCentroid();
            ret_val = point.getY();
        } else {
            throw new GISObjectException("This GISObject has no geometry.  Cannot find its envelope (bounding box).");
        }

        return ret_val;
    }

    public default double getLongitude() throws GISObjectException {
        double ret_val = Double.NaN;
        Geometry tGeometry = getGeometry();
        if (null != tGeometry) {
            Point point = tGeometry.getCentroid();
            ret_val = point.getX();
        } else {
            throw new GISObjectException("This GISObject has no geometry.  Cannot find its envelope (bounding box).");
        }

        return ret_val;
    }

    public default Envelope getEnvelope() throws GISObjectException {
        Envelope ret_val = null;
        Geometry tGeometry = getGeometry();
        if (null != tGeometry) {
            ret_val = tGeometry.getBoundary().getEnvelopeInternal();
        } else {
            throw new GISObjectException("This GISObject has no geometry.  Cannot find its envelope (bounding box).");
        }

        return ret_val;
    }

    /**
     * This function is useful in determining if a GISObject is openGIS
     * compliant in its rotation of points. To determine if a GISObject is
     * valid, however, please use the GISObject.isValid() call as this will test
     * also for GeoJSON compliance issues.
     *
     * @return This function will return true if the boundary polygon is ESRI
     * rotation and only if that polygon has no holes. Otherwise, openGIS
     * considers it to be openGIS compliant, if the boundary is ESRI shapefile
     * rotation but the polygon has a hole(s). NOTE: If no GIS Engine was
     * specified for this object, then a simple test will be made on the
     * boundary only to find an answer, otherwise, the GIS Engine defined will
     * be used to examine the entire object.
     *
     * @see GISObject#isValid()
     * @see gisobjects.db.GISEngineFactory#createGISEngine(java.sql.Connection)
     */
    public GISContourType getRotationType();

    public GISObject.GISObjectType getType();

    public GISObject insertHole(GISObject holeGeometry) throws GISObjectException;

    public GISObject intersection(GISObject object2) throws GISObjectException;

    public boolean intersects(GISObject object2) throws GISObjectException;

    /**
     * This function utilizes the underlying implementation's isValid() function
     * to check compliance with openGIS or GeoJSON standards for the data
     * contained therein. Currently, this class's implementations utilize
     * various geometry or feature classes of GeoTools and run those validation
     * procedures.
     *
     * @return Returns true if valid and false if not valid according to the
     * underlying implementation standards.
     * @see gisobjects.vector.GIS_Geometry#isValid()
     * @see gisobjects.vector.GIS_GeometryCollection#isValid()
     * @see gisobjects.vector.GIS_FeatureCollection#isValid()
     * @see gisobjects.db.MsSql#getOpenGISRotation(GISObjects.GISObject)
     * @see gisobjects.db.MsSql#isESRIRotation(GISObjects.GISObject)
     */
    public boolean isValid();
    
    public void makeValid(UsePurpose reason, GISType type) throws GISObjectException;

    public boolean overlaps(GISObject object2) throws GISObjectException;

    public void setGISEngine(GISEngine engine);

    public void setRotationType(GISContourType rotationType);

    public void setUseEngine(boolean useEngine);

    public JSONObject toJSON() throws IOException, JSONException;

    public boolean touches(GISObject object2) throws GISObjectException;

    public String toWKT();

    public GISObject union(GISObject object2) throws GISObjectException;

    public double[] getCentroid() throws GISObjectException;

    public double length() throws GISObjectException;

}