예제 #1
0
  @Override
  public ReferencedEnvelope getBounds() {
    try {
      ReferencedEnvelope bounds = featureSource.getBounds();
      if (bounds != null) {
        FeatureType schema = featureSource.getSchema();
        CoordinateReferenceSystem schemaCrs = schema.getCoordinateReferenceSystem();
        CoordinateReferenceSystem boundsCrs = bounds.getCoordinateReferenceSystem();

        if (boundsCrs == null && schemaCrs != null) {
          LOGGER.warning(
              "Bounds crs not defined; assuming bounds from schema are correct for "
                  + featureSource);
          bounds =
              new ReferencedEnvelope(
                  bounds.getMinX(),
                  bounds.getMaxX(),
                  bounds.getMinY(),
                  bounds.getMaxY(),
                  schemaCrs);
        }
        if (boundsCrs != null
            && schemaCrs != null
            && !CRS.equalsIgnoreMetadata(boundsCrs, schemaCrs)) {
          LOGGER.warning(
              "Bounds crs and schema crs are not consistent; forcing the use of the schema crs so they are consistent");
          // bounds = bounds.transform(schemaCrs, true );
          bounds =
              new ReferencedEnvelope(
                  bounds.getMinX(),
                  bounds.getMaxX(),
                  bounds.getMinY(),
                  bounds.getMaxY(),
                  schemaCrs);
        }
        return bounds;
      }
    } catch (IOException e) {
      // feature bounds unavailable
    }

    CoordinateReferenceSystem crs = featureSource.getSchema().getCoordinateReferenceSystem();
    if (crs != null) {
      // returns the envelope based on the CoordinateReferenceSystem
      Envelope envelope = CRS.getEnvelope(crs);
      if (envelope != null) {
        return new ReferencedEnvelope(envelope); // nice!
      } else {
        return new ReferencedEnvelope(crs); // empty bounds
      }
    } else {
      return null; // unknown
    }
  }
  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]);
  }
예제 #3
0
 public void addZoomLevel(ReferencedEnvelope bbox, int tileWidth, int tileHeight) {
   List<Grid> list = grids.getModelObject();
   final Grid newGrid = new Grid();
   if (list.isEmpty()) {
     BoundingBox extent =
         new BoundingBox(bbox.getMinX(), bbox.getMinY(), bbox.getMaxX(), bbox.getMaxY());
     final int levels = 1;
     GridSet tmpGridset =
         GridSetFactory.createGridSet(
             "stub",
             SRS.getEPSG4326(),
             extent,
             false,
             levels,
             1D,
             GridSetFactory.DEFAULT_PIXEL_SIZE_METER,
             tileWidth,
             tileHeight,
             false);
     Grid grid = tmpGridset.getGridLevels()[0];
     newGrid.setResolution(grid.getResolution());
     newGrid.setScaleDenominator(grid.getScaleDenominator());
   } else {
     Grid prev = list.get(list.size() - 1);
     newGrid.setResolution(prev.getResolution() / 2);
     newGrid.setScaleDenominator(prev.getScaleDenominator() / 2);
   }
   list.add(newGrid);
   grids.setModelObject(list);
   // TileMatrixSetEditor.this.convertInput();
 }
예제 #4
0
파일: WMS.java 프로젝트: roarbra/geoserver
  /**
   * Sets up the affine transform. Stolen from liteRenderer code.
   *
   * @param mapExtent the map extent
   * @param width the screen size
   * @param height
   * @return a transform that maps from real world coordinates to the screen
   */
  public static AffineTransform worldToScreenTransform(
      ReferencedEnvelope mapExtent, double width, double height) {

    // the transformation depends on an x/y ordering, if we have a lat/lon crs swap it
    CoordinateReferenceSystem crs = mapExtent.getCoordinateReferenceSystem();
    boolean swap = crs != null && CRS.getAxisOrder(crs) == AxisOrder.NORTH_EAST;
    if (swap) {
      mapExtent =
          new ReferencedEnvelope(
              mapExtent.getMinY(),
              mapExtent.getMaxY(),
              mapExtent.getMinX(),
              mapExtent.getMaxX(),
              null);
    }

    double scaleX = width / mapExtent.getWidth();
    double scaleY = height / mapExtent.getHeight();

    double tx = -mapExtent.getMinX() * scaleX;
    double ty = (mapExtent.getMinY() * scaleY) + height;

    AffineTransform at = new AffineTransform(scaleX, 0.0d, 0.0d, -scaleY, tx, ty);

    // if we swapped concatenate a transform that swaps back
    if (swap) {
      at.concatenate(new AffineTransform(0, 1, 1, 0, 0, 0));
    }

    return at;
  }
