/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.process.spatialstatistics; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.process.Process; import org.geotools.process.ProcessException; import org.geotools.process.ProcessFactory; import org.geotools.process.spatialstatistics.autocorrelation.JoinCountStatisticsOperation; import org.geotools.process.spatialstatistics.autocorrelation.JoinCountStatisticsOperation.JoinCount; import org.geotools.process.spatialstatistics.core.Params; import org.geotools.process.spatialstatistics.enumeration.ContiguityType; import org.geotools.util.logging.Logging; import org.opengis.filter.Filter; import org.opengis.util.ProgressListener; /** * Measure global spatial autocorrelation for binary data, i.e., with observations coded as 1 or B (for Black) and 0 or W (for White). * * @author Minpa Lee, MangoSystem * * @source $URL$ */ public class JoinCountStatisticsProcess extends AbstractStatisticsProcess { protected static final Logger LOGGER = Logging.getLogger(JoinCountStatisticsProcess.class); public JoinCountStatisticsProcess(ProcessFactory factory) { super(factory); } public ProcessFactory getFactory() { return factory; } public static JoinCountProcessResult process(SimpleFeatureCollection inputFeatures, Filter blackExpression, ContiguityType contiguityType, ProgressListener monitor) { Map<String, Object> map = new HashMap<String, Object>(); map.put(JoinCountStatisticsProcessFactory.inputFeatures.key, inputFeatures); map.put(JoinCountStatisticsProcessFactory.blackExpression.key, blackExpression); map.put(JoinCountStatisticsProcessFactory.contiguityType.key, contiguityType); Process process = new JoinCountStatisticsProcess(null); Map<String, Object> resultMap; try { resultMap = process.execute(map, monitor); return (JoinCountProcessResult) resultMap .get(JoinCountStatisticsProcessFactory.RESULT.key); } catch (ProcessException e) { LOGGER.log(Level.FINER, e.getMessage(), e); } return new JoinCountProcessResult(new JoinCount(inputFeatures.getSchema().getTypeName(), contiguityType)); } @Override public Map<String, Object> execute(Map<String, Object> input, ProgressListener monitor) throws ProcessException { SimpleFeatureCollection inputFeatures = (SimpleFeatureCollection) Params.getValue(input, JoinCountStatisticsProcessFactory.inputFeatures, null); Filter blackExpression = (Filter) Params.getValue(input, JoinCountStatisticsProcessFactory.blackExpression, null); if (inputFeatures == null || blackExpression == null) { throw new NullPointerException("inputFeatures, blackExpression parameters required"); } ContiguityType contiguityType = (ContiguityType) Params.getValue(input, JoinCountStatisticsProcessFactory.contiguityType, JoinCountStatisticsProcessFactory.contiguityType.sample); // start process String typeName = inputFeatures.getSchema().getTypeName(); JoinCount joinCount = new JoinCount(typeName, contiguityType); try { JoinCountStatisticsOperation operation = new JoinCountStatisticsOperation(); joinCount = operation.execute(inputFeatures, blackExpression, contiguityType); } catch (IOException e) { throw new ProcessException(e); } // end process Map<String, Object> resultMap = new HashMap<String, Object>(); resultMap.put(JoinCountStatisticsProcessFactory.RESULT.key, new JoinCountProcessResult( joinCount)); return resultMap; } public static class JoinCountProcessResult { String typeName; ContiguityType contiguityType = ContiguityType.Queen; int featureCount = 0; int blackCount = 0; int whiteCount = 0; int numberOfJoins = 0; int observedBB = 0; int observedWW = 0; int observedBW = 0; double expectedBB = 0; double expectedWW = 0; double expectedBW = 0; double stdDevBB = 0; double stdDevWW = 0; double stdDevBW = 0; double zScoreBB = 0; double zScoreWW = 0; double zScoreBW = 0; public JoinCountProcessResult(JoinCount joinCount) { this.typeName = joinCount.getTypeName(); this.contiguityType = joinCount.getContiguityType(); this.featureCount = joinCount.getFeatureCount(); this.blackCount = joinCount.getBlackCount(); this.whiteCount = joinCount.getWhiteCount(); this.numberOfJoins = joinCount.getNumberOfJoins(); this.observedBB = joinCount.getObservedBB(); this.observedBW = joinCount.getObservedBW(); this.observedWW = joinCount.getObservedWW(); this.expectedBB = joinCount.getExpectedBB(); this.expectedBW = joinCount.getExpectedBW(); this.expectedWW = joinCount.getExpectedWW(); this.stdDevBB = joinCount.getStdDevBB(); this.stdDevBW = joinCount.getStdDevBW(); this.stdDevWW = joinCount.getStdDevWW(); this.zScoreBB = joinCount.getzScoreBB(); this.zScoreBW = joinCount.getzScoreBW(); this.zScoreWW = joinCount.getzScoreWW(); } public String getTypeName() { return typeName; } public ContiguityType getContiguityType() { return contiguityType; } public int getFeatureCount() { return featureCount; } public int getBlackCount() { return blackCount; } public int getWhiteCount() { return whiteCount; } public int getNumberOfJoins() { return numberOfJoins; } public int getObservedBB() { return observedBB; } public int getObservedWW() { return observedWW; } public int getObservedBW() { return observedBW; } public double getExpectedBB() { return expectedBB; } public double getExpectedWW() { return expectedWW; } public double getExpectedBW() { return expectedBW; } public double getStdDevBB() { return stdDevBB; } public double getStdDevWW() { return stdDevWW; } public double getStdDevBW() { return stdDevBW; } public double getzScoreBB() { return zScoreBB; } public double getzScoreWW() { return zScoreWW; } public double getzScoreBW() { return zScoreBW; } @SuppressWarnings("nls") @Override public String toString() { final String sep = System.getProperty("line.separator"); StringBuffer sb = new StringBuffer(); sb.append("Type Name: ").append(getTypeName()).append(sep); sb.append("Contiguity Type: ").append(getContiguityType().toString()).append(sep); sb.append("Number of Features: ").append(getFeatureCount()).append(sep); sb.append("Number of Black: ").append(getBlackCount()).append(sep); sb.append("Number of White: ").append(getWhiteCount()).append(sep); sb.append("Number of Joins: ").append(getNumberOfJoins()).append(sep); sb.append("Observed BB Joins: ").append(getObservedBB()).append(sep); sb.append("Observed WW Joins: ").append(getObservedWW()).append(sep); sb.append("Observed BW Joins: ").append(getObservedBW()).append(sep); sb.append("Expected BB Joins: ").append(getExpectedBB()).append(sep); sb.append("Expected WW Joins: ").append(getExpectedWW()).append(sep); sb.append("Expected BW Joins: ").append(getExpectedBW()).append(sep); sb.append("Std Dev of Expected BB Joins: ").append(getStdDevBB()).append(sep); sb.append("Std Dev of Expected WW Joins: ").append(getStdDevWW()).append(sep); sb.append("Std Dev of Expected BW Joins: ").append(getStdDevBW()).append(sep); sb.append("Z-statistics BB Joins: ").append(getzScoreBB()).append(sep); sb.append("Z-statistics WW Joins: ").append(getzScoreWW()).append(sep); sb.append("Z-statistics BW Joins: ").append(getzScoreBW()).append(sep); return sb.toString(); } } }