Statistics
| Revision:

gvsig-geoprocess / org.gvsig.geoprocess / trunk / org.gvsig.geoprocess / org.gvsig.geoprocess.algorithm / org.gvsig.geoprocess.algorithm.spatialjoin / src / main / java / org / gvsig / geoprocess / algorithm / spatialjoin / SpatiallyIndexedSpatialJoinOperation.java @ 336

History | View | Annotate | Download (6.12 KB)

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

    
26
import java.util.Iterator;
27
import java.util.List;
28

    
29
import com.vividsolutions.jts.geom.Geometry;
30

    
31
import es.unex.sextante.core.Sextante;
32

    
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.EditableFeature;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureIndex;
37
import org.gvsig.fmap.dal.feature.FeatureIndexes;
38
import org.gvsig.fmap.dal.feature.FeatureSelection;
39
import org.gvsig.fmap.dal.feature.FeatureSet;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
42
import org.gvsig.fmap.geom.exception.CreateGeometryException;
43
import org.gvsig.fmap.geom.primitive.Envelope;
44
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
45
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
46
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
47
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
48
import org.gvsig.tools.dispose.DisposableIterator;
49

    
50
/**
51
 * 
52
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
53
 */
54
public class SpatiallyIndexedSpatialJoinOperation extends GeometryOperation {
55
        private FeatureStore               storeOverlay        = null;
56
        private FeatureSelection           featureSelection    = null;
57
        
58
        /**
59
         * Geometry.distance() is a costly operation. Thats the reason for we are
60
         * only using a nearest neighbor. TODO SpatialIndex works with Rectangle2D,
61
         * and this may be a simplification that drives to errors. Make additional
62
         * probes to use a number of default neighbors
63
         */
64
        static final int                  DEFAULT_NUM_NEIGBOURS = 1;
65

    
66
        /**
67
         * Number of neighbors that nearestFinder must found.
68
         */
69
        int                               numOfNeighbours       = DEFAULT_NUM_NEIGBOURS;
70

    
71
        /**
72
         * Specialized instance in nearest neighbor search.
73
         */
74
        private FeatureIndex              index                 = null;
75
        
76
        public SpatiallyIndexedSpatialJoinOperation(FlyrVectIVectorLayer targetLayer, String indexName, AbstractSextanteGeoProcess p) {
77
                super(p);
78
                FeatureIndexes indexes = targetLayer.getFeatureStore().getIndexes();
79
                index = indexes.getFeatureIndex(indexName);
80
                storeOverlay = targetLayer.getFeatureStore();
81
        }
82
        
83
        /*
84
         * (non-Javadoc)
85
         * @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
86
         */
87
        @SuppressWarnings({ "unchecked", "deprecation" })
88
        public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature featureInput) {
89
                if(g == null)
90
                        return lastEditFeature;
91
                
92
                if(featureSelection == null) {
93
                        try {
94
                                featureSelection = storeOverlay.getFeatureSelection();
95
                        } catch (DataException e1) {
96
                                //Sin selecci?n tiramos
97
                        }
98
                }
99

    
100
                try {
101
                        Geometry gJts = GeometryUtil.geomToJTS(g);
102
                        Envelope rect = g.getEnvelope();
103
                        FeatureSet featSet = index.getNearestFeatureSet(numOfNeighbours, rect);
104
                        double nearestDistance = Double.MAX_VALUE;
105

    
106
                        DisposableIterator it = featSet.iterator();
107
                        while(it.hasNext()) {
108
                                Feature feat = (Feature)it.next();
109
                                if( featureSelection != null && 
110
                                        !featureSelection.isEmpty() && 
111
                                        !featureSelection.isSelected(feat))
112
                                        continue;
113
                                List geomList = feat.getGeometries();
114

    
115
                                if(geomList == null) {
116
                                        org.gvsig.fmap.geom.Geometry g2 = feat.getDefaultGeometry();
117
                                        Geometry g2Jts = GeometryUtil.geomToJTS(g2);
118
                                        double dist = gJts.distance(g2Jts);
119
                                        if (dist <= nearestDistance) {
120
                                                nearestDistance = dist;
121
                                        }
122
                                        buildFeature(featureInput, feat, new Double(nearestDistance), g);
123
                                        continue;
124
                                }
125
                                
126
                                Iterator<org.gvsig.fmap.geom.Geometry> itGeom = geomList.iterator();
127
                                while(itGeom.hasNext()) {
128
                                        org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
129
                                        Geometry g2Jts = GeometryUtil.geomToJTS(g2);
130
                                        double dist = gJts.distance(g2Jts);
131
                                        if (dist <= nearestDistance) {
132
                                                nearestDistance = dist;
133
                                        }
134
                                    buildFeature(featureInput, feat, new Double(nearestDistance), g);
135
                                }
136
                        }
137
                        
138
                } catch(FeatureIndexException e) {
139
                        Sextante.addErrorToLog(e);
140
                } catch (DataException e) {
141
                        Sextante.addErrorToLog(e);
142
                }
143
                
144
                return lastEditFeature;
145
        }
146
        
147
        /**
148
         * Builds a feature and adds it to the output file
149
         * @param feat1
150
         * @param feat2
151
         * @param value
152
         * @param g
153
         * @throws DataException
154
         */
155
        private void buildFeature(Feature feat1, Feature feat2, Object value, org.gvsig.fmap.geom.Geometry g) throws DataException {
156
                EditableFeature outFeat = persister.getOutputFeatureStore().createNewFeature();
157
                int sizeFeat1 = feat1.getType().size() - 1;
158
                
159
                for (int i = 0; i < sizeFeat1; i++) 
160
                        outFeat.set(i, feat1.get(i));
161
                
162
                for (int i = sizeFeat1; i < sizeFeat1 + feat2.getType().size() - 1; i++) 
163
                        outFeat.set(i, feat2.get(i - sizeFeat1));
164
                
165
                outFeat.set(outFeat.getType().size() - 2, value);
166
                try {
167
                        persister.addFeature(outFeat, g);
168
                } catch (CreateGeometryException e) {
169
                        Sextante.addErrorToLog(e);
170
                }
171
        }
172

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

    
181
}