예제 #5
0
  @SuppressWarnings("deprecation")
  private void doOverlayImage(GC gc) {
    Point2D lowerLeft = new Point2D.Double(overlayEnvelope.getMinX(), overlayEnvelope.getMinY());
    worldToScreen.transform(lowerLeft, lowerLeft);

    Point2D upperRight = new Point2D.Double(overlayEnvelope.getMaxX(), overlayEnvelope.getMaxY());
    worldToScreen.transform(upperRight, upperRight);

    Rectangle bounds = overlayImage.getBounds();
    if (overlayDoXor) {
      gc.setXORMode(true);
    }

    gc.drawImage(
        overlayImage, //
        0, //
        0, //
        bounds.width, //
        bounds.height, //
        (int) lowerLeft.getX(), //
        (int) upperRight.getY(), //
        (int) (upperRight.getX() - lowerLeft.getX()), //
        (int) Math.abs(upperRight.getY() - lowerLeft.getY()) //
        );
    if (overlayDoXor) {
      gc.setXORMode(false);
    }
  }
예제 #6
0
 public static WorldArea toWorldArea(ReferencedEnvelope bounds) {
   WorldArea worldArea =
       new WorldArea(
           new WorldLocation(bounds.getMaxY(), bounds.getMinX(), 0),
           new WorldLocation(bounds.getMinY(), bounds.getMaxX(), 0));
   return worldArea;
 }
  @Override
  public FeatureIterator getSortedFeatures(
      GeometryDescriptor geom,
      ReferencedEnvelope latLongEnv,
      ReferencedEnvelope nativeEnv,
      Connection cacheConn)
      throws Exception {
    FeatureSource fs = featureType.getFeatureSource(null, null);

    // build the bbox filter
    FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);

    BBOX filter =
        ff.bbox(
            geom.getLocalName(),
            nativeEnv.getMinX(),
            nativeEnv.getMinY(),
            nativeEnv.getMaxX(),
            nativeEnv.getMaxY(),
            null);

    // build an optimized query (only the necessary attributes
    Query q = new Query();
    q.setFilter(filter);
    // TODO: enable this when JTS learns how to compute centroids
    // without triggering the
    // generation of Coordinate[] out of the sequences...
    // q.setHints(new Hints(Hints.JTS_COORDINATE_SEQUENCE_FACTORY,
    // PackedCoordinateSequenceFactory.class));
    q.setPropertyNames(new String[] {geom.getLocalName()});

    // return the reader
    return fs.getFeatures(q).features();
  }
예제 #8
0
  public static void moveMapTo(OLmaps mp, ShapeValue value) {

    Coordinate p1 = null, p2 = null;
    ShapeValue env = new ShapeValue(value.getEnvelope());
    try {
      env = env.transform(Geospace.get().getStraightGeoCRS());
    } catch (ThinklabException e2) {
      throw new ThinklabRuntimeException(e2);
    }
    ReferencedEnvelope e = env.getEnvelope();

    try {
      p1 =
          JTS.transform(
              new Coordinate(e.getMinX(), e.getMinY()),
              null,
              ARIESWebappPlugin.get().geoToGoogleTransform);
      p2 =
          JTS.transform(
              new Coordinate(e.getMaxX(), e.getMaxY()),
              null,
              ARIESWebappPlugin.get().geoToGoogleTransform);

    } catch (TransformException e1) {
      // shouldn't happen
      throw new ThinklabRuntimeException(e1);
    }

    mp.setBounds(p1.x, p1.y, p2.x, p2.y);
  }
예제 #9
0
        public boolean equals(Object obj) {
          if (obj == EVERYTHING) {
            return true;
          }
          if (obj instanceof ReferencedEnvelope) {
            ReferencedEnvelope other = (ReferencedEnvelope) obj;
            if (other.crs != EVERYTHING.crs) return false;
            if (other.getMinX() != EVERYTHING.getMinX()) return false;
            if (other.getMinY() != EVERYTHING.getMinY()) return false;
            if (other.getMaxX() != EVERYTHING.getMaxX()) return false;
            if (other.getMaxY() != EVERYTHING.getMaxY()) return false;

            return true;
          }
          return super.equals(obj);
        }
