Search in sources :

Example 1 with GeodeticCalculator

use of org.apache.sis.referencing.GeodeticCalculator in project geotoolkit by Geomatys.

the class JTS method orthodromicDistance.

/**
 * Computes the orthodromic distance between two points. This method: <p>
 * <ol> <li>Transforms both points to geographic coordinates
 * (<var>latitude</var>,<var>longitude</var>).</li> <li>Computes the
 * orthodromic distance between the two points using ellipsoidal
 * calculations.</li> </ol> <p> The real work is performed by
 * {@link GeodeticCalculator}. This convenience method simply manages a pool
 * of pre-defined geodetic calculators for the given coordinate reference
 * system in order to avoid repetitive object creation. If a large amount of
 * orthodromic distances need to be computed, direct use of
 * {@link GeodeticCalculator} provides better performance than this
 * convenience method.
 *
 * @param p1 First point
 * @param p2 Second point
 * @param crs Reference system the two points are in.
 * @return Orthodromic distance between the two points, in meters.
 * @throws TransformException if the coordinates can't be transformed from
 * the specified CRS to a
 * {@linkplain org.opengis.referencing.crs.GeographicCRS geographic CRS}.
 */
public static synchronized double orthodromicDistance(final Coordinate p1, final Coordinate p2, final CoordinateReferenceSystem crs) throws TransformException {
    ensureNonNull("p1", p1);
    ensureNonNull("p2", p2);
    ensureNonNull("crs", crs);
    /*
         * Need to synchronize because we use a single instance of a Map (CALCULATORS) as well as
         * shared instances of GeodeticCalculator and GeneralDirectPosition (POSITIONS). None of
         * them are thread-safe.
         */
    GeodeticCalculator gc = CALCULATORS.get(crs);
    if (gc == null) {
        gc = GeodeticCalculator.create(crs);
        CALCULATORS.put(crs, gc);
    }
    assert crs.equals(gc.getPositionCRS()) : crs;
    final GeneralDirectPosition pos = POSITIONS[Math.min(POSITIONS.length - 1, crs.getCoordinateSystem().getDimension())];
    pos.setCoordinateReferenceSystem(crs);
    copy(p1, pos.coordinates);
    gc.setStartPoint(pos);
    copy(p2, pos.coordinates);
    gc.setEndPoint(pos);
    return gc.getGeodesicDistance();
}
Also used : GeneralDirectPosition(org.apache.sis.geometry.GeneralDirectPosition) GeodeticCalculator(org.apache.sis.referencing.GeodeticCalculator)

Example 2 with GeodeticCalculator

use of org.apache.sis.referencing.GeodeticCalculator in project geotoolkit by Geomatys.

the class GeometryTransformer method drawArc.

/**
 * Draw a succession of segments representing an arc or a circle.
 * @implNote
 * This method checks given angles to ensure that a full circle is drawn using
 * the strict necessary amount of points.
 *
 * @param center The center point of the arc to draw. The unit of measure MUST
 * be consistent with the unit of given radius.
 * @param radius The Radius of the arc to draw. Unit must be the same as the
 * one of input center point.
 * @param startAzimuth Start of the drawn line relative to the geographic north (clockwise order).
 * @param endAzimuth End of the drawn line relative to the geographic north (clockwise order). If
 * it's inferior to start angle, the arc is drawn on counter-clockwise order. If superior, the arc is
 * drawn on clockwise order.
 * @param angularStep The step to apply on the trigonometric circle to find
 * next point of the arc. its sign will be adapted to match draw order (clockwise
 * or counter clockwise).
 * @return An arc, as a discrete succession of points of configured precision.
 */
