001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/security/owsrequestvalidator/wms/GetMapRequestValidator.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.security.owsrequestvalidator.wms; 037 038 import static org.deegree.security.drm.model.RightType.GETMAP; 039 import static org.deegree.security.owsrequestvalidator.Messages.getString; 040 041 import java.net.URL; 042 import java.util.ArrayList; 043 import java.util.HashMap; 044 import java.util.List; 045 import java.util.Map; 046 import java.util.regex.Matcher; 047 import java.util.regex.Pattern; 048 049 import org.deegree.datatypes.QualifiedName; 050 import org.deegree.datatypes.Types; 051 import org.deegree.framework.log.ILogger; 052 import org.deegree.framework.log.LoggerFactory; 053 import org.deegree.framework.util.ColorUtils; 054 import org.deegree.framework.util.MapUtils; 055 import org.deegree.framework.util.StringTools; 056 import org.deegree.framework.xml.XMLParsingException; 057 import org.deegree.graphics.sld.AbstractStyle; 058 import org.deegree.graphics.sld.NamedLayer; 059 import org.deegree.graphics.sld.NamedStyle; 060 import org.deegree.graphics.sld.SLDFactory; 061 import org.deegree.graphics.sld.StyledLayerDescriptor; 062 import org.deegree.model.crs.CRSFactory; 063 import org.deegree.model.crs.CoordinateSystem; 064 import org.deegree.model.crs.GeoTransformer; 065 import org.deegree.model.feature.Feature; 066 import org.deegree.model.feature.FeatureFactory; 067 import org.deegree.model.feature.FeatureProperty; 068 import org.deegree.model.feature.schema.FeatureType; 069 import org.deegree.model.feature.schema.PropertyType; 070 import org.deegree.model.spatialschema.Envelope; 071 import org.deegree.model.spatialschema.GeometryFactory; 072 import org.deegree.ogcwebservices.InvalidParameterValueException; 073 import org.deegree.ogcwebservices.OGCWebServiceRequest; 074 import org.deegree.ogcwebservices.wms.operation.GetMap; 075 import org.deegree.security.UnauthorizedException; 076 import org.deegree.security.drm.SecurityAccess; 077 import org.deegree.security.drm.SecurityAccessManager; 078 import org.deegree.security.drm.model.Role; 079 import org.deegree.security.drm.model.Service; 080 import org.deegree.security.drm.model.User; 081 import org.deegree.security.owsproxy.Condition; 082 import org.deegree.security.owsproxy.OperationParameter; 083 import org.deegree.security.owsproxy.Request; 084 import org.deegree.security.owsrequestvalidator.Messages; 085 import org.deegree.security.owsrequestvalidator.Policy; 086 087 /** 088 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 089 * @author last edited by: $Author: aschmitz $ 090 * 091 * @version 1.1, $Revision: 32121 $, $Date: 2011-10-10 16:51:09 +0200 (Mo, 10 Okt 2011) $ 092 * 093 * @since 1.1 094 */ 095 096 public class GetMapRequestValidator extends AbstractWMSRequestValidator { 097 098 private static final ILogger LOG = LoggerFactory.getLogger( GetMapRequestValidator.class ); 099 100 // known condition parameter 101 private static final String BBOX = "bbox"; 102 103 private static final String LAYERS = "layers"; 104 105 private static final String BGCOLOR = "bgcolor"; 106 107 private static final String TRANSPARENCY = "transparency"; 108 109 private static final String RESOLUTION = "resolution"; 110 111 private static final String SLD = "sld"; 112 113 private static final String INVALIDBBOX = Messages.getString( "GetMapRequestValidator.INVALIDBBOX" ); 114 115 private static final String INVALIDLAYER = Messages.getString( "GetMapRequestValidator.INVALIDLAYER" ); 116 117 private static final String INVALIDSTYLE = Messages.getString( "GetMapRequestValidator.INVALIDSTYLE" ); 118 119 private static final String INVALIDBGCOLOR = Messages.getString( "GetMapRequestValidator.INVALIDBGCOLOR" ); 120 121 private static final String INVALIDTRANSPARENCY = Messages.getString( "GetMapRequestValidator.INVALIDTRANSPARENCY" ); 122 123 private static final String INVALIDRESOLUTION = Messages.getString( "GetMapRequestValidator.INVALIDRESOLUTION" ); 124 125 private static final String INVALIDSLD = Messages.getString( "GetMapRequestValidator.INVALIDSLD" ); 126 127 private static final String MISSINGCRS = Messages.getString( "GetMapRequestValidator.MISSINGCRS" ); 128 129 private List<String> accessdRes = new ArrayList<String>(); 130 131 private static FeatureType mapFT = null; 132 133 private GeoTransformer gt = null; 134 135 static { 136 if ( mapFT == null ) { 137 mapFT = GetMapRequestValidator.createFeatureType(); 138 } 139 } 140 141 /** 142 * @param policy 143 */ 144 public GetMapRequestValidator( Policy policy ) { 145 super( policy ); 146 try { 147 gt = new GeoTransformer( "EPSG:4326" ); 148 } catch ( Exception e ) { 149 e.printStackTrace(); 150 } 151 } 152 153 /** 154 * validates the incoming GetMap request against the policy assigned to a validator 155 * 156 * @param request 157 * request to validate 158 * @param user 159 * name of the user who likes to perform the request (can be null) 160 */ 161 @Override 162 public void validateRequest( OGCWebServiceRequest request, User user ) 163 throws InvalidParameterValueException, UnauthorizedException { 164 165 accessdRes.clear(); 166 userCoupled = false; 167 Request req = policy.getRequest( "WMS", "GetMap" ); 168 // request is valid because no restrictions are made 169 if ( req.isAny() || req.getPreConditions().isAny() ) { 170 return; 171 } 172 Condition condition = req.getPreConditions(); 173 174 GetMap wmsreq = (GetMap) request; 175 176 validateVersion( condition, wmsreq.getVersion() ); 177 Envelope env = wmsreq.getBoundingBox(); 178 try { 179 env = gt.transform( env, wmsreq.getSrs() ); 180 } catch ( Exception e ) { 181 throw new InvalidParameterValueException( "condition envelope isn't in the right CRS ", e ); 182 } 183 validateBBOX( condition, env ); 184 validateLayers( condition, wmsreq.getLayers() ); 185 validateBGColor( condition, ColorUtils.toHexCode( "0x", wmsreq.getBGColor() ) ); 186 validateTransparency( condition, wmsreq.getTransparency() ); 187 validateExceptions( condition, wmsreq.getExceptions() ); 188 validateFormat( condition, wmsreq.getFormat() ); 189 validateMaxWidth( condition, wmsreq.getWidth() ); 190 validateMaxHeight( condition, wmsreq.getHeight() ); 191 validateResolution( condition, wmsreq ); 192 validateSLD( condition, wmsreq.getSLD_URL() ); 193 validateSLD_Body( condition, wmsreq.getStyledLayerDescriptor() ); 194 195 if ( userCoupled ) { 196 validateAgainstRightsDB( wmsreq, user ); 197 } 198 199 } 200 201 /** 202 * checks if the passed envelope is valid against the maximum bounding box defined in the policy. If 203 * <tt>user</ff> != <tt>null</tt> the maximu valid BBOX will be read from the user/rights repository 204 * 205 * @param condition 206 * condition containing the definition of the valid BBOX 207 * @param envelope 208 * @throws InvalidParameterValueException 209 */ 210 private void validateBBOX( Condition condition, Envelope envelope ) 211 throws InvalidParameterValueException { 212 213 OperationParameter op = condition.getOperationParameter( BBOX ); 214 215 // version is valid because no restrictions are made 216 if ( op.isAny() ) 217 return; 218 219 String v = op.getFirstAsString(); 220 String[] d = StringTools.toArray( v, ",", false ); 221 Envelope env = GeometryFactory.createEnvelope( Double.parseDouble( d[0] ), Double.parseDouble( d[1] ), 222 Double.parseDouble( d[2] ), Double.parseDouble( d[3] ), null ); 223 224 try { 225 env = gt.transform( env, d[4] ); 226 } catch ( Exception e ) { 227 throw new InvalidParameterValueException( MISSINGCRS, e ); 228 } 229 230 if ( !env.contains( envelope ) ) { 231 if ( !op.isUserCoupled() ) { 232 // if not user coupled the validation has failed 233 throw new InvalidParameterValueException( INVALIDBBOX + op.getFirstAsString() ); 234 } 235 userCoupled = true; 236 accessdRes.add( "BBOX: " + v ); 237 } 238 } 239 240 /** 241 * checks if the passed layres/styles are valid against the layers/styles list defined in the policy. If 242 * <tt>user</ff> != <tt>null</tt> the valid layers/styles will be read from the user/rights repository 243 * 244 * @param condition 245 * condition containing the definition of the valid layers/styles 246 * @param layers 247 * @throws InvalidParameterValueException 248 */ 249 private void validateLayers( Condition condition, GetMap.Layer[] layers ) 250 throws InvalidParameterValueException { 251 252 OperationParameter op = condition.getOperationParameter( LAYERS ); 253 254 // version is valid because no restrictions are made 255 if ( op.isAny() ) { 256 return; 257 } 258 259 List<String> v = op.getValues(); 260 // seperate layers from assigned styles 261 Map<String, String> map = new HashMap<String, String>(); 262 for ( int i = 0; i < v.size(); i++ ) { 263 String[] tmp = StringTools.toArray( v.get( i ), "|", false ); 264 map.put( tmp[0], tmp[1] ); 265 } 266 267 for ( int i = 0; i < layers.length; i++ ) { 268 String style = layers[i].getStyleName(); 269 String vs = map.get( layers[i].getName() ); 270 if ( vs == null ) { 271 if ( !op.isUserCoupled() ) { 272 throw new InvalidParameterValueException( INVALIDLAYER + layers[i].getName() ); 273 } 274 accessdRes.add( "Layers: " + layers[i].getName() ); 275 userCoupled = true; 276 } else if ( !style.equalsIgnoreCase( "default" ) && vs.indexOf( "$any$" ) < 0 && vs.indexOf( style ) < 0 ) { 277 // a style is valid for a layer if it's the default style 278 // or the layer accepts any style or a style is explicit defined 279 // to be valid 280 if ( !op.isUserCoupled() ) { 281 throw new InvalidParameterValueException( INVALIDSTYLE + layers[i].getName() + ':' + style ); 282 } 283 userCoupled = true; 284 accessdRes.add( "Styles: " + style ); 285 } 286 } 287 288 } 289 290 /** 291 * checks if the passed bgcolor is valid against the bgcolor(s) defined in the policy. If 292 * <tt>user</ff> != <tt>null</tt> the valid bgcolors will be read from the user/rights repository 293 * 294 * @param condition 295 * condition containing the definition of the valid bgcolors 296 * @param bgcolor 297 * @throws InvalidParameterValueException 298 */ 299 private void validateBGColor( Condition condition, String bgcolor ) 300 throws InvalidParameterValueException { 301 302 OperationParameter op = condition.getOperationParameter( BGCOLOR ); 303 304 // version is valid because no restrictions are made 305 if ( op.isAny() ) 306 return; 307 308 List<String> list = op.getValues(); 309 310 if ( !list.contains( bgcolor ) ) { 311 if ( !op.isUserCoupled() ) { 312 throw new InvalidParameterValueException( INVALIDBGCOLOR + bgcolor ); 313 } 314 accessdRes.add( "BGCOLOR" + bgcolor ); 315 userCoupled = true; 316 } 317 318 } 319 320 /** 321 * checks if the passed transparency is valid against the transparency defined in the policy. If 322 * <tt>user</ff> != <tt>null</tt> the valid transparency will be read from the user/rights repository 323 * 324 * @param condition 325 * condition containing the definition of the valid transparency 326 * @param transparency 327 * @throws InvalidParameterValueException 328 */ 329 private void validateTransparency( Condition condition, boolean transparency ) 330 throws InvalidParameterValueException { 331 332 OperationParameter op = condition.getOperationParameter( TRANSPARENCY ); 333 334 // version is valid because no restrictions are made 335 if ( op.isAny() ) 336 return; 337 338 List<String> v = op.getValues(); 339 String s = "" + transparency; 340 if ( !v.get( 0 ).equals( s ) && !v.get( v.size() - 1 ).equals( s ) ) { 341 if ( !op.isUserCoupled() ) { 342 throw new InvalidParameterValueException( INVALIDTRANSPARENCY + transparency ); 343 } 344 userCoupled = true; 345 accessdRes.add( "Transparency: " + transparency ); 346 } 347 348 } 349 350 /** 351 * checks if the requested map area/size is valid against the minimum resolution defined in the policy. If 352 * <tt>user</ff> != <tt>null</tt> the valid resolution will be read from the user/rights repository 353 * 354 * @param condition 355 * condition containing the definition of the valid resolution 356 * @throws InvalidParameterValueException 357 */ 358 private void validateResolution( Condition condition, GetMap gmr ) 359 throws InvalidParameterValueException { 360 361 OperationParameter op = condition.getOperationParameter( RESOLUTION ); 362 363 // version is valid because no restrictions are made 364 if ( op.isAny() ) 365 return; 366 367 double scale = 0; 368 try { 369 scale = calcScale( gmr ); 370 } catch ( Exception e ) { 371 throw new InvalidParameterValueException( StringTools.stackTraceToString( e ) ); 372 } 373 double compareRes = 0; 374 compareRes = op.getFirstAsDouble(); 375 if ( scale < compareRes ) { 376 if ( !op.isUserCoupled() ) { 377 throw new InvalidParameterValueException( INVALIDRESOLUTION + scale ); 378 } 379 userCoupled = true; 380 accessdRes.add( "resolution: " + scale ); 381 } 382 } 383 384 /** 385 * checks if the passed reference to a SLD document is valid against the defined in the policy. If 386 * <tt>user</ff> != <tt>null</tt> the valid sld reference addresses will be read from the user/rights repository 387 * 388 * @param condition 389 * condition containing the definition of the valid sldRef 390 * @param sldRef 391 * @throws InvalidParameterValueException 392 */ 393 private void validateSLD( Condition condition, URL sldRef ) 394 throws InvalidParameterValueException { 395 396 OperationParameter op = condition.getOperationParameter( SLD ); 397 OperationParameter gmop = condition.getOperationParameter( LAYERS ); 398 399 if ( op == null && sldRef != null ) { 400 throw new InvalidParameterValueException( INVALIDSLD + sldRef ); 401 } 402 // sldRef is valid because no restrictions are made 403 if ( sldRef == null || op.isAny() ) { 404 return; 405 } 406 407 // validate reference base of the SLD 408 List<String> list = op.getValues(); 409 String port = null; 410 if ( sldRef.getPort() != -1 ) { 411 port = ":" + sldRef.getPort(); 412 } else { 413 port = ":80"; 414 } 415 String addr = sldRef.getProtocol() + "://" + sldRef.getHost() + port; 416 if ( !list.contains( addr ) ) { 417 if ( !op.isUserCoupled() ) { 418 throw new InvalidParameterValueException( INVALIDSLD + sldRef ); 419 } 420 userCoupled = true; 421 } 422 423 // validate referenced dacument to be a valid SLD 424 StyledLayerDescriptor sld = null; 425 try { 426 sld = SLDFactory.createSLD( sldRef ); 427 } catch ( XMLParsingException e ) { 428 String s = org.deegree.i18n.Messages.getMessage( "WMS_SLD_IS_NOT_VALID", sldRef ); 429 throw new InvalidParameterValueException( s ); 430 } 431 432 // validate NamedLayers referenced by the SLD 433 NamedLayer[] nl = sld.getNamedLayers(); 434 List<String> v = gmop.getValues(); 435 // seperate layers from assigned styles 436 Map<String, String> map = new HashMap<String, String>(); 437 for ( int i = 0; i < v.size(); i++ ) { 438 String[] tmp = StringTools.toArray( v.get( i ), "|", false ); 439 map.put( tmp[0], tmp[1] ); 440 } 441 if ( !userCoupled ) { 442 for ( int i = 0; i < nl.length; i++ ) { 443 AbstractStyle st = nl[i].getStyles()[0]; 444 String style = null; 445 if ( st instanceof NamedStyle ) { 446 style = ( (NamedStyle) st ).getName(); 447 } else { 448 // use default as name if a UserStyle is defined 449 // to ensure that the style will be accepted by 450 // the validator 451 style = "default"; 452 } 453 String vs = map.get( nl[i].getName() ); 454 if ( vs == null ) { 455 if ( !op.isUserCoupled() ) { 456 throw new InvalidParameterValueException( INVALIDLAYER + nl[i].getName() ); 457 } 458 accessdRes.add( "Layers: " + nl[i].getName() ); 459 userCoupled = true; 460 } else if ( !style.equalsIgnoreCase( "default" ) && vs.indexOf( "$any$" ) < 0 461 && vs.indexOf( style ) < 0 ) { 462 // a style is valid for a layer if it's the default style 463 // or the layer accepts any style or a style is explicit defined 464 // to be valid 465 if ( !op.isUserCoupled() ) { 466 throw new InvalidParameterValueException( INVALIDSTYLE + nl[i].getName() + ':' + style ); 467 } 468 userCoupled = true; 469 accessdRes.add( "Styles: " + style ); 470 } 471 } 472 } 473 474 } 475 476 /** 477 * checks if the passed user is allowed to perform a GetMap request containing a SLD_BODY parameter. 478 * 479 * @param condition 480 * condition containing when SLD_BODY is valid or nots 481 * @param sld_body 482 */ 483 private void validateSLD_Body( Condition condition, StyledLayerDescriptor sld_body ) { 484 485 /* 486 * 487 * OperationParameter op = condition.getOperationParameter( SLD_BODY ); // version is valid because no 488 * restrictions are made if ( sld_body == null ||op.isAny() ) return; // at the moment it is just evaluated if 489 * the user is allowed // to perform a SLD request or not. no content validation will // be made boolean 490 * isAllowed = false; if ( op.isUserCoupled() ) { //TODO // get comparator list from security registry } if 491 * (!isAllowed ) { throw new InvalidParameterValueException( INVALIDSLD_BODY ); } 492 */ 493 } 494 495 /** 496 * validates the passed WMS GetMap request against a User- and Rights-Management DB. 497 * 498 * @param wmsreq 499 * @param user 500 * @throws InvalidParameterValueException 501 */ 502 private void validateAgainstRightsDB( GetMap wmsreq, User user ) 503 throws InvalidParameterValueException, UnauthorizedException { 504 505 if ( user == null ) { 506 StringBuffer sb = new StringBuffer( 1000 ); 507 sb.append( ' ' ); 508 for ( int i = 0; i < accessdRes.size(); i++ ) { 509 sb.append( accessdRes.get( i ) ).append( "; " ); 510 } 511 throw new UnauthorizedException( Messages.format( "RequestValidator.NOACCESS", sb ) ); 512 } 513 514 Double scale = null; 515 try { 516 scale = new Double( calcScale( wmsreq ) ); 517 } catch ( Exception e ) { 518 throw new InvalidParameterValueException( e ); 519 } 520 521 // create feature that describes the map request 522 FeatureProperty[] fps = new FeatureProperty[11]; 523 fps[0] = FeatureFactory.createFeatureProperty( new QualifiedName( "version" ), wmsreq.getVersion() ); 524 fps[1] = FeatureFactory.createFeatureProperty( new QualifiedName( "width" ), new Integer( wmsreq.getWidth() ) ); 525 fps[2] = FeatureFactory.createFeatureProperty( new QualifiedName( "height" ), new Integer( wmsreq.getHeight() ) ); 526 Envelope env = wmsreq.getBoundingBox(); 527 try { 528 env = gt.transform( env, wmsreq.getSrs() ); 529 } catch ( Exception e ) { 530 throw new InvalidParameterValueException( "A:condition envelope isn't in the right CRS ", e ); 531 } 532 Object geom = null; 533 try { 534 geom = GeometryFactory.createSurface( env, null ); 535 } catch ( Exception e1 ) { 536 e1.printStackTrace(); 537 } 538 fps[3] = FeatureFactory.createFeatureProperty( new QualifiedName( "GEOM" ), geom ); 539 fps[4] = FeatureFactory.createFeatureProperty( new QualifiedName( "format" ), wmsreq.getFormat() ); 540 fps[5] = FeatureFactory.createFeatureProperty( new QualifiedName( "bgcolor" ), 541 ColorUtils.toHexCode( "0x", wmsreq.getBGColor() ) ); 542 fps[6] = FeatureFactory.createFeatureProperty( new QualifiedName( "transparent" ), 543 "" + wmsreq.getTransparency() ); 544 fps[7] = FeatureFactory.createFeatureProperty( new QualifiedName( "exceptions" ), wmsreq.getExceptions() ); 545 fps[8] = FeatureFactory.createFeatureProperty( new QualifiedName( "resolution" ), scale ); 546 fps[9] = FeatureFactory.createFeatureProperty( new QualifiedName( "sld" ), wmsreq.getSLD_URL() ); 547 548 GetMap.Layer[] layers = wmsreq.getLayers(); 549 for ( int i = 0; i < layers.length; i++ ) { 550 fps[10] = FeatureFactory.createFeatureProperty( new QualifiedName( "style" ), layers[i].getStyleName() ); 551 Feature feature = FeatureFactory.createFeature( "id", mapFT, fps ); 552 553 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 554 for ( int ii = 0; ii < fps.length; ii++ ) { 555 LOG.logDebug( "compared property: ", fps[ii] ); 556 } 557 } 558 559 if ( securityConfig.getProxiedUrl() == null ) { 560 handleUserCoupledRules( user, feature, layers[i].getName(), "Layer", GETMAP ); 561 } else { 562 handleUserCoupledRules( user, feature, 563 "[" + securityConfig.getProxiedUrl() + "]:" + layers[i].getName(), "Layer", 564 GETMAP ); 565 // handle custom constraints (currently only maxwidth/height) 566 try { 567 SecurityAccessManager sam = SecurityAccessManager.getInstance(); 568 SecurityAccess access = sam.acquireAccess( user ); 569 Service service = access.getServiceByAddress( securityConfig.getProxiedUrl() ); 570 boolean authorized = false; 571 for ( Role r : user.getRoles( access ) ) { 572 String constr = access.getConstraints( r, service ); 573 if ( constr == null ) { 574 authorized = true; 575 break; 576 } 577 Pattern p = Pattern.compile( "maxWidth: ([0-9]+), maxHeight: ([0-9]+)" ); 578 Matcher m = p.matcher( constr ); 579 if ( m.find() ) { 580 int width = Integer.valueOf( m.group( 1 ) ); 581 int height = Integer.valueOf( m.group( 2 ) ); 582 if ( width == 0 && height == 0 ) { 583 authorized = true; 584 break; 585 } 586 if ( width >= wmsreq.getWidth() && height >= wmsreq.getHeight() ) { 587 authorized = true; 588 break; 589 } 590 } 591 } 592 if ( !authorized ) { 593 throw new UnauthorizedException( getString( "RequestValidator.UNAUTORIZEDACCESS" ) ); 594 } 595 } catch ( UnauthorizedException e ) { 596 throw e; 597 } catch ( Throwable e ) { 598 throw new UnauthorizedException( e ); 599 } 600 } 601 } 602 603 } 604 605 /** 606 * calculates the map scale as defined in the OGC WMS 1.1.1 specifications 607 * 608 * @return scale of the map 609 */ 610 private double calcScale( GetMap request ) 611 throws Exception { 612 613 Envelope bbox = request.getBoundingBox(); 614 615 CoordinateSystem crs = CRSFactory.create( request.getSrs() ); 616 return MapUtils.calcScale( request.getWidth(), request.getHeight(), bbox, crs, 1 ); 617 // would return scale denominator 618 // return MapUtils.calcScale( request.getWidth(), request.getHeight(), bbox, crs, DEFAULT_PIXEL_SIZE ); 619 } 620 621 private static FeatureType createFeatureType() { 622 PropertyType[] ftps = new PropertyType[11]; 623 ftps[0] = FeatureFactory.createSimplePropertyType( new QualifiedName( "version" ), Types.VARCHAR, false ); 624 ftps[1] = FeatureFactory.createSimplePropertyType( new QualifiedName( "width" ), Types.INTEGER, false ); 625 ftps[2] = FeatureFactory.createSimplePropertyType( new QualifiedName( "height" ), Types.INTEGER, false ); 626 ftps[3] = FeatureFactory.createSimplePropertyType( new QualifiedName( "GEOM" ), Types.GEOMETRY, false ); 627 ftps[4] = FeatureFactory.createSimplePropertyType( new QualifiedName( "format" ), Types.VARCHAR, false ); 628 ftps[5] = FeatureFactory.createSimplePropertyType( new QualifiedName( "bgcolor" ), Types.VARCHAR, false ); 629 ftps[6] = FeatureFactory.createSimplePropertyType( new QualifiedName( "transparent" ), Types.VARCHAR, false ); 630 ftps[7] = FeatureFactory.createSimplePropertyType( new QualifiedName( "exceptions" ), Types.VARCHAR, false ); 631 ftps[8] = FeatureFactory.createSimplePropertyType( new QualifiedName( "resolution" ), Types.DOUBLE, false ); 632 ftps[9] = FeatureFactory.createSimplePropertyType( new QualifiedName( "sld" ), Types.VARCHAR, false ); 633 ftps[10] = FeatureFactory.createSimplePropertyType( new QualifiedName( "style" ), Types.VARCHAR, false ); 634 635 return FeatureFactory.createFeatureType( "GetMap", false, ftps ); 636 } 637 638 }