예제 #10
0
    /** @param referencedEnvelope */
    private void handleEnvelope(
        ReferencedEnvelope referencedEnvelope,
        DimensionInfo timeInfo,
        ReaderDimensionsAccessor dimensions) {
      AttributesImpl attributes = new AttributesImpl();

      attributes.addAttribute(
          "", "srsName", "srsName", "", /* "WGS84(DD)" */ "urn:ogc:def:crs:OGC:1.3:CRS84");
      start("wcs:lonLatEnvelope", attributes);
      final StringBuffer minCP =
          new StringBuffer(Double.toString(referencedEnvelope.getMinX()))
              .append(" ")
              .append(referencedEnvelope.getMinY());
      final StringBuffer maxCP =
          new StringBuffer(Double.toString(referencedEnvelope.getMaxX()))
              .append(" ")
              .append(referencedEnvelope.getMaxY());

      element("gml:pos", minCP.toString());
      element("gml:pos", maxCP.toString());

      // are we going to report time?
      if (timeInfo != null && timeInfo.isEnabled()) {
        SimpleDateFormat timeFormat = dimensions.getTimeFormat();
        element("gml:timePosition", timeFormat.format(dimensions.getMinTime()));
        element("gml:timePosition", timeFormat.format(dimensions.getMaxTime()));
      }

      end("wcs:lonLatEnvelope");
    }
예제 #11
0
  private void equals(ReferencedEnvelope env, double xmin, double xmax, double ymin, double ymax) {
    double delta = 0.0000001;

    assertEquals(xmax, env.getMaxX(), delta);
    assertEquals(xmin, env.getMinX(), delta);
    assertEquals(ymax, env.getMaxY(), delta);
    assertEquals(ymin, env.getMinY(), delta);
  }
예제 #12
0
  /**
   * Checks the bounds process returned the expected envelope
   *
   * @param request
   * @param id
   * @throws Exception
   */
  void executeState1BoundsTest(String request, String id) throws Exception {
    if (!RemoteOWSTestSupport.isRemoteWMSStatesAvailable(LOGGER)) {
      LOGGER.warning("Remote OWS tests disabled, skipping test with " + id + " reference source");
      return;
    }

    MockHttpServletResponse resp = postAsServletResponse(root(), request);
    ReferencedEnvelope re = toEnvelope(resp.getOutputStreamContent());
    assertEquals(-91.516129, re.getMinX(), 0.001);
    assertEquals(36.986771, re.getMinY(), 0.001);
    assertEquals(-87.507889, re.getMaxX(), 0.001);
    assertEquals(42.509361, re.getMaxY(), 0.001);
  }
예제 #13
0
  @Test
  public void testGetAsXML() throws Exception {
    Document dom = getAsDOM("/rest/workspaces/sf/wmslayers/states.xml");

    assertEquals("wmsLayer", dom.getDocumentElement().getNodeName());
    assertXpathEvaluatesTo("states", "/wmsLayer/name", dom);
    assertXpathEvaluatesTo("EPSG:4326", "/wmsLayer/srs", dom);
    assertEquals(CRS.decode("EPSG:4326").toWKT(), xp.evaluate("/wmsLayer/nativeCRS", dom));

    WMSLayerInfo wml = catalog.getResourceByName("sf", "states", WMSLayerInfo.class);

    ReferencedEnvelope re = wml.getLatLonBoundingBox();
    assertXpathEvaluatesTo(re.getMinX() + "", "/wmsLayer/latLonBoundingBox/minx", dom);
    assertXpathEvaluatesTo(re.getMaxX() + "", "/wmsLayer/latLonBoundingBox/maxx", dom);
    assertXpathEvaluatesTo(re.getMinY() + "", "/wmsLayer/latLonBoundingBox/miny", dom);
    assertXpathEvaluatesTo(re.getMaxY() + "", "/wmsLayer/latLonBoundingBox/maxy", dom);
  }
