/* * 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.openoffice; // J2SE dependencies import com.sun.star.beans.XPropertySet; import com.sun.star.comp.loader.FactoryHelper; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.lang.XSingleServiceFactory; import com.sun.star.registry.XRegistryKey; import org.constellation.numeric.table.Interpolation; import org.constellation.numeric.table.Table; import org.constellation.numeric.table.TableFactory; import org.geotools.openoffice.Formulas; import org.geotools.openoffice.MethodInfo; import java.util.logging.Logger; import org.apache.sis.util.logging.Logging; /** * Implémentation de l'interface {@link XNumeric} qui sera exportée vers * <A HREF="http://www.openoffice.org">OpenOffice</A>. * * @version $Id$ * @author Martin Desruisseaux */ public class Numeric extends Formulas implements XNumeric { /** * The logger to use for all message to log in this package. */ private static final Logger LOGGER = Logging.getLogger("org.constellation.openoffice"); /** * Le nom sous lequel sera enregistré cette composante. * * <strong>Note:</strong> Bien que ce nom de correspondent pas aux conventions * du Java, on ne peut le changer car il correspond au nom attendu par OpenOffice. */ private static final String __serviceName = "org.constellation.openoffice.Numeric"; /** * Le service que l'on étend. */ private static final String ADDIN_SERVICE = "com.sun.star.sheet.AddIn"; /** * Construit une nouvelle instance du service. */ @SuppressWarnings("unchecked") public Numeric() { methods.put("getLocatedIndex", new MethodInfo("Numeric", "LOCATE.INDEX", "Retourne les index autour de la valeur xi spécifiée.", new String[] { "xOptions", "Fournit par OpenOffice.", "data", "Les données. Doit contenir au minimum une colonne, celle des x. " + "Toutes les colonnes suivantes (optionnelles) sont des y. Si une " + "valeur #N/A est trouvée dans l'une de ces colonnes, les index " + "retournés éviteront de pointer vers la ligne correspondante.", "xi", "La valeur xi pour laquelle on veut les index." })); methods.put("getInterpolated", new MethodInfo("Numeric", "INTERPOLATE", "Interpole les valeurs de y pour les valeurs xi spécifiées.", new String[] { "xOptions", "Fournit par OpenOffice.", "data", "Les données. Doit contenir au minimum deux colonnes. La première " + "colonne est celle des x. Toutes les colonnes suivantes sont celles " + "des y.", "xi", "Les valeurs xi pour lesquelles on veut interpoler.", "interpolation", "Le type d'interpolation: \"nearest\" ou \"linear\".", "skipMissingY", "VRAI pour ignorer les valeurs manquantes dans les vecteurs des y," + "ou FAUX pour retourner #N/A si de telles valeurs sont rencontrées." })); } /** * Returns a factory for creating the service. * This method is called by the {@code com.sun.star.comp.loader.JavaLoader}. * * @param implementation The name of the implementation for which a service is desired. * @param factories The service manager to be used if needed. * @param registry The registryKey * @return A factory for creating the component. */ public static XSingleServiceFactory __getServiceFactory( final String implementation, final XMultiServiceFactory factories, final XRegistryKey registry) { if (implementation.equals(Numeric.class.getName())) { return FactoryHelper.getServiceFactory(Numeric.class, __serviceName, factories, registry); } return null; } /** * Writes the service information into the given registry key. * This method is called by the {@code com.sun.star.comp.loader.JavaLoader}. * * @param registry The registry key. * @return {@code true} if the operation succeeded. */ public static boolean __writeRegistryServiceInfo(final XRegistryKey registry) { final String classname = Numeric.class.getName(); return FactoryHelper.writeRegistryServiceInfo(classname, __serviceName, registry) && FactoryHelper.writeRegistryServiceInfo(classname, ADDIN_SERVICE, registry); } /** * The service name that can be used to create such an object by a factory. */ public String getServiceName() { return __serviceName; } /** * Provides the supported service names of the implementation, including also * indirect service names. * * @return Sequence of service names that are supported. */ public String[] getSupportedServiceNames() { return new String[] {ADDIN_SERVICE, __serviceName}; } /** * Tests whether the specified service is supported, i.e. implemented by the implementation. * * @param name Name of service to be tested. * @return {@code true} if the service is supported, {@code false} otherwise. */ public boolean supportsService(final String name) { return name.equals(ADDIN_SERVICE) || name.equals(__serviceName); } /** * Construit une table pour les données spécifiées. */ private static Table createTable(final double[][] data, final Object interpolation) { final Interpolation type; if (interpolation == null) { type = Interpolation.NEAREST; } else if (interpolation instanceof Interpolation) { type = (Interpolation) interpolation; } else { type = Interpolation.valueOf(String.valueOf(interpolation).toUpperCase().trim()); } final double[] x = new double[data.length]; final double[][] y = new double[data.length==0 ? 0 : Math.max(data[0].length - 1, 0)][x.length]; for (int j=0; j<x.length; j++) { final double[] row = data[j]; x[j] = row[0]; for (int i=0; i<y.length;) { y[i][j] = row[++i]; } } return TableFactory.getDefault().create(x, y, type); } /** * {inheritDoc} */ public double[][] getLocatedIndex(final XPropertySet xOptions, final double[][] data, final double xi) { try { final int[] index = new int[3]; // TODO final Table table = createTable(data, Interpolation.NEAREST); table.locate(xi, index); final double[][] r = new double[index.length][]; for (int i=0; i<index.length; i++) { r[i] = new double[] {index[i]}; } return r; } catch (Throwable exception) { // Attrape aussi NoClassDefFoundError, qui se produit souvent. reportException("getLocatedIndex", exception); return getFailure(1, 1); } } /** * {inheritDoc} */ public double[][] getInterpolated(final XPropertySet xOptions, final double[][] data, final double[][] xi, final Object interpolation, final Object skipMissingY) { try { final Table table = createTable(data, interpolation); final int numY = Math.max(table.getNumCol()-1, 0); final double[][] r = new double[xi.length][]; double[] transfert = null; for (int j=0; j<r.length; j++) { final double[] source = xi[j]; final double[] target = new double[source.length * numY]; for (int i=0; i<source.length; i++) { transfert = table.interpolateAll(source[i], transfert); System.arraycopy(transfert, 0, target, i*numY, numY); } r[j] = target; } return r; } catch (Throwable exception) { // Attrape aussi NoClassDefFoundError, qui se produit souvent. reportException("getInterpolated", exception); return getFailure(xi.length, 1); } } /** * Retourne le journal dans lequel écrire d'éventuels avertissements. */ @Override protected Logger getLogger() { return LOGGER; } }