Пример #1
0
  @Test
  public void testDrawIntepolation() throws Exception {

    MapContent mc = new MapContent();
    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, 180, -90, 90), DefaultGeographicCRS.WGS84);

    BufferedImage testImage = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);

    GridCoverage2D testCoverage = new GridCoverageFactory().create("test", testImage, reWgs);
    GridCoverage2D coverage = new GridCoverage2D("test", testCoverage);

    // mocking a GridCoverageReader to wrap the testing coverage
    GridCoverage2DReader gridCoverageReader = Mockito.mock(GridCoverage2DReader.class);
    Mockito.when(gridCoverageReader.getOriginalEnvelope()).thenReturn(new GeneralEnvelope(reWgs));
    Mockito.when(gridCoverageReader.getCoordinateReferenceSystem())
        .thenReturn(DefaultGeographicCRS.WGS84);
    Mockito.when(gridCoverageReader.read(Mockito.any(GeneralParameterValue[].class)))
        .thenReturn(coverage);

    Layer layer =
        new FeatureLayer(
            FeatureUtilities.wrapGridCoverageReader(
                gridCoverageReader, new GeneralParameterValue[] {}),
            createRasterStyle());
    layer
        .getUserData()
        .put(
            StreamingRenderer.BYLAYER_INTERPOLATION,
            Interpolation.getInstance(Interpolation.INTERP_BICUBIC));
    mc.addLayer(layer);

    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);

    StreamingRenderer sr = new StreamingRenderer();
    sr.setMapContent(mc);

    Graphics2D graphics = (Graphics2D) image.getGraphics();

    sr.paint(graphics, new Rectangle(200, 200), reWgs);
    // test right interpolation hint is set on Graphics2D
    assertEquals(
        graphics.getRenderingHint(JAI.KEY_INTERPOLATION),
        Interpolation.getInstance(Interpolation.INTERP_BICUBIC));

    layer
        .getUserData()
        .put(
            StreamingRenderer.BYLAYER_INTERPOLATION,
            Interpolation.getInstance(Interpolation.INTERP_NEAREST));

    sr.paint(graphics, new Rectangle(200, 200), reWgs);
    // test right interpolation hint is set on Graphics2D
    assertEquals(
        graphics.getRenderingHint(JAI.KEY_INTERPOLATION),
        Interpolation.getInstance(Interpolation.INTERP_NEAREST));
  }
Пример #2
0
 /**
  * Test that point features are rendered at the expected image coordinates when the map is
  * rotated. StreamingRenderer
  *
  * @throws Exception
  */
 @Test
 public void testRotatedTransform() throws Exception {
   // If we rotate the world rectangle + 90 degrees around (0,0), we get the screen rectangle
   final Rectangle screen = new Rectangle(0, 0, 100, 50);
   final Envelope world = new Envelope(0, 50, 0, -100);
   final AffineTransform worldToScreen =
       AffineTransform.getRotateInstance(Math.toRadians(90), 0, 0);
   DefaultFeatureCollection fc = new DefaultFeatureCollection();
   fc.add(createPoint(0, 0));
   fc.add(createPoint(world.getMaxX(), world.getMinY()));
   MapContext mapContext = new DefaultMapContext(DefaultGeographicCRS.WGS84);
   mapContext.addLayer((FeatureCollection) fc, createPointStyle());
   BufferedImage image =
       new BufferedImage(screen.width, screen.height, BufferedImage.TYPE_4BYTE_ABGR);
   final StreamingRenderer sr = new StreamingRenderer();
   sr.setContext(mapContext);
   sr.paint(image.createGraphics(), screen, worldToScreen);
   assertTrue("Pixel should be drawn at 0,0 ", image.getRGB(0, 0) != 0);
   assertTrue(
       "Pixel should not be drawn in image centre ",
       image.getRGB(screen.width / 2, screen.height / 2) == 0);
   assertTrue(
       "Pixel should be drawn at image max corner ",
       image.getRGB(screen.width - 1, screen.height - 1) != 0);
 }
