示例#1
0
  /**
   * Construct a query based on the state of the user interface controls, and possibly workbecnh.
   *
   * @return A catalog query
   */
  Query createQuery() {
    Query filter = new Query();
    filter.text = text.getText();

    if (filter.text == null || filter.text.length() == 0) {
      text.setText("1500 Poydras St, New Orleans, LA"); // $NON-NLS-1$
    }

    filter.bbox = new Envelope();
    if (bbox.getSelection()) {
      // TODO get current editor
      try {
        IEditorPart editor = getSite().getPage().getActiveEditor();
        Object obj = editor.getEditorInput();
        Class mapType = obj.getClass();
        Method get = mapType.getMethod("getExtent"); // $NON-NLS-1$
        Object value = get.invoke(obj);
        ReferencedEnvelope world = (ReferencedEnvelope) value;
        filter.bbox = world.transform(DefaultGeographicCRS.WGS84, true);
      } catch (Throwable t) {
        LocationUIPlugin.log("ha ha", t); // $NON-NLS-1$
      }
    }
    return filter;
  }
  private static ReferencedEnvelope toNativeCrs(
      final GeneralEnvelope requestedEnvelope, final CoordinateReferenceSystem nativeCRS)
      throws IllegalArgumentException {

    ReferencedEnvelope reqEnv = toReferencedEnvelope(requestedEnvelope);

    if (!CRS.equalsIgnoreMetadata(nativeCRS, reqEnv.getCoordinateReferenceSystem())) {
      // we're being reprojected. We'll need to reproject reqEnv into
      // our native coordsys
      try {
        // ReferencedEnvelope origReqEnv = reqEnv;
        reqEnv = reqEnv.transform(nativeCRS, true);
      } catch (FactoryException fe) {
        // unable to reproject?
        throw new IllegalArgumentException(
            "Unable to find a reprojection from requested "
                + "coordsys to native coordsys for this request",
            fe);
      } catch (TransformException te) {
        throw new IllegalArgumentException(
            "Unable to perform reprojection from requested "
                + "coordsys to native coordsys for this request",
            te);
      }
    }
    return reqEnv;
  }
  public void testSkipProjectionErrors() throws Exception {
    // build map context
    MapContext mapContext = new DefaultMapContext(DefaultGeographicCRS.WGS84);
    mapContext.addLayer(createLineCollection(), createLineStyle());

    // build projected envelope to work with (small one around the area of
    // validity of utm zone 1, which being a Gauss projection is a vertical
    // slice parallel to the central meridian, -177°)
    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, -170, 20, 40), DefaultGeographicCRS.WGS84);
    CoordinateReferenceSystem utm1N = CRS.decode("EPSG:32601");
    System.out.println(CRS.getGeographicBoundingBox(utm1N));
    ReferencedEnvelope reUtm = reWgs.transform(utm1N, true);

    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);

    // setup the renderer and listen for errors
    StreamingRenderer sr = new StreamingRenderer();
    sr.setRendererHints(Collections.singletonMap(sr.OPTIMIZED_DATA_LOADING_KEY, Boolean.FALSE));
    sr.setContext(mapContext);
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {}

          public void errorOccurred(Exception e) {
            e.printStackTrace();
            errors++;
          }
        });
    errors = 0;
    sr.paint((Graphics2D) image.getGraphics(), new Rectangle(200, 200), reUtm);
    // we should get two errors since there are two features that cannot be
    // projected but the renderer itself should not throw exceptions
    assertEquals(2, errors);
  }
  protected Polygon toPolygon(ReferencedEnvelope env2) {
    ReferencedEnvelope env = env2;
    if (env == null) env = new ReferencedEnvelope(-180, 180, -90, 90, DefaultGeographicCRS.WGS84);

    AttributeDescriptor att = mapper.getSchema().getDescriptor(mapper.getBounds());
    CoordinateReferenceSystem crs = null;

    if (att instanceof GeometryDescriptor)
      crs = ((GeometryDescriptor) att).getCoordinateReferenceSystem();

    if (crs == null) crs = DefaultGeographicCRS.WGS84;

    GeometryFactory factory = new GeometryFactory();
    try {
      env = env.transform(crs, true);
    } catch (Exception e) {
      IssuesActivator.log("", e); // $NON-NLS-1$
    }

    return factory.createPolygon(
        factory.createLinearRing(
            new Coordinate[] {
              new Coordinate(env.getMinX(), env.getMinY()),
              new Coordinate(env.getMaxX(), env.getMinY()),
              new Coordinate(env.getMaxX(), env.getMaxY()),
              new Coordinate(env.getMinX(), env.getMaxY()),
              new Coordinate(env.getMinX(), env.getMinY()),
            }),
        new LinearRing[0]);
  }
  @Test
  public void testEventAfterDrawing() throws Exception {
    // build map context
    MapContent mc = new MapContent();
    mc.addLayer(new FeatureLayer(createLineCollection(), createLineStyle()));

    // build projected envelope to work with (small one around the area of
    // validity of utm zone 1, which being a Gauss projection is a vertical
    // slice parallel to the central meridian, -177°)
    ReferencedEnvelope reWgs =
        new ReferencedEnvelope(new Envelope(-180, -170, 20, 40), DefaultGeographicCRS.WGS84);
    CoordinateReferenceSystem utm1N = CRS.decode("EPSG:32601");
    ReferencedEnvelope reUtm = reWgs.transform(utm1N, true);

    BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR);

    // setup the renderer and listen for errors
    final AtomicInteger commandsCount = new AtomicInteger(0);
    final BlockingQueue<RenderingRequest> queue =
        new ArrayBlockingQueue<RenderingRequest>(10) {
          @Override
          public void put(RenderingRequest e) throws InterruptedException {
            commandsCount.incrementAndGet();
            super.put(e);
          }
        };
    StreamingRenderer sr =
        new StreamingRenderer() {
          @Override
          protected BlockingQueue<RenderingRequest> getRequestsQueue() {
            return queue;
          }
        };
    sr.setMapContent(mc);
    sr.addRenderListener(
        new RenderListener() {
          public void featureRenderer(SimpleFeature feature) {
            assertTrue(commandsCount.get() > 0);
            features++;
          }

          public void errorOccurred(Exception e) {
            errors++;
          }
        });
    errors = 0;
    features = 0;
    sr.paint((Graphics2D) image.getGraphics(), new Rectangle(200, 200), reUtm);

    // we should get errors since there are two features that cannot be
    // projected but the renderer itself should not throw exceptions
    assertTrue(errors > 0);
  }
 private ReferencedEnvelope createProjectedFilter(ObjectId metadataId) {
   final ReferencedEnvelope boundsFilter = this.boundsFilter;
   RevFeatureType featureType = ftypeSource.getFeatureType(metadataId);
   CoordinateReferenceSystem nativeCrs = featureType.type().getCoordinateReferenceSystem();
   if (null == nativeCrs || nativeCrs instanceof DefaultEngineeringCRS) {
     return boundsFilter;
   }
   ReferencedEnvelope transformedFilter;
   try {
     transformedFilter = boundsFilter.transform(nativeCrs, true);
   } catch (TransformException | FactoryException e) {
     throw Throwables.propagate(e);
   }
   return transformedFilter;
 }
  public void removeFeatures(Filter filter) throws IOException {
    // this we can optimize, it's a matter of mass updating the last
    // revisions (and before that, we have to compute the modified envelope)
    Filter versionedFilter =
        (Filter) store.buildVersionedFilter(schema.getTypeName(), filter, new RevisionInfo());

    // deal with the transaction, are we playing with auto commit or long running?
    Transaction t = getTransaction();
    boolean autoCommit = false;
    if (Transaction.AUTO_COMMIT.equals(t)) {
      t = new DefaultTransaction();
      autoCommit = true;
    }
    VersionedJdbcTransactionState state = store.wrapped.getVersionedJdbcTransactionState(t);

    // we need to mark the modified bounds and store their wgs84 version into the transaction
    ReferencedEnvelope bounds =
        locking.getBounds(new DefaultQuery(schema.getTypeName(), versionedFilter));
    if (bounds != null) {
      if (bounds.getCoordinateReferenceSystem() == null) {
        bounds = new ReferencedEnvelope(bounds, getSchema().getCoordinateReferenceSystem());
      }
      try {
        ReferencedEnvelope wgsBounds = null;
        if (bounds.getCoordinateReferenceSystem() != null)
          wgsBounds = bounds.transform(DefaultGeographicCRS.WGS84, true);
        else wgsBounds = bounds;
        state.expandDirtyBounds(wgsBounds);
        state.setTypeNameDirty(schema.getTypeName());
      } catch (Exception e) {
        throw new DataSourceException(
            "Problems computing and storing the " + "bounds affected by this feature removal", e);
      }
    }

    // now we can run the update
    locking.modifyFeatures(
        locking.getSchema().getDescriptor("expired"),
        new Long(state.getRevision()),
        versionedFilter);

    // if it's auto commit, don't forget to actually commit
    if (autoCommit) {
      t.commit();
      t.close();
    }
    store.listenerManager.fireFeaturesRemoved(schema.getTypeName(), t, bounds, false);
  }
  /**
   * Using the viewport bounds and combined wms layer extents, determines an appropriate bounding
   * box by projecting the viewport into the request CRS, intersecting the bounds, and returning the
   * result.
   *
   * @param wmsLayers all adjacent wms layers we are requesting
   * @param viewport map editor bounds and crs
   * @param requestCRS coordinate reference system supported by the server
   * @return the bbox to ask the server for
   * @throws MismatchedDimensionException
   * @throws TransformException
   * @throws FactoryException
   */
  public static ReferencedEnvelope calculateRequestBBox(
      List<Layer> wmsLayers,
      ReferencedEnvelope viewport,
      CoordinateReferenceSystem requestCRS,
      String version)
      throws MismatchedDimensionException, TransformException, FactoryException {
    /* The bounds of all wms layers on this server combined */
    ReferencedEnvelope layersBBox = getLayersBoundingBox(requestCRS, wmsLayers, version);
    if (isEnvelopeNull(layersBBox)) {
      // the wms server has no bounds
      WMSPlugin.log("Zero width/height envelope: wmsLayers = " + layersBBox); // $NON-NLS-1$
      layersBBox = null;
      // alternatively, we could impose a reprojected -180,180,-90,90
    }

    /* The viewport bounds projected to the request crs */
    ReferencedEnvelope reprojectedViewportBBox = viewport.transform(requestCRS, true);
    if (isEnvelopeNull(reprojectedViewportBBox)) {
      // viewport couldn't be reprojected
      WMSPlugin.log(
          "Zero width/height envelope: reprojected viewport from "
              + viewport //$NON-NLS-1$
              + " to "
              + requestCRS
              + " returned "
              + reprojectedViewportBBox); //$NON-NLS-1$ //$NON-NLS-2$
    }
    // alternative for better accuracy: new ReferencedEnvelope(JTS.transform(viewport, null,
    // CRS.findMathTransform(viewportCRS, crs, true), 4), crs);

    /* The intersection of the viewport and the combined wms layers */
    Envelope interestBBox;
    if (layersBBox == null) {
      interestBBox = reprojectedViewportBBox;
    } else {
      interestBBox = reprojectedViewportBBox.intersection(layersBBox);
    }
    if (isEnvelopeNull(interestBBox)) {
      // outside of bounds, do not draw
      WMSPlugin.trace(
          "Bounds of the data are outside the bounds of the viewscreen."); //$NON-NLS-1$
      return NILL_BOX;
    }

    /* The bounds of the request we are going to make */
    ReferencedEnvelope requestBBox = new ReferencedEnvelope(interestBBox, requestCRS);
    return requestBBox;
  }
  private ReferencedEnvelope createSearchEnv(DirectPosition2D pos, double radius) {
    final CoordinateReferenceSystem contextCRS = getMapContext().getCoordinateReferenceSystem();
    ReferencedEnvelope env =
        new ReferencedEnvelope(
            pos.x - radius, pos.x + radius, pos.y - radius, pos.y + radius, contextCRS);
    if (isTransformRequired()) {
      CoordinateReferenceSystem layerCRS =
          layerRef.get().getFeatureSource().getSchema().getCoordinateReferenceSystem();
      try {
        env = env.transform(layerCRS, true);
      } catch (Exception ex) {
        throw new IllegalStateException(ex);
      }
    }

    return env;
  }