private static Coordinate[] drawArc(final DirectPosition center, final Measure radius, final Measure startAzimuth, final Measure endAzimuth, final Measure angularStep) throws TransformException {
    ArgumentChecks.ensureNonNull("Center point", center);
    final CoordinateReferenceSystem sourceCrs = center.getCoordinateReferenceSystem();
    ArgumentChecks.ensureNonNull("coordinate reference system", sourceCrs);
    final SingleCRS hCrs = CRS.getHorizontalComponent(sourceCrs);
    if (hCrs == null) {
        throw new UnconvertibleObjectException("Cannot extract geometries without projected part.");
    }
    final int xAxis = AxisDirections.indexOfColinear(sourceCrs.getCoordinateSystem(), hCrs.getCoordinateSystem());
    final int yAxis = xAxis + 1;
    final GeodeticCalculator gc = GeodeticCalculator.create(sourceCrs);
    gc.setStartPoint(center);
    final Unit<Length> radiusUnit = gc.getDistanceUnit();
    final double r = radius.getUnit(Length.class).getConverterTo(radiusUnit).convert(radius.value);
    double theta = startAzimuth.getUnit(Angle.class).getConverterTo(Units.DEGREE).convert(startAzimuth.value);
    double end = endAzimuth.getUnit(Angle.class).getConverterTo(Units.DEGREE).convert(endAzimuth.value);
    double phi = end - theta;
    // Draw a circle. We don"t bother preserving iteration order
    double positivePhi = Math.abs(phi);
    final boolean isCircle = positivePhi - 1e-8 <= 0 || positivePhi >= 360.0;
    if (isCircle) {
        phi = 360.0;
    }
    double step = (phi < 0 ? -1 : 1) * angularStep.getUnit(Angle.class).getConverterTo(Units.DEGREE).convert(angularStep.value);
    if ((phi / step) < 3) {
        step = phi / 3;
    }
    final Coordinate[] arcPerimeter = new Coordinate[(int) Math.ceil(phi / step) + 1];
    final DoubleFunction<Coordinate> pointOnCircle = azimuth -> {
        azimuth = ((azimuth + 180) % 360) - 180;
        gc.setStartingAzimuth(azimuth);
        gc.setGeodesicDistance(r);
        final DirectPosition pt = gc.getEndPoint();
        return new Coordinate(pt.getOrdinate(xAxis), pt.getOrdinate(yAxis));
    };
    /* Don't entirely fill array. Last point will be computed in a sepcial case,
         * to ensure it's closed properly if it's a circle.
         */
    for (int i = 0; i < arcPerimeter.length - 1; i++, theta += step) {
        arcPerimeter[i] = pointOnCircle.apply(theta);
    }
    if (isCircle) {
        // Ensure last point is the start point
        arcPerimeter[arcPerimeter.length - 1] = arcPerimeter[0];
    } else {
        arcPerimeter[arcPerimeter.length - 1] = pointOnCircle.apply(end);
    }
    return arcPerimeter;
}
Also used : SingleCRS(org.opengis.referencing.crs.SingleCRS) Measure(org.apache.sis.internal.jaxb.gml.Measure) Unit(javax.measure.Unit) CRS(org.apache.sis.referencing.CRS) GeodeticCalculator(org.apache.sis.referencing.GeodeticCalculator) Spliterators(java.util.Spliterators) NoSuchAuthorityCodeException(org.opengis.referencing.NoSuchAuthorityCodeException) Coordinate(org.locationtech.jts.geom.Coordinate) MeasureType(org.geotoolkit.gml.xml.v321.MeasureType) PolygonPatchType(org.geotoolkit.gml.xml.v321.PolygonPatchType) Envelope(org.geotoolkit.gml.xml.Envelope) Matcher(java.util.regex.Matcher) SingleCRS(org.opengis.referencing.crs.SingleCRS) GeometryProperty(org.geotoolkit.gml.xml.GeometryProperty) Map(java.util.Map) Ring(org.geotoolkit.gml.xml.Ring) TransformException(org.opengis.referencing.operation.TransformException) MultiLineString(org.locationtech.jts.geom.MultiLineString) AxesConvention(org.apache.sis.referencing.cs.AxesConvention) AbstractCRS(org.apache.sis.referencing.crs.AbstractCRS) Logger(java.util.logging.Logger) MultiSurface(org.geotoolkit.gml.xml.MultiSurface) Objects(java.util.Objects) Cache(org.apache.sis.util.collection.Cache) List(java.util.List) Stream(java.util.stream.Stream) UnconvertibleObjectException(org.apache.sis.util.UnconvertibleObjectException) Polygon(org.locationtech.jts.geom.Polygon) Optional(java.util.Optional) Geometry(org.locationtech.jts.geom.Geometry) SurfaceType(org.geotoolkit.gml.xml.v321.SurfaceType) Pattern(java.util.regex.Pattern) Spliterator(java.util.Spliterator) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) FactoryException(org.opengis.util.FactoryException) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) Coordinates(org.geotoolkit.gml.xml.Coordinates) PointProperty(org.geotoolkit.gml.xml.PointProperty) ArgumentChecks(org.apache.sis.util.ArgumentChecks) DoubleFunction(java.util.function.DoubleFunction) LinearRing(org.locationtech.jts.geom.LinearRing) HashMap(java.util.HashMap) DirectPositionList(org.geotoolkit.gml.xml.DirectPositionList) Function(java.util.function.Function) Supplier(java.util.function.Supplier) CurveProperty(org.geotoolkit.gml.xml.CurveProperty) MultiGeometry(org.geotoolkit.gml.xml.MultiGeometry) ArrayList(java.util.ArrayList) Angle(javax.measure.quantity.Angle) AbstractGeometry(org.geotoolkit.gml.xml.AbstractGeometry) Length(javax.measure.quantity.Length) GeneralDirectPosition(org.apache.sis.geometry.GeneralDirectPosition) AbstractCurveSegment(org.geotoolkit.gml.xml.AbstractCurveSegment) WithCoordinates(org.geotoolkit.gml.xml.WithCoordinates) AxisDirections(org.apache.sis.internal.referencing.AxisDirections) PointPropertyType(org.geotoolkit.gml.xml.v321.PointPropertyType) CurveSegmentArrayProperty(org.geotoolkit.gml.xml.CurveSegmentArrayProperty) StreamSupport(java.util.stream.StreamSupport) Point(org.geotoolkit.gml.xml.Point) NoSuchElementException(java.util.NoSuchElementException) DirectPosition(org.opengis.geometry.DirectPosition) Units(org.apache.sis.measure.Units) GeometryFactory(org.locationtech.jts.geom.GeometryFactory) Iterator(java.util.Iterator) PolygonProperty(org.geotoolkit.gml.xml.PolygonProperty) JTS(org.geotoolkit.geometry.jts.JTS) AbstractSurface(org.geotoolkit.gml.xml.AbstractSurface) Consumer(java.util.function.Consumer) MultiCurve(org.geotoolkit.gml.xml.MultiCurve) GeometryCollection(org.locationtech.jts.geom.GeometryCollection) LineString(org.locationtech.jts.geom.LineString) AbstractMap(java.util.AbstractMap) ArcByCenterPointType(org.geotoolkit.gml.xml.v321.ArcByCenterPointType) Curve(org.geotoolkit.gml.xml.Curve) AbstractRingProperty(org.geotoolkit.gml.xml.AbstractRingProperty) MultiPoint(org.locationtech.jts.geom.MultiPoint) SurfaceProperty(org.geotoolkit.gml.xml.SurfaceProperty) Collections(java.util.Collections) LineStringProperty(org.geotoolkit.gml.xml.LineStringProperty) AbstractRing(org.geotoolkit.gml.xml.AbstractRing) GeneralDirectPosition(org.apache.sis.geometry.GeneralDirectPosition) DirectPosition(org.opengis.geometry.DirectPosition) Point(org.geotoolkit.gml.xml.Point) MultiPoint(org.locationtech.jts.geom.MultiPoint) GeodeticCalculator(org.apache.sis.referencing.GeodeticCalculator) UnconvertibleObjectException(org.apache.sis.util.UnconvertibleObjectException) Angle(javax.measure.quantity.Angle) Length(javax.measure.quantity.Length) Coordinate(org.locationtech.jts.geom.Coordinate) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 3 with GeodeticCalculator

use of org.apache.sis.referencing.GeodeticCalculator in project geotoolkit by Geomatys.

the class MeasureUtilities method calculateLenght.

public static double calculateLenght(final Geometry geom, final CoordinateReferenceSystem geomCRS, final Unit<Length> unit) {
    if (geom == null || !(geom instanceof LineString))
        return 0;
    final LineString line = (LineString) geom;
    Coordinate[] coords = line.getCoordinates();
    try {
        final GeodeticCalculator calculator = GeodeticCalculator.create(geomCRS);
        final GeneralDirectPosition pos = new GeneralDirectPosition(geomCRS);
        double length = 0;
        for (int i = 0, n = coords.length - 1; i < n; i++) {
            Coordinate coord1 = coords[i];
            Coordinate coord2 = coords[i + 1];
            pos.coordinates[0] = coord1.x;
            pos.coordinates[1] = coord1.y;
            calculator.setStartPoint(pos);
            pos.coordinates[0] = coord2.x;
            pos.coordinates[1] = coord2.y;
            calculator.setEndPoint(pos);
            length += calculator.getGeodesicDistance();
        }
        if (!Units.METRE.equals(unit)) {
            UnitConverter converter = Units.METRE.getConverterTo(unit);
            length = converter.convert(length);
        }
        return length;
    } catch (MismatchedDimensionException ex) {
        LOGGER.log(Level.WARNING, null, ex);
    }
    return 0;
}
Also used : GeneralDirectPosition(org.apache.sis.geometry.GeneralDirectPosition) LineString(org.locationtech.jts.geom.LineString) Coordinate(org.locationtech.jts.geom.Coordinate) UnitConverter(javax.measure.UnitConverter) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) GeodeticCalculator(org.apache.sis.referencing.GeodeticCalculator)

