Revision 43

View differences:

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

  
23
import java.util.ArrayList;
24
import java.util.Stack;
25

  
26
import org.gvsig.fmap.dal.exception.DataException;
27
import org.gvsig.fmap.dal.feature.EditableFeature;
28
import org.gvsig.fmap.dal.feature.Feature;
29
import org.gvsig.fmap.geom.exception.CreateGeometryException;
30
import org.gvsig.sextante.app.algorithm.base.util.GeometryUtil;
31
import org.gvsig.sextante.app.algorithm.base.util.JTSFacade;
32
import org.gvsig.sextante.app.extension.core.MapTools;
33

  
34
import com.vividsolutions.jts.geom.Geometry;
35
import com.vividsolutions.jts.geom.GeometryCollection;
36
import com.vividsolutions.jts.geom.GeometryFactory;
37
import com.vividsolutions.jts.geom.MultiPolygon;
38
import com.vividsolutions.jts.geom.Polygon;
39
import com.vividsolutions.jts.operation.buffer.BufferOp;
40
import com.vividsolutions.jts.operation.buffer.BufferParameters;
41

  
42
import es.unex.sextante.core.Sextante;
43
import es.unex.sextante.dataObjects.IVectorLayer;
44

  
45
/**
46
 * Buffer operation
47
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
48
 */
49
public class InOutBufferOperation extends BufferOperation {
50

  
51
	/**
52
	 * Builds an instance of this operation.
53
	 * @param distance
54
	 * @param layer
55
	 * @param userDistance
56
	 */
57
	public InOutBufferOperation(IDistance distance, IVectorLayer layer, double userDistance) {
58
		super(distance, layer, userDistance);
59
	}
60
	
61
	/*
62
	 * (non-Javadoc)
63
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
64
	 */
65
	@SuppressWarnings("unchecked")
66
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
67
		GeometryFactory geomFact = new GeometryFactory();
68
		Geometry newGeom = null;
69
		Geometry previousExteriorRing = null;
70
		Geometry previousInteriorRing = null;
71
		Geometry inputParam = GeometryUtil.geomToJTS(g);
72
		distance.setFeature(feature);
73
		double bufferDistance = distance.getBufferDistance(userDistance, projection, MapTools.getDistanceUnits(), MapTools.getMapUnits());
74
		
75
		for(int i = 1; i <= numberOfRadialBuffers; i++) {
76
			double distRing = i * bufferDistance;
77
			BufferOp bufOp = new BufferOp(inputParam);
78
			bufOp.setEndCapStyle(capBuffer == CAP_ROUND ? BufferParameters.CAP_ROUND : BufferParameters.CAP_SQUARE);
79
			Geometry out = bufOp.getResultGeometry(distRing);
80
			Geometry in = bufOp.getResultGeometry(-1 * distRing);
81
			boolean collapsedInterior = verifyNilGeometry(in);
82
			if(previousExteriorRing == null || previousInteriorRing == null){
83
				if(collapsedInterior)
84
					newGeom = out;
85
				else
86
					newGeom = JTSFacade.difference(out, in);
87
			} else {
88
				if(collapsedInterior) 
89
					newGeom = JTSFacade.difference(out, previousExteriorRing);
90
				else {
91
					Geometry outRing = JTSFacade.difference(out, previousExteriorRing);
92
					Geometry inRing = JTSFacade.difference(previousInteriorRing, in);
93
					
94
					Geometry[] geomArray = new Geometry[]{outRing, inRing};
95
					newGeom = geomFact.createGeometryCollection(geomArray);
96
					
97
					//FMap doesnt work with GeometryCollection, so we try to pass to a MultiPolygon.
98
					ArrayList polygons = new ArrayList();
99
					Stack stack = new Stack();
100
					stack.push(newGeom);
101
					while(stack.size() != 0) {
102
						GeometryCollection geCol = (GeometryCollection) stack.pop();
103
						
104
						for(int j = 0; j < geCol.getNumGeometries(); j++) {
105
							Geometry geometry = geCol.getGeometryN(j);
106
							if(geometry instanceof GeometryCollection)
107
								stack.push(geometry);
108
							if(geometry instanceof Polygon)
109
								polygons.add(geometry);
110
						}
111
					}
112
					
113
					Polygon[] pols = new Polygon[polygons.size()];
114
					polygons.toArray(pols);
115
					MultiPolygon newSolution = geomFact.createMultiPolygon(pols);
116
					newGeom = newSolution;
117
				}
118
			}
119
			try {
120
				lastEditFeature = persister.addFeature(feature, newGeom);
121
			} catch (CreateGeometryException e) {
122
				Sextante.addErrorToLog(e);
123
			} catch (DataException e) {
124
				Sextante.addErrorToLog(e);
125
			}
126
			previousExteriorRing = out;
127
			if(!collapsedInterior)
128
				previousInteriorRing = in;
129
		}
130
		return lastEditFeature;
131
	}
