001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/graphics/FeatureLayer.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044: package org.deegree.graphics;
045:
046: import java.util.ArrayList;
047: import java.util.List;
048:
049: import org.deegree.model.crs.CoordinateSystem;
050: import org.deegree.model.crs.GeoTransformer;
051: import org.deegree.model.feature.Feature;
052: import org.deegree.model.feature.FeatureCollection;
053: import org.deegree.model.feature.FeatureFactory;
054: import org.deegree.model.feature.FeatureProperty;
055: import org.deegree.model.spatialschema.Envelope;
056: import org.deegree.model.spatialschema.Geometry;
057: import org.deegree.model.spatialschema.GeometryFactory;
058: import org.deegree.model.spatialschema.Point;
059: import org.deegree.model.spatialschema.Position;
060:
061: /**
062: * A Layer is a collection of <tt>Feature</tt>s building a thematic 'unit' waterways or country
063: * borders for example. <tt>Feature</tt>s can be added or removed from the layer. A
064: * <tt>Feature</tt> can e changed by a modul of the application using the layer because only
065: * references to <tt>Feature</tt>s are stored within a layer.
066: *
067: *
068: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
069: * @version $Revision: 10222 $ $Date: 2008-02-21 05:10:50 -0800 (Thu, 21 Feb 2008) $
070: */
071:
072: public class FeatureLayer extends AbstractLayer {
073:
074: private FeatureCollection fc = null;
075:
076: /**
077: * creates a layer with EPSG:4326 as default coordinate system
078: */
079: protected FeatureLayer(String name) throws Exception {
080: super (name);
081:
082: fc = FeatureFactory.createFeatureCollection(name, 50);
083:
084: init(fc);
085: }
086:
087: /**
088: * Creates a new FeatureLayer object.
089: *
090: * @param name
091: * @param crs
092: *
093: * @throws Exception
094: */
095: protected FeatureLayer(String name, CoordinateSystem crs)
096: throws Exception {
097: super (name, crs);
098:
099: fc = FeatureFactory.createFeatureCollection(name, 50);
100:
101: init(fc);
102: }
103:
104: /**
105: * Creates a new AbstractLayer object.
106: *
107: * @param name
108: * @param crs
109: * @param fc
110: *
111: * @throws Exception
112: */
113: protected FeatureLayer(String name, CoordinateSystem crs,
114: FeatureCollection fc) throws Exception {
115: super (name, crs);
116: init(fc);
117: }
118:
119: /**
120: * initializes serveral parameters of the layer and homogenizes the coordinate reference systems
121: * of the features
122: *
123: * @param feature
124: * @throws Exception
125: */
126: private void init(FeatureCollection feature) throws Exception {
127:
128: this .fc = FeatureFactory.createFeatureCollection(feature
129: .getId(), feature.size());
130: // create object for coordinate transformation
131: GeoTransformer gt = new GeoTransformer(cs);
132: double minx = 9E99;
133: double maxx = -9E99;
134: double miny = 9E99;
135: double maxy = -9E99;
136: String s1 = cs.getName();
137: for (int i = 0; i < feature.size(); i++) {
138: Feature feat = feature.getFeature(i);
139: FeatureProperty[] prop = feat.getProperties();
140: FeatureProperty[] propN = new FeatureProperty[prop.length];
141: boolean changed = false;
142: for (int k = 0; k < prop.length; k++) {
143:
144: Object value = prop[k].getValue();
145: propN[k] = prop[k];
146: if (value instanceof Geometry) {
147:
148: CoordinateSystem _cs_ = ((Geometry) value)
149: .getCoordinateSystem();
150: String s2 = null;
151: if (_cs_ != null) {
152: s2 = _cs_.getName();
153: } else {
154: // default reference system
155: s2 = "EPSG:4326";
156: }
157:
158: if (!s1.equalsIgnoreCase(s2)) {
159: Geometry transformedGeometry = gt
160: .transform((Geometry) value);
161: propN[k] = FeatureFactory
162: .createFeatureProperty(prop[k]
163: .getName(), transformedGeometry);
164: changed = true;
165: value = transformedGeometry;
166: }
167: if (value instanceof Point) {
168: Position pos = ((Point) value).getPosition();
169: if (pos.getX() > maxx) {
170: maxx = pos.getX();
171: }
172: if (pos.getX() < minx) {
173: minx = pos.getX();
174: }
175: if (pos.getY() > maxy) {
176: maxy = pos.getY();
177: }
178: if (pos.getY() < miny) {
179: miny = pos.getY();
180: }
181: } else {
182: Envelope en = ((Geometry) value).getEnvelope();
183: if (en.getMax().getX() > maxx) {
184: maxx = en.getMax().getX();
185: }
186: if (en.getMin().getX() < minx) {
187: minx = en.getMin().getX();
188: }
189: if (en.getMax().getY() > maxy) {
190: maxy = en.getMax().getY();
191: }
192: if (en.getMin().getY() < miny) {
193: miny = en.getMin().getY();
194: }
195: }
196: }
197: }
198: if (changed) {
199: FeatureProperty[] fp = new FeatureProperty[propN.length];
200: for (int j = 0; j < fp.length; j++) {
201: fp[j] = FeatureFactory.createFeatureProperty(
202: propN[j].getName(), propN[j].getValue());
203: }
204: feat = FeatureFactory.createFeature(feat.getId(), feat
205: .getFeatureType(), fp);
206: }
207: fc.add(feat);
208: }
209:
210: boundingbox = GeometryFactory.createEnvelope(minx, miny, maxx,
211: maxy, null);
212:
213: }
214:
215: /**
216: *
217: *
218: */
219: private void recalculateBoundingbox() {
220:
221: double minx = 9E99;
222: double maxx = -9E99;
223: double miny = 9E99;
224: double maxy = -9E99;
225:
226: for (int i = 0; i < fc.size(); i++) {
227: Geometry[] prop = fc.getFeature(i)
228: .getGeometryPropertyValues();
229: for (int k = 0; k < prop.length; k++) {
230: if (prop[k] instanceof Point) {
231: Position pos = ((Point) prop[k]).getPosition();
232: if (pos.getX() > maxx) {
233: maxx = pos.getX();
234: }
235: if (pos.getX() < minx) {
236: minx = pos.getX();
237: }
238: if (pos.getY() > maxy) {
239: maxy = pos.getY();
240: }
241: if (pos.getY() < miny) {
242: miny = pos.getY();
243: }
244: } else {
245: Envelope en = (prop[k]).getEnvelope();
246: if (en.getMax().getX() > maxx) {
247: maxx = en.getMax().getX();
248: }
249: if (en.getMin().getX() < minx) {
250: minx = en.getMin().getX();
251: }
252: if (en.getMax().getY() > maxy) {
253: maxy = en.getMax().getY();
254: }
255: if (en.getMin().getY() < miny) {
256: miny = en.getMin().getY();
257: }
258: }
259: }
260: }
261:
262: boundingbox = GeometryFactory.createEnvelope(minx, miny, maxx,
263: maxy, null);
264:
265: }
266:
267: /**
268: * returns the feature that matches the submitted id
269: *
270: * @param id
271: * @return feature identified by its id
272: */
273: public Feature getFeatureById(String id) {
274: return fc.getFeature(id);
275: }
276:
277: /**
278: * returns the feature that matches the submitted id
279: *
280: * @param ids
281: * @return features identified by their id
282: */
283: public Feature[] getFeaturesById(String[] ids) {
284:
285: List<Feature> list = new ArrayList<Feature>();
286:
287: Feature feature = null;
288:
289: for (int i = 0; i < fc.size(); i++) {
290: feature = fc.getFeature(i);
291:
292: for (int k = 0; k < ids.length; k++) {
293: if (feature.getId().equals(ids[k])) {
294: list.add(feature);
295: break;
296: }
297: }
298: }
299:
300: return list.toArray(new Feature[list.size()]);
301: }
302:
303: /**
304: * returns the feature that matches the submitted index
305: *
306: * @param index
307: * @return a feature
308: */
309: public Feature getFeature(int index) {
310: Feature feature = fc.getFeature(index);
311: return feature;
312: }
313:
314: /**
315: * returns all features
316: *
317: * @return all features as array
318: */
319: public Feature[] getAllFeatures() {
320: return fc.toArray();
321: }
322:
323: /**
324: * adds a feature to the layer
325: *
326: * @param feature
327: * @throws Exception
328: */
329: public void addFeature(Feature feature) throws Exception {
330: fc.add(feature);
331: recalculateBoundingbox();
332: }
333:
334: /**
335: * adds a feature collection to the layer
336: *
337: * @param featureCollection
338: * @throws Exception
339: */
340: public void addFeatureCollection(FeatureCollection featureCollection)
341: throws Exception {
342: fc.add(featureCollection);
343: recalculateBoundingbox();
344: }
345:
346: /**
347: * removes a display Element from the layer
348: *
349: * @param feature
350: * @throws Exception
351: */
352: public void removeFeature(Feature feature) throws Exception {
353: fc.remove(feature);
354: recalculateBoundingbox();
355: }
356:
357: /**
358: * removes the display Element from the layer that matches the submitted id
359: *
360: * @param id
361: * @throws Exception
362: */
363: public void removeFeature(int id) throws Exception {
364: removeFeature(getFeature(id));
365: }
366:
367: /**
368: * returns the amount of features within the layer.
369: *
370: * @return number of contained features
371: */
372: public int getSize() {
373: return fc.size();
374: }
375:
376: /**
377: * sets the coordinate reference system of the MapView. If a new crs is set all geometries of
378: * GeometryFeatures will be transformed to the new coordinate reference system.
379: *
380: * @param crs
381: * @throws Exception
382: */
383: public void setCoordinatesSystem(CoordinateSystem crs)
384: throws Exception {
385: if (!cs.equals(crs)) {
386: this.cs = crs;
387: init(fc);
388: }
389: }
390: }
|