Search in sources :

Example 1 with ArcByCenterPointType

use of org.geotoolkit.gml.xml.v321.ArcByCenterPointType in project geotoolkit by Geomatys.

the class GeometrytoJTSTest method gmlArcToJTSTest.

@Test
public void gmlArcToJTSTest() throws Exception {
    final LengthType radius = new LengthType();
    radius.setValue(2.0);
    radius.setUom("m");
    final AngleType startAngle = new AngleType();
    startAngle.setValue(0);
    startAngle.setUom("rad");
    final AngleType endAngle = new AngleType();
    endAngle.setValue(270);
    endAngle.setUom("°");
    final ArcByCenterPointType arc = new ArcByCenterPointType();
    arc.setStartAngle(startAngle);
    arc.setEndAngle(endAngle);
    arc.setRadius(radius);
    arc.setPointProperty(new PointPropertyType(new PointType(new DirectPosition2D(0, 0))));
    final CurveType gmlCurve = new CurveType();
    gmlCurve.setSrsName("EPSG:3857");
    gmlCurve.setSegments(new CurveSegmentArrayPropertyType(Collections.singletonList(arc)));
    Geometry geom = GeometrytoJTS.toJTS(gmlCurve);
    // For geometric comparison, we oppose pure jts solution to the SIS geodetic calculator.
    final GeometricShapeFactory f = new GeometricShapeFactory(GF);
    f.setCentre(new Coordinate(0, 0));
    f.setSize(radius.getValue() * 2);
    // with this value, we should get points on trigonometric circle cardinalities (0, PI/2, PI, etc.), which eases comparison in debug.
    f.setNumPoints(17);
    // JTS angles are not azimuth, but pure trigonometric
    Geometry expectedArc = f.createArc(Math.PI, 3 / 2.0 * Math.PI);
    Assert.assertTrue(expectedArc.buffer(0.2).contains(geom));
    // Now, test in reverse (counter-clockwise) order
    endAngle.setValue(-90);
    geom = GeometrytoJTS.toJTS(gmlCurve);
    expectedArc = f.createArc(0, Math.PI);
    Assert.assertTrue(expectedArc.buffer(0.2).contains(geom));
}
Also used : Geometry(org.locationtech.jts.geom.Geometry) CurveSegmentArrayPropertyType(org.geotoolkit.gml.xml.v321.CurveSegmentArrayPropertyType) GeometricShapeFactory(org.locationtech.jts.util.GeometricShapeFactory) LengthType(org.geotoolkit.gml.xml.v321.LengthType) ArcByCenterPointType(org.geotoolkit.gml.xml.v321.ArcByCenterPointType) CurveType(org.geotoolkit.gml.xml.v321.CurveType) Coordinate(org.locationtech.jts.geom.Coordinate) AngleType(org.geotoolkit.gml.xml.v321.AngleType) PointType(org.geotoolkit.gml.xml.v321.PointType) ArcByCenterPointType(org.geotoolkit.gml.xml.v321.ArcByCenterPointType) PointPropertyType(org.geotoolkit.gml.xml.v321.PointPropertyType) DirectPosition2D(org.apache.sis.geometry.DirectPosition2D) Test(org.junit.Test)

Example 2 with ArcByCenterPointType

use of org.geotoolkit.gml.xml.v321.ArcByCenterPointType in project geotoolkit by Geomatys.

the class GeometryTransformer method getCoordinates.

/**
 * Check that given geometry is a primitive geometry (implements {@link WithCoordinates}), and
 * get its points.
 * @param source The geometry to extract points from.
 * @return Found points, never null, but can be empty.
 * @throws UnconvertibleObjectException If the given geometry does not implement {@link WithCoordinates}.
 */