132
	
133
	/*
134
	 * (non-Javadoc)
135
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
136
	 */
137
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
138
		invoke(g, (Feature)feature);
139
	}
140
}
0 141

  
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.buffer/src/main/java/org/gvsig/sextante/app/algorithm/buffer/BufferOperation.java
20 20
 */
21 21
package org.gvsig.sextante.app.algorithm.buffer;
22 22

  
23
import org.cresques.cts.IProjection;
23 24
import org.gvsig.fmap.dal.exception.DataException;
24 25
import org.gvsig.fmap.dal.feature.EditableFeature;
25 26
import org.gvsig.fmap.dal.feature.Feature;
26 27
import org.gvsig.fmap.dal.feature.FeatureStore;
28
import org.gvsig.fmap.geom.exception.CreateGeometryException;
27 29
import org.gvsig.sextante.app.algorithm.base.core.DALFeaturePersister;
28 30
import org.gvsig.sextante.app.algorithm.base.core.GeometryOperation;
31
import org.gvsig.sextante.app.algorithm.base.util.GeometryUtil;
29 32

  
33
import com.vividsolutions.jts.geom.Geometry;
34
import com.vividsolutions.jts.geom.GeometryCollection;
35

  
36
import es.unex.sextante.dataObjects.IVectorLayer;
37

  
30 38
/**
31 39
 * Buffer operation
32 40
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
33 41
 */