예제 #14
0
 public void testPolyLabeling() throws Exception {
   FeatureCollection collection = createPolyFeatureCollection();
   Style style = loadStyle("PolyStyle.sld");
   assertNotNull(style);
   MapContext map = new DefaultMapContext(DefaultGeographicCRS.WGS84);
   map.addLayer(collection, style);
   StreamingRenderer renderer = new StreamingRenderer();
   renderer.setContext(map);
   ReferencedEnvelope env = map.getLayerBounds();
   int boundary = 10;
   env =
       new ReferencedEnvelope(
           env.getMinX() - boundary,
           env.getMaxX() + boundary,
           env.getMinY() - boundary,
           env.getMaxY() + boundary,
           null);
   RendererBaseTest.showRender("testPolyLabeling", renderer, timout, env);
 }
    @Override
    public void sendContent(
        OutputStream out, Range range, Map<String, String> params, String contentType)
        throws IOException, BadRequestException {
      WorkbenchState state = WorkbenchState.instance(SessionContext.current());
      IMap map = state.getMap();

      try {
        JSONObject json = new JSONObject();
        json.put("width", -1);
        json.put("height", -1);

        ReferencedEnvelope extent = map.getExtent();
        json.put("minX", extent.getMinX());
        json.put("minY", extent.getMinY());
        json.put("maxX", extent.getMaxX());
        json.put("maxY", extent.getMaxY());

        out.write(json.toString(4).getBytes("UTF-8"));
      } catch (JSONException e) {
        throw new RuntimeException(e);
      }
    }
