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 @ 962

History | View | Annotate | Download (6.76 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.util.ArrayList;
26
import java.util.Collection;
27
import java.util.HashSet;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.ListIterator;
31
import java.util.Set;
32

    
33
import es.unex.sextante.core.Sextante;
34

    
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.feature.EditableFeature;
37
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureReference;
39
import org.gvsig.fmap.geom.Geometry;
40
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
41
import org.gvsig.fmap.geom.GeometryLocator;
42
import org.gvsig.fmap.geom.GeometryManager;
43
import org.gvsig.fmap.geom.SpatialIndex;
44
import org.gvsig.fmap.geom.exception.CreateGeometryException;
45
import org.gvsig.fmap.geom.primitive.Point;
46
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
47
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
48

    
49
/**
50
 * Disperse points operation
51
 *
52
 * @author fdiaz</a>
53
 */
54
public class DispersePointsOperation extends GeometryOperation {
55

    
56
    private SpatialIndex index;
57
    private double scatterRadius;
58
    private double matchDistance;
59
    private List<Set<FeatureReference>> groups;
60

    
61
    /**
62
     * Builds an instance of this operation.
63
     *
64
     * @param index
65
     * @param scatterRadius
66
     * @param matchDistance
67
     * @param p
68
     *
69
     */
70
    public DispersePointsOperation(SpatialIndex index, double scatterRadius, double matchDistance,
71
        AbstractSextanteGeoProcess p) {
72
        super(p);
73
        this.index = index;
74
        this.scatterRadius = scatterRadius;
75
        this.matchDistance = matchDistance;
76
        this.groups = new ArrayList<Set<FeatureReference>>();
77

    
78
    }
79

    
80
    public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
81
        // final MutableObject<Feature> foundFeature = new
82
        // MutableObject<Feature>(null);
83
        boolean addedFeature = false;
84
        if (g == null)
85
            return lastEditFeature;
86

    
87
        try {
88

    
89
            FeatureReference reference = feature.getReference();
90
            if (!isVisited(reference)) {
91
                Set<FeatureReference> group = new HashSet<FeatureReference>();
92
                // Iterator<?> iterator = index.queryNearest(g);
93
                Iterator<?> iterator = index.query(g.buffer(matchDistance));
94
                while (iterator.hasNext()) {
95
                    FeatureReference ref = (FeatureReference) iterator.next();
96
                    if (!isVisited(ref)) {
97
                        Feature feat = ref.getFeature().getCopy();
98
                        Geometry g2 = feat.getDefaultGeometry();
99
                        double dist = g.distance(g2);
100
                        if (dist <= matchDistance) {
101
                            group.add(ref);
102
                        }
103
                    }
104
                }
105
                groups.add(group);
106
                if (group.size() == 1) {
107
                    buildFeature(feature, g);
108
                } else {
109
                    buildFeatures(group);
110
                }
111
            }
112

    
113
        } catch (Exception e) {
114
            Sextante.addErrorToLog(e);
115
        }
116

    
117
        return lastEditFeature;
118
    }
119

    
120
    /**
121
     * @param group
122
     * @throws DataException
123
     * @throws CreateGeometryException
124
     */
125
    private void buildFeatures(Set<FeatureReference> group) throws CreateGeometryException, DataException {
126
        if (group.isEmpty()) {
127
            return;
128
        }
129

    
130
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
131

    
132
        int points = group.size();
133
        Point center = getCenter(group);
134

    
135
        double step = 2 * Math.PI / points;
136
        int i = 0;
137

    
138
        for (FeatureReference ref : group) {
139
            Feature feature = ref.getFeature().getCopy();
140
            buildFeature(feature,
141
                geomManager.createPoint(
142
                    center.getX() + (Math.cos(i * step) * this.scatterRadius),
143
                    center.getY() + (Math.sin(i * step) * this.scatterRadius),
144
                    SUBTYPES.GEOM2D));
145

    
146
            i++;
147
        }
148
    }
149

    
150
    /**
151
     * @param group
152
     * @return
153
     * @throws DataException
154
     * @throws CreateGeometryException
155
     */
156
    private Point getCenter(Set<FeatureReference> group) throws DataException, CreateGeometryException {
157
        double x = 0;
158
        double y = 0;
159
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
160
        for (FeatureReference ref : group) {
161
            Point point = (Point) ref.getFeature().getDefaultGeometry();
162
            x += point.getX();
163
            y += point.getY();
164
        }
165
        int size = group.size();
166
        return geomManager.createPoint(x / size, y / size, SUBTYPES.GEOM2D);
167
    }
168

    
169
    /*
170
     * (non-Javadoc)
171
     *
172
     * @see
173
     * org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org
174
     * .gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
175
     */
176
    public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
177
        invoke(g, (Feature) feature);
178
    }
179

    
180
    /**
181
     * Builds a feature and adds it to the output file
182
     *
183
     * @param feat
184
     * @param value
185
     * @param g
186
     * @throws DataException
187
     */
188
    private void buildFeature(Feature feat, org.gvsig.fmap.geom.Geometry g) throws DataException {
189
        EditableFeature outFeat = persister.getOutputFeatureStore().createNewFeature();
190
        int sizeFeat = feat.getType().size() - 1;
191

    
192
        for (int i = 0; i < sizeFeat; i++)
193
            outFeat.set(i, feat.get(i));
194

    
195
        try {
196
            persister.addFeature(outFeat, g);
197
        } catch (CreateGeometryException e) {
198
            Sextante.addErrorToLog(e);
199
        }
200
    }
201

    
202
    private boolean isVisited(FeatureReference ref) {
203
        for (Set<FeatureReference> group : groups) {
204
            if (group.contains(ref)) {
205
                return true;
206
            }
207
        }
208
        return false;
209
    }
210
}