34
public class BufferOperation extends GeometryOperation {
35

  
36
	public BufferOperation() {
37

  
42
public abstract class BufferOperation extends GeometryOperation {	
43
	public static final byte CAP_SQUARE                   = 0;
44
	public static final byte CAP_ROUND                    = 1;
45
	
46
	protected byte           capBuffer                    = CAP_ROUND;
47
	protected int            numberOfRadialBuffers        = 1;
48
	protected IDistance      distance                     = null;
49
	
50
	protected IVectorLayer   layer                        = null;
51
	protected IProjection    projection                   = null;
52
	protected double         userDistance                 = 0D;
53
	
54
	public BufferOperation(IDistance distance, IVectorLayer layer, double userDistance) {
55
		this.distance = distance;
56
		this.layer = layer;
57
		this.projection = (IProjection)layer.getCRS();
58
		this.userDistance = userDistance;
38 59
	}
39 60
	
40 61
	/**
......
47 68
	}
48 69

  
49 70
	
50
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
51
		
52
		return lastEditFeature;
71
	/**
72
	 * Verifys if a geometry buffer is null.
73
	 * It is useful when you're working with internal buffers. If the internal
74
	 * buffer distance is greater than the geometry radius, the buffer result
75
	 * will be null.
76
	 *
77
	 * @param newGeometry
78
	 * @return
79
	 */
80
	protected boolean verifyNilGeometry(Geometry newGeometry){
81
		if(newGeometry instanceof GeometryCollection){
82
			if(((GeometryCollection)newGeometry).getNumGeometries() == 0){
83
				//we have collapsed initial geometry
84
				return true;
85
			}
86
		}
87
		return false;
53 88
	}
54 89
	
90
	/**
91
	 * Adds a new feature
92
	 * @param feature
93
	 * @param newGeom
94
	 * @throws CreateGeometryException
95
	 * @throws DataException
96
	 * @deprecated No es necesario porque no hay diferencia entre las llamadas entre ambos invoke
97
	 */
98
	protected void addFeature(Feature feature, Geometry newGeom) throws CreateGeometryException, DataException {
99
		if(!(feature instanceof EditableFeature)) 
100
			lastEditFeature = persister.addFeature(feature, newGeom);
101
		else {
102
			org.gvsig.fmap.geom.Geometry g = GeometryUtil.jtsToGeom(newGeom);
103
			persister.addGeometryToExistingFeature((EditableFeature)feature, g);
104
		}
105
	}
106

  
107
	/**
108
	 * Sets type of cap flag
109
	 * @param typeOfCap
110
	 */
111
	public void setTypeOfCap(byte typeOfCap) {
112
		capBuffer = typeOfCap;
113
	}
114

  
115
	/**
116
	 * Sets number of radial rings buffers
117
	 * @param number
118
	 */
119
	public void setNumberOfRadialBuffers(int number) {
120
		numberOfRadialBuffers = number;
121
	}
55 122
	
56
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
57
		
58
	}
59 123
}
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.buffer/src/main/java/org/gvsig/sextante/app/algorithm/buffer/FieldDistance.java
21 21
package org.gvsig.sextante.app.algorithm.buffer;
22 22

  
23 23
import org.cresques.cts.IProjection;
24
import org.gvsig.fmap.dal.feature.Feature;
25
import org.gvsig.sextante.app.extension.core.MapTools;
24 26

  
25 27
/**
26 28
 * Computes a constant size of each geometry built
27 29
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
28 30
 */
29 31
public class FieldDistance implements IDistance {
30

  
32
	private Feature        feature                   = null;
33
	private int            attributePosition         = 0;
34
	
35
	public FieldDistance(int attributePosition) {
36
		this.attributePosition = attributePosition;
37
	}
38
	
39
	public void setFeature(Feature feature) {
40
		this.feature = feature;
41
	}
42
	
31 43
	/*
32 44
	 * (non-Javadoc)
33 45
	 * @see org.gvsig.sextante.app.algorithm.buffer.IDistance#getBufferDistance(double, org.cresques.cts.IProjection, int, int)
34 46
	 */
35
	public double getBufferDistance(double distance, IProjection viewProj,
47
	public double getBufferDistance(double distance, IProjection projection,
36 48
			int distanceUnits, int mapUnits) {
37
		return 0;
49
		double attr = 0D;
50
		Object obj = feature.get(attributePosition);
51
		if(obj instanceof Double)
52
			attr = ((Double)obj).doubleValue();
53
		else if(obj instanceof Integer) 
54
			attr = ((Integer)obj).doubleValue();
55
		else if(obj instanceof Float) 
56
			attr = ((Float)obj).doubleValue();
57
		else return 0;
58
		
59
		return MapTools.getInInternalUnits(attr, projection, distanceUnits, mapUnits);
38 60
	}
39 61

  
40 62
}
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.buffer/src/main/java/org/gvsig/sextante/app/algorithm/buffer/BufferAlgorithm.java
20 20
 */
21 21
package org.gvsig.sextante.app.algorithm.buffer;
22 22

  
23
import org.gvsig.fmap.dal.exception.DataException;
24
import org.gvsig.fmap.dal.feature.FeatureSet;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import org.gvsig.fmap.dal.feature.FeatureType;
23 27
import org.gvsig.sextante.app.algorithm.base.panel.AlgorithmOutputPanel;
24 28
import org.gvsig.sextante.app.extension.core.gvGeoAlgorithm;
29
import org.gvsig.sextante.app.extension.core.gvVectorLayer;
25 30

  
26 31
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
27 32
import es.unex.sextante.core.Sextante;
......
72 77
			m_Parameters.addNumericalValue(DISTANCE, Sextante.getText("Distance"), 0, AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE);
73 78
			m_Parameters.addTableField(FIELD, Sextante.getText("Field"), "LAYER");
74 79
			m_Parameters.addBoolean(DISSOLVE, Sextante.getText("Dissolve_entities"), false);
75
			m_Parameters.addBoolean(ROUND_BORDER, Sextante.getText("Round_border"), false);
80
			m_Parameters.addBoolean(ROUND_BORDER, Sextante.getText("Round_border"), true);
76 81
			m_Parameters.addSelection(AREA, Sextante.getText("Builds_influence_area"), sOptions);
77 82
			m_Parameters.addSelection(RING_NUMBER, Sextante.getText("Number_of_rings"), new String[]{"1", "2", "3"});
78 83
			setExternalParameters((Object)new AlgorithmOutputPanel());
......
93 98
	 * @see es.unex.sextante.core.GeoAlgorithm#processAlgorithm()
94 99
	 */
95 100
	public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
101
		IVectorLayer layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
102
		boolean selectedGeom = m_Parameters.getParameter(SELECTED_GEOM).getParameterValueAsBoolean();
103
		double dist = m_Parameters.getParameter(DISTANCE).getParameterValueAsDouble();
104
		int attributePosition = m_Parameters.getParameterValueAsInt(FIELD);
105
		boolean dissolve = m_Parameters.getParameter(DISSOLVE).getParameterValueAsBoolean();
106
		boolean round_border = m_Parameters.getParameter(ROUND_BORDER).getParameterValueAsBoolean();
107
		int inflArea = m_Parameters.getParameterValueAsInt(AREA);
108
		int rings = m_Parameters.getParameterValueAsInt(RING_NUMBER);
96 109
		
110
		FeatureStore storeLayer = null;
111
		if(layer instanceof gvVectorLayer)
112
			storeLayer = ((gvVectorLayer)layer).getFeatureStore();
113
		else
114
			return false;
115
		
116
		try {
117
			FeatureSet features = null;
118
			features = storeLayer.getFeatureSet();
119
			FeatureType featureType = features.getDefaultFeatureType();
120

  
121
			//Object to compute the distance
122
			IDistance distance = null;
123
			if(dist == 0)
124
				distance = new FieldDistance(attributePosition);
125
			else 
126
				distance = new ConstantDistance();
127

  
128
			//Object to compute the buffer operation
129
			BufferOperation operation = null;
130
			switch (inflArea) {
131
			case 0:
132
				operation = new OutBufferOperation(distance, layer, dist);
133
				break;
134
			case 1:
135
				operation = new InBufferOperation(distance, layer, dist);
136
				break;
137
			case 2:
138
				operation = new InOutBufferOperation(distance, layer, dist);
139
				break;
140
			}
141
			operation.setTypeOfCap(round_border ? BufferOperation.CAP_ROUND : BufferOperation.CAP_SQUARE);
142
			operation.setNumberOfRadialBuffers(rings + 1);
143

  
144
			//Builds the output FeatureStore
145
			FeatureStore outFeatStore = buildOutPutStore(featureType, org.gvsig.fmap.geom.Geometry.TYPES.SURFACE, Sextante.getText("Buffer"), RESULT);
146

  
147
			//Computes the operation
148
			operation.computesGeometryOperation(storeLayer, outFeatStore, attrNames, selectedGeom, true);
149
		} catch (DataException e) {
150
			Sextante.addErrorToLog(e);
151
			return false;
152
		}
153

  
154
		if(dissolve) {
155
			//TODO: Dissolve operation
156
		}
157

  
97 158
		return true;
98 159
	}
99 160

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

  
23
import org.gvsig.fmap.dal.exception.DataException;
24
import org.gvsig.fmap.dal.feature.EditableFeature;
25
import org.gvsig.fmap.dal.feature.Feature;
26
import org.gvsig.fmap.geom.exception.CreateGeometryException;
27
import org.gvsig.sextante.app.algorithm.base.util.GeometryUtil;
28
import org.gvsig.sextante.app.algorithm.base.util.JTSFacade;
29
import org.gvsig.sextante.app.extension.core.MapTools;
30

  
31
import com.vividsolutions.jts.geom.Geometry;
32
import com.vividsolutions.jts.operation.buffer.BufferOp;
33
import com.vividsolutions.jts.operation.buffer.BufferParameters;
34

  
35
import es.unex.sextante.core.Sextante;
36
import es.unex.sextante.dataObjects.IVectorLayer;
37

  
38
/**
39
 * Buffer operation
40
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
41
 */
42
public class InBufferOperation extends BufferOperation {
43
	
44
	/**
45
	 * Builds an instance of this operation.
46
	 * @param distance
47
	 * @param layer
48
	 * @param userDistance
49
	 */
50
	public InBufferOperation(IDistance distance, IVectorLayer layer, double userDistance) {
51
		super(distance, layer, userDistance);
52
	}
53
	
54
	/*
55
	 * (non-Javadoc)
56
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
57
	 */
58
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
59
		//if we have radial internal buffers, we start by most interior buffer
60
		Geometry newGeom = null;
61
		Geometry previousInteriorRing = null;
62
		Geometry inputParam = GeometryUtil.geomToJTS(g);
63
		distance.setFeature(feature);
64
		double bufferDistance = distance.getBufferDistance(userDistance, projection, MapTools.getDistanceUnits(), MapTools.getMapUnits());
65
		
66
		for(int i = numberOfRadialBuffers; i >= 1; i--) {
67
			double distRing = i * bufferDistance;
68
			BufferOp bufOp = new BufferOp(inputParam);
69
			bufOp.setEndCapStyle(capBuffer == CAP_ROUND ? BufferParameters.CAP_ROUND : BufferParameters.CAP_SQUARE);
70
			Geometry newGeometry = bufOp.getResultGeometry(-1 * distRing);
71
			
72
			if(verifyNilGeometry(newGeometry))
73
				return lastEditFeature;
74
			
75
			if(previousInteriorRing != null)
76
				newGeom = JTSFacade.difference(newGeometry, previousInteriorRing);
77
			else
78
				newGeom = newGeometry;
79
			
80
			try {
81
				lastEditFeature = persister.addFeature(feature, newGeom);
82
			} catch (CreateGeometryException e) {
83
				Sextante.addErrorToLog(e);
84
			} catch (DataException e) {
85
				Sextante.addErrorToLog(e);
86
			}
87
		}
88
		return lastEditFeature;
89
	}
90
	
91
	/*
92
	 * (non-Javadoc)
93
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
94
	 */
95
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
96
		invoke(g, (Feature)feature);
97
	}
