public String getFcInfo() throws IOException { StringBuffer sb = new StringBuffer(); FeatureStore fs = getWorkspace().getResource(FeatureStoreProvider.class, getId()); AppSchema schema = fs.getSchema(); FeatureType[] fts = schema.getRootFeatureTypes(); // sort the types by name Arrays.sort( fts, new Comparator<FeatureType>() { public int compare(FeatureType a, FeatureType b) { int order = a.getName().getNamespaceURI().compareTo(b.getName().getNamespaceURI()); if (order == 0) { order = a.getName().getLocalPart().compareTo(b.getName().getLocalPart()); } return order; } }); for (FeatureType ft : fts) { appendFcInfo(ft, sb, ""); sb.append("<br/>"); } return sb.toString(); }
public String getNumFtsAbstract() { FeatureStore fs = getWorkspace().getResource(FeatureStoreProvider.class, getId()); AppSchema schema = fs.getSchema(); int numFtsTotal = schema.getFeatureTypes(null, false, true).size(); int numFtsConcrete = schema.getFeatureTypes(null, false, false).size(); return "" + (numFtsTotal - numFtsConcrete); }
private void appendFtInfo(FeatureType ft, FeatureStore store, StringBuffer sb, String indent) throws IOException { if (ft instanceof FeatureCollectionType) { return; } if (ft.isAbstract()) { sb.append( indent + "- <i>" + ft.getName().getPrefix() + ":" + ft.getName().getLocalPart() + " (abstract)</i><br/>"); } else { if (store.isMapped(ft.getName())) { Query query = new Query(ft.getName(), null, 0, -1, -1); int numInstances = -1; try { numInstances = store.queryHits(query); } catch (Exception e) { e.printStackTrace(); } sb.append( indent + "- " + ft.getName().getPrefix() + ":" + ft.getName().getLocalPart() + " (" + numInstances + " instances)<br/>"); } else { sb.append( indent + "- " + ft.getName().getPrefix() + ":" + ft.getName().getLocalPart() + " (not mapped)<br/>"); } } FeatureType[] fts = ft.getSchema().getDirectSubtypes(ft); Arrays.sort( fts, new Comparator<FeatureType>() { public int compare(FeatureType a, FeatureType b) { int order = a.getName().getNamespaceURI().compareTo(b.getName().getNamespaceURI()); if (order == 0) { order = a.getName().getLocalPart().compareTo(b.getName().getLocalPart()); } return order; } }); for (FeatureType childType : fts) { appendFtInfo(childType, store, sb, indent + " "); } }
@Override public boolean isAvailable() { if (datastore == null) { LOG.debug( "Layer '{}' is not available, since its data store could not be loaded.", getName()); } else if (!datastore.isAvailable()) { LOG.debug("Layer '{}' is not available, since its data store is unavailable.", getName()); } return datastore != null && datastore.isAvailable(); }
/** * @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; }
public List<NamespaceBinding> getNamespaces() { Set<NamespaceBinding> namespaces = new TreeSet<NamespaceBinding>(); FeatureStore fs = getWorkspace().getResource(FeatureStoreProvider.class, getId()); if (fs == null) { return Collections.emptyList(); } AppSchema schema = fs.getSchema(); for (FeatureType ft : schema.getFeatureTypes()) { String prefix = ft.getName().getPrefix(); String ns = ft.getName().getNamespaceURI(); namespaces.add(new NamespaceBinding(prefix, ns)); } return new ArrayList<NamespaceBinding>(namespaces); }
@Override public Envelope getBbox() { if (super.getBbox() != null) { return super.getBbox(); } if (datastore == null || !datastore.isAvailable()) { return null; } // always use up-to-date envelope Envelope bbox = null; AppSchema schema = datastore.getSchema(); List<Style> styles = service.registry.getAll(getName()); List<QName> ftNames = new LinkedList<QName>(); for (Style s : styles) { if (s.getFeatureType() != null) { ftNames.add(s.getFeatureType()); } } if (ftNames.isEmpty()) { for (FeatureType t : schema.getFeatureTypes(null, false, false)) { ftNames.add(t.getName()); } } for (QName t : ftNames) { Envelope thisBox = null; try { thisBox = datastore.getEnvelope(t); } catch (FeatureStoreException e) { LOG.error("Error retrieving envelope from FeatureStore: " + e.getMessage(), e); } if (bbox == null) { bbox = thisBox; } else { if (thisBox != null) { bbox = bbox.merge(thisBox); } } } return bbox; }
/** * @param name * @param title * @param parent * @param file */ public FeatureLayer(MapService service, String name, String title, Layer parent, String file) { super(service, name, title, parent); // TODO what about the charset here? datastore = new ShapeFeatureStore(file, null, null, null, null, null, true, null, null); try { datastore.init(null); } catch (ResourceInitException e) { LOG.error( "Layer could not be loaded, because the error '{}' occurred while loading the shape file.", e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } if (!datastore.isAvailable()) { LOG.error("Layer could not be loaded, because the feature store is not available."); return; } ICRS crs = ((ShapeFeatureStore) datastore).getStorageCRS(); LinkedList<ICRS> ss = getSrs(); if (!ss.contains(crs) && !crs.getCode().equals(getUndefined())) { ss.addFirst(crs); } }
@Override public FeatureType getFeatureType() { return datastore.getSchema().getFeatureTypes()[0]; }
@Override public Pair<FeatureCollection, LinkedList<String>> getFeatures( final GetFeatureInfo fi, Style style) throws MissingDimensionValue, InvalidDimensionValue { try { final Pair<Filter, LinkedList<String>> dimFilter = getDimensionFilter(fi.getDimensions()); final Envelope clickBox = fi.getClickBox(); OperatorFilter filter = dimFilter == null ? null : (OperatorFilter) dimFilter.first; if (filter == null) { double scale = calcScaleWMS130( fi.getWidth(), fi.getHeight(), fi.getEnvelope(), fi.getCoordinateSystem(), DEFAULT_PIXEL_SIZE); filter = getStyleFilters(style, scale); } else { double scale = calcScaleWMS130( fi.getWidth(), fi.getHeight(), fi.getEnvelope(), fi.getCoordinateSystem(), DEFAULT_PIXEL_SIZE); OperatorFilter f = getStyleFilters(style, scale); if (f != null) { filter = new OperatorFilter(new And(filter.getOperator(), f.getOperator())); } } 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 Operator operator = filter == null ? null : filter.getOperator(); QName featureType = style == null ? null : style.getFeatureType(); LOG.debug("Querying the feature store(s)..."); FeatureCollection col; if (featureType == null) { List<Query> queries = map( datastore.getSchema().getFeatureTypes(null, false, false), new Mapper<Query, FeatureType>() { @Override public Query apply(FeatureType u) { return new Query( u.getName(), buildFilter(operator, u, clickBox, geomProp), -1, fi.getFeatureCount(), -1); } }); clearNulls(queries); col = clearDuplicates(datastore.query(queries.toArray(new Query[queries.size()]))); } else { FeatureType ft = datastore.getSchema().getFeatureType(featureType); Query query = new Query( featureType, buildFilter(operator, ft, clickBox, geomProp), -1, fi.getFeatureCount(), -1); col = clearDuplicates(datastore.query(query)); } LOG.debug("Finished querying the feature store(s)."); return new Pair<FeatureCollection, LinkedList<String>>( col, dimFilter == null ? new LinkedList<String>() : dimFilter.second); } 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); } return new Pair<FeatureCollection, LinkedList<String>>(null, new LinkedList<String>()); }
@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; }
@Override public void close() { if (datastore != null) { datastore.destroy(); } }