/** * Align given bounds with square size and expand by given fraction * * @param bounds * @param size * @return */ private ReferencedEnvelope align(ReferencedEnvelope bounds, double size, double expand) { bounds = new ReferencedEnvelope(bounds); bounds.expandBy(expand * size); double x = offset(bounds.getLowerCorner(), 0, size); double y = offset(bounds.getLowerCorner(), 1, size); bounds.translate(-x, -y); return bounds; }
@Override public void onClick() { ExtendedLayerEditor cadastreObjectLayer = getTargetCadastreObjectLayer(); if (cadastreObjectLayer.getFeatureCollection().size() > 0) { ReferencedEnvelope envelope = cadastreObjectLayer.getFeatureCollection().getBounds(); envelope.expandBy(10); this.getMapControl().setDisplayArea(envelope); } super.onClick(); }
/** Zooms the map to the selected object and highlight it in the map. */ @Override public void onSelectionConfirmed() { if (this.getSelectedElement() == null) { return; } SpatialSearchResultBean selectedObj = (SpatialSearchResultBean) this.getSelectedElement(); try { Geometry geom = PojoFeatureSource.getWkbReader().read(selectedObj.getTheGeom()); // Select the object on the map this.map.clearSelectedFeatures(); this.map.selectFeature(selectedObj.getId(), geom); // Zoom to map to the object ReferencedEnvelope boundsToZoom = JTS.toEnvelope(geom); boundsToZoom.expandBy(this.searchByObject.getZoomInBuffer().doubleValue()); this.map.setDisplayArea(boundsToZoom); } catch (ParseException ex) { Messaging.getInstance().show(GisMessage.LEFT_PANEL_FIND_ERROR); org.sola.common.logging.LogUtility.log(GisMessage.LEFT_PANEL_FIND_ERROR, ex); } }
/** * This method tries to automatically determine SRS, bounding box and output size based on the * layers provided by the user and any other parameters. * * <p>If bounds are not specified by the user, they are automatically se to the union of the * bounds of all layers. * * <p>The size of the output image defaults to 512 pixels, the height is automatically determined * based on the width to height ratio of the requested layers. This is also true if either height * or width are specified by the user. If both height and width are specified by the user, the * automatically determined bounding box will be adjusted to fit inside these bounds. * * <p>General idea 1) Figure out whether SRS has been specified, fall back to EPSG:4326 2) * Determine whether all requested layers use the same SRS, - if so, try to do bounding box * calculations in native coordinates 3) Aggregate the bounding boxes (in EPSG:4326 or native) 4a) * If bounding box has been specified, adjust height of image to match 4b) If bounding box has not * been specified, but height has, adjust bounding box */ public static void autoSetBoundsAndSize(GetMapRequest getMap) { // Get the layers List<MapLayerInfo> layers = getMap.getLayers(); /** 1) Check what SRS has been requested */ String reqSRS = getMap.getSRS(); // if none, try to determine which SRS to use // and keep track of whether we can use native all the way boolean useNativeBounds = true; if (reqSRS == null) { reqSRS = guessCommonSRS(layers); forceSRS(getMap, reqSRS); } /** 2) Compare requested SRS */ for (int i = 0; useNativeBounds && i < layers.size(); i++) { if (layers.get(i) != null) { String layerSRS = layers.get(i).getSRS(); useNativeBounds = reqSRS.equalsIgnoreCase(layerSRS) && layers.get(i).getResource().getNativeBoundingBox() != null; } else { useNativeBounds = false; } } CoordinateReferenceSystem reqCRS; try { reqCRS = CRS.decode(reqSRS); } catch (Exception e) { throw new ServiceException(e); } // Ready to determine the bounds based on the layers, if not specified Envelope aggregateBbox = getMap.getBbox(); boolean specifiedBbox = true; // If bbox is not specified by request if (aggregateBbox == null) { specifiedBbox = false; // Get the bounding box from the layers for (int i = 0; i < layers.size(); i++) { MapLayerInfo layerInfo = layers.get(i); ReferencedEnvelope curbbox; try { curbbox = layerInfo.getLatLongBoundingBox(); if (useNativeBounds) { ReferencedEnvelope nativeBbox = layerInfo.getBoundingBox(); if (nativeBbox == null) { try { CoordinateReferenceSystem nativeCrs = layerInfo.getCoordinateReferenceSystem(); nativeBbox = curbbox.transform(nativeCrs, true); } catch (Exception e) { throw new ServiceException("Best effort native bbox computation failed", e); } } curbbox = nativeBbox; } } catch (Exception e) { throw new RuntimeException(e); } if (aggregateBbox != null) { aggregateBbox.expandToInclude(curbbox); } else { aggregateBbox = curbbox; } } ReferencedEnvelope ref = null; // Reproject back to requested SRS if we have to if (!useNativeBounds && !reqSRS.equalsIgnoreCase(SRS)) { try { ref = new ReferencedEnvelope(aggregateBbox, CRS.decode("EPSG:4326")); aggregateBbox = ref.transform(reqCRS, true); } catch (ProjectionException pe) { ref.expandBy(-1 * ref.getWidth() / 50, -1 * ref.getHeight() / 50); try { aggregateBbox = ref.transform(reqCRS, true); } catch (FactoryException e) { e.printStackTrace(); } catch (TransformException e) { e.printStackTrace(); } // And again... } catch (NoSuchAuthorityCodeException e) { e.printStackTrace(); } catch (TransformException e) { e.printStackTrace(); } catch (FactoryException e) { e.printStackTrace(); } } } // Just in case if (aggregateBbox == null) { forceSRS(getMap, DefaultWebMapService.SRS); aggregateBbox = DefaultWebMapService.BBOX; } // Start the processing of adjust either the bounding box // or the pixel height / width double bbheight = aggregateBbox.getHeight(); double bbwidth = aggregateBbox.getWidth(); double bbratio = bbwidth / bbheight; double mheight = getMap.getHeight(); double mwidth = getMap.getWidth(); if (mheight > 0.5 && mwidth > 0.5 && specifiedBbox) { // This person really doesnt want our help, // we'll warp it any way they like it... } else { if (mheight > 0.5 && mwidth > 0.5) { // Fully specified, need to adjust bbox double mratio = mwidth / mheight; // Adjust bounds to be less than ideal to meet spec if (bbratio > mratio) { // Too wide, need to increase height of bb double diff = ((bbwidth / mratio) - bbheight) / 2; aggregateBbox.expandBy(0, diff); } else { // Too tall, need to increase width of bb double diff = ((bbheight * mratio) - bbwidth) / 2; aggregateBbox.expandBy(diff, 0); } adjustBounds(reqSRS, aggregateBbox); } else if (mheight > 0.5) { mwidth = bbratio * mheight; } else { if (mwidth > 0.5) { mheight = (mwidth / bbratio >= 1) ? mwidth / bbratio : 1; } else { if (bbratio > 1) { mwidth = MAX_SIDE; mheight = (mwidth / bbratio >= 1) ? mwidth / bbratio : 1; } else { mheight = MAX_SIDE; mwidth = (mheight * bbratio >= 1) ? mheight * bbratio : 1; } // make sure OL output height is sufficient to show the OL scale bar fully if (mheight < MIN_OL_HEIGHT && ("application/openlayers".equalsIgnoreCase(getMap.getFormat()) || "openlayers".equalsIgnoreCase(getMap.getFormat()))) { mheight = MIN_OL_HEIGHT; mwidth = (mheight * bbratio >= 1) ? mheight * bbratio : 1; } } } // Actually set the bounding box and size of image getMap.setBbox(aggregateBbox); getMap.setWidth((int) mwidth); getMap.setHeight((int) mheight); } }