org.integratedmodelling.engine.geospace.extents.SpaceExtent Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
* Copyright (C) 2007, 2015:
*
* - Ferdinando Villa - integratedmodelling.org - any
* other authors listed in @author annotations
*
* All rights reserved. This file is part of the k.LAB software suite, meant to enable
* modular, collaborative, integrated development of interoperable data and model
* components. For details, see http://integratedmodelling.org.
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the Affero General Public License Version 3 or any later version.
*
* This program is distributed in the hope that it will be useful, but without any
* warranty; without even the implied warranty of merchantability or fitness for a
* particular purpose. See the Affero General Public License for more details.
*
* You should have received a copy of the Affero General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite
* 330, Boston, MA 02111-1307, USA. The license is also available at:
* https://www.gnu.org/licenses/agpl.html
*******************************************************************************/
package org.integratedmodelling.engine.geospace.extents;
import java.util.BitSet;
import java.util.Iterator;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.integratedmodelling.api.knowledge.IConcept;
import org.integratedmodelling.api.metadata.IMetadata;
import org.integratedmodelling.api.modelling.IExtent;
import org.integratedmodelling.api.modelling.IModelBean;
import org.integratedmodelling.api.modelling.IObservableSemantics;
import org.integratedmodelling.api.modelling.IObserver;
import org.integratedmodelling.api.modelling.IScale;
import org.integratedmodelling.api.modelling.IScale.Index;
import org.integratedmodelling.api.modelling.IScale.Locator;
import org.integratedmodelling.api.modelling.ITopologicallyComparable;
import org.integratedmodelling.api.modelling.storage.IStorage;
import org.integratedmodelling.api.space.IGrid;
import org.integratedmodelling.api.space.IShape;
import org.integratedmodelling.api.space.ISpatialExtent;
import org.integratedmodelling.api.space.ISpatialIndex;
import org.integratedmodelling.api.space.ITessellation;
import org.integratedmodelling.api.time.ITemporalExtent;
import org.integratedmodelling.collections.Pair;
import org.integratedmodelling.collections.Path;
import org.integratedmodelling.common.configuration.KLAB;
import org.integratedmodelling.common.interfaces.NetworkDeserializable;
import org.integratedmodelling.common.interfaces.NetworkSerializable;
import org.integratedmodelling.common.knowledge.Observation;
import org.integratedmodelling.common.model.runtime.Space;
import org.integratedmodelling.common.space.IGeometricShape;
import org.integratedmodelling.common.space.SpaceLocator;
import org.integratedmodelling.common.vocabulary.NS;
import org.integratedmodelling.engine.geospace.Geospace;
import org.integratedmodelling.engine.geospace.coverage.raster.RasterActivationLayer;
import org.integratedmodelling.engine.geospace.coverage.vector.VectorCoverage;
import org.integratedmodelling.engine.geospace.literals.ShapeValue;
import org.integratedmodelling.engine.modelling.runtime.mediators.GridToGrid;
import org.integratedmodelling.engine.modelling.runtime.mediators.GridToShape;
import org.integratedmodelling.engine.modelling.runtime.mediators.ShapeToGrid;
import org.integratedmodelling.engine.modelling.runtime.mediators.ShapeToShape;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabInternalErrorException;
import org.integratedmodelling.exceptions.KlabInternalRuntimeException;
import org.integratedmodelling.exceptions.KlabRuntimeException;
import org.integratedmodelling.exceptions.KlabUnsupportedOperationException;
import org.integratedmodelling.exceptions.KlabValidationException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Geometry;
/**
* Slated to substitute all other spatial extents - defines itself to the optimal
* representation by merging other partially specified ones.
*
* @author Ferd
*
*/
public class SpaceExtent extends Observation implements ISpatialExtent, Iterable, IGeometricShape,
NetworkSerializable, NetworkDeserializable {
ShapeValue shape = null;
Grid grid = null;
ReferencedEnvelope envelope = null;
CoordinateReferenceSystem crs = null;
VectorCoverage features = null;
double gridResolution = -1.0;
ISpatialIndex index = null;
int extentType = INCONSISTENT;
// the four states this can be in
/**
* Extent has only been set with info that require a merge before we can establish
* what the usable extent will be.
*/
public static final int INCONSISTENT = -1;
/**
* extent represents a shape location (may be single, multiple or a point) of
* multiplicity 1.
*/
public static final int SINGLE_SHAPE = 0;
/**
* Extent represents more than one shape, with one state per shape.
*/
public static final int MULTIPLE_SHAPE = 1;
/**
* Extent represents a grid, possibly with a shape that doesn't cover it entirely.
*/
public static final int GRID = 2;
class Tessellation implements ITessellation {
@Override
public Iterator iterator() {
// TODO return a shape iterator built upon the _features field.
return null;
}
}
/*
* cloning constructor
*/
private SpaceExtent(SpaceExtent extent) {
shape = extent.shape;
grid = extent.grid;
envelope = extent.envelope;
crs = extent.crs;
features = extent.features;
extentType = extent.extentType;
}
// @Override
public BitSet getMask() {
return grid == null ? null : ((RasterActivationLayer) (grid.activationLayer));
}
/**
* Return the world in lat/lon. TODO add one with a grid parameter in m.
*
* @return the world
*/
public static SpaceExtent WORLD() {
return new SpaceExtent(ShapeValue.WORLD());
}
public SpaceExtent(ShapeValue shape) {
this.shape = shape;
crs = shape.getCRS();
envelope = shape.getEnvelope();
extentType = SINGLE_SHAPE;
}
public SpaceExtent(Grid grid) {
this.grid = grid;
shape = grid.getShape();
envelope = grid.getEnvelope();
extentType = GRID;
crs = grid.crs;
}
public SpaceExtent(ShapeValue shape, int x, int y) throws KlabException {
// TODO no activation layer
this.grid = new Grid(shape, x, y, true);
this.shape = shape;
envelope = shape.getEnvelope();
extentType = GRID;
}
public SpaceExtent(VectorCoverage vector) {
features = vector;
extentType = MULTIPLE_SHAPE;
}
public SpaceExtent() {
extentType = INCONSISTENT;
}
public SpaceExtent(double resolution) {
gridResolution = resolution;
extentType = INCONSISTENT;
// TODO review - this is a forcing.
}
public SpaceExtent(IGeometricShape shape, IGrid grid) throws KlabException {
this.crs = Geospace.getCRSFromID("EPSG:" + shape.getSRID());
this.shape = new ShapeValue(shape.getGeometry(), crs);
if (grid != null) {
this.grid = new Grid(this.shape, grid.getXCells(), grid.getYCells());
if (grid instanceof Grid) {
this.grid.offsetInSupergrid = ((Grid)grid).offsetInSupergrid;
this.grid.superGridId = ((Grid)grid).superGridId;
}
this.envelope = ((Grid) grid).getEnvelope();
} else {
this.envelope = this.shape.getEnvelope();
}
}
@Override
public IExtent merge(IExtent extent, boolean force) throws KlabException {
if (extent instanceof Space && force) {
SpaceExtent ret = new SpaceExtent(this);
if (!((Space) extent).isForcing()) {
throw new KlabUnsupportedOperationException("cannot merge non-forcing foreign spatial extent in SpatialExtent");
}
ret.grid = new Grid(getShape(), Grid.parseResolution(((Space) extent).getForcingDefinition()));
return ret;
}
if (!(extent instanceof SpaceExtent)) {
throw new KlabValidationException("space extent cannot merge non-space extent");
}
SpaceExtent ret = new SpaceExtent(this);
SpaceExtent oth = (SpaceExtent) extent;
/*
* TODO figure out mandatory vs. not. These are all false, which probably
* shouldn't be - either pass to merge or be smarter.
*/
if (oth.grid != null) {
ret.set(oth.grid, force);
} else if (oth.features != null) {
ret.set(oth.features, oth.shape, force);
} else if (oth.shape != null) {
ret.set(oth.shape, force);
} else if (oth.gridResolution > 0.0) {
ret.setGridResolution(oth.gridResolution, force);
}
return ret;
}
/*
* constructor & merger w/ multiple shapes + optional boundary. If mandatory, we HAVE
* to have these, and incompatible previous specs are an error.
*/
public void set(VectorCoverage vector, ShapeValue shape, boolean mandatory)
throws KlabException {
if (extentType == INCONSISTENT) {
if (gridResolution > 0.0) {
/*
* make grid; subset to union of shapes
*/
} else {
features = vector;
extentType = MULTIPLE_SHAPE;
}
} else if (extentType == GRID) {
/*
* TODO error if mandatory, else activate the grid
*/
}
if (shape != null) {
/*
* intersect existing shape if any
*/
if (this.shape != null) {
this.shape = this.shape.intersection(shape);
} else {
this.shape = shape;
}
}
}
/*
* constructor & merger w/ grid + optional boundary. If mandatory, we HAVE to have
* these, and incompatible previous specs are an error.
*/
public void set(Grid grid, boolean mandatory) throws KlabException {
if (extentType == INCONSISTENT) {
this.grid = grid;
} else if (!mandatory) {
throw new KlabValidationException("conflicting spatial extent merge: grid -> "
+ getTypeLabel());
} else {
/*
* TODO - we want to force a grid.
*/
}
}
private String getTypeLabel() {
switch (extentType) {
case INCONSISTENT:
return "inconsistent";
case GRID:
return "grid";
case SINGLE_SHAPE:
return "single shape";
case MULTIPLE_SHAPE:
return "multiple shape";
}
return null;
}
/*
* constructor & merger w/ single shape. If mandatory, we HAVE to have these, and
* incompatible previous specs are an error.
*/
public void set(ShapeValue shape, boolean mandatory) throws KlabException {
/*
* TODO lots to do here - particularly, if we force a new shape on a grid, must
* recompute multiplicity etc. The new shape may be larger if this is called by
* union() (which does not happen at the moment, but intersection() can).
*/
if (extentType == INCONSISTENT) {
this.shape = shape;
if (gridResolution > 0.0) {
grid = new Grid(shape, gridResolution);
extentType = GRID;
}
} else if (extentType == GRID) {
/*
* mandatory? subset the grid : complain
*/
if (mandatory) {
grid.createActivationLayer(shape);
} else {
throw new KlabValidationException("conflicting spatial extent merge: shape -> grid");
}
} else if (extentType == SINGLE_SHAPE) {
/*
* if mandatory intersect shapes; if not, complain
*/
if (mandatory) {
this.shape = shape.intersection(shape);
} else {
throw new KlabValidationException("conflicting spatial extent merge: shape -> shape");
}
} else if (extentType == MULTIPLE_SHAPE) {
/*
* filter the shapes that intersect the given one and set them to the
* intersection.
*/
features = intersectFeatures(features, shape);
}
}
private VectorCoverage intersectFeatures(VectorCoverage _features2, ShapeValue shape) {
throw new KlabRuntimeException("unsupported shape intersection");
}
/*
* Set the grid resolution and become a grid if we have a boundary. If mandatory, we
* HAVE to have this, and incompatible previous specs are an error.
*/
public void setGridResolution(double res, boolean mandatory) throws KlabException {
gridResolution = res;
/*
* adopt, adapt and improve
*/
if (extentType == GRID) {
/*
* resample if mandatory, complain otherwise
*/
} else if (extentType == SINGLE_SHAPE) {
/*
* make grid
*/
grid = new Grid(shape, gridResolution);
extentType = GRID;
} else if (extentType == MULTIPLE_SHAPE) {
/*
* make grid with union
*/
}
}
@Override
public boolean isConsistent() {
return extentType != INCONSISTENT && !getShape().isEmpty() && getShape().isValid();
}
@Override
public Type getGeometryType() {
return getShape().getGeometryType();
}
@Override
public long getValueCount() {
return getMultiplicity();
}
@Override
public boolean isSpatiallyDistributed() {
return getValueCount() > 1;
}
@Override
public boolean isTemporallyDistributed() {
return false;
}
@Override
public IObserver getObserver() {
// TODO Auto-generated method stub
return null;
}
@Override
public long getMultiplicity() {
if (grid != null) {
return grid.getCellCount();
}
if (features != null) {
// TODO
}
// TODO the rest
return 1;
}
@Override
public IExtent intersection(IExtent other) throws KlabException {
if (!(other instanceof SpaceExtent)) {
throw new KlabValidationException("non-spatial extent being intersected with a spatial one");
}
SpaceExtent oth = (SpaceExtent) other;
ShapeValue mys = getShape();
ShapeValue its = oth.getShape();
if (mys == null && its == null) {
return new SpaceExtent();
} else if (mys == null && its != null) {
return new SpaceExtent(its);
} else if (mys != null && its == null) {
return new SpaceExtent(mys);
}
return new SpaceExtent(mys.intersection(its));
}
@Override
public IExtent union(IExtent other) throws KlabException {
if (!(other instanceof SpaceExtent)) {
throw new KlabValidationException("non-spatial extent being intersected with a spatial one");
}
SpaceExtent oth = (SpaceExtent) other;
ShapeValue mys = getShape();
ShapeValue its = oth.getShape();
if (mys == null && its == null) {
return new SpaceExtent();
} else if (mys == null && its != null) {
return new SpaceExtent(its);
} else if (mys != null && its == null) {
return new SpaceExtent(mys);
}
return new SpaceExtent(mys.union(its));
}
@Override
public boolean contains(IExtent o) throws KlabException {
SpaceExtent e = (SpaceExtent) o;
return shape.contains(e.shape);
}
@Override
public boolean overlaps(IExtent o) throws KlabException {
SpaceExtent e = (SpaceExtent) o;
return shape.overlaps(e.shape);
}
@Override
public boolean intersects(IExtent o) throws KlabException {
SpaceExtent e = (SpaceExtent) o;
return shape.intersects(e.shape);
}
@Override
public IConcept getDomainConcept() {
return KLAB.c(NS.SPACE_DOMAIN);
}
@Override
public IExtent collapse() {
// TODO Auto-generated method stub
return null;
}
@Override
public ISpatialExtent getExtent(int stateIndex) {
if (grid != null) {
return new SpaceExtent(grid.getCellPolygon(stateIndex));
}
// TODO return n-th shape if vector coverage != null
// TODO return self if index = 0 && it's a single shape.
return null;
}
@Override
public boolean isCovered(int stateIndex) {
return grid == null || grid.isCovered(stateIndex);
}
@Override
public Object getValue(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public Iterator iterator() {
// TODO Auto-generated method stub
return null;
}
public boolean isGrid() {
return grid != null;
}
@Override
public Grid getGrid() {
return grid;
}
@Override
public ShapeValue getShape() {
return shape;
}
public ReferencedEnvelope getEnvelope() {
return envelope;
}
@Override
public boolean isTemporal() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isSpatial() {
// TODO Auto-generated method stub
return true;
}
@Override
public ISpatialExtent getSpace() {
return this;
}
@Override
public ITemporalExtent getTime() {
return null;
}
public CoordinateReferenceSystem getCRS() {
return crs;
}
@Override
public Pair, Double> checkCoverage(ITopologicallyComparable obj)
throws KlabException {
if (this.shape == null) {
throw new KlabInternalErrorException("checking coverage on an indefinite spatial extent");
}
ShapeValue other = null;
if (obj instanceof SpaceExtent) {
other = ((SpaceExtent) obj).getShape();
} else if (obj instanceof ShapeValue) {
other = (ShapeValue) obj;
}
if (other == null) {
throw new KlabInternalErrorException("checking spatial coverage of a non-spatial object");
}
ShapeValue common = this.shape.intersection(other);
double prop = common.getGeometry().getArea() / this.shape.getGeometry().getArea();
return new Pair<>(common, prop);
}
@Override
public ITopologicallyComparable union(ITopologicallyComparable obj) throws KlabException {
SpaceExtent ret = new SpaceExtent(this);
if (this.shape == null) {
return ret;
}
ShapeValue other = null;
if (obj instanceof SpaceExtent) {
other = ((SpaceExtent) obj).getShape();
} else if (obj instanceof ShapeValue) {
other = (ShapeValue) obj;
}
if (other == null) {
return new SpaceExtent();
}
ShapeValue common = this.shape.union(other);
ret.set(common, true);
return ret;
}
@Override
public ITopologicallyComparable intersection(ITopologicallyComparable obj)
throws KlabException {
SpaceExtent ret = new SpaceExtent(this);
if (this.shape == null) {
return ret;
}
ShapeValue other = null;
if (obj instanceof SpaceExtent) {
other = ((SpaceExtent) obj).getShape();
} else if (obj instanceof ShapeValue) {
other = (ShapeValue) obj;
}
if (other == null) {
return new SpaceExtent();
}
ShapeValue common = this.shape.intersection(other);
return new SpaceExtent(common);
}
@Override
public double getCoveredExtent() {
return shape == null ? 0 : shape.getArea();
}
@Override
public String toString() {
return "S[" + envelope + "]";
}
@Override
public boolean isEmpty() {
return shape == null || shape.getGeometry().isEmpty();
}
@Override
public double getMinX() {
return envelope.getMinX();
}
@Override
public double getMinY() {
return envelope.getMinY();
}
@Override
public double getMaxX() {
return envelope.getMaxX();
}
@Override
public double getMaxY() {
return envelope.getMaxY();
}
@Override
public IScale getScale() {
// TODO won't be called, but it should return the scale we're part of
return null;
}
// @Override
// public Object adapt() {
//
// Map ret = new HashMap();
//
// ret.put("multiplicity", getValueCount());
// ret.put("domain", getDomainConcept().toString());
//
// ret.put("minx", getEnvelope().getMinX());
// ret.put("miny", getEnvelope().getMinY());
// ret.put("maxx", getEnvelope().getMaxX());
// ret.put("maxy", getEnvelope().getMaxY());
//
// if (_grid != null) {
// ret.put("grid", _grid.adapt());
// }
// ShapeValue shape = getShape();
// if (shape != null) {
// ret.put("shape", shape.toString());
// }
// ret.put("crs", Geospace.getCRSIdentifier(_crs, true));
// return ret;
// }
@Override
public int[] getDimensionSizes() {
if (features != null) {
// TODO number of features return new int[] {)
} else if (grid != null) {
return new int[] { grid.getXCells(), grid.getYCells() };
}
return new int[] { 1 };
}
@Override
public int[] getDimensionOffsets(int linearOffset, boolean rowFirst) {
if (features != null) {
return new int[] { linearOffset };
} else if (grid != null) {
if (rowFirst) {
int[] xy = grid.getXYOffsets(linearOffset);
return new int[] { xy[1], xy[0] };
}
return grid.getXYOffsets(linearOffset);
}
return new int[] { 0 };
}
@Override
public ISpatialExtent getExtent() {
return shape == null ? null : shape.asExtent();
}
@Override
public String getCRSCode() {
return Geospace.getCRSIdentifier(crs, false);
}
@Override
public ITessellation getTessellation() {
return new Tessellation();
}
@Override
public IStorage getStorage() {
// TODO Auto-generated method stub
return null;
}
@Override
public Iterator iterator(Index index) {
// TODO Auto-generated method stub
return null;
}
@Override
public IMetadata getMetadata() {
// TODO Auto-generated method stub
return null;
}
//
// @Override
// public IConcept getDirectType() {
// // TODO Auto-generated method stub
// return null;
// }
//
// @Override
// public INamespace getNamespace() {
// // TODO Auto-generated method stub
// return null;
// }
//
// @Override
// public boolean is(Object other) {
// // TODO Auto-generated method stub
// return false;
// }
@Override
public int locate(Locator locator) {
if (locator instanceof SpaceLocator) {
if (locator.isAll())
return GENERIC_LOCATOR;
if (grid != null) {
if (((SpaceLocator) locator).isLatLon()) {
return getGrid()
.getOffsetFromWorldCoordinates(((SpaceLocator) locator).lon, ((SpaceLocator) locator).lat);
} else {
return getGrid().getOffset(((SpaceLocator) locator).x, ((SpaceLocator) locator).y);
}
}
}
return INAPPROPRIATE_LOCATOR;
}
@Override
public Geometry getStandardizedGeometry() {
return shape.getStandardizedGeometry();
}
@Override
public Geometry getGeometry() {
return shape.getGeometry();
}
public static IExtent sanitize(ISpatialExtent e) throws KlabException {
if (e instanceof SpaceExtent) {
return e;
}
SpaceExtent ret = null;
String crsId = e.getCRSCode();
ShapeValue shape = new ShapeValue(((IGeometricShape) e).getGeometry(), Geospace.getCRSFromID(crsId));
if (e.getGrid() != null) {
Grid grid = new Grid(shape, e.getGrid().getXCells(), e.getGrid().getYCells());
ret = new SpaceExtent(grid);
} else {
ret = new SpaceExtent(shape);
}
return ret;
}
@Override
public String asText() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getSRID() {
return Integer.parseInt(Path.getLast(Geospace.getCRSIdentifier(crs, true), ':'));
}
@Override
public Mediator getMediator(IExtent extent, IObservableSemantics observable, IConcept trait) {
if (getGrid() != null && ((ISpatialExtent) extent).getGrid() == null
&& ((ISpatialExtent) extent).getMultiplicity() == 1) {
return new GridToShape(observable, this, ShapeValue
.sanitize(((ISpatialExtent) extent).getShape()).asExtent(), trait);
}
if (getGrid() == null && ((ISpatialExtent) extent).getGrid() != null
&& getMultiplicity() == 1) {
return new ShapeToGrid(observable, ShapeValue
.sanitize(((ISpatialExtent) extent).getShape()).asExtent(), this);
}
if (getGrid() != null && ((ISpatialExtent) extent).getGrid() != null) {
return new GridToGrid(observable, this, extent, trait);
}
if (getGrid() == null && ((ISpatialExtent) extent).getGrid() == null) {
return new ShapeToShape(observable, this, ShapeValue
.sanitize(((ISpatialExtent) extent).getShape()).asExtent());
}
return null;
}
@Override
public double getArea() {
return shape.getArea();
}
@Override
public ISpatialIndex getIndex(boolean makeNew) {
if (makeNew) {
return KLAB.MFACTORY.getSpatialIndex(this);
}
if (this.index == null) {
this.index = KLAB.MFACTORY.getSpatialIndex(this);
}
return this.index;
}
@Override
public boolean isConstant() {
return getMultiplicity() == 1;
}
@Override
public void deserialize(IModelBean object) {
if (!(object instanceof org.integratedmodelling.common.beans.Space)) {
throw new KlabInternalRuntimeException("cannot adapt a "
+ object.getClass().getCanonicalName() + " to a spatial extent");
}
org.integratedmodelling.common.beans.Space bean = (org.integratedmodelling.common.beans.Space) object;
extentType = SINGLE_SHAPE;
this.crs = Geospace.getCRSFromID(bean.getCrs());
this.envelope = new ReferencedEnvelope(bean.getMinX(), bean.getMaxX(), bean.getMinY(), bean
.getMaxY(), this.crs);
if (bean.getShape() != null) {
try {
this.shape = new ShapeValue(bean.getShape());
} catch (KlabValidationException e) {
throw new KlabRuntimeException(e);
}
}
if (bean.getGrid() != null) {
extentType = GRID;
this.grid = new Grid(crs, bean.getGrid().getMinX(), bean.getGrid().getMinY(), bean.getGrid()
.getMaxX(), bean.getGrid().getMaxY(), bean
.getGrid().getXDivs(), bean.getGrid().getYDivs());
if (this.shape != null) {
grid.shape = this.shape;
} else {
this.envelope = grid.getEnvelope();
this.shape = new ShapeValue(this.envelope);
}
}
}
@SuppressWarnings("unchecked")
@Override
public T serialize(Class desiredClass) {
if (!desiredClass.isAssignableFrom(org.integratedmodelling.common.beans.Space.class)) {
throw new KlabInternalRuntimeException("cannot adapt a space extent to "
+ desiredClass.getCanonicalName());
}
org.integratedmodelling.common.beans.Space ret = new org.integratedmodelling.common.beans.Space();
ret.setMinX(getMinX());
ret.setMinY(getMinY());
ret.setMaxX(getMaxX());
ret.setMaxY(getMaxY());
ret.setCrs(getCRSCode());
ret.setMultiplicity(getMultiplicity());
if (getShape() != null) {
ret.setShape("EPSG:4326 " + getStandardizedGeometry().toString());
}
if (grid != null) {
org.integratedmodelling.common.beans.Grid grd = new org.integratedmodelling.common.beans.Grid();
grd.setMinX(grid.getMinX());
grd.setMinY(grid.getMinY());
grd.setMaxX(grid.getMaxX());
grd.setMaxY(grid.getMaxY());
grd.setXDivs(grid.getXCells());
grd.setYDivs(grid.getYCells());
if (getShape() != null) {
grd.setShape("EPSG:4326 " + getStandardizedGeometry().toString());
}
ret.setGrid(grd);
}
return (T) ret;
}
@Override
public boolean isDynamic() {
return false;
}
/**
* Builds a 1-cell grid from a non-gridded extent. Does not set it in the extent
* (i.e., {@link #getGrid()} will keep returning null after this is called).
*
* @return
*/
public Grid makeGrid() {
try {
return new Grid(getShape(), 1, 1);
} catch (KlabException e) {
throw new KlabRuntimeException(e);
}
}
@Override
public void addChangeListener(ChangeListener listener) {
// TODO Auto-generated method stub
}
@Override
public Class getGeometryClass() {
return getGeometry() == null ? null : getGeometry().getClass();
}
}