Пример #3
0
  public void testSkipProjectionErrors() throws Exception {
    // build map context
    MapContext mapContext = new DefaultMapContext(DefaultGeographicCRS.WGS84);
    mapContext.addLayer(createLineCollection(), createLineStyle());

    // build projected envelope to work with (small one around the area of
    // validity of utm zone 1, which being a Gauss projection is a vertical
    // slice parallel to the central meridian, -177°)
    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, -170, 20, 40), DefaultGeographicCRS.WGS84);
    CoordinateReferenceSystem utm1N = CRS.decode("EPSG:32601");
    System.out.println(CRS.getGeographicBoundingBox(utm1N));
    ReferencedEnvelope reUtm = reWgs.transform(utm1N, true);

    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);

    // setup the renderer and listen for errors
    StreamingRenderer sr = new StreamingRenderer();
    sr.setRendererHints(Collections.singletonMap(sr.OPTIMIZED_DATA_LOADING_KEY, Boolean.FALSE));
    sr.setContext(mapContext);
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {}

          public void errorOccurred(Exception e) {
            e.printStackTrace();
            errors++;
          }
        });
    errors = 0;
    sr.paint((Graphics2D) image.getGraphics(), new Rectangle(200, 200), reUtm);
    // we should get two errors since there are two features that cannot be
    // projected but the renderer itself should not throw exceptions
    assertEquals(2, errors);
  }
Пример #4
0
  /*
   * https://osgeo-org.atlassian.net/browse/GEOT-5287
   */
  @Test
  public void testEmptyGeometryRendering() throws Exception {

    MapContent mc = new MapContent();

    /*
     * We simulate reading empty geometries with this properties and mocking the capability to
     * filter, so that no filter layer is installed over our data and the empty geometry reaches
     * rendering code. These geometries are in EPSG:32717 because the 0,0 coordinate is in the
     * pole.
     */
    File dir = new File(TestData.getResource(this, "empty-geom-rendering.properties").toURI());
    PropertyDataStore dataStore =
        new PropertyDataStore(dir.getParentFile()) {
          @Override
          protected ContentFeatureSource createFeatureSource(ContentEntry entry)
              throws IOException {
            return new PropertyFeatureSource(entry, Query.ALL) {
              @Override
              protected boolean canFilter() {
                return true;
              }
            };
          }
        };
    /*
     * Set up the rendering of previous empty geometry
     */
    StyleBuilder sb = new StyleBuilder();
    Style style = sb.createStyle(sb.createPolygonSymbolizer());
    Layer layer = new FeatureLayer(dataStore.getFeatureSource("empty-geom-rendering"), style);
    mc.addLayer(layer);
    StreamingRenderer sr = new StreamingRenderer();
    sr.setMapContent(mc);
    BufferedImage img = new BufferedImage(40, 40, BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics = img.createGraphics();
    Rectangle paintArea = new Rectangle(40, 40);
    // An EPSG:8357 extent on the EPSG:32717 area of application.
    double minx = -8929252.1;
    double maxx = -8708634.6;
    double miny = -491855.7;
    double maxy = -271204.3;
    ReferencedEnvelope referencedEnvelope =
        new ReferencedEnvelope(
            new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny), CRS.decode("EPSG:3857"));
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {}

          public void errorOccurred(Exception e) {
            errors++;
          }
        });
    errors = 0;

    sr.paint(graphics, paintArea, referencedEnvelope);

    assertTrue(errors == 0);
  }