示例#10
0
  @Test
  public void testTruncateByBounds() throws Exception {

    String layerName = tileLayer.getName();
    ReferencedEnvelope bounds;
    // bounds outside layer bounds (which are -180,0,0,90)
    bounds = new ReferencedEnvelope(10, 20, 10, 20, DefaultGeographicCRS.WGS84);
    BoundingBox layerBounds = tileLayer.getGridSubset("EPSG:4326").getGridSet().getOriginalExtent();

    assertFalse(bounds.intersects(layerBounds.getMinX(), layerBounds.getMinY()));
    assertFalse(bounds.intersects(layerBounds.getMaxX(), layerBounds.getMaxY()));

    mediator.truncate(layerName, bounds);

    verify(tileBreeder, never()).dispatchTasks(any(GWCTask[].class));

    // bounds intersecting layer bounds
    bounds = new ReferencedEnvelope(-10, -10, 10, 10, DefaultGeographicCRS.WGS84);

    mediator.truncate(layerName, bounds);

    int numGridsets = tileLayer.getGridSubsets().size();
    int numFormats = tileLayer.getMimeTypes().size();
    int numStyles = 1 /* default */ + tileLayer.getInfo().cachedStyles().size();
    final int expected = numGridsets * numFormats * numStyles;
    verify(tileBreeder, times(expected)).dispatchTasks(any(GWCTask[].class));

    reset(tileBreeder);
    bounds = bounds.transform(CRS.decode("EPSG:900913"), true);
    mediator.truncate(layerName, bounds);
    verify(tileBreeder, times(expected)).dispatchTasks(any(GWCTask[].class));

    reset(tileBreeder);
    bounds = mediator.getAreaOfValidity(CRS.decode("EPSG:2083")); // Terra del Fuego
    mediator.truncate(layerName, bounds);
    verify(tileBreeder, never()).dispatchTasks(any(GWCTask[].class));

    reset(tileBreeder);
    bounds = mediator.getAreaOfValidity(CRS.decode("EPSG:26986")); // Massachussets
    mediator.truncate(layerName, bounds);
    verify(tileBreeder, times(expected)).dispatchTasks(any(GWCTask[].class));
  }
