/* * 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.core; import java.io.BufferedWriter; import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; import org.geotools.process.spatialstatistics.core.AbstractWeightMatrix.SpatialWeightMatrixType; import org.geotools.util.logging.Logging; /** * SpatialWeightMatrixResult * * @author Minpa Lee, MangoSystem * * @source $URL$ */ public class WeightMatrix { protected static final Logger LOGGER = Logging.getLogger(WeightMatrix.class); private final String newLine = System.getProperty("line.separator"); private final String space = " "; private String uniqueField; private String typeName; private SpatialWeightMatrixType spatialWeightMatrixType = SpatialWeightMatrixType.Distance; // primaryID, <secondaryID, distance> private LinkedHashMap<Object, Hashtable<Object, Double>> items; public int getFeatureCount() { return this.items.size(); } public String getUniqueField() { return uniqueField; } public void setUniqueField(String uniqueField) { if (uniqueField == null || uniqueField.isEmpty()) { this.uniqueField = "FeatureID"; } else { this.uniqueField = uniqueField; } } public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } public SpatialWeightMatrixType getSpatialWeightMatrixType() { return spatialWeightMatrixType; } public void setSpatialWeightMatrixType(SpatialWeightMatrixType spatialWeightMatrixType) { this.spatialWeightMatrixType = spatialWeightMatrixType; } public LinkedHashMap<Object, Hashtable<Object, Double>> getItems() { return items; } public void setItems(LinkedHashMap<Object, Hashtable<Object, Double>> items) { this.items = items; } public WeightMatrix(SpatialWeightMatrixType spatialWeightMatrixType) { this.setSpatialWeightMatrixType(spatialWeightMatrixType); this.setItems(new LinkedHashMap<Object, Hashtable<Object, Double>>()); } public void setupVariables(String typeName, String uniqueField) { this.setUniqueField(uniqueField); this.setTypeName(typeName); } public void visit(Object primaryID, Object secondaryID) { this.visit(primaryID, secondaryID, Double.valueOf(1.0)); } public void visit(Object primaryID, Object secondaryID, Double distance) { if (!items.containsKey(primaryID)) { items.put(primaryID, new Hashtable<Object, Double>()); } items.get(primaryID).put(secondaryID, distance); } public boolean isNeighbor(SpatialEvent source, SpatialEvent target) { return isNeighbor(source.id, target.id); } public boolean isNeighbor(Object primaryID, Object secondaryID) { if (items.containsKey(primaryID)) { return items.get(primaryID).containsKey(secondaryID); } return false; } public double getWeight(SpatialEvent source, SpatialEvent target) { return getWeight(source.id, target.id); } public double getWeight(Object primaryID, Object secondaryID) { return isNeighbor(primaryID, secondaryID) ? 1.0 : 0.0; } public void save(File outputFile, Charset charset) throws IOException { if (spatialWeightMatrixType == SpatialWeightMatrixType.Distance) { writeDistance(outputFile, charset); } else { writeContiguity(outputFile, charset); } } public boolean load(File swmFile, Charset charset) { // TODO code here return false; } private void writeContiguity(File outputFile, Charset charset) throws IOException { BufferedWriter writer = null; try { FileOutputStream fos = new FileOutputStream(outputFile); writer = new BufferedWriter(new OutputStreamWriter(fos, charset)); StringBuffer sb = new StringBuffer(); // header : 0 25 seoul_series sgg_cd sb.append("0").append(space).append(this.getFeatureCount()).append(space); sb.append(this.getTypeName()).append(space).append(this.getUniqueField()); writer.write(sb.append(newLine).toString()); // matrix for (Entry<Object, Hashtable<Object, Double>> entry : items.entrySet()) { Object primaryID = entry.getKey(); int count = entry.getValue().size(); // 11170 7 sb.setLength(0); sb.append(primaryID.toString()).append(space).append(count); writer.write(sb.append(newLine).toString()); // 11440 11590 11140 11200 11650 11560 11680 sb.setLength(0); for (Entry<Object, Double> second : entry.getValue().entrySet()) { if (sb.length() > 0) { sb.append(space); } sb.append(second.getKey().toString()); } writer.write(sb.append(newLine).toString()); } writer.flush(); } catch (FileNotFoundException e) { LOGGER.log(Level.WARNING, e.getMessage()); } finally { closeQuietly(writer); } } private void writeDistance(File outputFile, Charset charset) throws IOException { BufferedWriter writer = null; try { FileOutputStream fos = new FileOutputStream(outputFile); writer = new BufferedWriter(new OutputStreamWriter(fos, charset)); StringBuffer sb = new StringBuffer(); // header : 0 25 seoul_series sgg_cd sb.append("0").append(space).append(this.getFeatureCount()).append(space); sb.append(this.getTypeName()).append(space).append(this.getUniqueField()); writer.write(sb.append(newLine).toString()); // matrix for (Entry<Object, Hashtable<Object, Double>> entry : items.entrySet()) { Object primaryID = entry.getKey(); for (Entry<Object, Double> second : entry.getValue().entrySet()) { // 11545 11620 4029.25183 sb.setLength(0); sb.append(primaryID.toString()).append(space); sb.append(second.getKey().toString()).append(" "); sb.append(second.getValue()); writer.write(sb.append(newLine).toString()); } } writer.flush(); } catch (FileNotFoundException e) { LOGGER.log(Level.WARNING, e.getMessage(), e); } finally { closeQuietly(writer); } } private void closeQuietly(Closeable io) { try { if (io != null) { io.close(); } } catch (IOException e) { LOGGER.log(Level.FINER, e.getMessage(), e); } } }