98
}
0 99

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

  
23
import org.gvsig.fmap.dal.exception.DataException;
24
import org.gvsig.fmap.dal.feature.EditableFeature;
25
import org.gvsig.fmap.dal.feature.Feature;
26
import org.gvsig.fmap.geom.exception.CreateGeometryException;
27
import org.gvsig.sextante.app.algorithm.base.util.GeometryUtil;
28
import org.gvsig.sextante.app.algorithm.base.util.JTSFacade;
29
import org.gvsig.sextante.app.extension.core.MapTools;
30

  
31
import com.vividsolutions.jts.geom.Geometry;
32
import com.vividsolutions.jts.operation.buffer.BufferOp;
33
import com.vividsolutions.jts.operation.buffer.BufferParameters;
34

  
35
import es.unex.sextante.core.Sextante;
36
import es.unex.sextante.dataObjects.IVectorLayer;
37

  
38
/**
39
 * Buffer operation
40
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
41
 */
42
public class OutBufferOperation extends BufferOperation {
43

  
44
	/**
45
	 * Builds an instance of this operation.
46
	 * @param distance
47
	 * @param layer
48
	 * @param userDistance
49
	 */
50
	public OutBufferOperation(IDistance distance, IVectorLayer layer, double userDistance) {
51
		super(distance, layer, userDistance);
52
	}
53

  
54
	/*
55
	 * (non-Javadoc)
56
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
57
	 */
58
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
59
		Geometry newGeom = null;
60
		Geometry previousExteriorRing = null;
61
		Geometry inputParam = GeometryUtil.geomToJTS(g);
62
		distance.setFeature(feature);
63
		double bufferDistance = distance.getBufferDistance(userDistance, projection, MapTools.getDistanceUnits(), MapTools.getMapUnits());
64
		
65
		for(int i = 1; i <= numberOfRadialBuffers; i++) {
66
			double distRing = i * bufferDistance;
67
			BufferOp bufOp = new BufferOp(inputParam);
68
			bufOp.setEndCapStyle(capBuffer == CAP_ROUND ? BufferParameters.CAP_ROUND : BufferParameters.CAP_SQUARE);
69
			Geometry newGeometry = bufOp.getResultGeometry(distRing);
70
			if(previousExteriorRing != null) 
71
				newGeom = JTSFacade.difference(newGeometry, previousExteriorRing);
72
			else
73
				newGeom = newGeometry;
74
			
75
			try {
76
				lastEditFeature = persister.addFeature(feature, newGeom);
77
			} catch (CreateGeometryException e) {
78
				Sextante.addErrorToLog(e);
79
			} catch (DataException e) {
80
				Sextante.addErrorToLog(e);
81
			}
82
		}
83
		return lastEditFeature;
84
	}
