@Test @DirtiesContext public void testExecute() throws Exception { Configuration config = configurationFactory.getConfig(getFile(BASE_DIR + "config.yaml")); PJsonObject requestData = loadJsonRequestData(); final AbstractJasperReportOutputFormat format = (AbstractJasperReportOutputFormat) this.outputFormat.get("pngOutputFormat"); testPrint(config, requestData, "default-aoi", format, 40); getAreaOfInterest(requestData).put("display", "CLIP"); testPrint(config, requestData, "clip-full-aoi", format, 30); getAreaOfInterest(requestData).remove("display"); requestData = loadJsonRequestData(); getPagingAttributes(requestData).put("aoiDisplay", "clip"); testPrint(config, requestData, "clip-page-aoi", format, 40); getPagingAttributes(requestData).put("aoiDisplay", "render"); testPrint(config, requestData, "default-aoi", format, 40); getPagingAttributes(requestData).put("aoiDisplay", "none"); testPrint(config, requestData, "none-aoi", format, 40); getAreaOfInterest(requestData).put("display", "CLIP"); getPagingAttributes(requestData).put("aoiDisplay", "RENDER"); testPrint(config, requestData, "full-clip-sub-render", format, 40); getAreaOfInterest(requestData).put("display", "CLIP"); getPagingAttributes(requestData).put("aoiDisplay", "NONE"); testPrint(config, requestData, "full-clip-sub-none", format, 40); getAreaOfInterest(requestData).put("display", "CLIP"); getPagingAttributes(requestData).put("aoiDisplay", "NONE"); testPrint(config, requestData, "full-clip-sub-none", format, 40); getAreaOfInterest(requestData).put("display", "NONE"); getPagingAttributes(requestData).put("aoiDisplay", "NONE"); testPrint(config, requestData, "all-none", format, 40); getAreaOfInterest(requestData).put("display", "NONE"); getPagingAttributes(requestData).put("aoiDisplay", "NONE"); getMapAttributes(requestData).put("dpi", 254); testPrint(config, requestData, "higher-dpi", format, 40); config = configurationFactory.getConfig(getFile(BASE_DIR + "config-scalebar.yaml")); requestData = loadJsonRequestData(); testPrint(config, requestData, "scalebar", format, 45); }
@SuppressWarnings("unchecked") @Override public final Output execute(final Input values, final ExecutionContext context) { final MapAttributeValues map = values.map; final PagingAttribute.PagingProcessorValues paging = values.paging; CoordinateReferenceSystem projection = map.getMapBounds().getProjection(); final Rectangle paintArea = new Rectangle(map.getMapSize()); final DistanceUnit projectionUnit = DistanceUnit.fromProjection(projection); AreaOfInterest areaOfInterest = map.areaOfInterest; if (areaOfInterest == null) { areaOfInterest = new AreaOfInterest(); areaOfInterest.display = AreaOfInterest.AoiDisplay.NONE; ReferencedEnvelope mapBBox = map.getMapBounds().toReferencedEnvelope(paintArea); areaOfInterest.setPolygon(this.geometryFactory.toGeometry(mapBBox)); } Envelope aoiBBox = areaOfInterest.getArea().getEnvelopeInternal(); final double paintAreaWidthIn = paintArea.getWidth() * paging.scale / PDF_DPI; final double paintAreaHeightIn = paintArea.getHeight() * paging.scale / PDF_DPI; final double paintAreaWidth = DistanceUnit.IN.convertTo(paintAreaWidthIn, projectionUnit); final double paintAreaHeight = DistanceUnit.IN.convertTo(paintAreaHeightIn, projectionUnit); final double overlapProj = DistanceUnit.IN.convertTo(paging.overlap * paging.scale / PDF_DPI, projectionUnit); final int nbWidth = (int) Math.ceil((aoiBBox.getWidth() + overlapProj) / (paintAreaWidth - overlapProj)); final int nbHeight = (int) Math.ceil((aoiBBox.getHeight() + overlapProj) / (paintAreaHeight - overlapProj)); final double marginWidth = (paintAreaWidth * nbWidth - (nbWidth - 1) * overlapProj - aoiBBox.getWidth()) / 2; final double marginHeight = (paintAreaHeight * nbHeight - (nbHeight - 1) * overlapProj - aoiBBox.getHeight()) / 2; final double minX = aoiBBox.getMinX() - marginWidth - overlapProj / 2; final double minY = aoiBBox.getMinY() - marginHeight - overlapProj / 2; LOGGER.info("Paging generate a grid of {}x{} potential maps.", nbWidth, nbHeight); final int[][] mapIndexes = new int[nbWidth][nbHeight]; final Envelope[][] mapsBounds = new Envelope[nbWidth][nbHeight]; int mapIndex = 0; for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { final double x1 = minX + i * (paintAreaWidth - overlapProj); final double x2 = x1 + paintAreaWidth; final double y1 = minY + j * (paintAreaHeight - overlapProj); final double y2 = y1 + paintAreaHeight; Coordinate[] coords = new Coordinate[]{ new Coordinate(x1, y1), new Coordinate(x1, y2), new Coordinate(x2, y2), new Coordinate(x2, y1), new Coordinate(x1, y1) }; LinearRing ring = this.geometryFactory.createLinearRing(coords); final Polygon bbox = this.geometryFactory.createPolygon(ring); if (areaOfInterest.getArea().intersects(bbox)) { mapsBounds[i][j] = bbox.getEnvelopeInternal(); mapIndexes[i][j] = mapIndex; mapIndex++; } else { mapIndexes[i][j] = DO_NOT_RENDER_BBOX_INDEX; } } } final List<Map<String, Object>> mapList = new ArrayList<>(); for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { if (mapIndexes[i][j] != DO_NOT_RENDER_BBOX_INDEX) { Map<String, Object> mapValues = new HashMap<>(); mapValues.put("name", mapIndexes[i][j]); mapValues.put("left", i != 0 ? mapIndexes[i - 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("bottom", j != 0 ? mapIndexes[i][j - 1] : DO_NOT_RENDER_BBOX_INDEX); mapValues .put("right", i != nbWidth - 1 ? mapIndexes[i + 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("top", j != nbHeight - 1 ? mapIndexes[i][j + 1] : DO_NOT_RENDER_BBOX_INDEX); final Envelope mapsBound = mapsBounds[i][j]; MapAttributeValues theMap = map.copy( map.getWidth(), map.getHeight(), (@Nonnull final MapAttributeValues input) -> { input.center = null; input.bbox = new double[]{ mapsBound.getMinX(), mapsBound.getMinY(), mapsBound.getMaxX(), mapsBound.getMaxY() }; if (paging.aoiDisplay != null) { input.areaOfInterest.display = paging.aoiDisplay; } if (paging.aoiStyle != null) { input.areaOfInterest.style = paging.aoiStyle; } return null; } ); mapValues.put(MAP_KEY, theMap); mapList.add(mapValues); } } } LOGGER.info("Paging generate {} maps definitions.", mapList.size()); DataSourceAttributeValue datasourceAttributes = new DataSourceAttributeValue(); datasourceAttributes.attributesValues = mapList.toArray(new Map[mapList.size()]); return new Output(datasourceAttributes); }
CreateMapPagesProcessor extends AbstractProcessor<CreateMapPagesProcessor.Input, CreateMapPagesProcessor.Output> implements ProvideAttributes, RequireAttributes { @SuppressWarnings("unchecked") @Override public final Output execute(final Input values, final ExecutionContext context) { final MapAttributeValues map = values.map; final PagingAttribute.PagingProcessorValues paging = values.paging; CoordinateReferenceSystem projection = map.getMapBounds().getProjection(); final Rectangle paintArea = new Rectangle(map.getMapSize()); final DistanceUnit projectionUnit = DistanceUnit.fromProjection(projection); AreaOfInterest areaOfInterest = map.areaOfInterest; if (areaOfInterest == null) { areaOfInterest = new AreaOfInterest(); areaOfInterest.display = AreaOfInterest.AoiDisplay.NONE; ReferencedEnvelope mapBBox = map.getMapBounds().toReferencedEnvelope(paintArea); areaOfInterest.setPolygon(this.geometryFactory.toGeometry(mapBBox)); } Envelope aoiBBox = areaOfInterest.getArea().getEnvelopeInternal(); final double paintAreaWidthIn = paintArea.getWidth() * paging.scale / PDF_DPI; final double paintAreaHeightIn = paintArea.getHeight() * paging.scale / PDF_DPI; final double paintAreaWidth = DistanceUnit.IN.convertTo(paintAreaWidthIn, projectionUnit); final double paintAreaHeight = DistanceUnit.IN.convertTo(paintAreaHeightIn, projectionUnit); final double overlapProj = DistanceUnit.IN.convertTo(paging.overlap * paging.scale / PDF_DPI, projectionUnit); final int nbWidth = (int) Math.ceil((aoiBBox.getWidth() + overlapProj) / (paintAreaWidth - overlapProj)); final int nbHeight = (int) Math.ceil((aoiBBox.getHeight() + overlapProj) / (paintAreaHeight - overlapProj)); final double marginWidth = (paintAreaWidth * nbWidth - (nbWidth - 1) * overlapProj - aoiBBox.getWidth()) / 2; final double marginHeight = (paintAreaHeight * nbHeight - (nbHeight - 1) * overlapProj - aoiBBox.getHeight()) / 2; final double minX = aoiBBox.getMinX() - marginWidth - overlapProj / 2; final double minY = aoiBBox.getMinY() - marginHeight - overlapProj / 2; LOGGER.info("Paging generate a grid of {}x{} potential maps.", nbWidth, nbHeight); final int[][] mapIndexes = new int[nbWidth][nbHeight]; final Envelope[][] mapsBounds = new Envelope[nbWidth][nbHeight]; int mapIndex = 0; for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { final double x1 = minX + i * (paintAreaWidth - overlapProj); final double x2 = x1 + paintAreaWidth; final double y1 = minY + j * (paintAreaHeight - overlapProj); final double y2 = y1 + paintAreaHeight; Coordinate[] coords = new Coordinate[]{ new Coordinate(x1, y1), new Coordinate(x1, y2), new Coordinate(x2, y2), new Coordinate(x2, y1), new Coordinate(x1, y1) }; LinearRing ring = this.geometryFactory.createLinearRing(coords); final Polygon bbox = this.geometryFactory.createPolygon(ring); if (areaOfInterest.getArea().intersects(bbox)) { mapsBounds[i][j] = bbox.getEnvelopeInternal(); mapIndexes[i][j] = mapIndex; mapIndex++; } else { mapIndexes[i][j] = DO_NOT_RENDER_BBOX_INDEX; } } } final List<Map<String, Object>> mapList = new ArrayList<>(); for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { if (mapIndexes[i][j] != DO_NOT_RENDER_BBOX_INDEX) { Map<String, Object> mapValues = new HashMap<>(); mapValues.put("name", mapIndexes[i][j]); mapValues.put("left", i != 0 ? mapIndexes[i - 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("bottom", j != 0 ? mapIndexes[i][j - 1] : DO_NOT_RENDER_BBOX_INDEX); mapValues .put("right", i != nbWidth - 1 ? mapIndexes[i + 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("top", j != nbHeight - 1 ? mapIndexes[i][j + 1] : DO_NOT_RENDER_BBOX_INDEX); final Envelope mapsBound = mapsBounds[i][j]; MapAttributeValues theMap = map.copy( map.getWidth(), map.getHeight(), (@Nonnull final MapAttributeValues input) -> { input.center = null; input.bbox = new double[]{ mapsBound.getMinX(), mapsBound.getMinY(), mapsBound.getMaxX(), mapsBound.getMaxY() }; if (paging.aoiDisplay != null) { input.areaOfInterest.display = paging.aoiDisplay; } if (paging.aoiStyle != null) { input.areaOfInterest.style = paging.aoiStyle; } return null; } ); mapValues.put(MAP_KEY, theMap); mapList.add(mapValues); } } } LOGGER.info("Paging generate {} maps definitions.", mapList.size()); DataSourceAttributeValue datasourceAttributes = new DataSourceAttributeValue(); datasourceAttributes.attributesValues = mapList.toArray(new Map[mapList.size()]); return new Output(datasourceAttributes); } }
CreateMapPagesProcessor extends AbstractProcessor<CreateMapPagesProcessor.Input, CreateMapPagesProcessor.Output> implements ProvideAttributes, RequireAttributes { @SuppressWarnings("unchecked") @Override public final Output execute(final Input values, final ExecutionContext context) { final MapAttributeValues map = values.map; final PagingAttribute.PagingProcessorValues paging = values.paging; CoordinateReferenceSystem projection = map.getMapBounds().getProjection(); final Rectangle paintArea = new Rectangle(map.getMapSize()); final DistanceUnit projectionUnit = DistanceUnit.fromProjection(projection); AreaOfInterest areaOfInterest = map.areaOfInterest; if (areaOfInterest == null) { areaOfInterest = new AreaOfInterest(); areaOfInterest.display = AreaOfInterest.AoiDisplay.NONE; ReferencedEnvelope mapBBox = map.getMapBounds().toReferencedEnvelope(paintArea); areaOfInterest.setPolygon(this.geometryFactory.toGeometry(mapBBox)); } Envelope aoiBBox = areaOfInterest.getArea().getEnvelopeInternal(); final double paintAreaWidthIn = paintArea.getWidth() * paging.scale / PDF_DPI; final double paintAreaHeightIn = paintArea.getHeight() * paging.scale / PDF_DPI; final double paintAreaWidth = DistanceUnit.IN.convertTo(paintAreaWidthIn, projectionUnit); final double paintAreaHeight = DistanceUnit.IN.convertTo(paintAreaHeightIn, projectionUnit); final double overlapProj = DistanceUnit.IN.convertTo(paging.overlap * paging.scale / PDF_DPI, projectionUnit); final int nbWidth = (int) Math.ceil((aoiBBox.getWidth() + overlapProj) / (paintAreaWidth - overlapProj)); final int nbHeight = (int) Math.ceil((aoiBBox.getHeight() + overlapProj) / (paintAreaHeight - overlapProj)); final double marginWidth = (paintAreaWidth * nbWidth - (nbWidth - 1) * overlapProj - aoiBBox.getWidth()) / 2; final double marginHeight = (paintAreaHeight * nbHeight - (nbHeight - 1) * overlapProj - aoiBBox.getHeight()) / 2; final double minX = aoiBBox.getMinX() - marginWidth - overlapProj / 2; final double minY = aoiBBox.getMinY() - marginHeight - overlapProj / 2; LOGGER.info("Paging generate a grid of {}x{} potential maps.", nbWidth, nbHeight); final int[][] mapIndexes = new int[nbWidth][nbHeight]; final Envelope[][] mapsBounds = new Envelope[nbWidth][nbHeight]; int mapIndex = 0; for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { final double x1 = minX + i * (paintAreaWidth - overlapProj); final double x2 = x1 + paintAreaWidth; final double y1 = minY + j * (paintAreaHeight - overlapProj); final double y2 = y1 + paintAreaHeight; Coordinate[] coords = new Coordinate[]{ new Coordinate(x1, y1), new Coordinate(x1, y2), new Coordinate(x2, y2), new Coordinate(x2, y1), new Coordinate(x1, y1) }; LinearRing ring = this.geometryFactory.createLinearRing(coords); final Polygon bbox = this.geometryFactory.createPolygon(ring); if (areaOfInterest.getArea().intersects(bbox)) { mapsBounds[i][j] = bbox.getEnvelopeInternal(); mapIndexes[i][j] = mapIndex; mapIndex++; } else { mapIndexes[i][j] = DO_NOT_RENDER_BBOX_INDEX; } } } final List<Map<String, Object>> mapList = new ArrayList<>(); for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { if (mapIndexes[i][j] != DO_NOT_RENDER_BBOX_INDEX) { Map<String, Object> mapValues = new HashMap<>(); mapValues.put("name", mapIndexes[i][j]); mapValues.put("left", i != 0 ? mapIndexes[i - 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("bottom", j != 0 ? mapIndexes[i][j - 1] : DO_NOT_RENDER_BBOX_INDEX); mapValues .put("right", i != nbWidth - 1 ? mapIndexes[i + 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("top", j != nbHeight - 1 ? mapIndexes[i][j + 1] : DO_NOT_RENDER_BBOX_INDEX); final Envelope mapsBound = mapsBounds[i][j]; MapAttributeValues theMap = map.copy( map.getWidth(), map.getHeight(), (@Nonnull final MapAttributeValues input) -> { input.center = null; input.bbox = new double[]{ mapsBound.getMinX(), mapsBound.getMinY(), mapsBound.getMaxX(), mapsBound.getMaxY() }; if (paging.aoiDisplay != null) { input.areaOfInterest.display = paging.aoiDisplay; } if (paging.aoiStyle != null) { input.areaOfInterest.style = paging.aoiStyle; } return null; } ); mapValues.put(MAP_KEY, theMap); mapList.add(mapValues); } } } LOGGER.info("Paging generate {} maps definitions.", mapList.size()); DataSourceAttributeValue datasourceAttributes = new DataSourceAttributeValue(); datasourceAttributes.attributesValues = mapList.toArray(new Map[mapList.size()]); return new Output(datasourceAttributes); } protected  CreateMapPagesProcessor(); }
CreateMapPagesProcessor extends AbstractProcessor<CreateMapPagesProcessor.Input, CreateMapPagesProcessor.Output> implements ProvideAttributes, RequireAttributes { @SuppressWarnings("unchecked") @Override public final Output execute(final Input values, final ExecutionContext context) { final MapAttributeValues map = values.map; final PagingAttribute.PagingProcessorValues paging = values.paging; CoordinateReferenceSystem projection = map.getMapBounds().getProjection(); final Rectangle paintArea = new Rectangle(map.getMapSize()); final DistanceUnit projectionUnit = DistanceUnit.fromProjection(projection); AreaOfInterest areaOfInterest = map.areaOfInterest; if (areaOfInterest == null) { areaOfInterest = new AreaOfInterest(); areaOfInterest.display = AreaOfInterest.AoiDisplay.NONE; ReferencedEnvelope mapBBox = map.getMapBounds().toReferencedEnvelope(paintArea); areaOfInterest.setPolygon(this.geometryFactory.toGeometry(mapBBox)); } Envelope aoiBBox = areaOfInterest.getArea().getEnvelopeInternal(); final double paintAreaWidthIn = paintArea.getWidth() * paging.scale / PDF_DPI; final double paintAreaHeightIn = paintArea.getHeight() * paging.scale / PDF_DPI; final double paintAreaWidth = DistanceUnit.IN.convertTo(paintAreaWidthIn, projectionUnit); final double paintAreaHeight = DistanceUnit.IN.convertTo(paintAreaHeightIn, projectionUnit); final double overlapProj = DistanceUnit.IN.convertTo(paging.overlap * paging.scale / PDF_DPI, projectionUnit); final int nbWidth = (int) Math.ceil((aoiBBox.getWidth() + overlapProj) / (paintAreaWidth - overlapProj)); final int nbHeight = (int) Math.ceil((aoiBBox.getHeight() + overlapProj) / (paintAreaHeight - overlapProj)); final double marginWidth = (paintAreaWidth * nbWidth - (nbWidth - 1) * overlapProj - aoiBBox.getWidth()) / 2; final double marginHeight = (paintAreaHeight * nbHeight - (nbHeight - 1) * overlapProj - aoiBBox.getHeight()) / 2; final double minX = aoiBBox.getMinX() - marginWidth - overlapProj / 2; final double minY = aoiBBox.getMinY() - marginHeight - overlapProj / 2; LOGGER.info("Paging generate a grid of {}x{} potential maps.", nbWidth, nbHeight); final int[][] mapIndexes = new int[nbWidth][nbHeight]; final Envelope[][] mapsBounds = new Envelope[nbWidth][nbHeight]; int mapIndex = 0; for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { final double x1 = minX + i * (paintAreaWidth - overlapProj); final double x2 = x1 + paintAreaWidth; final double y1 = minY + j * (paintAreaHeight - overlapProj); final double y2 = y1 + paintAreaHeight; Coordinate[] coords = new Coordinate[]{ new Coordinate(x1, y1), new Coordinate(x1, y2), new Coordinate(x2, y2), new Coordinate(x2, y1), new Coordinate(x1, y1) }; LinearRing ring = this.geometryFactory.createLinearRing(coords); final Polygon bbox = this.geometryFactory.createPolygon(ring); if (areaOfInterest.getArea().intersects(bbox)) { mapsBounds[i][j] = bbox.getEnvelopeInternal(); mapIndexes[i][j] = mapIndex; mapIndex++; } else { mapIndexes[i][j] = DO_NOT_RENDER_BBOX_INDEX; } } } final List<Map<String, Object>> mapList = new ArrayList<>(); for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { if (mapIndexes[i][j] != DO_NOT_RENDER_BBOX_INDEX) { Map<String, Object> mapValues = new HashMap<>(); mapValues.put("name", mapIndexes[i][j]); mapValues.put("left", i != 0 ? mapIndexes[i - 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("bottom", j != 0 ? mapIndexes[i][j - 1] : DO_NOT_RENDER_BBOX_INDEX); mapValues .put("right", i != nbWidth - 1 ? mapIndexes[i + 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("top", j != nbHeight - 1 ? mapIndexes[i][j + 1] : DO_NOT_RENDER_BBOX_INDEX); final Envelope mapsBound = mapsBounds[i][j]; MapAttributeValues theMap = map.copy( map.getWidth(), map.getHeight(), (@Nonnull final MapAttributeValues input) -> { input.center = null; input.bbox = new double[]{ mapsBound.getMinX(), mapsBound.getMinY(), mapsBound.getMaxX(), mapsBound.getMaxY() }; if (paging.aoiDisplay != null) { input.areaOfInterest.display = paging.aoiDisplay; } if (paging.aoiStyle != null) { input.areaOfInterest.style = paging.aoiStyle; } return null; } ); mapValues.put(MAP_KEY, theMap); mapList.add(mapValues); } } } LOGGER.info("Paging generate {} maps definitions.", mapList.size()); DataSourceAttributeValue datasourceAttributes = new DataSourceAttributeValue(); datasourceAttributes.attributesValues = mapList.toArray(new Map[mapList.size()]); return new Output(datasourceAttributes); } protected  CreateMapPagesProcessor(); @Override final Input createInputParameter(); @SuppressWarnings("unchecked") @Override final Output execute(final Input values, final ExecutionContext context); void setAttribute(final String name, final Attribute attribute); Map<String, Attribute> getAttributes(); }
CreateMapPagesProcessor extends AbstractProcessor<CreateMapPagesProcessor.Input, CreateMapPagesProcessor.Output> implements ProvideAttributes, RequireAttributes { @SuppressWarnings("unchecked") @Override public final Output execute(final Input values, final ExecutionContext context) { final MapAttributeValues map = values.map; final PagingAttribute.PagingProcessorValues paging = values.paging; CoordinateReferenceSystem projection = map.getMapBounds().getProjection(); final Rectangle paintArea = new Rectangle(map.getMapSize()); final DistanceUnit projectionUnit = DistanceUnit.fromProjection(projection); AreaOfInterest areaOfInterest = map.areaOfInterest; if (areaOfInterest == null) { areaOfInterest = new AreaOfInterest(); areaOfInterest.display = AreaOfInterest.AoiDisplay.NONE; ReferencedEnvelope mapBBox = map.getMapBounds().toReferencedEnvelope(paintArea); areaOfInterest.setPolygon(this.geometryFactory.toGeometry(mapBBox)); } Envelope aoiBBox = areaOfInterest.getArea().getEnvelopeInternal(); final double paintAreaWidthIn = paintArea.getWidth() * paging.scale / PDF_DPI; final double paintAreaHeightIn = paintArea.getHeight() * paging.scale / PDF_DPI; final double paintAreaWidth = DistanceUnit.IN.convertTo(paintAreaWidthIn, projectionUnit); final double paintAreaHeight = DistanceUnit.IN.convertTo(paintAreaHeightIn, projectionUnit); final double overlapProj = DistanceUnit.IN.convertTo(paging.overlap * paging.scale / PDF_DPI, projectionUnit); final int nbWidth = (int) Math.ceil((aoiBBox.getWidth() + overlapProj) / (paintAreaWidth - overlapProj)); final int nbHeight = (int) Math.ceil((aoiBBox.getHeight() + overlapProj) / (paintAreaHeight - overlapProj)); final double marginWidth = (paintAreaWidth * nbWidth - (nbWidth - 1) * overlapProj - aoiBBox.getWidth()) / 2; final double marginHeight = (paintAreaHeight * nbHeight - (nbHeight - 1) * overlapProj - aoiBBox.getHeight()) / 2; final double minX = aoiBBox.getMinX() - marginWidth - overlapProj / 2; final double minY = aoiBBox.getMinY() - marginHeight - overlapProj / 2; LOGGER.info("Paging generate a grid of {}x{} potential maps.", nbWidth, nbHeight); final int[][] mapIndexes = new int[nbWidth][nbHeight]; final Envelope[][] mapsBounds = new Envelope[nbWidth][nbHeight]; int mapIndex = 0; for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { final double x1 = minX + i * (paintAreaWidth - overlapProj); final double x2 = x1 + paintAreaWidth; final double y1 = minY + j * (paintAreaHeight - overlapProj); final double y2 = y1 + paintAreaHeight; Coordinate[] coords = new Coordinate[]{ new Coordinate(x1, y1), new Coordinate(x1, y2), new Coordinate(x2, y2), new Coordinate(x2, y1), new Coordinate(x1, y1) }; LinearRing ring = this.geometryFactory.createLinearRing(coords); final Polygon bbox = this.geometryFactory.createPolygon(ring); if (areaOfInterest.getArea().intersects(bbox)) { mapsBounds[i][j] = bbox.getEnvelopeInternal(); mapIndexes[i][j] = mapIndex; mapIndex++; } else { mapIndexes[i][j] = DO_NOT_RENDER_BBOX_INDEX; } } } final List<Map<String, Object>> mapList = new ArrayList<>(); for (int j = 0; j < nbHeight; j++) { for (int i = 0; i < nbWidth; i++) { if (mapIndexes[i][j] != DO_NOT_RENDER_BBOX_INDEX) { Map<String, Object> mapValues = new HashMap<>(); mapValues.put("name", mapIndexes[i][j]); mapValues.put("left", i != 0 ? mapIndexes[i - 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("bottom", j != 0 ? mapIndexes[i][j - 1] : DO_NOT_RENDER_BBOX_INDEX); mapValues .put("right", i != nbWidth - 1 ? mapIndexes[i + 1][j] : DO_NOT_RENDER_BBOX_INDEX); mapValues.put("top", j != nbHeight - 1 ? mapIndexes[i][j + 1] : DO_NOT_RENDER_BBOX_INDEX); final Envelope mapsBound = mapsBounds[i][j]; MapAttributeValues theMap = map.copy( map.getWidth(), map.getHeight(), (@Nonnull final MapAttributeValues input) -> { input.center = null; input.bbox = new double[]{ mapsBound.getMinX(), mapsBound.getMinY(), mapsBound.getMaxX(), mapsBound.getMaxY() }; if (paging.aoiDisplay != null) { input.areaOfInterest.display = paging.aoiDisplay; } if (paging.aoiStyle != null) { input.areaOfInterest.style = paging.aoiStyle; } return null; } ); mapValues.put(MAP_KEY, theMap); mapList.add(mapValues); } } } LOGGER.info("Paging generate {} maps definitions.", mapList.size()); DataSourceAttributeValue datasourceAttributes = new DataSourceAttributeValue(); datasourceAttributes.attributesValues = mapList.toArray(new Map[mapList.size()]); return new Output(datasourceAttributes); } protected  CreateMapPagesProcessor(); @Override final Input createInputParameter(); @SuppressWarnings("unchecked") @Override final Output execute(final Input values, final ExecutionContext context); void setAttribute(final String name, final Attribute attribute); Map<String, Attribute> getAttributes();  }