示例#11
0
 /**
  * Sets the bounds on the viewport model. This may be overridden. This implementation will set the
  * model to {@link #boundsToDisplay} if it is non-null otherwise will use the scale denominator.
  * Or if the scaleDenominator is <1 it will zoom to the model's current bounds.
  *
  * @param model the viewport model to set the bounds on.
  * @param currentBounds the bounds of the original map
  */
 public void setBounds(ViewportModel model, ReferencedEnvelope currentBounds) {
   if (boundsToDisplay != null) {
     ReferencedEnvelope destinationBox = boundsToDisplay;
     try {
       destinationBox = boundsToDisplay.transform(model.getCRS(), true);
     } catch (TransformException e) {
       ProjectUIPlugin.log(
           "Unable to transform to the viewport's CRS (ApplicationGIS#drawMap()", e);
     } catch (FactoryException e) {
       ProjectUIPlugin.log(
           "Unable to transform to the viewport's CRS (ApplicationGIS#drawMap()", e);
     }
     model.zoomToBox(destinationBox);
   } else {
     model.setBounds(currentBounds);
     if (scaleDenominator > 0) {
       model.setScale(scaleDenominator);
     }
   }
 }
  private ReferencedEnvelope calcLayersBounds(
      Collection<ILayer> layers, CoordinateReferenceSystem crs, IProgressMonitor monitor)
      throws Exception {
    log.debug("### mapCRS: " + crs); // $NON-NLS-1$

    ReferencedEnvelope result = null; // new ReferencedEnvelope( crs );
    for (ILayer layer : layers) {
      try {
        IGeoResource res = layer.getGeoResource();
        if (res == null) {
          continue;
        }
        ReferencedEnvelope bbox =
            SetLayerBoundsOperation.obtainBoundsFromResources(layer, crs, monitor);
        if (!bbox.getCoordinateReferenceSystem().equals(crs)) {
          bbox = bbox.transform(crs, true);
        }
        log.debug("layer: " + layer + ", bbox= " + bbox); // $NON-NLS-1$ //$NON-NLS-2$

        if (result == null) {
          result = bbox;
        } else {
          result.expandToInclude(bbox);
        }
        log.debug("result: bbox=  " + result); // $NON-NLS-1$
      } catch (Exception e) {
        // XXX mark layers!?
        log.debug("", e); // $NON-NLS-1$
        log.warn(
            "skipping layer: " + layer.getLabel() + " (" + e.toString(),
            e); //$NON-NLS-1$ //$NON-NLS-2$
        layer.setLayerStatus(
            new LayerStatus(
                Status.WARNING,
                LayerStatus.UNSPECIFIED,
                Messages.get("LayerStatus_noCrs"),
                e)); //$NON-NLS-1$
      }
    }
    return result != null ? result : ReferencedEnvelope.EVERYTHING.transform(crs, true);
  }
  @Test
  public void testTransformReproject() throws Exception {
    // grab the style
    Style style = RendererBaseTest.loadStyle(this, "reproject-rt.sld");
    // grab the data
    File property = new File(TestData.getResource(this, "point.properties").toURI());
    PropertyDataStore ds = new PropertyDataStore(property.getParentFile());
    FeatureSource fs = ds.getFeatureSource("point");

    // prepare a feature layer with a query and the rendering tx
    FeatureLayer layer = new FeatureLayer(fs, style);

    // prepare a bbox in UTM-32N
    ReferencedEnvelope reWgs84 = new ReferencedEnvelope(0, 12, 0, 12, CRS.decode("EPSG:4326"));
    ReferencedEnvelope reUTM32N = reWgs84.transform(CRS.decode("EPSG:3857"), true);

    // render it
    MapContent mc = new MapContent();
    mc.addLayer(layer);
    StreamingRenderer renderer = new StreamingRenderer();
    final AtomicInteger counter = new AtomicInteger();
    renderer.addRenderListener(
        new RenderListener() {

          @Override
          public void featureRenderer(SimpleFeature feature) {
            counter.incrementAndGet();
          }

          @Override
          public void errorOccurred(Exception e) {}
        });
    renderer.setMapContent(mc);
    BufferedImage image =
        RendererBaseTest.showRender("Lines with circle stroke", renderer, TIME, reUTM32N);

    // if everything went fine we rendered all the features
    assertEquals(10, counter.get());
    assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2));
  }
  /**
   * Gets a feature iterator on the results of a BBox query. BBox is used because intersects
   * occasionally throws a Side-conflict error so it is not a good query.
   *
   * <p>However maybe a better way is to try intersects then if that fails do a bbox? For now we do
   * bbox and test it with intersects
   *
   * @return Pair of an option containing the first feature if it exists, and an iterator with the
   *     rest
   */
  private FeatureIterator<SimpleFeature> getFeatureIterator() throws IOException {
    ILayer editLayer = parameters.handler.getEditLayer();
    FeatureStore<SimpleFeatureType, SimpleFeature> store = getResource(editLayer);

    // transforms the bbox to the layer crs
    ReferencedEnvelope bbox = handler.getContext().getBoundingBox(event.getPoint(), SEARCH_SIZE);
    try {
      bbox = bbox.transform(parameters.handler.getEditLayer().getCRS(), true);
    } catch (TransformException e) {
      logTransformationWarning(e);
    } catch (FactoryException e) {
      logTransformationWarning(e);
    }
    // creates a bbox filter using the bbox in the layer crs and grabs the features present in this
    // bbox
    Filter createBBoxFilter = createBBoxFilter(bbox, editLayer, filterType);
    FeatureCollection<SimpleFeatureType, SimpleFeature> collection =
        store.getFeatures(createBBoxFilter);

    FeatureIterator<SimpleFeature> reader =
        new IntersectTestingIterator(bbox, collection.features());

    return reader;
  }
  @Test
  public void testTransformReprojectedGridCoverage() throws Exception {
    Style style = RendererBaseTest.loadStyle(this, "coverageCenter.sld");

    GeoTiffReader reader = new GeoTiffReader(TestData.copy(this, "geotiff/world.tiff"));

    MapContent mc = new MapContent();
    mc.addLayer(new GridCoverageLayer(reader.read(null), style));

    StreamingRenderer renderer = new StreamingRenderer();
    renderer.setMapContent(mc);

    ReferencedEnvelope reWgs84 =
        new ReferencedEnvelope(-70, 70, -160, 160, CRS.decode("EPSG:4326"));
    ReferencedEnvelope re = reWgs84.transform(CRS.decode("EPSG:3857"), true);

    BufferedImage image =
        RendererBaseTest.showRender("Lines with circle stroke", renderer, TIME, re);
    // if everything worked we are going to have a red dot in the middle of the map
    assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2));
    assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 2));
    assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 4));
    assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 4));
  }
  /**
   * 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);
    }
  }
  public synchronized void render(
      Graphics2D destination, ReferencedEnvelope bounds, IProgressMonitor monitor)
      throws RenderException {

    int endLayerStatus = ILayer.DONE;
    try {
      if (bounds == null || bounds.isNull()) {
        bounds = getContext().getImageBounds();
      }

      if (monitor.isCanceled()) return;

      getContext().setStatus(ILayer.WAIT);

      WebMapServer wms = getWMS();

      GetMapRequest request = wms.createGetMapRequest();

      // put in default exception format we understand as a client
      // (if suppoted by the server)
      WMSCapabilities capabilities = wms.getCapabilities();
      if (capabilities
          .getRequest()
          .getGetMap()
          .getFormats()
          .contains(GetMapRequest.EXCEPTION_XML)) {
        request.setExceptions(GetMapRequest.EXCEPTION_XML);
      }
      setImageFormat(wms, request);

      if (monitor.isCanceled()) return;

      double currScale = getContext().getViewportModel().getScaleDenominator();
      List<ILayer> layers = getLayers();
      for (int i = layers.size() - 1; i >= 0; i--) {
        ILayer ilayer = layers.get(i);
        Layer layer;
        double minScale = 0;
        double maxScale = Double.MAX_VALUE;
        layer = ilayer.getResource(org.geotools.data.ows.Layer.class, null);
        // check if there are min/max scale rules
        StyleBlackboard sb = (StyleBlackboard) ilayer.getStyleBlackboard();
        Style style = (Style) sb.lookup(Style.class);
        if (style != null) {
          Rule rule = style.getFeatureTypeStyles()[0].getRules()[0];
          minScale = rule.getMinScaleDenominator();
          maxScale = rule.getMaxScaleDenominator();
        }

        if (currScale >= minScale && currScale <= maxScale) {
          // check for a wms style
          StyleImpl wmsStyle =
              (StyleImpl) ilayer.getStyleBlackboard().get(WMSStyleContent.WMSSTYLE);
          if (wmsStyle != null) {
            request.addLayer(layer, wmsStyle);
          } else {
            request.addLayer(layer);
          }
        }
      }

      if (monitor.isCanceled()) return;

      List<Layer> wmsLayers = getWMSLayers();
      if (wmsLayers == null || wmsLayers.isEmpty()) {
        endLayerStatus = ILayer.WARNING;
        return;
      }

      // figure out request CRS
      String requestCRScode = findRequestCRS(wmsLayers, getViewportCRS(), getContext().getMap());
      // TODO: make findRequestCRS more efficient (we are running CRS.decode at *least* twice)
      CoordinateReferenceSystem requestCRS = CRS.decode(requestCRScode);

      // figure out viewport
      //            ReferencedEnvelope viewport;
      //            Envelope viewportBBox = getViewportBBox();
      //            CoordinateReferenceSystem viewportCRS = getViewportCRS();
      //            if (viewportBBox == null) {
      //                // change viewport to world
      //                viewportBBox = new Envelope(-180, 180, -90, 90);
      //                if (!DefaultGeographicCRS.WGS84.equals(viewportCRS)) { // reproject
      //                    viewport = new ReferencedEnvelope(viewportBBox,
      // DefaultGeographicCRS.WGS84);
      //                    viewportBBox = viewport.transform(viewportCRS, true);
      //                }
      //            }

      ReferencedEnvelope requestBBox = null;
      Envelope backprojectedBBox = null; // request bbox projected to the viewport crs
      //            viewport = new ReferencedEnvelope(viewportBBox, viewportCRS);
      //            requestBBox = calculateRequestBBox(wmsLayers, viewport, requestCRS);

      requestBBox = calculateRequestBBox(wmsLayers, bounds, requestCRS, capabilities.getVersion());

      // check that a request is needed (not out of a bounds, invalid, etc)
      if (requestBBox == NILL_BOX) {
        endLayerStatus = ILayer.WARNING;
        return;
      }
      assert requestBBox.getCoordinateReferenceSystem().equals(requestCRS);

      if (requestBBox.getCoordinateReferenceSystem().equals(getViewportCRS())) {
        backprojectedBBox = (Envelope) requestBBox;
      } else {
        backprojectedBBox = (Envelope) requestBBox.transform(getViewportCRS(), true);
      }

      if (WMSPlugin.isDebugging(Trace.RENDER)) {
        WMSPlugin.trace("Viewport CRS: " + getViewportCRS().getName()); // $NON-NLS-1$
        WMSPlugin.trace("Request CRS: " + requestCRS.getName()); // $NON-NLS-1$
        WMSPlugin.trace("Context Image bounds: " + getContext().getImageBounds()); // $NON-NLS-1$
        WMSPlugin.trace("Request BBox  bounds: " + requestBBox); // $NON-NLS-1$
        WMSPlugin.trace("Backprojected request bounds: " + backprojectedBBox); // $NON-NLS-1$
      }

      Service wmsService = capabilities.getService();
      Dimension maxDimensions = new Dimension(wmsService.getMaxWidth(), wmsService.getMaxHeight());
      //            Dimension imageDimensions =
      // calculateImageDimensions(getContext().getMapDisplay()
      //                    .getDisplaySize(), maxDimensions, getViewportBBox(), backprojectedBBox);
      Dimension imageDimensions =
          calculateImageDimensions(
              getContext().getImageSize(), maxDimensions, bounds, backprojectedBBox);
      if (imageDimensions.height < 1 || imageDimensions.width < 1) {
        endLayerStatus = ILayer.WARNING;
        return;
      }
      request.setDimensions(
          imageDimensions.width + "", imageDimensions.height + ""); // $NON-NLS-1$ //$NON-NLS-2$
      // epsg could be under identifiers or authority.
      Set<ReferenceIdentifier> identifiers = requestCRS.getIdentifiers();
      String srs = identifiers.isEmpty() ? EPSG_4326 : identifiers.iterator().next().toString();
      request.setSRS(srs); // EPSG_4326
      request.setBBox(requestBBox);
      // request.setBBox(requestBBox.getMinX() + "," + requestBBox.getMinY()+ "," +
      // requestBBox.getMaxX()+ "," + requestBBox.getMaxY());

      if (monitor.isCanceled()) return;

      setFilter(wms, request);

      // request.setProperty("DACS_ACS", null);
      BufferedImage image = readImage(wms, request, monitor);

      if (monitor.isCanceled()) return;

      if (image == null) {
        Exception e = new RuntimeException(Messages.BasicWMSRenderer2_unable_to_decode_image);
        throw wrapException(e);
      }

      // backprojectedBBox or viewportBBox
      renderGridCoverage(destination, backprojectedBBox, imageDimensions, requestBBox, image);

    } catch (Exception e) {
      if (e instanceof RenderException) throw (RenderException) e;
      throw new RenderException(e);
    } finally {
      getContext().setStatus(endLayerStatus);
      if (endLayerStatus == ILayer.DONE) {
        // clear the status message (rendering was successful)
        getContext().setStatusMessage(null);
      }
    }
  }
示例#18
0
  /**
   * Loads the feature collection based on the current styling and the scale denominator. If no
   * feature is going to be returned a null feature collection will be returned instead
   *
   * @param featureSource
   * @param layer
   * @param mapContent
   * @param wms
   * @param scaleDenominator
   * @return
   * @throws Exception
   */
  public static SimpleFeatureCollection loadFeatureCollection(
      SimpleFeatureSource featureSource,
      Layer layer,
      WMSMapContent mapContent,
      WMS wms,
      double scaleDenominator)
      throws Exception {
    SimpleFeatureType schema = featureSource.getSchema();

    Envelope envelope = mapContent.getRenderingArea();
    ReferencedEnvelope aoi =
        new ReferencedEnvelope(envelope, mapContent.getCoordinateReferenceSystem());
    CoordinateReferenceSystem sourceCrs = schema.getCoordinateReferenceSystem();

    boolean reprojectBBox =
        (sourceCrs != null)
            && !CRS.equalsIgnoreMetadata(aoi.getCoordinateReferenceSystem(), sourceCrs);
    if (reprojectBBox) {
      aoi = aoi.transform(sourceCrs, true);
    }

    Filter filter = createBBoxFilter(schema, aoi);

    // now build the query using only the attributes and the bounding
    // box needed
    Query q = new Query(schema.getTypeName());
    q.setFilter(filter);

    // now, if a definition query has been established for this layer,
    // be sure to respect it by combining it with the bounding box one.
    Query definitionQuery = layer.getQuery();

    if (definitionQuery != Query.ALL) {
      if (q == Query.ALL) {
        q = (Query) definitionQuery;
      } else {
        q = (Query) DataUtilities.mixQueries(definitionQuery, q, "KMLEncoder");
      }
    }

    // handle startIndex requested by client query
    q.setStartIndex(definitionQuery.getStartIndex());

    // check the regionating strategy
    RegionatingStrategy regionatingStrategy = null;
    String stratname = (String) mapContent.getRequest().getFormatOptions().get("regionateBy");
    if (("auto").equals(stratname)) {
      Catalog catalog = wms.getGeoServer().getCatalog();
      Name name = layer.getFeatureSource().getName();
      stratname =
          catalog
              .getFeatureTypeByName(name)
              .getMetadata()
              .get("kml.regionateStrategy", String.class);
      if (stratname == null || "".equals(stratname)) {
        stratname = "best_guess";
        LOGGER.log(
            Level.FINE,
            "No default regionating strategy has been configured in "
                + name
                + "; using automatic best-guess strategy.");
      }
    }

    if (stratname != null) {
      regionatingStrategy = findStrategyByName(stratname);

      // if a strategy was specified but we did not find it, let the user
      // know
      if (regionatingStrategy == null)
        throw new ServiceException("Unknown regionating strategy " + stratname);
    }

    // try to load less features by leveraging regionating strategy and the
    // SLD
    Filter regionatingFilter = Filter.INCLUDE;

    if (regionatingStrategy != null)
      regionatingFilter = regionatingStrategy.getFilter(mapContent, layer);

    Filter ruleFilter =
        summarizeRuleFilters(
            getLayerRules(featureSource.getSchema(), layer.getStyle()), scaleDenominator);
    Filter finalFilter = joinFilters(q.getFilter(), ruleFilter, regionatingFilter);
    if (finalFilter == Filter.EXCLUDE) {
      // if we don't have any feature to return
      return null;
    }
    q.setFilter(finalFilter);

    // make sure we output in 4326 since that's what KML mandates
    CoordinateReferenceSystem wgs84;
    try {
      wgs84 = CRS.decode("EPSG:4326");
    } catch (Exception e) {
      throw new RuntimeException(
          "Cannot decode EPSG:4326, the CRS subsystem must be badly broken...");
    }
    if (sourceCrs != null && !CRS.equalsIgnoreMetadata(wgs84, sourceCrs)) {
      return new ReprojectFeatureResults(featureSource.getFeatures(q), wgs84);
    }

    return featureSource.getFeatures(q);
  }
    protected void handleLayerGroups(List<LayerGroupInfo> layerGroups)
        throws FactoryException, TransformException {
      if (layerGroups == null || layerGroups.size() == 0) {
        return;
      }

      Collections.sort(
          layerGroups,
          new Comparator<LayerGroupInfo>() {
            public int compare(LayerGroupInfo o1, LayerGroupInfo o2) {
              return o1.getName().compareTo(o2.getName());
            }
          });

      for (LayerGroupInfo layerGroup : layerGroups) {
        String layerName = layerGroup.getName();

        AttributesImpl qatts = new AttributesImpl();
        boolean queryable = wmsConfig.isQueryable(layerGroup);
        qatts.addAttribute("", "queryable", "queryable", "", queryable ? "1" : "0");
        // qatts.addAttribute("", "opaque", "opaque", "", "1");
        // qatts.addAttribute("", "cascaded", "cascaded", "", "1");
        start("Layer", qatts);
        element("Name", layerName);
        element("Title", layerName);
        element("Abstract", "Layer-Group type layer: " + layerName);

        final ReferencedEnvelope layerGroupBounds = layerGroup.getBounds();
        final ReferencedEnvelope latLonBounds =
            layerGroupBounds.transform(DefaultGeographicCRS.WGS84, true);

        String authority =
            layerGroupBounds
                .getCoordinateReferenceSystem()
                .getIdentifiers()
                .toArray()[0]
                .toString();

        element("SRS", authority);

        handleLatLonBBox(latLonBounds);
        handleBBox(layerGroupBounds, authority);

        // Aggregated metadata links (see GEOS-4500)
        List<LayerInfo> layers = layerGroup.getLayers();
        Set<MetadataLinkInfo> aggregatedLinks = new HashSet<MetadataLinkInfo>();
        for (LayerInfo layer : layers) {
          List<MetadataLinkInfo> metadataLinks = layer.getResource().getMetadataLinks();
          if (metadataLinks != null) {
            aggregatedLinks.addAll(metadataLinks);
          }
        }
        handleMetadataList(aggregatedLinks);

        // the layer style is not provided since the group does just have
        // one possibility, the lack of styles that will make it use
        // the default ones for each layer

        end("Layer");
      }
    }