private Spliterator<Coordinate> getCoordinates(final Object source) throws UnconvertibleObjectException {
    List<Double> values = null;
    if (source instanceof WithCoordinates) {
        final Coordinates coords = ((WithCoordinates) source).getCoordinates();
        if (coords != null) {
            /* HACK : In GML 3, coordinates are just a list of decimal values.
                 * The grouping by coordinate is done using "srsDimension" attribute
                 * on parent geometry type. However, with GML 2, there's another
                 * possibility : Coordinates use two distinct separators : one for
                 * decimal value separation, and another for coordinate separation.
                 * To manage both ways, we first check if coordinates object has
                 * succeeded in splitting underlying decimals in coordinates. If
                 * it does (return arrays with more than one element), we use
                 * that approach. Otherwise, we fallback on standard way which
                 * will try to determine manually the number of dimensions.
                 */
            Iterator<double[]> it = coords.points().iterator();
            if (it.hasNext() && it.next().length > 1) {
                return coords.points().map(GeometryTransformer::toCoordinate).spliterator();
            } else {
                values = coords.getValues();
            }
        } else if (source instanceof Point) {
            DirectPosition dp = ((Point) source).getPos();
            if (dp != null) {
                return Stream.of(convertDirectPosition(dp)).spliterator();
            } else
                // recognized object, but no value. Empty geometry
                return Spliterators.emptySpliterator();
        }
    }
    // TODO : below conditions should be removed when proper abstraction is setup on GML geometry definition.
    if (values == null) {
        final boolean isLineString = source instanceof org.geotoolkit.gml.xml.LineString;
        final boolean isLineStringSegment = source instanceof org.geotoolkit.gml.xml.LineStringSegment;
        if (isLineString || isLineStringSegment) {
            final DirectPositionList posList;
            if (isLineString) {
                posList = ((org.geotoolkit.gml.xml.LineString) source).getPosList();
            } else {
                posList = ((org.geotoolkit.gml.xml.LineStringSegment) source).getPosList();
            }
            if (posList != null) {
                values = posList.getValue();
            } else {
                final List<? extends DirectPosition> pList;
                if (isLineString) {
                    pList = ((org.geotoolkit.gml.xml.LineString) source).getPos();
                } else {
                    pList = ((org.geotoolkit.gml.xml.LineStringSegment) source).getPos();
                }
                if (pList != null) {
                    return pList.stream().map(GeometryTransformer::convertDirectPosition).filter(Objects::nonNull).spliterator();
                } else {
                    // We've identified a line, but there's no data in it
                    values = Collections.EMPTY_LIST;
                }
            }
        } else if (source instanceof org.geotoolkit.gml.xml.LinearRing) {
            // Note : do not check "getCoordinates", because it should have been done above.
            values = asDoubles(() -> ((org.geotoolkit.gml.xml.LinearRing) source).getPosList());
        } else if (source instanceof org.geotoolkit.gml.xml.v311.GeodesicStringType) {
            values = asDoubles(() -> ((org.geotoolkit.gml.xml.v311.GeodesicStringType) source).getPosList());
        } else if (source instanceof org.geotoolkit.gml.xml.v321.GeodesicStringType) {
            values = asDoubles(() -> ((org.geotoolkit.gml.xml.v321.GeodesicStringType) source).getPosList());
        } else if (source instanceof Curve) {
            CurveSegmentArrayProperty segments = ((Curve) source).getSegments();
            if (segments != null) {
                final List<? extends AbstractCurveSegment> curveSegments = segments.getAbstractCurveSegment();
                if (curveSegments != null) {
                    return curveSegments.stream().flatMap(seg -> StreamSupport.stream(getCoordinates(seg), false)).spliterator();
                }
            }
            // If we arrive here, we've got an empty curve.
            values = Collections.EMPTY_LIST;
        } else if (source instanceof ArcByCenterPointType) {
            final ArcByCenterPointType arc = (ArcByCenterPointType) source;
            org.opengis.geometry.DirectPosition dp = arc.getPos();
            if (dp == null) {
                PointPropertyType pp = arc.getPointProperty();
                if (pp == null) {
                    pp = arc.getPointRep();
                }
                if (pp == null) {
                    throw new UnconvertibleObjectException("Not enough information to build an arc.");
                }
                final Geometry point = new GeometryTransformer(pp.getPoint(), this).get();
                dp = JTS.toEnvelope(point).getLowerCorner();
            }
            CoordinateReferenceSystem crs = dp.getCoordinateReferenceSystem();
            if (crs == null) {
                crs = getSrsName().map(this::findCRS).orElseThrow(() -> new UnconvertibleObjectException("Cannot create an arc without its coordinate reference system"));
                final GeneralDirectPosition gdp = new GeneralDirectPosition(dp);
                gdp.setCoordinateReferenceSystem(crs);
                dp = gdp;
            }
            try {
                final Measure startAngle, endAngle;
                // If we miss a start or end angle, it means we're in presence of a circle.
                if (arc.getStartAngle() == null || arc.getEndAngle() == null) {
                    startAngle = new Measure(0, Units.DEGREE);
                    endAngle = new Measure(360, Units.DEGREE);
                } else {
                    startAngle = asMeasure(arc.getStartAngle());
                    endAngle = asMeasure(arc.getEndAngle());
                }
                final Coordinate[] coordinates = drawArc(dp, asMeasure(arc.getRadius()), startAngle, endAngle, ARC_PRECISION);
                return Spliterators.spliterator(coordinates, Spliterator.ORDERED);
            } catch (TransformException ex) {
                throw new UnconvertibleObjectException("Cannot draw an arc.", ex);
            }
        } else if (source instanceof org.geotoolkit.gml.xml.v311.ArcByCenterPointType) {
            // TODO : factorize with above case
            final org.geotoolkit.gml.xml.v311.ArcByCenterPointType arc = (org.geotoolkit.gml.xml.v311.ArcByCenterPointType) source;
            org.opengis.geometry.DirectPosition dp = arc.getPos();
            if (dp == null) {
                org.geotoolkit.gml.xml.v311.PointPropertyType pp = arc.getPointProperty();
                if (pp == null) {
                    pp = arc.getPointRep();
                }
                if (pp == null) {
                    throw new UnconvertibleObjectException("Not enough information to build an arc.");
                }
                final Geometry point = new GeometryTransformer(pp.getPoint(), this).get();
                dp = JTS.toEnvelope(point).getLowerCorner();
            }
            CoordinateReferenceSystem crs = dp.getCoordinateReferenceSystem();
            if (crs == null) {
                crs = getSrsName().map(this::findCRS).orElseThrow(() -> new UnconvertibleObjectException("Cannot create an arc without its coordinate reference system"));
                final GeneralDirectPosition gdp = new GeneralDirectPosition(dp);
                gdp.setCoordinateReferenceSystem(crs);
                dp = gdp;
            }
            try {
                final Measure startAngle, endAngle;
                // If we miss a start or end angle, it means we're in presence of a circle.
                if (arc.getStartAngle() == null || arc.getEndAngle() == null) {
                    startAngle = new Measure(0, Units.DEGREE);
                    endAngle = new Measure(360, Units.DEGREE);
                } else {
                    startAngle = asMeasure(arc.getStartAngle());
                    endAngle = asMeasure(arc.getEndAngle());
                }
                final Coordinate[] coordinates = drawArc(dp, asMeasure(arc.getRadius()), startAngle, endAngle, ARC_PRECISION);
                return Spliterators.spliterator(coordinates, Spliterator.ORDERED);
            } catch (TransformException ex) {
                throw new UnconvertibleObjectException("Cannot draw an arc.", ex);
            }
        }
    }
    if (values != null) {
        if (values.isEmpty()) {
            return Spliterators.emptySpliterator();
        }
        return new CoordinateSpliterator(values, getCoordinateDimension());
    }
    throw new UnconvertibleObjectException("Cannot extract coordinates from source geometry.");
}
Also used : 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) GeneralDirectPosition(org.apache.sis.geometry.GeneralDirectPosition) CurveSegmentArrayProperty(org.geotoolkit.gml.xml.CurveSegmentArrayProperty) UnconvertibleObjectException(org.apache.sis.util.UnconvertibleObjectException) ArcByCenterPointType(org.geotoolkit.gml.xml.v321.ArcByCenterPointType) Measure(org.apache.sis.internal.jaxb.gml.Measure) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) DirectPosition(org.opengis.geometry.DirectPosition) Coordinates(org.geotoolkit.gml.xml.Coordinates) WithCoordinates(org.geotoolkit.gml.xml.WithCoordinates) MultiCurve(org.geotoolkit.gml.xml.MultiCurve) Curve(org.geotoolkit.gml.xml.Curve) TransformException(org.opengis.referencing.operation.TransformException) Point(org.geotoolkit.gml.xml.Point) MultiPoint(org.locationtech.jts.geom.MultiPoint) Geometry(org.locationtech.jts.geom.Geometry) MultiGeometry(org.geotoolkit.gml.xml.MultiGeometry) AbstractGeometry(org.geotoolkit.gml.xml.AbstractGeometry) MultiLineString(org.locationtech.jts.geom.MultiLineString) LineString(org.locationtech.jts.geom.LineString) DirectPositionList(org.geotoolkit.gml.xml.DirectPositionList) Coordinate(org.locationtech.jts.geom.Coordinate) WithCoordinates(org.geotoolkit.gml.xml.WithCoordinates) PointPropertyType(org.geotoolkit.gml.xml.v321.PointPropertyType)

Aggregations

ArcByCenterPointType (org.geotoolkit.gml.xml.v321.ArcByCenterPointType)2 PointPropertyType (org.geotoolkit.gml.xml.v321.PointPropertyType)2 Coordinate (org.locationtech.jts.geom.Coordinate)2 Geometry (org.locationtech.jts.geom.Geometry)2 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 DoubleFunction (java.util.function.DoubleFunction)1 Function (java.util.function.Function)1 Supplier (java.util.function.Supplier)1