Пример #5
0
  @Test
  public void testEventAfterDrawing() throws Exception {
    // build map context
    MapContent mc = new MapContent();
    mc.addLayer(new FeatureLayer(createLineCollection(), createLineStyle()));

    // build projected envelope to work with (small one around the area of
    // validity of utm zone 1, which being a Gauss projection is a vertical
    // slice parallel to the central meridian, -177°)
    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, -170, 20, 40), DefaultGeographicCRS.WGS84);
    CoordinateReferenceSystem utm1N = CRS.decode("EPSG:32601");
    ReferencedEnvelope reUtm = reWgs.transform(utm1N, true);

    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);

    // setup the renderer and listen for errors
    final AtomicInteger commandsCount = new AtomicInteger(0);
    final BlockingQueue<RenderingRequest> queue =
        new ArrayBlockingQueue<RenderingRequest>(10) {
          @Override
          public void put(RenderingRequest e) throws InterruptedException {
            commandsCount.incrementAndGet();
            super.put(e);
          }
        };
    StreamingRenderer sr =
        new StreamingRenderer() {
          @Override
          protected BlockingQueue<RenderingRequest> getRequestsQueue() {
            return queue;
          }
        };
    sr.setMapContent(mc);
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {
            assertTrue(commandsCount.get() > 0);
            features++;
          }

          public void errorOccurred(Exception e) {
            errors++;
          }
        });
    errors = 0;
    features = 0;
    sr.paint((Graphics2D) image.getGraphics(), new Rectangle(200, 200), reUtm);

    // we should get errors since there are two features that cannot be
    // projected but the renderer itself should not throw exceptions
    assertTrue(errors > 0);
  }
Пример #6
0
  /**
   * Test that we don't have the geometry added twice by StreamingRenderer#findStyleAttributes when
   * geofence is filtering a layer.
   *
   * @throws Exception
   */
  @Test
  public void testFindLineStyleAttributeWithAddedFilter() throws Exception {
    final List<Filter> filters = new ArrayList<Filter>();

    SimpleFeatureSource testSource =
        new CollectionFeatureSource(createLineCollection()) {
          @Override
          public SimpleFeatureCollection getFeatures(Query query) {
            filters.add(query.getFilter());
            return super.getFeatures(query);
          }
        };

    Style style = createPointStyle();
    MapContent mc = new MapContent();
    FeatureLayer layer = new FeatureLayer(testSource, style);
    mc.addLayer(layer);

    StreamingRenderer sr = new StreamingRenderer();
    sr.setMapContent(mc);

    ReferencedEnvelope envelope =
        new ReferencedEnvelope(0, 100, 0, 100, DefaultGeographicCRS.WGS84);

    // simulate geofence adding a bbox
    BBOX bbox = StreamingRenderer.filterFactory.bbox("", 30, 60, 30, 60, "WGS84");
    StyleFactoryImpl sf = new StyleFactoryImpl();
    Rule bboxRule =
        sf.createRule(
            new Symbolizer[0], new DescriptionImpl(), new Graphic[0], "bbox", bbox, false, 1e12, 0);
    style.featureTypeStyles().get(0).rules().add(bboxRule);

    BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
    Graphics2D graphics = bi.createGraphics();
    try {
      sr.paint(graphics, new Rectangle(5, 5, 7, 7), envelope);
    } finally {
      graphics.dispose();
    }

    // must have only one bbox, not two
    assertEquals(1, filters.size());
    assertEquals(FastBBOX.class, filters.get(0).getClass());
  }