예제 #16
0
  private void createTABFile(
      ReferencedEnvelope transformedBBox,
      final int width,
      final int height,
      final String baseFile,
      final String ext)
      throws IOException {

    final StringBuffer buff = new StringBuffer(baseFile);
    buff.append(".tab");
    final File tabFile = new File(buff.toString());

    final PrintWriter out = new PrintWriter(new FileOutputStream(tabFile));

    try {
      out.println("!table");
      out.println("!version 300");
      out.println("!charset UTF-8");
      out.println("");
      out.println("Definition Table");
      out.println("File " + tabFile.getName().replace(".tab", ".") + ext);
      out.println("Type \"RASTER\"");
      out.println(
          "("
              + transformedBBox.getMinX()
              + ","
              + transformedBBox.getMinY()
              + ") (0,0) Label \"Pt 1\",");
      out.println(
          "("
              + transformedBBox.getMaxX()
              + ","
              + transformedBBox.getMinY()
              + ") ("
              + width
              + ",0) Label \"Pt 2\",");
      out.println(
          "("
              + transformedBBox.getMaxX()
              + ","
              + transformedBBox.getMaxY()
              + ") ("
              + width
              + ","
              + height
              + ") Label \"Pt 3\",");
      out.println(
          "("
              + transformedBBox.getMinX()
              + ","
              + transformedBBox.getMaxY()
              + ") (0,"
              + height
              + ") Label \"Pt 4\",");

      InputStream in =
          WcsCoverageReader.class
              .getClassLoader()
              .getResourceAsStream("org/georchestra/extractorapp/proj4MapinfoTab.properties");
      Properties properties = new Properties();
      properties.load(in);

      MIFProjReader tabProjReader = new MIFProjReader();

      Iterator<ReferenceIdentifier> iter =
          transformedBBox.getCoordinateReferenceSystem().getIdentifiers().iterator();
      String crsCode = iter.next().toString();
      int crs = Integer.valueOf(crsCode.replace("EPSG:", ""));

      out.println("CoordSys Earth Projection " + tabProjReader.toMifCoordSys(crs));
      out.print(
          "units \""
              + CRSUtilities.getUnit(
                      transformedBBox.getCoordinateReferenceSystem().getCoordinateSystem())
                  .toString()
              + "\"");

      /**
       * GeneralDerivedCRS crs = (GeneralDerivedCRS)request.responseCRS; Conversion
       * conversionFromBase = crs.getConversionFromBase();
       *
       * <p>Unit<?> unit = CRSUtilities.getUnit(crs.getCoordinateSystem()); GeodeticDatum datum =
       * (GeodeticDatum)crs.getDatum();
       *
       * <p>// Specific MAPINFO TAB format String projType =
       * conversionFromBase.getMethod().getName().getCode(); String datumCode =
       * datum.getEllipsoid().getName().getCode();
       *
       * <p>Map <String, Integer> projectionTypes = new HashMap<String, Integer>();
       * projectionTypes.put("Lambert Conic Conformal (2SP)", 3);
       *
       * <p>Map <String, Integer> datumCodes = new HashMap<String, Integer>(); datumCodes.put("GRS
       * 1980", 33);
       *
       * <p>// get params from CRS Map<String, String> params= new HashMap<String, String>(); for
       * (final GeneralParameterValue param : conversionFromBase.getParameterValues().values()) { if
       * (param instanceof ParameterValue) { final double value = ((ParameterValue<?>)
       * param).doubleValue(); params.put(param.getDescriptor().getName().getCode(),
       * String.valueOf(value)); } }
       *
       * <p>out.print("CoordSys Earth "); out.print("Projection " + projectionTypes.get(projType) +
       * ", "); out.print(datumCodes.get(datumCode) + ", "); out.print(unit.toString() + ", ");
       * out.print(params.get("central_meridian") + ", ");
       * out.print(params.get("latitude_of_origin") + ", ");
       * out.print(params.get("standard_parallel_2") + ", ");
       * out.print(params.get("standard_parallel_1") + ", "); out.print(params.get("false_easting")
       * + ", "); out.print(params.get("false_northing") + ", ");
       */
      out.flush();
    } finally {
      out.close();
    }
  }
  private DefaultFeatureCollection createFeaturesFromSpacing(
      final MapfishMapContext mapContext,
      final SimpleFeatureBuilder featureBuilder,
      final GridParam layerData,
      final LabelPositionCollector labels) {
    GeometryFactory geometryFactory = new GeometryFactory();
    ReferencedEnvelope bounds = mapContext.toReferencedEnvelope();

    CoordinateReferenceSystem mapCrs = bounds.getCoordinateReferenceSystem();
    String unit = layerData.calculateLabelUnit(mapCrs);
    MathTransform labelTransform = layerData.calculateLabelTransform(mapCrs);

    final double incrementX = layerData.spacing[0];
    final double incrementY = layerData.spacing[1];
    double minX = GridUtils.calculateFirstLine(bounds, layerData, 0);
    double minY = GridUtils.calculateFirstLine(bounds, layerData, 1);

    MapfishMapContext rootContext = mapContext.getRootContext();
    Polygon rotatedBounds = GridUtils.calculateBounds(rootContext);
    AffineTransform worldToScreenTransform = GridUtils.getWorldToScreenTransform(mapContext);

    DefaultFeatureCollection features = new DefaultFeatureCollection();
    int i = 0;
    int j;

    boolean addBorderFeatures = true;
    for (double x = minX; x < bounds.getMaxX(); x += incrementX) {
      i++;
      j = 0;

      if (!onRightBorder(bounds, x)) { // don't add the border features twice.
        GridUtils.bottomBorderLabel(
            labels,
            geometryFactory,
            rotatedBounds,
            unit,
            x,
            worldToScreenTransform,
            labelTransform,
            layerData.getGridLabelFormat());
        GridUtils.topBorderLabel(
            labels,
            geometryFactory,
            rotatedBounds,
            unit,
            x,
            worldToScreenTransform,
            labelTransform,
            layerData.getGridLabelFormat());
      }
      for (double y = minY; y < bounds.getMaxY(); y += incrementY) {
        j++;

        if (addBorderFeatures && !onRightBorder(bounds, x) && !onTopBorder(bounds, y)) {
          GridUtils.leftBorderLabel(
              labels,
              geometryFactory,
              rotatedBounds,
              unit,
              y,
              worldToScreenTransform,
              labelTransform,
              layerData.getGridLabelFormat());
          GridUtils.rightBorderLabel(
              labels,
              geometryFactory,
              rotatedBounds,
              unit,
              y,
              worldToScreenTransform,
              labelTransform,
              layerData.getGridLabelFormat());
        }
        if (!onTopBorder(bounds, y)
            && !onBottomBorder(bounds, y)
            && !onLeftBorder(bounds, x)
            && !onRightBorder(bounds, x)) { // don't add the border features twice.
          featureBuilder.reset();
          Point geom = geometryFactory.createPoint(new Coordinate(x, y));
          featureBuilder.set(Grid.ATT_GEOM, geom);
          features.add(featureBuilder.buildFeature("grid." + i + "." + j));
        }
      }
      addBorderFeatures = false;
    }
    return features;
  }
 private boolean onTopBorder(final ReferencedEnvelope bounds, final double y) {
   return y >= bounds.getMaxY();
 }