85
	
86
	/*
87
	 * (non-Javadoc)
88
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
89
	 */
90
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
91
		invoke(g, (Feature)feature);
92
	}
93
}
0 94

  
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.buffer/src/main/java/org/gvsig/sextante/app/algorithm/buffer/IDistance.java
21 21
package org.gvsig.sextante.app.algorithm.buffer;
22 22

  
23 23
import org.cresques.cts.IProjection;
24
import org.gvsig.fmap.dal.feature.Feature;
24 25

  
25 26
/**
26 27
 * Computes a size of each geometry built
......
29 30
public interface IDistance {
30 31
	
31 32
	/**
33
	 * Sets the current feature
34
	 * @param feature
35
	 */
36
	public void setFeature(Feature feature);
37
	
38
	/**
32 39
	 * Gets the distance using the specific method
33 40
	 * @param distance
34 41
	 *        distace 
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.buffer/src/main/java/org/gvsig/sextante/app/algorithm/buffer/ConstantDistance.java
21 21
package org.gvsig.sextante.app.algorithm.buffer;
22 22

  
23 23
import org.cresques.cts.IProjection;
24
import org.gvsig.fmap.dal.feature.Feature;
25
import org.gvsig.sextante.app.extension.core.MapTools;
24 26

  
25 27
/**
26 28
 * Computes a constant size of each geometry built
......
32 34
	 * (non-Javadoc)
33 35
	 * @see org.gvsig.sextante.app.algorithm.buffer.IDistance#getBufferDistance(double, org.cresques.cts.IProjection, int, int)
34 36
	 */
