/** * @param style * @param gm * @param queries * @return a list of dimension warnings * @throws MissingDimensionValue * @throws InvalidDimensionValue */ public LinkedList<String> collectQueries(Style style, final GetMap gm, LinkedList<Query> queries) throws MissingDimensionValue, InvalidDimensionValue { final Envelope bbox = gm.getBoundingBox(); Set<Expression> exprs = new HashSet<Expression>(); final ValueReference geomProp; exprs.addAll(Styles.getGeometryExpressions(style)); if (exprs.size() == 1 && exprs.iterator().next() instanceof ValueReference) { geomProp = (ValueReference) exprs.iterator().next(); } else { geomProp = null; } final Pair<Filter, LinkedList<String>> dimFilter = getDimensionFilter(gm.getDimensions()); final Filter filter = gm.getFilterForLayer(this.getName(), dimFilter == null ? null : dimFilter.first, style); if (style != null) { QName ftName = style.getFeatureType(); if (ftName != null && datastore.getSchema().getFeatureType(ftName) == null) { LOG.warn("FeatureType '" + ftName + "' from style is not known to the FeatureStore."); return new LinkedList<String>(); } } QName featureType = style == null ? null : style.getFeatureType(); final int maxFeatures = gm.getRenderingOptions().getMaxFeatures(getName()); if (featureType == null && datastore != null) { queries.addAll( map( datastore.getSchema().getFeatureTypes(null, false, false), new Mapper<Query, FeatureType>() { @Override public Query apply(FeatureType u) { Filter fil = Filters.addBBoxConstraint(bbox, filter, geomProp); return new Query( u.getName(), fil, round(gm.getScale()), maxFeatures, gm.getResolution()); } })); } else { Query query = new Query( featureType, Filters.addBBoxConstraint(bbox, filter, geomProp), round(gm.getScale()), maxFeatures, gm.getResolution()); queries.add(query); } return dimFilter == null ? new LinkedList<String>() : dimFilter.second; }
@Override public LinkedList<String> paintMap(Graphics2D g, GetMap gm, Style style) throws MissingDimensionValue, InvalidDimensionValue { LinkedList<Query> queries = new LinkedList<Query>(); LinkedList<String> warnings = collectQueries(style, gm, queries); Java2DRenderer renderer = new Java2DRenderer( g, gm.getWidth(), gm.getHeight(), gm.getBoundingBox(), gm.getPixelSize()); Java2DTextRenderer textRenderer = new Java2DTextRenderer(renderer); // TODO @SuppressWarnings({"rawtypes", "unchecked"}) XPathEvaluator<Feature> evaluator = (XPathEvaluator) new TypedObjectNodeXPathEvaluator(); if (queries.isEmpty()) { LOG.warn("No queries were generated. Is the configuration correct?"); return warnings; } FeatureInputStream rs = null; try { rs = datastore.query(queries.toArray(new Query[queries.size()])); // TODO Should this always be done on this level? What about min and maxFill values? rs = new ThreadedFeatureInputStream(rs, 100, 20); int max = gm.getRenderingOptions().getMaxFeatures(getName()); int cnt = 0; double resolution = gm.getResolution(); // TODO get rid of resolution handling on this code level completely // if ( !gm.getCoordinateSystem().equals( datastore.getStorageSRS() ) ) { // try { // Envelope b = new GeometryTransformer( datastore.getStorageSRS() ).transform( // gm.getBoundingBox() ); // resolution = Utils.calcResolution( b, gm.getWidth(), gm.getHeight() ); // } catch ( IllegalArgumentException e ) { // LOG.warn( "Calculating the resolution failed: '{}'", e.getLocalizedMessage() ); // LOG.trace( "Stack trace:", e ); // } catch ( TransformationException e ) { // LOG.warn( "Calculating the resolution failed: '{}'", e.getLocalizedMessage() ); // LOG.trace( "Stack trace:", e ); // } catch ( UnknownCRSException e ) { // LOG.warn( "Calculating the resolution failed: '{}'", e.getLocalizedMessage() ); // LOG.trace( "Stack trace:", e ); // } // } for (Feature f : rs) { try { render(f, evaluator, style, renderer, textRenderer, gm.getScale(), resolution); } catch (IllegalArgumentException e) { LOG.warn("Unable to render feature, probably a curve had multiple/non-linear segments."); LOG.warn("Error message was: {}", e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } if (max > 0 && ++cnt == max) { LOG.debug("Reached max features of {} for layer '{}', stopping.", max, this); break; } } } catch (FilterEvaluationException e) { LOG.warn("A filter could not be evaluated. The error was '{}'.", e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } catch (FeatureStoreException e) { LOG.warn( "Data could not be fetched from the feature store. The error was '{}'.", e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } finally { if (rs != null) { rs.close(); } } return warnings; }