예제 #19
0
  /** {@link BBOX} support? */
  @Test
  public void testDataStoreSupportsPlainBBOXInterface() throws Exception {
    if (url == null) return;
    final WFS_1_0_0_DataStore wfs = WFSDataStoreReadTest.getDataStore(url);
    final SimpleFeatureType ft = wfs.getSchema(TO_EDIT_TYPE);
    final ReferencedEnvelope bounds = wfs.getFeatureSource(TO_EDIT_TYPE).getBounds();

    final FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
    final BBOX bbox =
        ff.bbox(
            "the_geom",
            bounds.getMinX(),
            bounds.getMinY(),
            bounds.getMaxX(),
            bounds.getMaxY(),
            null);

    /** This one does not implement the deprecated geotools filter interfaces */
    final BBOX strictBBox =
        new BBOX() {

          public boolean evaluate(Object object) {
            return bbox.evaluate(object);
          }

          public Object accept(FilterVisitor visitor, Object extraData) {
            return bbox.accept(visitor, extraData);
          }

          public Expression getExpression2() {
            return bbox.getExpression2();
          }

          public Expression getExpression1() {
            return bbox.getExpression1();
          }

          public String getSRS() {
            return bbox.getSRS();
          }

          public String getPropertyName() {
            return bbox.getPropertyName();
          }

          public double getMinY() {
            return bbox.getMinY();
          }

          public double getMinX() {
            return bbox.getMinX();
          }

          public double getMaxY() {
            return bbox.getMaxY();
          }

          public double getMaxX() {
            return bbox.getMaxX();
          }

          public MatchAction getMatchAction() {
            return MatchAction.ANY;
          }

          public BoundingBox getBounds() {
            return bbox.getBounds();
          }
        };

    final Query query = new Query(ft.getTypeName());
    query.setFilter(strictBBox);

    FeatureReader<SimpleFeatureType, SimpleFeature> reader;

    reader = wfs.getFeatureReaderGet(query, Transaction.AUTO_COMMIT);
    assertNotNull(reader);

    reader = wfs.getFeatureReaderPost(query, Transaction.AUTO_COMMIT);
    assertNotNull(reader);
  }
  @Test
  public void testLakeDrawingCase() throws Exception {
    URL url = TestsPlugin.getDefault().getBundle().getResource("data/lake.gml"); // $NON-NLS-1$
    InputStream in = url.openConnection().getInputStream();

    InputStreamReader filereader = new InputStreamReader(in);

    InputSource input = new InputSource(filereader);
    DefaultFeatureCollection collection = new DefaultFeatureCollection();
    GMLReceiver receiver = new GMLReceiver(collection);
    GMLFilterFeature filterFeature = new GMLFilterFeature(receiver);
    GMLFilterGeometry filterGeometry = new GMLFilterGeometry(filterFeature);
    GMLFilterDocument filterDocument = new GMLFilterDocument(filterGeometry);
    try {
      // parse xml
      XMLReader reader = XMLReaderFactory.createXMLReader();
      reader.setContentHandler(filterDocument);
      reader.parse(input);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    SimpleFeature feature = collection.features().next();
    ReferencedEnvelope bounds = new ReferencedEnvelope(feature.getBounds());
    bounds =
        new ReferencedEnvelope(
            bounds.getMinX() - (bounds.getWidth() / 8),
            bounds.getMaxX() + (bounds.getWidth() / 8),
            bounds.getMinY() - (bounds.getHeight() / 4),
            bounds.getMaxY() + (bounds.getHeight() / 4),
            DefaultGeographicCRS.WGS84);
    EditBlackboard map =
        new EditBlackboard(
            SCREEN.x,
            SCREEN.y,
            ScaleUtils.worldToScreenTransform(bounds, new Dimension(100, 100)),
            layerToWorld);

    map.setGeometries((Geometry) feature.getDefaultGeometry(), null);

    Polygon poly = (Polygon) ((MultiPolygon) feature.getDefaultGeometry()).getGeometryN(0);

    PrimitiveShape shell = map.getGeoms().get(0).getShell();
    assertEquals(poly.getExteriorRing().getCoordinates().length, shell.getNumCoords());
    for (int i = 0; i < shell.getNumCoords(); i++) {
      assertEquals(
          "i=" + i, poly.getExteriorRing().getCoordinateN(i), shell.getCoord(i)); // $NON-NLS-1$
    }
    assertEquals(shell.getCoord(0), shell.getCoord(shell.getNumCoords() - 1));
    assertEquals(shell.getPoint(0), shell.getPoint(shell.getNumPoints() - 1));

    List<PrimitiveShape> holes = map.getGeoms().get(0).getHoles();

    for (int j = 0; j < holes.size(); j++) {
      PrimitiveShape hole = holes.get(j);
      for (int i = 0; i < hole.getNumCoords(); i++) {
        assertEquals(
            "hole=" + j + "i=" + i,
            poly.getInteriorRingN(j).getCoordinateN(i),
            hole.getCoord(i)); // $NON-NLS-1$ //$NON-NLS-2$
      }
      assertEquals(hole.getCoord(0), hole.getCoord(hole.getNumCoords() - 1));
      assertEquals(hole.getPoint(0), hole.getPoint(hole.getNumPoints() - 1));
    }
  }
  /**
   * @see net.refractions.udig.render.internal.wmsc.basic#renderTile(Graphics2D graphics, WMTTile
   *     tile, CoordinateReferenceSystem crs, RasterSymbolizer style)
   * @param graphics
   * @param tile
   * @param style
   * @throws FactoryException
   * @throws TransformException
   * @throws RenderException
   */
  private void renderTile(
      Graphics2D graphics, WMTTile tile, RasterSymbolizer style, WMTRenderJob renderJob)
      throws Exception {

    if (tile == null || tile.getBufferedImage() == null) {
      return;
    }

    // create a gridcoverage from the tile image
    GridCoverageFactory factory = new GridCoverageFactory();

    // get the tile bounds in the CRS the tiles were drawn in
    ReferencedEnvelope tileBndsMercatorRef =
        renderJob.projectTileToTileProjectedCrs(tile.getExtent());

    GridCoverage2D coverage =
        (GridCoverage2D)
            factory.create(
                "GridCoverage", tile.getBufferedImage(), tileBndsMercatorRef); // $NON-NLS-1$

    Envelope2D coveragebounds = coverage.getEnvelope2D();

    // bounds of tile
    ReferencedEnvelope bnds =
        new ReferencedEnvelope(
            coveragebounds.getMinX(),
            coveragebounds.getMaxX(),
            coveragebounds.getMinY(),
            coveragebounds.getMaxY(),
            renderJob.getCrsTilesProjected());

    // reproject tile bounds to map CRS
    bnds = renderJob.projectTileProjectedToMapCrs(bnds);

    // determine screen coordinates of tiles
    Point upperLeft = getContext().worldToPixel(new Coordinate(bnds.getMinX(), bnds.getMinY()));
    Point bottomRight = getContext().worldToPixel(new Coordinate(bnds.getMaxX(), bnds.getMaxY()));
    Rectangle tileSize = new Rectangle(upperLeft);
    tileSize.add(bottomRight);

    // render
    try {
      CoordinateReferenceSystem crs = getContext().getCRS();
      AffineTransform worldToScreen = RendererUtilities.worldToScreenTransform(bnds, tileSize, crs);
      GridCoverageRenderer paint = new GridCoverageRenderer(crs, bnds, tileSize, worldToScreen);

      paint.paint(graphics, coverage, style);

      if (TESTING) {
        //            if(true){
        /* for testing draw border around tiles */
        graphics.setColor(Color.BLACK);
        graphics.drawLine(
            (int) tileSize.getMinX(),
            (int) tileSize.getMinY(),
            (int) tileSize.getMinX(),
            (int) tileSize.getMaxY());
        graphics.drawLine(
            (int) tileSize.getMinX(),
            (int) tileSize.getMinY(),
            (int) tileSize.getMaxX(),
            (int) tileSize.getMinY());
        graphics.drawLine(
            (int) tileSize.getMaxX(),
            (int) tileSize.getMinY(),
            (int) tileSize.getMaxX(),
            (int) tileSize.getMaxY());
        graphics.drawLine(
            (int) tileSize.getMinX(),
            (int) tileSize.getMaxY(),
            (int) tileSize.getMaxX(),
            (int) tileSize.getMaxY());
        graphics.drawString(
            tile.getId(), ((int) tileSize.getMaxX() - 113), ((int) tileSize.getMaxY() - 113));
      }
    } catch (Throwable t) {
      WMTPlugin.log("Error Rendering tile. Painting Tile " + tile.getId(), t); // $NON-NLS-1$
    }
  }