35
	public double getBufferDistance(double distance, IProjection viewProj,
37
	public double getBufferDistance(double distance, IProjection projection,
36 38
			int distanceUnits, int mapUnits) {
37
		return 0;
39
		return MapTools.getInInternalUnits(distance, projection, distanceUnits, mapUnits);
38 40
	}
39 41

  
42
	public void setFeature(Feature feature) {
43
	}
44

  
40 45
}
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.buffer/pom.xml
18 18
   			<artifactId>org.gvsig.sextante.app.algorithm.base</artifactId>
19 19
   			<version>0.55.0-SNAPSHOT</version>
20 20
   		</dependency>
21
   		<dependency>
22
		    <groupId>org.gvsig</groupId>
23
   			<artifactId>org.gvsig.sextante.app.algorithm.dissolve</artifactId>
24
   			<version>0.55.0-SNAPSHOT</version>
25
   		</dependency>
21 26
	</dependencies>
22 27
</project>
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.base/src/main/java/org/gvsig/sextante/app/algorithm/base/util/UnitUtils.java
1
/*
2
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2010 Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 */
21
package org.gvsig.sextante.app.algorithm.base.util;
22

  
23
import org.cresques.cts.IProjection;
24
import org.gvsig.fmap.mapcontext.MapContext;
25

  
26
/**
27
 * Utility methods to manage distances
28
 * (conversion from user entries to internal units,
29
 * verifying if projection is planar or we are
30
 * working with geographic coordinates, etc.)
31
 * @author azabala
32
 *
33
 */
34
public class UnitUtils {
35

  
36
	public static final double EARTH_RADIUS = 6378137d;
37

  
38
	/**
39
	 * For computing with geodetic coordinates:
40
	 * returns the angular measure (in radians)
41
	 * for a distance over the earth along a
42
	 * meridiam.
43
	 * Because this consideration is an approximation,
44
	 * we consideer the eart like an sphere (not an
45
	 * ellipsoid)
46
	 * @param dist distance in meters
47
	 * @return arc of meridian whose length is the specified
48
	 * distance
49
	 */
50
	public static double toSexaAngularMeasure(double dist) {
51
		/*
52
		 *  dist = 6378km(terrestrial radius) -> 2PI
53
		 *  passed distance -> incognite
54
		 */
55
		return Math.toDegrees((2 * Math.PI * dist)/EARTH_RADIUS);
56
	}
57

  
58
	/**
59
	 * Converts a distance entered by user in the GUI in the same distance
60
	 * in internal units (measure units)
61
	 *
62
	 * */
63
	public static double getInInternalUnits(double userEntryDistance,
64
													IProjection proj,
65
													int distanceUnits,
66
													int mapUnits) {
67
		// VCN he modificado esto a como creo que deber?a de estar,
68
		//as? tiene en cuenta para calcular la distancia tanto las unidades
69
		//en las que se encuentra la cartograf?a como las unidades de medida
70
		//seleccionadas por el usuario.
71
		double[] trans2Meter = MapContext.getDistanceTrans2Meter();
72
		double distInInternalUnits = (userEntryDistance/trans2Meter[mapUnits]) *
73
								trans2Meter[distanceUnits];
74

  
75
		//if layer's projections is in geographics coords, pass distance to a angular measure
76

  
77
		if( (proj != null) && !(proj.isProjected())) {
78
			distInInternalUnits =
79
				UnitUtils.toSexaAngularMeasure(distInInternalUnits);
80
		}
81
		return distInInternalUnits;
82
	}
83
}
84

  
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.extension/src/main/java/org/gvsig/sextante/app/extension/core/MapTools.java
1
/*
2
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2010 Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 */
21
package org.gvsig.sextante.app.extension.core;
22

  
23
import org.cresques.cts.IProjection;
24
import org.gvsig.andami.PluginServices;
25
import org.gvsig.andami.ui.mdiManager.IWindow;
26
import org.gvsig.app.project.documents.view.gui.AbstractViewPanel;
27
import org.gvsig.fmap.mapcontext.MapContext;
28

  
29

  
30
/**
31
 * Map utilities
32
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
33
 */