示例#20
0
  @Override
  public void draw(MapGraphicContext context) {

    // Initialize
    ILayer graticule = context.getLayer();
    GraticuleStyle style = GraticuleStyle.getStyle(graticule);

    // Ensure CRS?
    if (graticule instanceof Layer) {
      // Initialize CRS?
      if (style.isInitCRS()) {
        // Only initialize once
        style.setInitCRS(false);
        // Apply CRS from context
        GraticuleCRSConfigurator.apply((Layer) graticule, context.getCRS());
      } else if (mismatch(graticule, style)) {
        // Apply CRS from
        GraticuleCRSConfigurator.apply((Layer) graticule, style.getCRS());
      }
    }

    // Sanity checks
    if (MAX_SCALE < context.getMap().getViewportModel().getScaleDenominator()) {
      graticule.setStatus(ILayer.ERROR);
      graticule.setStatusMessage(Messages.GraticuleGraphic_Maximum_Scale + MAX_SCALE);
      return;
    }
    Unit<?> unit = CRSUtilities.getUnit(graticule.getCRS().getCoordinateSystem());
    if (!SI.METER.equals(unit)) {
      graticule.setStatus(ILayer.ERROR);
      graticule.setStatusMessage(Messages.GraticuleGraphic_Illegal_CRS);
      return;
    }
    final IWorkbench workbench = PlatformUI.getWorkbench();
    if (workbench == null) return;

    // Start working on layer
    graticule.setStatus(ILayer.WORKING);
    graticule.setStatusMessage(null);

    // Get display to work on
    final Display display = workbench.getDisplay();

    // Set styles
    Font plain = GraticuleStyle.getFontStyle(context).getFont();
    Font bold = plain.deriveFont(Font.BOLD);

    // Initialize the graphics handle
    ViewportGraphics g = context.getGraphics();

    // Set font size
    g.setFont(bold);

    // Get bounds of viewport
    ReferencedEnvelope bounds = context.getViewportModel().getBounds();

    try {

      // Get square size limited to minimum size of 100 pixels
      double size = size(context, unit, 100);

      // Sanity check
      if (size < 100) return;

      // Convert square size to pixels
      int sx = (int) (size / context.getViewportModel().getPixelSize().x);
      int sy = (int) (size / context.getViewportModel().getPixelSize().y);

      // Make transform from Graticule to map CRS
      MathTransform transform = CRS.findMathTransform(graticule.getCRS(), context.getCRS(), false);

      // Transform bounds into Graticule CRS
      bounds = bounds.transform(graticule.getCRS(), true);

      // Get squares inside bounds
      SimpleFeatureIterator it = squares(bounds, size);

      // Draw one squares at the time (only top and left lines are drawn)
      while (it.hasNext()) {

        // Initialize states
        int i = 0;
        Point current = null;

        // Initialize lines
        List<Line> lines = new ArrayList<Line>(2);
        List<Label> labels = new ArrayList<Label>(2);

        // Get next geometry
        Geometry geom = (Geometry) it.next().getDefaultGeometry();

        // Get coordinates in graticule CRS
        Coordinate[] coords = geom.getCoordinates();

        // Get x-coordinate label from upper left corner
        String tx = getLabel(coords[0].x, size, unit, style);

        // Get y-coordinate label from lower left corner
        String ty = getLabel(coords[2].y, size, unit, style);

        // Insert gap with label?
        boolean vgap = isGap(tx, unit, style);
        boolean hgap = isGap(ty, unit, style);

        // Transform coordinates into Map CRS
        coords = JTS.transform(geom, transform).getCoordinates();

        // Create lines and labels for this square
        for (Coordinate c : coords) {

          // Build paths
          switch (i) {
            case 1:

              // -----------------------
              // Vertical line
              // -----------------------

              // Create line path
              current =
                  vert(
                      display,
                      g,
                      sy,
                      style.getLineWidth(),
                      current,
                      context.worldToPixel(c),
                      hgap,
                      vgap,
                      lines);

              // Add xx label?
              if (hgap) {
                labels.add(new Label(current, tx, vgap ? bold : plain));
                current = context.worldToPixel(c);
              }

              break;
            case 2:

              // -----------------------
              // Horizontal line
              // -----------------------

              // Create line path
              current =
                  horz(
                      display,
                      g,
                      sx,
                      style.getLineWidth(),
                      current,
                      context.worldToPixel(c),
                      vgap,
                      hgap,
                      lines);

              // Add yy label?
              if (vgap) {
                labels.add(new Label(current, ty, hgap ? bold : plain));
                current = context.worldToPixel(c);
              }

              break;

            default:
              current = context.worldToPixel(c);
              break;
          }
          i++;
        }

        // Draw lines
        for (Line line : lines) line.draw(g, style);

        // Draw labels?
        if (style.isShowLabels()) for (Label label : labels) label.draw(g, style);
      }

      // // Get lower left corner coordinates
      // int x = llc.x;
      // int y = llc.y;
      //
      // // Print borders
      // g.setColor(lc);
      // g.setStroke(ViewportGraphics.LINE_SOLID, 5);
      //
      // // Inner rectangle
      // g.drawRect(x + d + l, y + d + l, w - 2 * (d + l), h - 2 * (d + l));
      //
      // // Make white border
      // g.setColor(Color.WHITE);
      //
      // // Left
      // g.drawRect(x, y, d, h);
      // g.fillRect(x, y, d, h);
      //
      // // Bottom
      // g.drawRect(x, y, w, d);
      // g.fillRect(x, y, w, d);
      //
      // // Right
      // g.drawRect(x + w - d, y, d, h);
      // g.fillRect(x + w - d, y, d, h);
      //
      // // Top
      // g.drawRect(x, y + h - d, w, d);
      // g.fillRect(x, y + h - d, w, d);

    } catch (IOException ex) {
      MapGraphicPlugin.log(Messages.GraticuleGraphic_Error, ex);
    } catch (FactoryException ex) {
      MapGraphicPlugin.log(Messages.GraticuleGraphic_Error, ex);
    } catch (MismatchedDimensionException ex) {
      MapGraphicPlugin.log(Messages.GraticuleGraphic_Error, ex);
    } catch (TransformException ex) {
      MapGraphicPlugin.log(Messages.GraticuleGraphic_Error, ex);
    }

    // Finished working on layer
    graticule.setStatus(ILayer.DONE);
  }