Skip to content

Commit

Permalink
Merge pull request #263 from gama-platform/improve-image-layer
Browse files Browse the repository at this point in the history
  • Loading branch information
lesquoyb authored Aug 21, 2024
2 parents 9842794 + f0e097c commit 4acd159
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 42 deletions.
62 changes: 25 additions & 37 deletions gama.core/src/gama/core/outputs/layers/ImageLayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
********************************************************************************************************/
package gama.core.outputs.layers;

import java.awt.image.BufferedImage;

import gama.core.common.geometry.Envelope3D;
import gama.core.common.geometry.Scaling3D;
import gama.core.common.interfaces.IGraphics;
Expand All @@ -25,7 +23,6 @@
import gama.gaml.operators.Cast;
import gama.gaml.statements.draw.AssetDrawingAttributes;
import gama.gaml.types.GamaFileType;
import gama.gaml.types.IType;

/**
* Written by drogoul Modified on 9 nov. 2009
Expand All @@ -43,7 +40,7 @@ public class ImageLayer extends AbstractLayer {
IImageProvider cachedImageProvider;

/** The provider. */
IExpression provider;
IExpression providerExpression;

/** The is potentially variable. */
boolean isProviderPotentiallyVariable;
Expand All @@ -64,12 +61,12 @@ public class ImageLayer extends AbstractLayer {
*/
public ImageLayer(final IScope scope, final ILayerStatement layer) {
super(layer);
provider = ((ImageLayerStatement) definition).imageExpression;
isImageProvider = isImageProvider();
isProviderPotentiallyVariable = !provider.isContextIndependant();
providerExpression = ((ImageLayerStatement) definition).imageExpression;
isImageProvider = isImageProvider(scope);
isProviderPotentiallyVariable = !providerExpression.isContextIndependant();
if (!isImageProvider) {
if (provider.isConst() || !isProviderPotentiallyVariable) {
Object value = provider.value(scope);
if (providerExpression.isConst() || !isProviderPotentiallyVariable) {
Object value = providerExpression.value(scope);
if (value instanceof String s) {
cachedImageProvider = createFileFromString(scope, s);
} else if (value instanceof IImageProvider p) {
Expand All @@ -81,7 +78,7 @@ public ImageLayer(final IScope scope, final ILayerStatement layer) {
isImageProvider = true;
}
} else if (!isProviderPotentiallyVariable) {
cachedImageProvider = createImageProviderFromFileExpression(scope);
cachedImageProvider = getImageFromProvider(scope, providerExpression.value(scope));
isImageProvider = true;
}

Expand All @@ -92,27 +89,16 @@ public ImageLayer(final IScope scope, final ILayerStatement layer) {
*
* @return true, if is image provider
*/
private boolean isImageProvider() {
IType<?> providerType = provider.getGamlType();
return IImageProvider.class.isAssignableFrom(providerType.toClass());
private boolean isImageProvider(IScope scope) {
var providerClass = providerExpression.value(scope).getClass(); // Needs to be evaluated else what is GamaIntMatrix at runtime is considered GamaMatrix
return IImageProvider.class.isAssignableFrom(providerClass);
}

@Override
protected ILayerData createData() {
return new ImageLayerData(definition);
}

/**
* Creates the file from file expression.
*
* @param scope
* the scope
* @return the gama image file
*/
private IImageProvider createImageProviderFromFileExpression(final IScope scope) {
return verifyFile(scope, provider.value(scope));
}

/**
* Creates the file from string.
*
Expand All @@ -124,22 +110,22 @@ private IImageProvider createImageProviderFromFileExpression(final IScope scope)
*/
private IImageProvider createFileFromString(final IScope scope, final String imageFileName) {
final IGamaFile<?, ?> result = GamaFileType.createFile(scope, imageFileName, false, null);
return verifyFile(scope, result);
return getImageFromProvider(scope, result);
}

/**
* Verify file.
* Verify that the provider and the environment is well setup and use it to generate an image (reuse the previous one in case it should be cached)
*
* @param scope
* the scope
* @param input
* the input
* @return the gama image file
* @return the gama image provider after the image generation
*/
private IImageProvider verifyFile(final IScope scope, final Object input) throws GamaRuntimeFileException, GamaRuntimeException {
private IImageProvider getImageFromProvider(final IScope scope, final Object input) throws GamaRuntimeFileException, GamaRuntimeException {
if (input == cachedImageProvider) return cachedImageProvider;
if (!(input instanceof IImageProvider result))
throw GamaRuntimeException.error("Not a provider of images: " + provider.serializeToGaml(false), scope);
throw GamaRuntimeException.error("Not a provider of images: " + providerExpression.serializeToGaml(false), scope);
try {
result.getImage(scope, !getData().getRefresh());
} catch (final GamaRuntimeFileException ex) {
Expand Down Expand Up @@ -167,16 +153,17 @@ private Envelope3D computeEnvelope(final IScope scope, final IImageProvider file
}

/**
* Builds the image.
* Builds the image and returns the provider
*
* @param scope
* the scope
* @return the gama image file
* @return the gama image provider
*/
protected IImageProvider buildImage(final IScope scope) {
if (!isProviderPotentiallyVariable) return cachedImageProvider;
return isImageProvider ? createImageProviderFromFileExpression(scope)
: createFileFromString(scope, Cast.asString(scope, provider.value(scope)));
return isImageProvider
? getImageFromProvider(scope, providerExpression.value(scope))
: createFileFromString(scope, Cast.asString(scope, providerExpression.value(scope)));
}


Expand All @@ -187,20 +174,21 @@ public void privateDraw(final IGraphicsScope scope, final IGraphics dg) {
final AssetDrawingAttributes attributes = new AssetDrawingAttributes(null, true);
attributes.setUseCache(!getData().getRefresh());

final IImageProvider file = buildImage(scope);
final IImageProvider actualProvider = buildImage(scope);
if (env != null) {
final GamaPoint loc;
if (dg.is2D()) {
loc = new GamaPoint(env.getMinX(), env.getMinY());
} else {
loc = new GamaPoint(env.getWidth() / 2 + env.getMinX(), env.getHeight() / 2 + env.getMinY());
loc = new GamaPoint(env.getMinX() + env.getWidth() / 2, env.getMinY() + env.getHeight() / 2);
}
attributes.setLocation(loc);
attributes.setSize(Scaling3D.of(env.getWidth(), env.getHeight(), 0));
}

if (file != null) {
dg.drawAsset(file, attributes);
if (actualProvider != null) {
// TODO: possibly drawn a second time ? shouldn't we use drawImage and return a BufferedImage from buildImage instead ?
dg.drawAsset(actualProvider, attributes);
}
else {
//TODO: should probably raise some kind of error/warning
Expand Down
6 changes: 3 additions & 3 deletions gama.core/src/gama/gaml/operators/spatial/SpatialPunctal.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.operation.distance.DistanceOp;

import gama.annotations.precompiler.IConcept;
import gama.annotations.precompiler.IOperatorCategory;
import gama.annotations.precompiler.Reason;
import gama.annotations.precompiler.GamlAnnotations.doc;
import gama.annotations.precompiler.GamlAnnotations.example;
import gama.annotations.precompiler.GamlAnnotations.no_test;
import gama.annotations.precompiler.GamlAnnotations.operator;
import gama.annotations.precompiler.GamlAnnotations.test;
import gama.annotations.precompiler.IConcept;
import gama.annotations.precompiler.IOperatorCategory;
import gama.annotations.precompiler.Reason;
import gama.core.common.geometry.GeometryUtils;
import gama.core.metamodel.shape.GamaPoint;
import gama.core.metamodel.shape.IShape;
Expand Down
4 changes: 2 additions & 2 deletions gama.extension.image/src/gama/extension/image/GamaImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ private static int grayDoubleToRGB(final double d) {
* @return the gama image
*/
public static GamaImage from(final GamaSpatialMatrix g) {
GamaImage gi = new GamaImage(g.numCols, g.numRows, TYPE_INT_RGB, "matrix" + System.currentTimeMillis());
GamaImage gi = new GamaImage(g.numCols, g.numRows, TYPE_INT_ARGB, "matrix" + System.currentTimeMillis());
final int[] imageData = ((DataBufferInt) gi.getRaster().getDataBuffer()).getData();
System.arraycopy(g.getDisplayData(), 0, imageData, 0, imageData.length);
return gi;
Expand All @@ -243,7 +243,7 @@ public static GamaImage from(final GamaSpatialMatrix g) {
*/
public static GamaImage from(final IScope scope, final GamaIntMatrix g) {
BufferedImage im = g.getImage(scope);
return from(im, false, "matrix" + System.currentTimeMillis());
return from(im, true, "matrix" + System.currentTimeMillis());
}

/**
Expand Down

0 comments on commit 4acd159

Please sign in to comment.