From: <bma...@us...> - 2008-08-12 10:15:45
|
Revision: 3775 http://fudaa.svn.sourceforge.net/fudaa/?rev=3775&view=rev Author: bmarchan Date: 2008-08-12 10:15:52 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Une collection contenant tous types de geometrie. Modified Paths: -------------- branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISGeometryFactory.java Added Paths: ----------- branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISZoneCollectionGeometry.java Modified: branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISGeometryFactory.java =================================================================== --- branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISGeometryFactory.java 2008-08-12 10:10:08 UTC (rev 3774) +++ branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISGeometryFactory.java 2008-08-12 10:15:52 UTC (rev 3775) @@ -192,4 +192,36 @@ public Geometry createGeometry(final Geometry _g){ return super.createGeometry(_g); } + /** + * Cr\xE9e une g\xE9om\xE9trie de classe donn\xE9e. + * @param _init La classe a cr\xE9er. + * @param _seq La sequance de coordonn\xE9es. + * @return La g\xE9om\xE9trie. + */ + public Geometry createGeometry(final Class _clazz, final Coordinate[] _coordinates){ + return createGeometry(_clazz,getCoordinateSequenceFactory().create(_coordinates)); + } + + /** + * Cr\xE9e une g\xE9om\xE9trie de classe donn\xE9e. + * @param _init La classe a cr\xE9er. + * @param _seq La sequance de coordonn\xE9es. + * @return La g\xE9om\xE9trie. + */ + public Geometry createGeometry(final Class _clazz, final CoordinateSequence _seq){ + if (_clazz==GISPolygoneNiveau.class) + return createLinearRingNiveau(_seq); + else if (_clazz==GISPolygone.class) + return createLinearRing(_seq); + else if (_clazz==GISPolyligneNiveau.class) + return createLineStringNiveau(_seq); + else if (_clazz==GISPolyligne.class) + return createLineString(_seq); + else if (_clazz==GISMultiPoint.class) + return createMultiPoint(_seq); + else if (_clazz==GISPoint.class) + return createPoint(_seq); + else + return null; + } } \ No newline at end of file Added: branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISZoneCollectionGeometry.java =================================================================== --- branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISZoneCollectionGeometry.java (rev 0) +++ branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISZoneCollectionGeometry.java 2008-08-12 10:15:52 UTC (rev 3775) @@ -0,0 +1,336 @@ +/* + * @creation 21 mars 2005 + * @modification $Date: 2008-04-01 07:22:48 $ + * @license GNU General Public License 2 + * @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne + * @mail de...@fu... + */ +package org.fudaa.ctulu.gis; + +import gnu.trove.TIntArrayList; + +import java.util.Arrays; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.CoordinateSequence; +import com.vividsolutions.jts.geom.Geometry; + +import com.memoire.fu.FuLog; + +import org.fudaa.ctulu.CtuluCommandComposite; +import org.fudaa.ctulu.CtuluCommandContainer; +import org.fudaa.ctulu.CtuluLib; +import org.fudaa.ctulu.CtuluLibArray; +import org.fudaa.ctulu.CtuluLibString; +import org.fudaa.ctulu.CtuluListSelectionInterface; +import org.fudaa.ctulu.CtuluUI; +import org.fudaa.ctulu.collection.CtuluCollectionDouble; + +/** + * Une collection pour les g\xE9om\xE9tries quelconques. + * + * @author Bertrand Marchand + * @version $Id: GISZoneCollectionMultiPoint.java,v 1.1.2.2 2008-04-01 07:22:48 bmarchan Exp $ + */ +public class GISZoneCollectionGeometry extends GISZoneCollection { + + public GISZoneCollectionGeometry() { + this(null); + } + + /** + * @param _listener le listener + */ + public GISZoneCollectionGeometry(final GISZoneListener _listener) { + this(10, _listener); + } + + /** + * @param _listener le listener + */ + public GISZoneCollectionGeometry(final GISZoneListener _listener, final GISZoneCollectionGeometry _col) { + this(10, _listener); + if (_col != null) { + for (int i = 0; i < _col.getNumGeometries(); i++) { + super.geometry_.add(_col.getGeometry(i), null, null); + } + } + } + + public GISZoneCollectionGeometry(final int _nbObject, final GISZoneListener _listener) { + super(_nbObject); + listener_ = _listener; + } + + /** + * Cr\xE9e un tableau de valeurs d'attributs.<p> + * + * Les valeurs peuvent \xEAtre globales ou atomiques. + * + * @param _init Les valeurs d'initialisation, dans l'ordre et au nombre des mod\xE8les d'attributs. + * Si null, les valeurs par d\xE9faut sont affect\xE9es (voir {@link GISAttributeInterface#getDefaultValue()}) + * @param _dest La g\xE9ometrie. + * @param _isClosed Param\xE8tre inutilis\xE9. + * @return + */ + protected Object[] createAttributeList(final Object[] _init, final Geometry _dest, final boolean _isClosed) { + final Object[] rf = new Object[getNbAttributes()]; + if (_init != null && _init.length != getNbAttributes()) { + throw new IllegalArgumentException("bad size"); + } + for (int i = getNbAttributes() - 1; i >= 0; i--) { + rf[i]=createOrAssignAttribut(i,_init==null?null:_init[i],_dest); + } + return rf; + } + + /** + * Ne peut \xEAtre utilis\xE9 que si la liste contient des objets GIS homogenes. + */ + public void addCoordinateSequence(final CoordinateSequence _seq, final Object[] _data, + final CtuluCommandContainer _cmd) { + throw new IllegalAccessError("Can't call this method"); + } + + public void addGeometry(final Geometry _geom, final Object[] _data, final CtuluCommandContainer _cmd) { + if (!(_geom instanceof GISCoordinateSequenceContainerInterface)) + throw new IllegalArgumentException("Bad type geometry"); + + if (isGeomModifiable_) { + geometry_.add(_geom, Arrays.asList(createAttributeList(_data, _geom, true)), _cmd); + } + } + + public boolean accept(final GISVisitor _v) { + final int nb = getNumGeometries(); + for (int i = 0; i < nb; i++) { + if (!((GISCoordinateSequenceContainerInterface)getGeometry(i)).accept(_v)) { + return false; + } + } + return true; + } + /** + * @todo Les poly de niveau sont mal trait\xE9es + */ + public void addAtomic(final int _ligneIdx, final int _idxBefore, final double _x, final double _y, + final CtuluCommandContainer _cmd) { + if (!isGeomModifiable_) { + return; + } + Geometry geom = (Geometry)super.geometry_.getValueAt(_ligneIdx); + final Coordinate[] oldcs = geom.getCoordinates(); + final int initSize = oldcs.length; + final Coordinate[] cs = new Coordinate[initSize + 1]; + int idx = 0; + for (int i = 0; i < initSize; i++) { + cs[idx++] = (Coordinate)oldcs[i].clone(); + if (i == _idxBefore) { + cs[idx++] = new Coordinate(_x, _y, oldcs[i].z); + } + } + + geom = GISGeometryFactory.INSTANCE.createGeometry(geom.getClass(),cs); + setValue(_ligneIdx,geom, _cmd); + } + + /** + * @param _idx l'indice de la ligne a changer + * @param _geom la nouvelle ligne + * @param _cmd le receveur de commande + */ + public void setValue(final int _idx, final Geometry _geom, final CtuluCommandContainer _cmd) { + if (!isGeomModifiable_) { + return; + } + final Geometry old = (Geometry) super.geometry_.getValueAt(_idx); + if (old.getNumPoints() == _geom.getNumPoints() || !containsAtomicAttribute()) { + super.geometry_.setObject(_idx, _geom, _cmd); + } else { + final CtuluCommandComposite cmp = new CtuluCommandComposite(); + for (int i = getNbAttributes() - 1; i >= 0; i--) { + final GISAttributeInterface att = getAttribute(i); + if (att.isAtomicValue()) { + final GISAttributeModel m = (GISAttributeModel) (getModelListener(i).getObjectValueAt(_idx)); + final GISReprojectInterpolateurI interpolateur = GISZoneAttributeFactory.create1DInterpolateur(att, old, + _geom, m); + getModelListener(i).setObject(_idx, m.deriveNewModel(_geom.getNumPoints(), interpolateur), cmp); + } + } + super.geometry_.setObject(_idx, _geom, cmp); + if (_cmd != null) { + _cmd.addCmd(cmp.getSimplify()); + } + } + } + + public CoordinateSequence getCoordinateSequence(final int _i) { + if (!(getGeometry(_i) instanceof GISCoordinateSequenceContainerInterface)) return null; + return ((GISCoordinateSequenceContainerInterface) getGeometry(_i)).getCoordinateSequence(); + } + + public Class getDataStoreClass() { + return GISCoordinateSequenceContainerInterface.class; + } + + public double getDoubleValue(final int _idxAtt, final int _idxGeom) { + if (getAttribute(_idxAtt).isAtomicValue()) { + return CtuluLibArray.getMoyenne(((CtuluCollectionDouble) getModel(_idxAtt).getObjectValueAt(_idxGeom)).getValues()); + } + return ((CtuluCollectionDouble) getModel(_idxAtt)).getValue(_idxGeom); + } + + public void postImport(final int _firstIdx) { + final GISAttributeModel model = getModel(attributeIsZ_); + if (attributeIsZ_ == null || model == null) return; + + if (attributeIsZ_.isAtomicValue()) { + final int nb = getNumGeometries(); + for (int i = (_firstIdx < 0 ? 0 : _firstIdx); i < nb; i++) { + final CoordinateSequence seq = getCoordinateSequence(i); + final GISAttributeModelDoubleArray arr = (GISAttributeModelDoubleArray) model.getObjectValueAt(i); + for (int k = seq.size() - 1; k >= 0; k--) { + arr.set(k, seq.getOrdinate(k, 2)); + } + } + } + // L'attribut est global : On r\xE9cup\xE9re les coordonn\xE9es, qu'on moyenne. + else { + final int nb = getNumGeometries(); + for (int i = (_firstIdx < 0 ? 0 : _firstIdx); i < nb; i++) { + final CoordinateSequence seq = getCoordinateSequence(i); + double moy=0; + for (int k = seq.size() - 1; k >= 0; k--) { + moy+=seq.getOrdinate(k, 2); + } + model.setObject(i,new Double(moy/seq.size()),null); + } + } + } + + public void setCoordinateSequence(final int _idx, final CoordinateSequence _newSeq, final CtuluCommandContainer _cmd) { + final Geometry old = (Geometry) super.geometry_.getValueAt(_idx); + if (_newSeq != null && _newSeq.size() == old.getNumPoints()) { + final CoordinateSequence seq = GISGeometryFactory.INSTANCE.getCoordinateSequenceFactory().create(_newSeq); + geometry_.setObject(_idx, GISGeometryFactory.INSTANCE.createGeometry(old.getClass(), seq), _cmd); + } + } + + public void updateListeners() { + for (int i = getNbAttributes() - 1; i >= 0; i--) { + final GISAttributeModelListener m = getModelListener(i); + if (m != null) { + if (m.getAttribute().isAtomicValue()) { + for (int j = m.getSize() - 1; j >= 0; j--) { + ((GISAttributeModelListener) m.getObjectValueAt(j)).setListener(this); + } + + } else { + m.setListener(this); + } + } + } + } + + public boolean containsAtomicAttribute() { + for (int i = getNbAttributes() - 1; i >= 0; i--) { + if (getAttribute(i).isAtomicValue()) { + return true; + } + } + return false; + } + + public boolean removeAtomics(final int _idxGeom, final CtuluListSelectionInterface _sel, final CtuluUI _ui, + final CtuluCommandContainer _cmd) { + if (_sel == null || _sel.isEmpty()) { + return false; + } + boolean r = true; + final Geometry old = (Geometry) getGeometry(_idxGeom); + int nbPt = old.getNumPoints(); + // les nouvelles coordonnees. + final Coordinate[] newCs = new Coordinate[nbPt]; + // cette liste contient les indice a enlever : creee que si necessaire + // si des attribute atomics existent + final TIntArrayList idxToRemove = containsAtomicAttribute() ? new TIntArrayList(nbPt) : null; + + // compteur tempo + int count = 0; + for (int idxPt = 0; idxPt < nbPt; idxPt++) { + if (_sel.isSelected(idxPt)) { + if (idxToRemove != null) { + idxToRemove.add(idxPt); + } + } else { + newCs[count++] = (Coordinate)old.getCoordinates()[idxPt].clone(); + } + } + Geometry newGeom = null; + + // Un polygone + if (old instanceof GISPolygone && count<3) { + r = false; + if (_ui != null) { + _ui.error(null, CtuluLib.getS("La ligne brisee doit contenir {0} points au moins", CtuluLibString.TROIS), + false); + } + } + + // Une polyligne + else if (old instanceof GISPolyligne && count<2) { + r = false; + if (_ui != null) { + _ui.error(null, CtuluLib.getS("La ligne brisee doit contenir {0} points au moins", CtuluLibString.DEUX), + false); + } + } + + // Un multipoint + else if (old instanceof GISMultiPoint&&count<1) { + r=false; + if (_ui!=null) { + _ui.error(null, CtuluLib.getS("Le multipoint doit contenir {0} points au moins", CtuluLibString.UN), false); + } + } + else { + final Coordinate[] coord=new Coordinate[count]; + System.arraycopy(newCs, 0, coord, 0, coord.length); + newGeom=GISGeometryFactory.INSTANCE.createGeometry(old.getClass(), coord); + newGeom.setUserData(old.getUserData()); + } + + if (r) { + super.geometry_.setObject(_idxGeom, newGeom, _cmd); + // si des attributs atomics sont concerne + if (idxToRemove != null && idxToRemove.size() > 0) { + final int[] idx = idxToRemove.toNativeArray(); + Arrays.sort(idx); + for (int i = getNbAttributes() - 1; i >= 0; i--) { + // attribut atomic + if (getAttribute(i).isAtomicValue()) { + // dans ce cas on recupere le model contenant cet attribut + final GISAttributeModel m = getModelListener(i); + // on recupere le sous-model concerne par la modif de geometrie + final GISAttributeModel atomicModel = (GISAttributeModel) m.getObjectValueAt(_idxGeom); + // on le change + m.setObject(_idxGeom, atomicModel.createSubModel(idx), _cmd); + } + } + } + } + return r; + } + + public boolean addAll(final GISDataModel _model, final CtuluCommandContainer _cmd, final boolean _doPostImport) { + if (!isGeomModifiable_ || _model == null) { + return false; + } + // Controle que les geometries pass\xE9e sont du bon type + for (int i=0; i<_model.getNumGeometries(); i++) { + if (!(_model.getGeometry(i) instanceof GISCoordinateSequenceContainerInterface)) + throw new IllegalArgumentException("Bad geometry"); + } + return super.addAll(_model, _cmd, _doPostImport); + } +} Property changes on: branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/org/fudaa/ctulu/gis/GISZoneCollectionGeometry.java ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |