/** * Get the data type of the command attribute * * @param wfs datastore * @return data type as Class */ private Class<?> getDataType(WFSContentDataStore wfs) { SimpleFeatureType schema; Class<?> clazz = null; try { schema = wfs.getSchema(_wfsngTypeName); // get schema clazz = schema.getType(_command.getPropertyName()).getBinding(); // get data type as Class } catch (IOException e) { e.printStackTrace(); } if (clazz == null) { throw new RuntimeException( "Should never happen, we need to know what type is the attribute of"); } return clazz; }
/** * Upload all the features from the WFS and then prepare the factories to fulfill the different * type of classifications and displays * * @throws DocServiceException */ private void doClassification() throws DocServiceException { try { // connect to the remote WFS WFSContentDataStore wfs = connectToWFS(_command.getWFSUrl()); // check if property name exists SimpleFeatureType ft = wfs.getSchema(_wfsngTypeName); int index = ft.indexOf(_command.getPropertyName()); if (index == -1) { throw new DocServiceException( _command.getPropertyName() + " is not an attribute of " + _command.getFeatureTypeName(), HttpServletResponse.SC_BAD_REQUEST); } // Load all the features FeatureSource<SimpleFeatureType, SimpleFeature> source = wfs.getFeatureSource(_wfsngTypeName); FeatureCollection<SimpleFeatureType, SimpleFeature> featuresCollection = source.getFeatures(); // We need a display (Symbolizers) and a value (Filters) fatories to generate a SLD file I_SymbolizerFactory symbolizerFact = null; // create symbols I_FilterFactory filterFact = null; // create filters // execute different type of classification given the type requested by user if (_command.getClassifType() == E_ClassifType.CHOROPLETHS || _command.getClassifType() == E_ClassifType.PROP_SYMBOLS) { // Classification on continuous values. Sorting is needed to classify: // Double values are mandatory (for now) if (getDataType(wfs) == String.class) { // choropleths and prop symbols use quantile classification // therefore classify on string type has no purpose throw new DocServiceException( "Classification on continous values (" + _command.getClassifType() + ").\n" + "Attribute " + _command.getPropertyName() + " is string type." + " Therefore no classification on contiuous values can be done." + " It needs be a meaningful comparable type (numerical, date...)." + " Use unique values classification instead.", HttpServletResponse.SC_BAD_REQUEST); } else if ((getDataType(wfs) != Double.class) && (getDataType(wfs) != Float.class) && (getDataType(wfs) != Integer.class) && (getDataType(wfs) != Long.class) && (getDataType(wfs) != Short.class)) { // for now, only double, float, integer, and short types are supported // FIXME deal with others numerical types, dates... // they all must be comparable type as sorting is required for classification throw new DocServiceException( "Classification on " + getDataType(wfs).getName() + " type is not supported.", HttpServletResponse.SC_NOT_IMPLEMENTED); } // get values to classify ArrayList<Double> values = getDoubleValues(featuresCollection.features(), _command.getPropertyName()); filterFact = new ContinuousFilterFactory( values, _command.getClassCount(), _command.getPropertyName()); if (_command.getClassifType() == E_ClassifType.CHOROPLETHS) { switch (_command.getSymbolType()) { case POLYGON: symbolizerFact = new PolygonSymbolizerFactory( _command.getClassCount(), _command.getFirstColor(), _command.getLastColor()); break; case LINE: symbolizerFact = new LineSymbolizerFactory( _command.getClassCount(), _command.getFirstColor(), _command.getLastColor()); break; case POINT: symbolizerFact = new PointSymbolizerFactory( _command.getClassCount(), _command.getFirstColor(), _command.getLastColor()); break; default: throw new DocServiceException( "Choropleths classification on symbol type: " + _command.getSymbolType() + " is not supported.", HttpServletResponse.SC_BAD_REQUEST); } } else if (_command.getClassifType() == E_ClassifType.PROP_SYMBOLS) { switch (_command.getSymbolType()) { case LINE: symbolizerFact = new LineSymbolizerFactory( _command.getClassCount(), _command.getMinSize(), _command.getMaxSize()); // customizing is possible // symbolizerFact.setColor(Color.BLUE); break; case POINT: symbolizerFact = new PointSymbolizerFactory( _command.getClassCount(), _command.getMinSize(), _command.getMaxSize()); // customizing is possible // symbolizerFact.setColor(Color.BLUE); // symbolizerFact.setSymbol(StyleBuilder.MARK_CROSS); break; default: throw new DocServiceException( "Proportional symbols classification on symbol type: " + _command.getSymbolType() + " is not supported.", HttpServletResponse.SC_BAD_REQUEST); } } } else if (_command.getClassifType() == E_ClassifType.UNIQUE_VALUES) { // no needs to classify on Unique Values. They can be kept as Strings. Set<String> values = getUniqueStringValues(featuresCollection.features(), _command.getPropertyName()); filterFact = new DiscreteFilterFactory(values, _command.getPropertyName()); switch (_command.getSymbolType()) { case POLYGON: symbolizerFact = new PolygonSymbolizerFactory(_command.getPaletteID(), values.size()); break; case LINE: symbolizerFact = new LineSymbolizerFactory(_command.getPaletteID(), values.size()); break; case POINT: symbolizerFact = new PointSymbolizerFactory(_command.getPaletteID(), values.size()); break; default: throw new DocServiceException( "Unique values classification on symbol type: " + _command.getSymbolType() + " is not supported.", HttpServletResponse.SC_BAD_REQUEST); } } else { throw new DocServiceException( "Unknown classification type: " + _command.getClassifType(), HttpServletResponse.SC_BAD_REQUEST); } assert (symbolizerFact != null); assert (filterFact != null); // With those 2 factories a FeatureTypeStyle can be created FeatureTypeStyle fts = createFeatureTypeStyle(filterFact, symbolizerFact); // Use FeatureTypeStyle to generate a complete SLD object _sld = createSLD(fts); } catch (IOException e) { e.printStackTrace(); // could happened when communicating with WFS } }