root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridAnalysis / costInRoutes / CostInRoutesAlgorithm.java @ 59
History | View | Annotate | Download (5.51 KB)
1 | 59 | nbrodin | package es.unex.sextante.gridAnalysis.costInRoutes; |
---|---|---|---|
2 | |||
3 | |||
4 | import com.vividsolutions.jts.geom.Coordinate; |
||
5 | import com.vividsolutions.jts.geom.Geometry; |
||
6 | |||
7 | import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer; |
||
8 | import es.unex.sextante.core.GeoAlgorithm; |
||
9 | import es.unex.sextante.core.Sextante; |
||
10 | import es.unex.sextante.dataObjects.IFeature; |
||
11 | import es.unex.sextante.dataObjects.IFeatureIterator; |
||
12 | import es.unex.sextante.dataObjects.IRasterLayer; |
||
13 | import es.unex.sextante.dataObjects.IVectorLayer; |
||
14 | import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
||
15 | import es.unex.sextante.exceptions.RepeatedParameterNameException; |
||
16 | import es.unex.sextante.outputs.IOutputChannel; |
||
17 | import es.unex.sextante.outputs.Output; |
||
18 | import es.unex.sextante.outputs.OutputVectorLayer; |
||
19 | import es.unex.sextante.shapesTools.ShapesTools; |
||
20 | |||
21 | public class CostInRoutesAlgorithm |
||
22 | extends
|
||
23 | GeoAlgorithm { |
||
24 | |||
25 | public static final String ROUTES = "ROUTES"; |
||
26 | public static final String COST = "COST"; |
||
27 | public static final String RESULT = "RESULT"; |
||
28 | |||
29 | private IRasterLayer m_Cost;
|
||
30 | private double[] m_dDist; |
||
31 | private double[] m_dCost; |
||
32 | private double m_dLastX, m_dLastY; |
||
33 | private int m_iPoints = 0; |
||
34 | private int m_iCurrentRoute; |
||
35 | |||
36 | |||
37 | @Override
|
||
38 | public void defineCharacteristics() { |
||
39 | |||
40 | setName(Sextante.getText("Cost_for_predefined_routes"));
|
||
41 | setGroup(Sextante.getText("Cost_distances_and_routes"));
|
||
42 | setUserCanDefineAnalysisExtent(true);
|
||
43 | |||
44 | try {
|
||
45 | m_Parameters.addInputVectorLayer(ROUTES, Sextante.getText("Routes"), AdditionalInfoVectorLayer.SHAPE_TYPE_LINE, true); |
||
46 | m_Parameters.addInputRasterLayer(COST, Sextante.getText("Cost"), true); |
||
47 | addOutputVectorLayer(RESULT, Sextante.getText("Routes_and_cost"));
|
||
48 | } |
||
49 | catch (final RepeatedParameterNameException e) { |
||
50 | Sextante.addErrorToLog(e); |
||
51 | } |
||
52 | |||
53 | } |
||
54 | |||
55 | |||
56 | @Override
|
||
57 | public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
||
58 | |||
59 | final IVectorLayer routes = m_Parameters.getParameterValueAsVectorLayer(ROUTES);
|
||
60 | m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST); |
||
61 | |||
62 | if (routes.getShapesCount() == 0) { |
||
63 | return false; |
||
64 | } |
||
65 | |||
66 | final int iShapesCount = routes.getShapesCount(); |
||
67 | m_iCurrentRoute = 0;
|
||
68 | m_Cost.setFullExtent(); |
||
69 | m_dCost = new double[routes.getShapesCount()]; |
||
70 | m_dDist = new double[routes.getShapesCount()]; |
||
71 | final IFeatureIterator iter = routes.iterator();
|
||
72 | while (iter.hasNext() && setProgress(m_iCurrentRoute, iShapesCount)) {
|
||
73 | m_iPoints = 0;
|
||
74 | final IFeature feature = iter.next();
|
||
75 | final Geometry geom = feature.getGeometry();
|
||
76 | processLine(geom.getCoordinates()); |
||
77 | m_iCurrentRoute++; |
||
78 | } |
||
79 | iter.close(); |
||
80 | |||
81 | if (m_Task.isCanceled()) {
|
||
82 | return false; |
||
83 | } |
||
84 | |||
85 | final Object[][] values = new Object[2][routes.getShapesCount()]; |
||
86 | final String[] sFields = { Sextante.getText("Distance"), Sextante.getText("Cost") }; |
||
87 | final Class[] types = { Double.class, Double.class }; |
||
88 | for (int i = 0; i < routes.getShapesCount(); i++) { |
||
89 | values[0][i] = new Double(m_dDist[i]); |
||
90 | values[1][i] = new Double(m_dCost[i]); |
||
91 | } |
||
92 | final IOutputChannel channel = getOutputChannel(RESULT);
|
||
93 | final Output out = new OutputVectorLayer(); |
||
94 | out.setName(RESULT); |
||
95 | out.setDescription(Sextante.getText("Routes"));
|
||
96 | out.setOutputChannel(channel); |
||
97 | out.setOutputObject(ShapesTools.addFields(m_OutputFactory, routes, channel, sFields, values, types)); |
||
98 | addOutputObject(out); |
||
99 | |||
100 | return true; |
||
101 | |||
102 | } |
||
103 | |||
104 | |||
105 | private void processLine(final Coordinate coords[]) { |
||
106 | |||
107 | int i;
|
||
108 | double x, y, x2, y2;
|
||
109 | |||
110 | for (i = 0; i < coords.length - 1; i++) { |
||
111 | x = coords[i].x; |
||
112 | y = coords[i].y; |
||
113 | x2 = coords[i + 1].x;
|
||
114 | y2 = coords[i + 1].y;
|
||
115 | processSegment(x, y, x2, y2); |
||
116 | } |
||
117 | |||
118 | } |
||
119 | |||
120 | |||
121 | private void processSegment(double x, |
||
122 | double y,
|
||
123 | final double x2, |
||
124 | final double y2) { |
||
125 | |||
126 | double dx, dy, d, n;
|
||
127 | |||
128 | dx = Math.abs(x2 - x);
|
||
129 | dy = Math.abs(y2 - y);
|
||
130 | |||
131 | if ((dx > 0.0) || (dy > 0.0)) { |
||
132 | if (dx > dy) {
|
||
133 | dx /= m_Cost.getWindowCellSize(); |
||
134 | n = dx; |
||
135 | dy /= dx; |
||
136 | dx = m_Cost.getWindowCellSize(); |
||
137 | } |
||
138 | else {
|
||
139 | dy /= m_Cost.getWindowCellSize(); |
||
140 | n = dy; |
||
141 | dx /= dy; |
||
142 | dy = m_Cost.getWindowCellSize(); |
||
143 | } |
||
144 | |||
145 | if (x2 < x) {
|
||
146 | dx = -dx; |
||
147 | } |
||
148 | |||
149 | if (y2 < y) {
|
||
150 | dy = -dy; |
||
151 | } |
||
152 | |||
153 | for (d = 0.0; d <= n; d++, x += dx, y += dy) { |
||
154 | addPoint(x, y); |
||
155 | } |
||
156 | } |
||
157 | |||
158 | } |
||
159 | |||
160 | |||
161 | private void addPoint(final double x, |
||
162 | final double y) { |
||
163 | |||
164 | double dDX, dDY;
|
||
165 | |||
166 | final double z = m_Cost.getValueAt(x, y); |
||
167 | |||
168 | if (m_iPoints == 0) { |
||
169 | m_dDist[m_iCurrentRoute] = 0.0;
|
||
170 | m_dCost[m_iCurrentRoute] = 0.0;
|
||
171 | } |
||
172 | else {
|
||
173 | dDX = x - m_dLastX; |
||
174 | dDY = y - m_dLastY; |
||
175 | m_dDist[m_iCurrentRoute] += Math.sqrt(dDX * dDX + dDY * dDY);
|
||
176 | if (!m_Cost.isNoDataValue(z)) {
|
||
177 | m_dCost[m_iCurrentRoute] += z; |
||
178 | } |
||
179 | } |
||
180 | |||
181 | m_dLastX = x; |
||
182 | m_dLastY = y; |
||
183 | m_iPoints++; |
||
184 | |||
185 | } |
||
186 | |||
187 | } |