This is an automated email from the ASF dual-hosted git repository. jsorel pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 646a6e2a15 Add stateful present method on GraphicsPortrayer 646a6e2a15 is described below commit 646a6e2a159dbf944ad07163746b9fe4ccd704b7 Author: jsorel <johann.so...@geomatys.com> AuthorDate: Fri Mar 8 15:37:42 2024 +0100 Add stateful present method on GraphicsPortrayer --- .../apache/sis/map/service/GraphicsPortrayer.java | 35 +++++++++++++++++ .../org/apache/sis/map/service/StylePainter.java | 22 ++++++++--- .../org/apache/sis/map/service/se1/SEPainter.java | 15 ++++++-- .../sis/map/service/GraphicsPortrayerTest.java | 45 +++++++++++++++++++++- 4 files changed, 108 insertions(+), 9 deletions(-) diff --git a/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/GraphicsPortrayer.java b/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/GraphicsPortrayer.java index 9b6d019caf..4ed1e56d0f 100644 --- a/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/GraphicsPortrayer.java +++ b/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/GraphicsPortrayer.java @@ -161,6 +161,41 @@ public final class GraphicsPortrayer { painter.paint(scene, layer); } + /** + * Present given map. + * + * @param map to present, not null + * @throws IllegalArgumentException if canvas is not property configured + * @throws RenderingException if a rendering procedure fails. + */ + public synchronized Stream<Presentation> present(MapItem map) throws RenderingException { + return present(init(), map); + } + + private Stream<Presentation> present(Scene2D scene, MapItem map) throws RenderingException { + if (map == null || !map.isVisible()) return Stream.empty(); + if (map instanceof MapLayer) { + return present(scene, (MapLayer) map); + } else if (map instanceof MapLayers) { + final MapLayers layers = (MapLayers) map; + Stream<Presentation> stream = Stream.empty(); + for (MapItem item : layers.getComponents()) { + stream = Stream.concat(stream, present(scene, item)); + } + return stream; + } else { + return Stream.empty(); + } + } + + private Stream<Presentation> present(Scene2D scene, MapLayer layer) throws RenderingException { + final Style style = layer.getStyle(); + if (style == null) return Stream.empty(); + final StylePainter painter = PAINTERS.get(style.getClass()); + if (painter == null) return Stream.empty(); + return painter.present(scene, layer); + } + /** * Compute visual intersection of given map. * diff --git a/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/StylePainter.java b/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/StylePainter.java index 4a41426485..29da097ea1 100644 --- a/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/StylePainter.java +++ b/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/StylePainter.java @@ -26,8 +26,6 @@ import org.apache.sis.style.Style; /** * A Painter is responsible for portraying and querying resource on a scene. * - * Currently the API only support stateless rendering. - * * @author Johann Sorel (Geomatys) */ public interface StylePainter { @@ -40,7 +38,7 @@ public interface StylePainter { Class<? extends Style> getStyleClass(); /** - * Stateless portraying og the given map layer. + * Stateless portraying of the given map layer. * * @param scene parameters for rendering * @param layer having supported style class. @@ -49,9 +47,23 @@ public interface StylePainter { void paint(Scene2D scene, MapLayer layer) throws RenderingException; /** - * Search for elements in the scene which intersect the given area. + * Statefull portraying of the given map layer. + * <p> + * Any exception should be returned in the stream as ExceptionPresentation, this allows + * to still have some results even if a data caused an error. + * <p> + * The nature of the Presentation instance should be related to the style API used. * - * Any exception should be returned in the stream as ExceptionPresentations, this allows + * @param scene parameters for rendering + * @param layer having supported style class. + * @return stream of presentation objects. + */ + Stream<Presentation> present(Scene2D scene, MapLayer layer); + + /** + * Search for elements in the scene which intersect the given area. + * <p> + * Any exception should be returned in the stream as ExceptionPresentation, this allows * to still have some results even if a data caused an error. * * @param scene parameters of the scene diff --git a/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/se1/SEPainter.java b/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/se1/SEPainter.java index a55523d2c5..d8f9e1d08b 100644 --- a/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/se1/SEPainter.java +++ b/incubator/src/org.apache.sis.portrayal.map/main/org/apache/sis/map/service/se1/SEPainter.java @@ -42,15 +42,24 @@ public final class SEPainter implements StylePainter { /** * Render the given map using default SEPortrayer configuration. * - * @param mapItem to be rendered, not null. + * @param layer to be rendered, not null. * @return this portrayer */ - public void paint(Scene2D scene, MapLayer mapItem) { - try (Stream<Presentation> stream = new SEPortrayer().present(scene.grid, mapItem)) { + @Override + public void paint(Scene2D scene, MapLayer layer) { + try (Stream<Presentation> stream = new SEPortrayer().present(scene.grid, layer)) { paint(scene, stream); } } + /** + * {@inheritDoc } + */ + @Override + public Stream<Presentation> present(Scene2D scene, MapLayer layer) { + return new SEPortrayer().present(scene.grid, layer); + } + /** * Render the given stream of Presentations. * diff --git a/incubator/src/org.apache.sis.portrayal.map/test/org/apache/sis/map/service/GraphicsPortrayerTest.java b/incubator/src/org.apache.sis.portrayal.map/test/org/apache/sis/map/service/GraphicsPortrayerTest.java index 975d8908cc..94bad9e233 100644 --- a/incubator/src/org.apache.sis.portrayal.map/test/org/apache/sis/map/service/GraphicsPortrayerTest.java +++ b/incubator/src/org.apache.sis.portrayal.map/test/org/apache/sis/map/service/GraphicsPortrayerTest.java @@ -32,8 +32,10 @@ import org.apache.sis.coverage.grid.GridGeometry; import org.apache.sis.coverage.grid.GridOrientation; import org.apache.sis.feature.builder.AttributeRole; import org.apache.sis.feature.builder.FeatureTypeBuilder; +import org.apache.sis.feature.privy.AttributeConvention; import org.apache.sis.map.MapLayer; import org.apache.sis.map.Presentation; +import org.apache.sis.map.SEPresentation; import org.apache.sis.referencing.CRS; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.storage.FeatureSet; @@ -77,7 +79,7 @@ public class GraphicsPortrayerTest { * Sanity test for rendering. */ @Test - public void testRendering() throws RenderingException { + public void testPortray() throws RenderingException { final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName("test"); @@ -109,6 +111,47 @@ public class GraphicsPortrayerTest { assertEquals(color2, new Color(0,0,0,0).getRGB()); } + /** + * Sanity test for presentation. + */ + @Test + public void testPresent() throws RenderingException { + + final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); + ftb.setName("test"); + ftb.addAttribute(String.class).setName(AttributeConvention.IDENTIFIER); + ftb.addAttribute(Geometry.class).setName("geom").addRole(AttributeRole.DEFAULT_GEOMETRY); + final FeatureType ft = ftb.build(); + + final Feature feature = ft.newInstance(); + LineString geom = GF.createLineString(new Coordinate[]{new Coordinate(0,0), new Coordinate(0,90)}); + geom.setUserData(WORLD.getCoordinateReferenceSystem()); + feature.setPropertyValue(AttributeConvention.IDENTIFIER, "test-1"); + feature.setPropertyValue("geom", geom); + + final FeatureSet featureSet = new MemoryFeatureSet(null, ft, Arrays.asList(feature)); + + final LineSymbolizer<Feature> symbolizer = new LineSymbolizer<>(FeatureTypeStyle.FACTORY); + final Symbology style = createStyle(symbolizer); + + final MapLayer item = new MapLayer(); + item.setData(featureSet); + item.setStyle(style); + + try (Stream<Presentation> stream = new GraphicsPortrayer() + .setDomain(WORLD) + .present(item)) { + Object[] presentations = stream.toArray(); + assertEquals(1, presentations.length); + assertTrue(presentations[0] instanceof SEPresentation); + final SEPresentation pe = (SEPresentation) presentations[0]; + assertEquals(item, pe.getLayer()); + assertEquals(featureSet, pe.getResource()); + assertEquals("test-1", pe.getCandidate().getPropertyValue(AttributeConvention.IDENTIFIER)); + assertEquals(symbolizer, pe.getSymbolizer()); + } + } + /** * Sanity test for intersection. */