Statistics
| Revision:

gvsig-geoprocess / org.gvsig.sextante / trunk / org.gvsig.sextante.app / org.gvsig.sextante.app.algorithm / org.gvsig.sextante.app.algorithm.spatialjoin / src / main / java / org / gvsig / sextante / app / algorithm / spatialjoin / SpatiallyIndexedSpatialJoinOperation.java @ 172

History | View | Annotate | Download (5.29 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2010 Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.sextante.app.algorithm.spatialjoin;
20

    
21
import java.util.Iterator;
22
import java.util.List;
23

    
24
import com.vividsolutions.jts.geom.Geometry;
25

    
26
import es.unex.sextante.core.Sextante;
27

    
28
import org.gvsig.fmap.dal.exception.DataException;
29
import org.gvsig.fmap.dal.feature.EditableFeature;
30
import org.gvsig.fmap.dal.feature.Feature;
31
import org.gvsig.fmap.dal.feature.FeatureIndex;
32
import org.gvsig.fmap.dal.feature.FeatureIndexes;
33
import org.gvsig.fmap.dal.feature.FeatureSet;
34
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
35
import org.gvsig.fmap.geom.exception.CreateGeometryException;
36
import org.gvsig.fmap.geom.primitive.Envelope;
37
import org.gvsig.geoprocess.core.gvVectorLayer;
38
import org.gvsig.sextante.app.algorithm.base.core.GeometryOperation;
39
import org.gvsig.sextante.app.algorithm.base.util.GeometryUtil;
40
import org.gvsig.tools.dispose.DisposableIterator;
41

    
42
/**
43
 * 
44
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
45
 */
46
public class SpatiallyIndexedSpatialJoinOperation extends GeometryOperation {
47
        /**
48
         * Geometry.distance() is a costly operation. Thats the reason for we are
49
         * only using a nearest neighbor. TODO SpatialIndex works with Rectangle2D,
50
         * and this may be a simplification that drives to errors. Make additional
51
         * probes to use a number of default neighbors
52
         */
53
        static final int                  DEFAULT_NUM_NEIGBOURS = 1;
54

    
55
        /**
56
         * Number of neighbors that nearestFinder must found.
57
         */
58
        int                               numOfNeighbours       = DEFAULT_NUM_NEIGBOURS;
59

    
60
        /**
61
         * Specialized instance in nearest neighbor search.
62
         */
63
        private FeatureIndex              index                 = null;
64
        
65
        public SpatiallyIndexedSpatialJoinOperation(gvVectorLayer targetLayer, String indexName) {
66
                FeatureIndexes indexes = targetLayer.getFeatureStore().getIndexes();
67
                index = indexes.getFeatureIndex(indexName);
68
        }
69
        
70
        /*
71
         * (non-Javadoc)
72
         * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
73
         */
74
        @SuppressWarnings("unchecked")
75
        public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature featureInput) {
76
                if(g == null)
77
                        return lastEditFeature;
78

    
79
                try {
80
                        Geometry gJts = GeometryUtil.geomToJTS(g);
81
                        Envelope rect = g.getEnvelope();
82
                        FeatureSet featSet = index.getNearestFeatureSet(numOfNeighbours, rect);
83
                        double nearestDistance = Double.MAX_VALUE;
84

    
85
                        DisposableIterator it = featSet.iterator();
86
                        while(it.hasNext()) {
87
                                Feature feat = (Feature)it.next();
88
                                List geomList = feat.getGeometries();
89

    
90
                                if(geomList == null) {
91
                                        org.gvsig.fmap.geom.Geometry g2 = feat.getDefaultGeometry();
92
                                        Geometry g2Jts = GeometryUtil.geomToJTS(g2);
93
                                        double dist = gJts.distance(g2Jts);
94
                                        if (dist <= nearestDistance) {
95
                                                nearestDistance = dist;
96
                                        }
97
                                        buildFeature(featureInput, feat, new Double(nearestDistance), g);
98
                                        continue;
99
                                }
100
                                
101
                                Iterator<org.gvsig.fmap.geom.Geometry> itGeom = geomList.iterator();
102
                                while(itGeom.hasNext()) {
103
                                        org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
104
                                        Geometry g2Jts = GeometryUtil.geomToJTS(g2);
105
                                        double dist = gJts.distance(g2Jts);
106
                                        if (dist <= nearestDistance) {
107
                                                nearestDistance = dist;
108
                                        }
109
                                    buildFeature(featureInput, feat, new Double(nearestDistance), g);
110
                                }
111
                        }
112
                        
113
                } catch(FeatureIndexException e) {
114
                        Sextante.addErrorToLog(e);
115
                } catch (DataException e) {
116
                        Sextante.addErrorToLog(e);
117
                }
118
                
119
                return lastEditFeature;
120
        }
121
        
122
        /**
123
         * Builds a feature and adds it to the output file
124
         * @param feat1
125
         * @param feat2
126
         * @param value
127
         * @param g
128
         * @throws DataException
129
         */
130
        private void buildFeature(Feature feat1, Feature feat2, Object value, org.gvsig.fmap.geom.Geometry g) throws DataException {
131
                EditableFeature outFeat = persister.getOutputFeatureStore().createNewFeature();
132
                int sizeFeat1 = feat1.getType().size() - 1;
133
                
134
                for (int i = 0; i < sizeFeat1; i++) 
135
                        outFeat.set(i, feat1.get(i));
136
                
137
                for (int i = sizeFeat1; i < sizeFeat1 + feat2.getType().size() - 1; i++) 
138
                        outFeat.set(i, feat2.get(i - sizeFeat1));
139
                
140
                outFeat.set(outFeat.getType().size() - 2, value);
141
                try {
142
                        persister.addFeature(outFeat, g);
143
                } catch (CreateGeometryException e) {
144
                        Sextante.addErrorToLog(e);
145
                }
146
        }
147

    
148
        /*
149
         * (non-Javadoc)
150
         * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
151
         */
152
        public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature featureInput) {
153
                
154
        }
155

    
156
}