Statistics
| Revision:

gvsig-geoprocess / org.gvsig.geoprocess / trunk / org.gvsig.geoprocess / org.gvsig.geoprocess.algorithm / org.gvsig.geoprocess.algorithm.dispersepoints / src / main / java / org / gvsig / geoprocess / algorithm / dispersepoints / DispersePointsOperation.java @ 1260

History | View | Annotate | Download (6.18 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2017 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.geoprocess.algorithm.dispersepoints;
24

    
25
import java.io.File;
26
import java.util.ArrayList;
27
import java.util.Collection;
28
import java.util.HashSet;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.ListIterator;
32
import java.util.NavigableSet;
33
import java.util.Set;
34

    
35
import org.mapdb.DB;
36
import org.mapdb.DBMaker;
37

    
38
import es.unex.sextante.core.Sextante;
39

    
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.feature.EditableFeature;
42
import org.gvsig.fmap.dal.feature.Feature;
43
import org.gvsig.fmap.dal.feature.FeatureReference;
44
import org.gvsig.fmap.geom.Geometry;
45
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
46
import org.gvsig.fmap.geom.GeometryLocator;
47
import org.gvsig.fmap.geom.GeometryManager;
48
import org.gvsig.fmap.geom.SpatialIndex;
49
import org.gvsig.fmap.geom.exception.CreateGeometryException;
50
import org.gvsig.fmap.geom.primitive.Point;
51
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
52
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.folders.FoldersManager;
55

    
56
/**
57
 * Disperse points operation
58
 *
59
 * @author fdiaz</a>
60
 */
61
public class DispersePointsOperation extends GeometryOperation {
62

    
63
    private SpatialIndex index;
64
    private double scatterRadius;
65
    private double matchDistance;
66
    NavigableSet<Integer> processed;
67

    
68
    /**
69
     * Builds an instance of this operation.
70
     *
71
     * @param index
72
     * @param scatterRadius
73
     * @param matchDistance
74
     * @param p
75
     *
76
     */
77
    public DispersePointsOperation(SpatialIndex index, double scatterRadius, double matchDistance,
78
        AbstractSextanteGeoProcess p) {
79
        super(p);
80
        this.index = index;
81
        this.scatterRadius = scatterRadius;
82
        this.matchDistance = matchDistance;
83

    
84
        FoldersManager folderManager = ToolsLocator.getFoldersManager();
85
        File dbfile = folderManager.getUniqueTemporaryFile("dispersepoints.mapdb");
86

    
87
        // Creariamos la BBDD
88
        DB db = DBMaker.fileDB(dbfile).fileMmapEnable().make();
89
        // Y dentro de ella una tabla "processed" para nuestro set.
90
        processed = (NavigableSet<Integer>) db.treeSet("processed").create();
91

    
92
    }
93

    
94
    public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
95
        boolean addedFeature = false;
96
        if (g == null)
97
            return lastEditFeature;
98

    
99
        try {
100

    
101
            FeatureReference reference = feature.getReference();
102
            if (!processed.contains(reference.hashCode())) {
103
                final List<FeatureReference> group = new ArrayList<FeatureReference>();
104
                Iterator<?> iterator = index.query(g.buffer(matchDistance));
105
                while (iterator.hasNext()) {
106
                    FeatureReference ref = (FeatureReference) iterator.next();
107
                    if (!processed.contains(ref.hashCode())) {
108
                        Feature feat = ref.getFeature().getCopy();
109
                        Geometry g2 = feat.getDefaultGeometry();
110
                        double dist = g.distance(g2);
111
                        if (dist <= matchDistance) {
112
                            group.add(ref);
113
                            processed.add(ref.hashCode());
114
                        }
115
                    }
116
                }
117
                if (group.size() == 1) {
118
                    buildFeature(feature, g);
119
                } else {
120
                    buildFeatures(group, (Point) g);
121
                }
122
            }
123

    
124
        } catch (Exception e) {
125
            Sextante.addErrorToLog(e);
126
        }
127

    
128
        return lastEditFeature;
129
    }
130

    
131
    /**
132
     * @param group
133
     * @throws DataException
134
     * @throws CreateGeometryException
135
     */
136
    private void buildFeatures(List<FeatureReference> group, Point center) throws CreateGeometryException, DataException {
137
        if (group.isEmpty()) {
138
            return;
139
        }
140

    
141
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
142

    
143
        int points = group.size();
144

    
145
        double step = 2 * Math.PI / points;
146
        int i = 0;
147

    
148
        for (FeatureReference ref : group) {
149
            Feature feature = ref.getFeature().getCopy();
150
            buildFeature(feature,
151
                geomManager.createPoint(
152
                    center.getX() + (Math.cos(i * step) * this.scatterRadius),
153
                    center.getY() + (Math.sin(i * step) * this.scatterRadius),
154
                    SUBTYPES.GEOM2D));
155

    
156
            i++;
157
        }
158
    }
159

    
160
    /*
161
     * (non-Javadoc)
162
     *
163
     * @see
164
     * org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org
165
     * .gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
166
     */
167
    public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
168
        invoke(g, (Feature) feature);
169
    }
170

    
171
    /**
172
     * Builds a feature and adds it to the output file
173
     *
174
     * @param feat
175
     * @param value
176
     * @param g
177
     * @throws DataException
178
     */
179
    private void buildFeature(Feature feat, org.gvsig.fmap.geom.Geometry g) throws DataException {
180
        EditableFeature outFeat = persister.getOutputFeatureStore().createNewFeature(feat);
181
        
182
        try {
183
            persister.addFeature(outFeat, g);
184
        } catch (CreateGeometryException e) {
185
            Sextante.addErrorToLog(e);
186
        }
187
    }
188
}