/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.constellation.map.featureinfo; import org.constellation.ws.MimeType; import org.geotoolkit.coverage.GridSampleDimension; import org.geotoolkit.display.PortrayalException; import org.geotoolkit.display2d.canvas.RenderingContext2D; import org.geotoolkit.display2d.primitive.ProjectedCoverage; import org.geotoolkit.display2d.primitive.ProjectedFeature; import org.geotoolkit.display2d.primitive.SearchAreaJ2D; import org.geotoolkit.display2d.service.CanvasDef; import org.geotoolkit.display2d.service.SceneDef; import org.geotoolkit.display2d.service.ViewDef; import org.geotoolkit.feature.ComplexAttribute; import org.geotoolkit.feature.Feature; import org.geotoolkit.feature.Property; import org.geotoolkit.feature.type.PropertyDescriptor; import org.geotoolkit.map.FeatureMapLayer; import org.geotoolkit.ows.xml.GetFeatureInfo; import org.opengis.util.InternationalString; import javax.measure.unit.Unit; import java.awt.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.opengis.util.GenericName; /** * A generic FeatureInfoFormat that produce CSV output for Features and Coverages. * Supported mimeTypes are : * <ul> * <li>text/plain</li> * </ul> * * @author Quentin Boileau (Geomatys) * @author Johann Sorel (Geomatys) */ public class CSVFeatureInfoFormat extends AbstractTextFeatureInfoFormat { private static final class LayerResult{ private String layerName; private String layerType; private final List<String> values = new ArrayList<>(); } private final Map<String,LayerResult> results = new HashMap<>(); public CSVFeatureInfoFormat() { } /** * {@inheritDoc} */ @Override protected void nextProjectedFeature(ProjectedFeature graphic, RenderingContext2D context, SearchAreaJ2D queryArea) { final FeatureMapLayer layer = graphic.getLayer(); final String layerName = layer.getName(); final Feature feature = graphic.getCandidate(); final Collection<PropertyDescriptor> descs = feature.getType().getDescriptors(); LayerResult result = results.get(layerName); if(result==null){ //first feature of this type result = new LayerResult(); result.layerName = layerName; //feature type final StringBuilder typeBuilder = new StringBuilder(); for(PropertyDescriptor pd : descs){ final GenericName propName = pd.getName(); typeBuilder.append(propName.toString()); typeBuilder.append(':'); typeBuilder.append(pd.getType().getBinding().getSimpleName()); typeBuilder.append(';'); } result.layerType = typeBuilder.toString(); results.put(layerName, result); } //the feature values final StringBuilder dataBuilder = new StringBuilder(); for(PropertyDescriptor pd : descs){ final Property prop = feature.getProperty(pd.getName()); if(prop instanceof ComplexAttribute){ dataBuilder.append("...complex attribute, use GML or HTML output..."); }else if(prop !=null){ dataBuilder.append(String.valueOf(prop.getValue())); } dataBuilder.append(';'); } result.values.add(dataBuilder.toString()); } @Override protected void nextProjectedCoverage(ProjectedCoverage graphic, RenderingContext2D context, SearchAreaJ2D queryArea) { final List<Map.Entry<GridSampleDimension,Object>> covResults = FeatureInfoUtilities.getCoverageValues(graphic, context, queryArea); if (covResults == null) { return; } final String layerName = graphic.getLayer().getCoverageReference().getName().tip().toString(); LayerResult result = results.get(layerName); if(result==null){ //first feature of this type result = new LayerResult(); result.layerName = layerName; //coverage type final StringBuilder typeBuilder = new StringBuilder(); for (final Map.Entry<GridSampleDimension,Object> entry : covResults) { final GridSampleDimension gsd = entry.getKey(); final InternationalString title = gsd.getDescription(); if(title!=null){ typeBuilder.append(title); } final Unit unit = gsd.getUnits(); if(unit!=null){ typeBuilder.append(unit.toString()); } typeBuilder.append(';'); } result.layerType = typeBuilder.toString(); results.put(layerName, result); } //the coverage values final StringBuilder dataBuilder = new StringBuilder(); for(Map.Entry<GridSampleDimension,Object> entry : covResults){ dataBuilder.append(String.valueOf(entry.getValue())); dataBuilder.append(';'); } result.values.add(dataBuilder.toString()); } /** * {@inheritDoc} */ @Override public Object getFeatureInfo(SceneDef sdef, ViewDef vdef, CanvasDef cdef, Rectangle searchArea, GetFeatureInfo getFI) throws PortrayalException { //fill coverages and features maps getCandidates(sdef, vdef, cdef, searchArea, -1); final StringBuilder builder = new StringBuilder(); // optimization move this filter to getCandidates Integer maxValue = getFeatureCount(getFI); if (maxValue == null) { maxValue = 1; } for(LayerResult result : results.values()){ builder.append(result.layerName).append('\n'); builder.append(result.layerType).append('\n'); int cpt = 0; for (final String record : result.values) { builder.append(record).append('\n'); cpt++; if (cpt >= maxValue) break; } builder.append('\n'); } results.clear(); return builder.toString(); } /** * {@inheritDoc} */ @Override public List<String> getSupportedMimeTypes() { return Collections.singletonList(MimeType.TEXT_PLAIN); } }