34
public class MapTools {
35
	public static final double EARTH_RADIUS = 6378137d;
36
	
37
	/**
38
	 * For computing with geodetic coordinates:
39
	 * returns the angular measure (in radians)
40
	 * for a distance over the earth along a
41
	 * meridiam.
42
	 * Because this consideration is an approximation,
43
	 * we consideer the eart like an sphere (not an
44
	 * ellipsoid)
45
	 * @param dist distance in meters
46
	 * @return arc of meridian whose length is the specified
47
	 * distance
48
	 */
49
	public static double toSexaAngularMeasure(double dist) {
50
		/*
51
		 *  dist = 6378km(terrestrial radius) -> 2PI
52
		 *  passed distance -> incognite
53
		 */
54
		return Math.toDegrees((2 * Math.PI * dist) / EARTH_RADIUS);
55
	}
56

  
57
	/**
58
	 * Converts a distance entered by user in the GUI in the same distance
59
	 * in internal units (measure units)
60
	 *
61
	 * */
62
	public static double getInInternalUnits(double userEntryDistance,
63
													IProjection proj,
64
													int distanceUnits,
65
													int mapUnits) {
66
		double[] trans2Meter = MapContext.getDistanceTrans2Meter();
67
		double distInInternalUnits = (userEntryDistance/trans2Meter[mapUnits]) *
68
								trans2Meter[distanceUnits];
69

  
70
		if( (proj != null) && !(proj.isProjected())) 
71
			distInInternalUnits = toSexaAngularMeasure(distInInternalUnits);
72
		
73
		return distInInternalUnits;
74
	}
75
	
76
	/**
77
	 * <p>Gets the measurement unit used by this view port for the map.</p>
78
	 *
79
	 * @return Returns the current map measure unit
80
	 */
81
	public static int getMapUnits() {
82
		IWindow w = PluginServices.getMDIManager().getActiveWindow();
83
		if(!(w instanceof AbstractViewPanel)) {
84
			IWindow[] wList = PluginServices.getMDIManager().getAllWindows();
85
			for (int i = 0; i < wList.length; i++) {
86
				if(wList[i] instanceof AbstractViewPanel)
87
					w = (IWindow)wList[i];
88
			}
89
		}
90

  
91
		if(w != null && w instanceof AbstractViewPanel) {
92
			IProjection proj = ((AbstractViewPanel)w).getMapControl().getViewPort().getProjection();
93
			if(proj.isProjected())
94
				return ((AbstractViewPanel)w).getMapControl().getViewPort().getMapUnits();
95
		} 
96
		return 1;
97
	}
98
	
99
	/**
100
	 * <p>Returns the measurement unit of this view port used for measuring distances and displaying information.</p>
101
	 *
102
	 * @return the measurement unit of this view used for measuring distances and displaying information
103
	 */
104
	public static int getDistanceUnits() {
105
		IWindow w = PluginServices.getMDIManager().getActiveWindow();
106
		if(!(w instanceof AbstractViewPanel)) {
107
			IWindow[] wList = PluginServices.getMDIManager().getAllWindows();
108
			for (int i = 0; i < wList.length; i++) {
109
				if(wList[i] instanceof AbstractViewPanel)
110
					w = (IWindow)wList[i];
111
			}
112
		}
113
		
114
		if(w != null && w instanceof AbstractViewPanel)
115
			return ((AbstractViewPanel)w).getMapControl().getViewPort().getDistanceUnits();
116
		else 
117
			return 1;
118
	}
119
	
120
}
0 121

  

Also available in: Unified diff