Example 4 with GeodeticCalculator

use of org.apache.sis.referencing.GeodeticCalculator in project geotoolkit by Geomatys.

the class CanvasUtilities method getGeographicScale.

/**
 * Returns the geographic scale, in a ground unit manner, relation between map display size
 * and real ground unit meters.
 *
 * @throws IllegalStateException If the affine transform used for conversion is in illegal state.
 */
public static double getGeographicScale(Point2D center, AffineTransform2D objToDisp, CoordinateReferenceSystem crs) throws TransformException {
    final double[] P1 = new double[] { center.getX(), center.getY() };
    final double[] P2 = new double[] { P1[0], P1[1] + 1 };
    final AffineTransform trs;
    try {
        trs = objToDisp.createInverse();
    } catch (NoninvertibleTransformException ex) {
        throw new TransformException(ex.getLocalizedMessage(), ex);
    }
    trs.transform(P1, 0, P1, 0, 1);
    trs.transform(P2, 0, P2, 0, 1);
    final Unit unit = crs.getCoordinateSystem().getAxis(0).getUnit();
    final double distance;
    if (unit.isCompatible(Units.METRE)) {
        final Point2D p1 = new Point2D.Double(P1[0], P1[1]);
        final Point2D p2 = new Point2D.Double(P2[0], P2[1]);
        final UnitConverter conv = unit.getConverterTo(Units.METRE);
        distance = conv.convert(p1.distance(p2));
    } else {
        /*
             * If the latitude coordinates (for example) are outside the +/-90°
             * range, translate the points in order to bring them back in the
             * domain of validity.
             */
        final CoordinateSystem cs = crs.getCoordinateSystem();
        for (int i = cs.getDimension(); --i >= 0; ) {
            final CoordinateSystemAxis axis = cs.getAxis(i);
            double delta = P1[i] - axis.getMaximumValue();
            if (delta > 0) {
                P1[i] -= delta;
                P2[i] -= delta;
            }
            delta = P2[i] - axis.getMaximumValue();
            if (delta > 0) {
                P1[i] -= delta;
                P2[i] -= delta;
            }
            delta = axis.getMinimumValue() - P1[i];
            if (delta > 0) {
                P1[i] += delta;
                P2[i] += delta;
            }
            delta = axis.getMinimumValue() - P2[i];
            if (delta > 0) {
                P1[i] += delta;
                P2[i] += delta;
            }
        }
        final GeodeticCalculator gc = GeodeticCalculator.create(crs);
        final GeneralDirectPosition pos1 = new GeneralDirectPosition(crs);
        pos1.setOrdinate(0, P1[0]);
        pos1.setOrdinate(1, P1[1]);
        final GeneralDirectPosition pos2 = new GeneralDirectPosition(crs);
        pos2.setOrdinate(0, P2[0]);
        pos2.setOrdinate(1, P2[1]);
        try {
            gc.setStartPoint(pos1);
            gc.setEndPoint(pos2);
        } catch (IllegalArgumentException ex) {
            // the coordinate can be out of the crs area, which causes this exception
            throw new TransformException(ex.getLocalizedMessage(), ex);
        }
        distance = gc.getGeodesicDistance();
    }
    final double displayToDevice = 1f / DEFAULT_DPI * 0.0254f;
    return distance / displayToDevice;
}
Also used : GeneralDirectPosition(org.apache.sis.geometry.GeneralDirectPosition) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) TransformException(org.opengis.referencing.operation.TransformException) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) Unit(javax.measure.Unit) GeodeticCalculator(org.apache.sis.referencing.GeodeticCalculator) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) Point2D(java.awt.geom.Point2D) UnitConverter(javax.measure.UnitConverter) AffineTransform(java.awt.geom.AffineTransform)

Aggregations

GeneralDirectPosition (org.apache.sis.geometry.GeneralDirectPosition)4 GeodeticCalculator (org.apache.sis.referencing.GeodeticCalculator)4 Unit (javax.measure.Unit)2 UnitConverter (javax.measure.UnitConverter)2 AffineTransform (java.awt.geom.AffineTransform)1 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)1 Point2D (java.awt.geom.Point2D)1 AbstractMap (java.util.AbstractMap)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Map (java.util.Map)1 NoSuchElementException (java.util.NoSuchElementException)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Spliterator (java.util.Spliterator)1 Spliterators (java.util.Spliterators)1 Consumer (java.util.function.Consumer)1