Пример #7
0
  @Test
  public void testRepeatedEnvelopeExpansion() throws Exception {
    final List<Filter> filters = new ArrayList<Filter>();

    SimpleFeatureSource testSource =
        new CollectionFeatureSource(createLineCollection()) {
          @Override
          public SimpleFeatureCollection getFeatures(Query query) {
            filters.add(query.getFilter());
            return super.getFeatures(query);
          }
        };

    StyleBuilder sb = new StyleBuilder();
    Style style20 = sb.createStyle(sb.createLineSymbolizer(20));
    Style style10 = sb.createStyle(sb.createLineSymbolizer(10));

    MapContent mc = new MapContent();
    mc.addLayer(new FeatureLayer(testSource, style20));
    mc.addLayer(new FeatureLayer(testSource, style10));

    StreamingRenderer sr = new StreamingRenderer();
    sr.setMapContent(mc);
    BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
    Graphics2D graphics = bi.createGraphics();
    sr.paint(
        graphics,
        new Rectangle(0, 0, 100, 100),
        new ReferencedEnvelope(0, 100, 0, 100, DefaultGeographicCRS.WGS84));
    graphics.dispose();

    System.out.println(filters);
    assertEquals(2, filters.size());
    Filter f1 = filters.get(0);
    assertTrue(f1 instanceof BBOX);
    BoundingBox bbox1 = ((BBOX) f1).getBounds();
    ReferencedEnvelope expected =
        new ReferencedEnvelope(-11, 111, -11, 111, DefaultGeographicCRS.WGS84);
    assertEquals(expected, bbox1);
    Filter f2 = filters.get(1);
    assertTrue(f2 instanceof BBOX);
    BoundingBox bbox2 = ((BBOX) f2).getBounds();
    assertEquals(new ReferencedEnvelope(-6, 106, -6, 106, DefaultGeographicCRS.WGS84), bbox2);
  }
Пример #8
0
  @Test
  public void testScreenMapMemory() {
    // build a feature source with two zig-zag line occupying the same position
    LiteCoordinateSequence cs =
        new LiteCoordinateSequence(new double[] {0, 0, 1, 1, 2, 0, 3, 1, 4, 0});
    SimpleFeature zigzag1 =
        SimpleFeatureBuilder.build(
            testLineFeatureType, new Object[] {gf.createLineString(cs)}, "zz1");
    SimpleFeature zigzag2 =
        SimpleFeatureBuilder.build(
            testLineFeatureType, new Object[] {gf.createLineString(cs)}, "zz2");
    DefaultFeatureCollection fc = new DefaultFeatureCollection();
    fc.add(zigzag1);
    fc.add(zigzag2);
    SimpleFeatureSource zzSource = new CollectionFeatureSource(fc);

    // prepare the map
    MapContent mc = new MapContent();
    StyleBuilder sb = new StyleBuilder();
    mc.addLayer(new FeatureLayer(zzSource, sb.createStyle(sb.createLineSymbolizer())));
    StreamingRenderer sr = new StreamingRenderer();
    sr.setMapContent(mc);

    // collect rendered features
    final List<SimpleFeature> features = new ArrayList<SimpleFeature>();
    RenderListener renderedFeaturesCollector =
        new RenderListener() {

          @Override
          public void featureRenderer(SimpleFeature feature) {
            features.add(feature);
          }

          @Override
          public void errorOccurred(Exception e) {
            // nothing to do
          }
        };
    sr.addRenderListener(renderedFeaturesCollector);
    BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
    Graphics2D graphics = bi.createGraphics();
    // have the lines be smaller than a 1/3 of a pixel
    sr.paint(
        graphics,
        new Rectangle(0, 0, 1, 1),
        new ReferencedEnvelope(0, 8, 0, 8, DefaultGeographicCRS.WGS84));

    // check we only rendered one feature
    assertEquals(1, features.size());
    assertEquals("zz1", features.get(0).getID());

    // now have the lines be big enough to be painted instead
    features.clear();
    sr.paint(
        graphics,
        new Rectangle(0, 0, 1, 1),
        new ReferencedEnvelope(0, 1, 0, 1, DefaultGeographicCRS.WGS84));
    assertEquals(2, features.size());
    assertEquals("zz1", features.get(0).getID());
    assertEquals("zz2", features.get(1).getID());

    graphics.dispose();
  }
