diff --git a/msi.gama.core/src/msi/gama/util/matrix/GamaField.java b/msi.gama.core/src/msi/gama/util/matrix/GamaField.java index 978e4843d4..8acfee4dbb 100644 --- a/msi.gama.core/src/msi/gama/util/matrix/GamaField.java +++ b/msi.gama.core/src/msi/gama/util/matrix/GamaField.java @@ -341,9 +341,26 @@ public IList getCellsIntersecting(final IScope scope, final IShape shape } } return inEnv; - } + @Override + public IList getCellsOverlapping(final IScope scope, final IShape shape) { + computeDimensions(scope); + Envelope3D env = Envelope3D.of(shape); + IList inEnv = GamaListFactory.create(Types.GEOMETRY); + GamaPoint p = new GamaPoint(); + for (double i = env.getMinX(); i < env.getMaxX(); i += cellDimensions.x) { + for (double j = env.getMinY(); j < env.getMaxY(); j += cellDimensions.y) { + p.setLocation(i, j, 0); + IShape s = getCellShapeAt(scope, p); + if( (s!=null) && (s.intersects(shape)) ){ + inEnv.add(s); + } + } + } + return inEnv; + } + @Override public IList getLocationsIntersecting(final IScope scope, final IShape shape) { computeDimensions(scope); diff --git a/msi.gama.core/src/msi/gama/util/matrix/IField.java b/msi.gama.core/src/msi/gama/util/matrix/IField.java index 242c165ba9..4ae5363aa0 100644 --- a/msi.gama.core/src/msi/gama/util/matrix/IField.java +++ b/msi.gama.core/src/msi/gama/util/matrix/IField.java @@ -177,6 +177,16 @@ default void setCellSize(final IScope scope, final GamaPoint size) { */ IList getCellsIntersecting(IScope scope, IShape shape); + /** + * Returns a list of the 'cells' (rectangle shapes) that overlap the geometry passed in parameter + * + * @param scope + * @param shape + * @return + */ + IList getCellsOverlapping(IScope scope, IShape shape); + + /** * Gets the locations intersecting. * diff --git a/msi.gama.core/src/msi/gaml/types/GamaFieldType.java b/msi.gama.core/src/msi/gaml/types/GamaFieldType.java index f0d693356e..fc3c7aa1df 100644 --- a/msi.gama.core/src/msi/gaml/types/GamaFieldType.java +++ b/msi.gama.core/src/msi/gaml/types/GamaFieldType.java @@ -271,7 +271,7 @@ public static IShape buildShapeFromFieldLocation(final IScope scope, final IFiel } /** - * Gets the shapes from geometry. + * Gets the shapes from geometry (cells with a point inside the geometry). * * @param scope the scope * @param field the field @@ -284,10 +284,33 @@ public static IShape buildShapeFromFieldLocation(final IScope scope, final IFiel content_type = IType.GEOMETRY, category = { IOperatorCategory.GRID }, concept = { IConcept.GRID }, - doc = { @doc ("Returns the list of 'cells' that 'intersect' with the geometry passed in argument. The cells are ordered by their x-, then y-coordinates") }) + doc = { @doc ("Returns the list of 'cells' that 'intersect' with the geometry passed in argument. " + + "(Intersection is understood as the cell center is insside the geometry; if the geometry is a polyline or a point, results will not be accurate." + + "The cells are ordered by their x-, then y-coordinates") }) public static IList getShapesFromGeometry(final IScope scope, final IField field, final IShape shape) { return field.getCellsIntersecting(scope, shape); } + + /** + * Gets the shapes from geometry (cells overlapping the geometry). + * + * @param scope the scope + * @param field the field + * @param shape the shape + * @return the shapes from geometry + */ + @operator ( + value = "cells_overlapping", + can_be_const = false, + content_type = IType.GEOMETRY, + category = { IOperatorCategory.GRID }, + concept = { IConcept.GRID }, + doc = { @doc ("Returns the list of 'cells' that 'overlap' the geometry passed in argument. " + + "It is much less efficient than the cells_in operator, but is relevant is a polynie or a point. " + + "The cells are ordered by their x-, then y-coordinates") }) + public static IList getShapesOverGeometry(final IScope scope, final IField field, final IShape shape) { + return field.getCellsOverlapping(scope, shape); + } /** * Gets the values from geometry.