/** * Checks if our WPS can really handle this process inputs and outputs * * @param pf * @param name * @return */ Set<Name> getProcessBlacklist() { synchronized (PROCESS_BLACKLIST) { if (PROCESS_BLACKLIST == Collections.EMPTY_SET) { Set<Name> blacklist = new HashSet<Name>(); for (ProcessFactory pf : Processors.getProcessFactories()) { int count = 0; for (Name name : pf.getNames()) { try { // check inputs for (Parameter<?> p : pf.getParameterInfo(name).values()) { List<ProcessParameterIO> ppios = ProcessParameterIO.findAll(p, context); if (ppios.isEmpty()) { LOGGER.log( Level.INFO, "Blacklisting process " + name.getURI() + " as the input " + p.key + " of type " + p.type + " cannot be handled"); blacklist.add(name); } } // check outputs for (Parameter<?> p : pf.getResultInfo(name, null).values()) { List<ProcessParameterIO> ppios = ProcessParameterIO.findAll(p, context); if (ppios.isEmpty()) { LOGGER.log( Level.INFO, "Blacklisting process " + name.getURI() + " as the output " + p.key + " of type " + p.type + " cannot be handled"); blacklist.add(name); } } } catch (Throwable t) { blacklist.add(name); } if (!blacklist.contains(name)) { count++; } } LOGGER.info("Found " + count + " bindable processes in " + pf.getTitle()); } PROCESS_BLACKLIST = blacklist; } } return PROCESS_BLACKLIST; }
public Function function(Name processName, List<Expression> args, Literal fallback) { // if the param function just return it if (processName.equals(new NameImpl(ParameterFunction.NAME))) { return new ParameterFunction(fallback, args); } // lookup the process if (functionNames == null) { init(); } if (!processToFunction.containsKey(processName)) { // no such function return null; } else { // wrap the process org.geotools.process.Process process = Processors.createProcess(processName); Map<String, Parameter<?>> parameters = Processors.getParameterInfo(processName); if (process instanceof RenderingProcess) { return new RenderingProcessFunction( processName.getLocalPart(), processName, args, parameters, (RenderingProcess) process, fallback); } else { return new ProcessFunction( processName.getLocalPart(), processName, args, parameters, process, fallback); } } }
public void testProcess() throws ParseException, InterruptedException, ExecutionException { WKTReader wktReader = new WKTReader(new GeometryFactory()); Geometry geom = wktReader.read("MULTIPOINT (1 1, 5 4, 7 9, 5 5, 2 2)"); Name name = new NameImpl("spatial", "octagonalEnvelope"); org.geotools.process.Process process = Processors.createProcess(name); System.out.println("Executing process: " + name); for (Map.Entry<String, Parameter<?>> entry : Processors.getParameterInfo(name).entrySet()) { System.out.println("\t" + entry.getKey() + ":\t" + entry.getValue()); } ProcessExecutor engine = Processors.newProcessExecutor(2); // quick map of inputs Map<String, Object> input = new KVP("geom", geom); Progress working = engine.submit(process, input); // you could do other stuff whle working is doing its thing if (working.isCancelled()) { return; } Map<String, Object> result = working.get(); // get is BLOCKING Geometry octo = (Geometry) result.get("result"); System.out.println(octo); }
public void testSPI() throws Exception { NameImpl bufferName = new NameImpl("JTS", "buffer"); ProcessFactory factory = Processors.createProcessFactory(bufferName); assertNotNull(factory); assertTrue(factory instanceof GeometryProcessFactory); org.geotools.process.Process buffer = Processors.createProcess(bufferName); assertNotNull(buffer); }
private synchronized void init() { if (functionNames == null) { // collect and sort the factories to have a reproducable list of function names List<ProcessFactory> factories = new ArrayList<ProcessFactory>(Processors.getProcessFactories()); Collections.sort(factories, FACTORY_COMPARATOR); // collect name and params of all processes resulting in a single output processToFunction = new HashMap<Name, FunctionName>(); functionNames = new ArrayList<FunctionName>(); for (ProcessFactory factory : factories) { for (Name processName : factory.getNames()) { Map<String, Parameter<?>> resultInfo = factory.getResultInfo(processName, null); // check there is a single output if (getPrimary(resultInfo) != null) { Map<String, Parameter<?>> parameterInfo = factory.getParameterInfo(processName); List<String> argumentNames = new ArrayList<String>(parameterInfo.keySet()); FunctionName functionName = new FunctionNameImpl(processName, argumentNames); functionNames.add(functionName); processToFunction.put(processName, functionName); } } } // add the parameter function functionNames.add(new FunctionNameImpl(ParameterFunction.NAME, -1)); } }
public WPSCapabilitiesType run(GetCapabilitiesType request) throws WPSException { // do the version negotiation dance List<String> provided = Collections.singletonList("1.0.0"); List<String> accepted = null; if (request.getAcceptVersions() != null) accepted = request.getAcceptVersions().getVersion(); String version = RequestUtils.getVersionOws11(provided, accepted); if (!"1.0.0".equals(version)) { throw new WPSException("Could not understand version:" + version); } // TODO: add update sequence negotiation // encode the response Wps10Factory wpsf = Wps10Factory.eINSTANCE; Ows11Factory owsf = Ows11Factory.eINSTANCE; WPSCapabilitiesType caps = wpsf.createWPSCapabilitiesType(); caps.setVersion("1.0.0"); // TODO: make configurable caps.setLang("en"); // ServiceIdentification ServiceIdentificationType si = owsf.createServiceIdentificationType(); caps.setServiceIdentification(si); si.getTitle().add(Ows11Util.languageString(wps.getTitle())); si.getAbstract().add(Ows11Util.languageString(wps.getAbstract())); KeywordsType kw = Ows11Util.keywords(wps.keywordValues()); ; if (kw != null) { si.getKeywords().add(kw); } si.setServiceType(Ows11Util.code("WPS")); si.getServiceTypeVersion().add("1.0.0"); si.setFees(wps.getFees()); if (wps.getAccessConstraints() != null) { si.getAccessConstraints().add(wps.getAccessConstraints()); } // ServiceProvider ServiceProviderType sp = owsf.createServiceProviderType(); caps.setServiceProvider(sp); // TODO: set provder name from context GeoServerInfo geoServer = wps.getGeoServer().getGlobal(); if (geoServer.getContact().getContactOrganization() != null) { sp.setProviderName(geoServer.getContact().getContactOrganization()); } else { sp.setProviderName("GeoServer"); } sp.setProviderSite(owsf.createOnlineResourceType()); sp.getProviderSite().setHref(geoServer.getOnlineResource()); sp.setServiceContact(responsibleParty(geoServer, owsf)); // OperationsMetadata OperationsMetadataType om = owsf.createOperationsMetadataType(); caps.setOperationsMetadata(om); OperationType gco = owsf.createOperationType(); gco.setName("GetCapabilities"); gco.getDCP().add(Ows11Util.dcp("wps", request)); om.getOperation().add(gco); OperationType dpo = owsf.createOperationType(); dpo.setName("DescribeProcess"); dpo.getDCP().add(Ows11Util.dcp("wps", request)); om.getOperation().add(dpo); OperationType eo = owsf.createOperationType(); eo.setName("Execute"); eo.getDCP().add(Ows11Util.dcp("wps", request)); om.getOperation().add(eo); ProcessOfferingsType po = wpsf.createProcessOfferingsType(); caps.setProcessOfferings(po); // gather the process list for (ProcessFactory pf : Processors.getProcessFactories()) { for (Name name : pf.getNames()) { if (!getProcessBlacklist().contains(name)) { ProcessBriefType p = wpsf.createProcessBriefType(); p.setProcessVersion(pf.getVersion(name)); po.getProcess().add(p); p.setIdentifier(Ows11Util.code(name)); p.setTitle(Ows11Util.languageString(pf.getTitle(name))); p.setAbstract(Ows11Util.languageString(pf.getDescription(name))); } } } // sort it ECollections.sort( po.getProcess(), new Comparator() { public int compare(Object o1, Object o2) { ProcessBriefType pb1 = (ProcessBriefType) o1; ProcessBriefType pb2 = (ProcessBriefType) o2; final String id1 = pb1.getIdentifier().getValue(); final String id2 = pb2.getIdentifier().getValue(); return id1.compareTo(id2); } }); LanguagesType1 languages = wpsf.createLanguagesType1(); caps.setLanguages(languages); DefaultType2 defaultLanguage = wpsf.createDefaultType2(); languages.setDefault(defaultLanguage); defaultLanguage.setLanguage("en-US"); LanguagesType supportedLanguages = wpsf.createLanguagesType(); languages.setSupported(supportedLanguages); supportedLanguages.getLanguage().add("en-US"); return caps; // Version detection and alternative invocation if being implemented. }
/** * Takes a GetLegendGraphicRequest and produces a BufferedImage that then can be used by a * subclass to encode it to the appropriate output format. * * @param request the "parsed" request, where "parsed" means that it's values are already * validated so this method must not take care of verifying the requested layer exists and the * like. * @throws ServiceException if there are problems creating a "sample" feature instance for the * FeatureType <code>request</code> returns as the required layer (which should not occur). */ public BufferedImage buildLegendGraphic(GetLegendGraphicRequest request) throws ServiceException { // list of images to be rendered for the layers (more than one if // a layer group is given) List<RenderedImage> layersImages = new ArrayList<RenderedImage>(); List<LegendRequest> layers = request.getLegends(); // List<FeatureType> layers=request.getLayers(); // List<Style> styles=request.getStyles(); // List<String> rules=request.getRules(); boolean forceLabelsOn = false; boolean forceLabelsOff = false; if (request.getLegendOptions().get("forceLabels") instanceof String) { String forceLabelsOpt = (String) request.getLegendOptions().get("forceLabels"); if (forceLabelsOpt.equalsIgnoreCase("on")) { forceLabelsOn = true; } else if (forceLabelsOpt.equalsIgnoreCase("off")) { forceLabelsOff = true; } } boolean forceTitlesOff = false; if (request.getLegendOptions().get("forceTitles") instanceof String) { String forceTitlesOpt = (String) request.getLegendOptions().get("forceTitles"); if (forceTitlesOpt.equalsIgnoreCase("off")) { forceTitlesOff = true; } } for (LegendRequest legend : layers) { FeatureType layer = legend.getFeatureType(); // style and rule to use for the current layer Style gt2Style = legend.getStyle(); if (gt2Style == null) { throw new NullPointerException("request.getStyle()"); } // get rule corresponding to the layer index // normalize to null for NO RULE String ruleName = legend.getRule(); // was null // width and height, we might have to rescale those in case of DPI usage int w = request.getWidth(); int h = request.getHeight(); // apply dpi rescale double dpi = RendererUtilities.getDpi(request.getLegendOptions()); double standardDpi = RendererUtilities.getDpi(Collections.emptyMap()); if (dpi != standardDpi) { double scaleFactor = dpi / standardDpi; w = (int) Math.round(w * scaleFactor); h = (int) Math.round(h * scaleFactor); DpiRescaleStyleVisitor dpiVisitor = new DpiRescaleStyleVisitor(scaleFactor); dpiVisitor.visit(gt2Style); gt2Style = (Style) dpiVisitor.getCopy(); } // apply UOM rescaling if we have a scale if (request.getScale() > 0) { double pixelsPerMeters = RendererUtilities.calculatePixelsPerMeterRatio( request.getScale(), request.getLegendOptions()); UomRescaleStyleVisitor rescaleVisitor = new UomRescaleStyleVisitor(pixelsPerMeters); rescaleVisitor.visit(gt2Style); gt2Style = (Style) rescaleVisitor.getCopy(); } boolean strict = request.isStrict(); final boolean transparent = request.isTransparent(); RenderedImage titleImage = null; // if we have more than one layer, we put a title on top of each layer legend if (layers.size() > 1 && !forceTitlesOff) { titleImage = getLayerTitle(legend, w, h, transparent, request); } // Check for rendering transformation boolean hasVectorTransformation = false; boolean hasRasterTransformation = false; List<FeatureTypeStyle> ftsList = gt2Style.featureTypeStyles(); for (int i = 0; i < ftsList.size(); i++) { FeatureTypeStyle fts = ftsList.get(i); Expression exp = fts.getTransformation(); if (exp != null) { ProcessFunction processFunction = (ProcessFunction) exp; Name processName = processFunction.getProcessName(); Map<String, Parameter<?>> outputs = Processors.getResultInfo(processName, null); if (outputs.isEmpty()) { continue; } Parameter<?> output = outputs.values().iterator().next(); // we assume there is only one output if (SimpleFeatureCollection.class.isAssignableFrom(output.getType())) { hasVectorTransformation = true; break; } else if (GridCoverage2D.class.isAssignableFrom(output.getType())) { hasRasterTransformation = true; break; } } } final boolean buildRasterLegend = (!strict && layer == null && LegendUtils.checkRasterSymbolizer(gt2Style)) || (LegendUtils.checkGridLayer(layer) && !hasVectorTransformation) || hasRasterTransformation; // Just checks LegendInfo currently, should check gtStyle final boolean useProvidedLegend = layer != null && legend.getLayerInfo() != null; RenderedImage legendImage = null; if (useProvidedLegend) { legendImage = getLayerLegend(legend, w, h, transparent, request); } if (buildRasterLegend) { final RasterLayerLegendHelper rasterLegendHelper = new RasterLayerLegendHelper(request, gt2Style, ruleName); final BufferedImage image = rasterLegendHelper.getLegend(); if (image != null) { if (titleImage != null) { layersImages.add(titleImage); } layersImages.add(image); } } else if (useProvidedLegend && legendImage != null) { if (titleImage != null) { layersImages.add(titleImage); } layersImages.add(legendImage); } else { final Feature sampleFeature; if (layer == null || hasVectorTransformation) { sampleFeature = createSampleFeature(); } else { sampleFeature = createSampleFeature(layer); } final FeatureTypeStyle[] ftStyles = gt2Style.featureTypeStyles().toArray(new FeatureTypeStyle[0]); final double scaleDenominator = request.getScale(); final Rule[] applicableRules; if (ruleName != null) { Rule rule = LegendUtils.getRule(ftStyles, ruleName); if (rule == null) { throw new ServiceException( "Specified style does not contains a rule named " + ruleName); } applicableRules = new Rule[] {rule}; } else { applicableRules = LegendUtils.getApplicableRules(ftStyles, scaleDenominator); } final NumberRange<Double> scaleRange = NumberRange.create(scaleDenominator, scaleDenominator); final int ruleCount = applicableRules.length; /** * A legend graphic is produced for each applicable rule. They're being held here until the * process is done and then painted on a "stack" like legend. */ final List<RenderedImage> legendsStack = new ArrayList<RenderedImage>(ruleCount); final SLDStyleFactory styleFactory = new SLDStyleFactory(); double minimumSymbolSize = MINIMUM_SYMBOL_SIZE; // get minSymbolSize from LEGEND_OPTIONS, if defined if (request.getLegendOptions().get("minSymbolSize") instanceof String) { String minSymbolSizeOpt = (String) request.getLegendOptions().get("minSymbolSize"); try { minimumSymbolSize = Double.parseDouble(minSymbolSizeOpt); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid minSymbolSize value: should be a number"); } } // calculate the symbols rescaling factor necessary for them to be // drawn inside the icon box double symbolScale = calcSymbolScale(w, h, layer, sampleFeature, applicableRules, minimumSymbolSize); for (int i = 0; i < ruleCount; i++) { final RenderedImage image = ImageUtils.createImage(w, h, (IndexColorModel) null, transparent); final Map<RenderingHints.Key, Object> hintsMap = new HashMap<RenderingHints.Key, Object>(); final Graphics2D graphics = ImageUtils.prepareTransparency( transparent, LegendUtils.getBackgroundColor(request), image, hintsMap); graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Feature sample = getSampleFeatureForRule(layer, sampleFeature, applicableRules[i]); FilterFactory ff = CommonFactoryFinder.getFilterFactory(); final Symbolizer[] symbolizers = applicableRules[i].getSymbolizers(); final GraphicLegend graphic = applicableRules[i].getLegend(); // If this rule has a legend graphic defined in the SLD, use it if (graphic != null) { if (this.samplePoint == null) { Coordinate coord = new Coordinate(w / 2, h / 2); try { this.samplePoint = new LiteShape2(geomFac.createPoint(coord), null, null, false); } catch (Exception e) { this.samplePoint = null; } } shapePainter.paint(graphics, this.samplePoint, graphic, scaleDenominator, false); } else { for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) { Symbolizer symbolizer = symbolizers[sIdx]; if (symbolizer instanceof RasterSymbolizer) { // skip it } else { // rescale symbols if needed if (symbolScale > 1.0 && symbolizer instanceof PointSymbolizer) { PointSymbolizer pointSymbolizer = cloneSymbolizer(symbolizer); if (pointSymbolizer.getGraphic() != null) { double size = getPointSymbolizerSize(sample, pointSymbolizer, Math.min(w, h) - 4); pointSymbolizer .getGraphic() .setSize(ff.literal(size / symbolScale + minimumSymbolSize)); symbolizer = pointSymbolizer; } } Style2D style2d = styleFactory.createStyle(sample, symbolizer, scaleRange); LiteShape2 shape = getSampleShape(symbolizer, w, h); if (style2d != null) { shapePainter.paint(graphics, shape, style2d, scaleDenominator); } } } } if (image != null && titleImage != null) { layersImages.add(titleImage); titleImage = null; } legendsStack.add(image); graphics.dispose(); } // JD: changed legend behavior, see GEOS-812 // this.legendGraphic = scaleImage(mergeLegends(legendsStack), request); BufferedImage image = mergeLegends(legendsStack, applicableRules, request, forceLabelsOn, forceLabelsOff); if (image != null) { layersImages.add(image); } } } // all legend graphics are merged if we have a layer group BufferedImage finalLegend = mergeLegends(layersImages, null, request, forceLabelsOn, forceLabelsOff); if (finalLegend == null) { throw new IllegalArgumentException("no legend passed"); } return finalLegend; }