Пример #9
0
  @Test
  public void testDeadlockOnException() throws Exception {

    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, 180, -90, 90), DefaultGeographicCRS.WGS84);

    // create the grid coverage that throws a OOM
    BufferedImage testImage = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);
    GridCoverage2D testCoverage = new GridCoverageFactory().create("test", testImage, reWgs);
    GridCoverage2D oomCoverage =
        new GridCoverage2D("test", testCoverage) {

          @Override
          public RenderedImage getRenderedImage() {
            throw new OutOfMemoryError("Boom!");
          }
        };

    // also have a collections of features to create the deadlock once the painter
    // thread is dead
    SimpleFeatureCollection lines = createLineCollection();

    Style rasterStyle = createRasterStyle();
    Style lineStyle = createLineStyle();

    MapContent mapContent = new MapContent();
    mapContent.addLayer(new GridCoverageLayer(oomCoverage, rasterStyle));
    mapContent.addLayer(new FeatureLayer(lines, lineStyle));

    final StreamingRenderer sr =
        new StreamingRenderer() {

          // makes it easy to reproduce the deadlock, just two features are sufficient
          protected BlockingQueue<RenderingRequest> getRequestsQueue() {
            return new RenderingBlockingQueue(1);
          }
        };
    sr.setMapContent(mapContent);
    final List<Exception> exceptions = new ArrayList<Exception>();
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {
            features++;
          }

          public void errorOccurred(Exception e) {
            errors++;
            exceptions.add(e);
          }
        });
    errors = 0;
    features = 0;
    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);
    sr.paint((Graphics2D) image.getGraphics(), new Rectangle(200, 200), reWgs);

    // all the lines should have been painted, the coverage reports as painted too
    // since the reporting happens in the main thread that does not error
    assertEquals(4, features);
    assertEquals(1, errors);
    assertTrue(exceptions.get(0).getCause() instanceof OutOfMemoryError);
  }
Пример #10
0
  @Test
  public void testInfiniteLoopAvoidance() throws Exception {
    final Exception sentinel =
        new RuntimeException("This is the one that should be thrown in hasNext()");

    // setup the mock necessary to have the renderer hit into the exception in hasNext()
    SimpleFeatureIterator it2 = createNiceMock(SimpleFeatureIterator.class);
    expect(it2.hasNext()).andThrow(sentinel).anyTimes();
    replay(it2);

    SimpleFeatureCollection fc = createNiceMock(SimpleFeatureCollection.class);
    expect(fc.features()).andReturn(it2);
    expect(fc.size()).andReturn(200);
    expect(fc.getSchema()).andReturn(testLineFeatureType).anyTimes();
    replay(fc);

    SimpleFeatureSource fs = createNiceMock(SimpleFeatureSource.class);
    expect(fs.getFeatures((Query) anyObject())).andReturn(fc);
    expect(fs.getSchema()).andReturn(testLineFeatureType).anyTimes();
    expect(fs.getSupportedHints()).andReturn(new HashSet()).anyTimes();
    replay(fs);

    // build map context
    MapContext mapContext = new DefaultMapContext(DefaultGeographicCRS.WGS84);
    mapContext.addLayer(fs, createLineStyle());

    // setup the renderer and listen for errors
    final StreamingRenderer sr = new StreamingRenderer();
    sr.setContext(mapContext);
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {
            features++;
          }

          public void errorOccurred(Exception e) {
            errors++;

            if (errors > 2) {
              // we dont' want to block the loop in case of regression on this bug
              sr.stopRendering();
            }

            // but we want to make sure we're getting
            Throwable t = e;
            while (t != sentinel && t.getCause() != null) t = t.getCause();
            assertSame(sentinel, t);
          }
        });
    errors = 0;
    features = 0;
    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);
    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, -170, 20, 40), DefaultGeographicCRS.WGS84);
    sr.paint((Graphics2D) image.getGraphics(), new Rectangle(200, 200), reWgs);

    // we should get two errors since there are two features that cannot be
    // projected but the renderer itself should not throw exceptions
    assertEquals(0, features);
    assertEquals(1, errors);
  }