001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/xml/GeometryUtils.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 53177 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 package org.deegree.framework.xml;
044
045 import java.util.List;
046
047 import org.deegree.framework.util.StringTools;
048 import org.deegree.model.crs.GeoTransformer;
049 import org.deegree.model.spatialschema.Envelope;
050 import org.deegree.model.spatialschema.GMLGeometryAdapter;
051 import org.deegree.model.spatialschema.Geometry;
052 import org.deegree.model.spatialschema.MultiSurface;
053 import org.deegree.model.spatialschema.Point;
054 import org.deegree.model.spatialschema.Position;
055 import org.deegree.model.spatialschema.Ring;
056 import org.deegree.model.spatialschema.Surface;
057 import org.deegree.ogcbase.CommonNamespaces;
058 import org.w3c.dom.Element;
059 import org.w3c.dom.Node;
060
061 /**
062 * Utility methods for handling geometries within XSLT transformations
063 *
064 *
065 * @version $Revision: 9339 $
066 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
067 * @author last edited by: $Author: apoth $
068 *
069 * @version 1.0. $Revision: 9339 $, $Date: 2007-12-27 13:31:52 +0100 (Do, 27 Dez 2007) $
070 *
071 * @since 2.0
072 */
073 public class GeometryUtils {
074
075 private static NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
076
077 /**
078 *
079 * @param node
080 * @return
081 */
082 public static String getPolygonCoordinatesFromEnvelope( Node node ) {
083 StringBuffer sb = new StringBuffer( 500 );
084 try {
085 Envelope env = GMLGeometryAdapter.wrapBox( (Element) node, null );
086 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() ).append(
087 ' ' );
088 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMax().getY() ).append(
089 ' ' );
090 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMax().getY() ).append(
091 ' ' );
092 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMin().getY() ).append(
093 ' ' );
094 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() );
095 } catch ( Exception e ) {
096 e.printStackTrace();
097 sb.append( StringTools.stackTraceToString( e ) );
098 }
099 return sb.toString();
100 }
101
102 /**
103 *
104 * @param node
105 * @return
106 */
107 public static String getEnvelopeFromGeometry( Node node ) {
108 StringBuffer sb = new StringBuffer( 500 );
109 try {
110 Envelope env = GMLGeometryAdapter.wrap( (Element) node, null ).getEnvelope();
111 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() ).append(
112 ' ' );
113 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMax().getY() ).append(
114 ' ' );
115 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMax().getY() ).append(
116 ' ' );
117 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMin().getY() ).append(
118 ' ' );
119 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() );
120 } catch ( Exception e ) {
121 e.printStackTrace();
122 sb.append( StringTools.stackTraceToString( e ) );
123 }
124 return sb.toString();
125 }
126
127 /**
128 * returns the coordinates of the out ring of a polygon as comma seperated
129 * list. The coordinate tuples are seperated by a blank. If required the
130 * polygon will first transformed to the target CRS
131 *
132 * @param node
133 * @param sourceCRS
134 * @param targetCRS
135 * @return
136 */
137 public static String getPolygonOuterRing( Node node, String sourceCRS, String targetCRS ) {
138 StringBuffer coords = new StringBuffer( 10000 );
139
140 try {
141 Surface surface = (Surface) GMLGeometryAdapter.wrap( (Element) node, sourceCRS );
142 if ( !targetCRS.equals( sourceCRS ) ) {
143 GeoTransformer gt = new GeoTransformer( targetCRS );
144 surface = (Surface) gt.transform( surface );
145 }
146 Position[] pos = surface.getSurfaceBoundary().getExteriorRing().getPositions();
147 int dim = pos[0].getCoordinateDimension();
148 for ( int i = 0; i < pos.length; i++ ) {
149 coords.append( pos[i].getX() ).append( ',' ).append( pos[i].getY() );
150 if ( dim == 3 ) {
151 coords.append( ',' ).append( pos[i].getZ() );
152 }
153 coords.append( ' ' );
154 }
155 } catch ( Exception e ) {
156 e.printStackTrace();
157 }
158
159 return coords.toString();
160 }
161
162 /**
163 *
164 * @param node
165 * @param index
166 * @param sourceCRS
167 * @param targetCRS
168 * @return
169 */
170 public static String getPolygonInnerRing( Node node, int index, String sourceCRS,
171 String targetCRS ) {
172 StringBuffer coords = new StringBuffer( 10000 );
173
174 if ( "Polygon".equals( node.getLocalName() ) ||
175 "Surface".equals( node.getLocalName() ) ) {
176 try {
177 Surface surface = (Surface) GMLGeometryAdapter.wrap( (Element) node, sourceCRS );
178 if ( !targetCRS.equals( sourceCRS ) ) {
179 GeoTransformer gt = new GeoTransformer( targetCRS );
180 surface = (Surface) gt.transform( surface );
181 }
182 Position[] pos = surface.getSurfaceBoundary().getInteriorRings()[index-1].getPositions();
183 int dim = pos[0].getCoordinateDimension();
184 for ( int i = 0; i < pos.length; i++ ) {
185 coords.append( pos[i].getX() ).append( ',' ).append( pos[i].getY() );
186 if ( dim == 3 ) {
187 coords.append( ',' ).append( pos[i].getZ() );
188 }
189 coords.append( ' ' );
190 }
191 } catch ( Exception e ) {
192 e.printStackTrace();
193 }
194 }
195 return coords.toString();
196 }
197
198 /**
199 *
200 * @param node
201 * @return
202 */
203 public static double calcArea( Node node ) {
204 double area = -1;
205 try {
206 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null );
207 if ( geom instanceof Surface ) {
208 area = ( (Surface) geom ).getArea();
209 } else if ( geom instanceof MultiSurface ) {
210 area = ( (MultiSurface) geom ).getArea();
211 }
212 } catch ( Exception e ) {
213 e.printStackTrace();
214 }
215 return area;
216 }
217
218 /**
219 *
220 * @param node
221 * @return
222 */
223 public static double calcOuterBoundaryLength( Node node ) {
224 double length = 0;
225 try {
226 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null );
227 if ( geom instanceof Surface ) {
228 Ring ring = ( (Surface) geom ).getSurfaceBoundary().getExteriorRing();
229 length = ring.getAsCurveSegment().getLength();
230 } else if ( geom instanceof MultiSurface ) {
231 MultiSurface ms =( (MultiSurface) geom );
232 for ( int i = 0; i < ms.getSize(); i++ ) {
233 Ring ring = ms.getSurfaceAt( i ).getSurfaceBoundary().getExteriorRing();
234 length += ring.getAsCurveSegment().getLength();
235 }
236 }
237 } catch ( Exception e ) {
238 e.printStackTrace();
239 }
240 return length;
241 }
242
243
244 /**
245 * returns the centroid X coordinate of the geometry represented by the
246 * passed Node
247 *
248 * @param node
249 * @param targetCRS
250 * @return
251 */
252 public static double getCentroidX( Node node, String targetCRS ) {
253 if ( node != null ) {
254 Point point = null;
255 try {
256 if ( "Envelope".equals( node.getLocalName() ) ) {
257 Envelope env = GMLGeometryAdapter.wrapBox( (Element) node, null );
258 point = env.getCentroid();
259 } else {
260 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null );
261 point = geom.getCentroid();
262 }
263 GeoTransformer gt = new GeoTransformer( targetCRS );
264 point = (Point) gt.transform( point );
265 } catch ( Exception e ) {
266 e.printStackTrace();
267 }
268
269 return point.getX();
270 }
271 return -1;
272 }
273
274 /**
275 * returns the centroid Y coordinate of the geometry represented by the
276 * passed Node
277 *
278 * @param node
279 * @param targetCRS
280 * @return
281 */
282 public static double getCentroidY( Node node, String targetCRS ) {
283 if ( node != null ) {
284 Point point = null;
285 try {
286 if ( "Envelope".equals( node.getLocalName() ) ) {
287 Envelope env = GMLGeometryAdapter.wrapBox( (Element) node, null );
288 point = env.getCentroid();
289 } else {
290 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null );
291 point = geom.getCentroid();
292 }
293 GeoTransformer gt = new GeoTransformer( targetCRS );
294 point = (Point) gt.transform( point );
295 } catch ( Exception e ) {
296 e.printStackTrace();
297 }
298 return point.getY();
299 }
300 return -1;
301 }
302
303 public static String getCurveCoordinates(Node node) {
304 StringBuffer sb = new StringBuffer(10000);
305 try {
306 List<Node> list = XMLTools.getNodes( node, ".//gml:posList | gml:pos | gml:coordinates", nsc );
307 for ( Node node2 : list ) {
308 String s = XMLTools.getStringValue( node2 ).trim();
309 if ( node2.getLocalName().equals( "posList" ) ) {
310 String[] sl = StringTools.toArray( s, " ", false );
311 int dim = XMLTools.getNodeAsInt( node2, "./@srsDimension", nsc, 2 );
312 for ( int i = 0; i < sl.length; i++ ) {
313 sb.append( sl[i] );
314 if ( (i+1) % dim == 0 ) {
315 sb.append( ' ' );
316 } else {
317 sb.append( ',' );
318 }
319 }
320 } else if ( node2.getLocalName().equals( "pos" ) ) {
321 String[] sl = StringTools.toArray( s, "\t\n\r\f ,", false );
322 for ( int i = 0; i < sl.length; i++ ) {
323 sb.append( sl[i] );
324 if ( i < sl.length-1) {
325 sb.append( ',' );
326 } else {
327 sb.append( ' ' );
328 }
329 }
330 } else if ( node2.getLocalName().equals( "coordinates" ) ) {
331 sb.append( s );
332 }
333 }
334 } catch ( XMLParsingException e ) {
335 e.printStackTrace();
336 }
337 return sb.toString();
338 }
339
340 }