root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / lighting / fresnelLos / FresnelLOSAlgorithm.java @ 59
History | View | Annotate | Download (7.26 KB)
1 |
package es.unex.sextante.lighting.fresnelLos; |
---|---|
2 |
|
3 |
import java.awt.geom.Point2D; |
4 |
|
5 |
import org.jfree.chart.ChartFactory; |
6 |
import org.jfree.chart.ChartPanel; |
7 |
import org.jfree.chart.JFreeChart; |
8 |
import org.jfree.chart.plot.PlotOrientation; |
9 |
import org.jfree.data.xy.XYSeries; |
10 |
import org.jfree.data.xy.XYSeriesCollection; |
11 |
|
12 |
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue; |
13 |
import es.unex.sextante.core.AnalysisExtent; |
14 |
import es.unex.sextante.core.GeoAlgorithm; |
15 |
import es.unex.sextante.core.Sextante; |
16 |
import es.unex.sextante.dataObjects.IRasterLayer; |
17 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
18 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
19 |
import es.unex.sextante.rasterWrappers.GridCell; |
20 |
|
21 |
public class FresnelLOSAlgorithm |
22 |
extends
|
23 |
GeoAlgorithm { |
24 |
|
25 |
public static final String DEM = "DEM"; |
26 |
public static final String POINT = "POINT"; |
27 |
public static final String POINT2 = "POINT2"; |
28 |
public static final String HEIGHT = "HEIGHT"; |
29 |
public static final String HEIGHT2 = "HEIGHT2"; |
30 |
public static final String GRAPH = "GRAPH"; |
31 |
public static final String LAMBDA = "LAMBDA"; |
32 |
|
33 |
private IRasterLayer m_DEM = null; |
34 |
private GridCell m_Point, m_Point2;
|
35 |
private double m_dHeight, m_dHeight2; |
36 |
private final XYSeriesCollection m_Dataset = new XYSeriesCollection(); |
37 |
private double m_dFrequency; |
38 |
|
39 |
|
40 |
@Override
|
41 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
42 |
|
43 |
m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM); |
44 |
final Point2D pt = m_Parameters.getParameterValueAsPoint(POINT); |
45 |
final Point2D pt2 = m_Parameters.getParameterValueAsPoint(POINT2); |
46 |
m_dHeight = m_Parameters.getParameterValueAsDouble(HEIGHT); |
47 |
m_dHeight2 = m_Parameters.getParameterValueAsDouble(HEIGHT2); |
48 |
m_dFrequency = m_Parameters.getParameterValueAsDouble(LAMBDA); |
49 |
|
50 |
final AnalysisExtent ge = new AnalysisExtent(m_DEM); |
51 |
m_Point = ge.getGridCoordsFromWorldCoords(pt); |
52 |
m_Point2 = ge.getGridCoordsFromWorldCoords(pt2); |
53 |
|
54 |
final double x = ge.getXMin() + m_Point.getX() * ge.getCellSize(); |
55 |
final double y = ge.getYMax() - m_Point.getY() * ge.getCellSize(); |
56 |
final double x2 = ge.getXMin() + m_Point2.getX() * ge.getCellSize(); |
57 |
final double y2 = ge.getYMax() - m_Point2.getY() * ge.getCellSize(); |
58 |
|
59 |
ge.setXRange(x, x2, true);
|
60 |
ge.setYRange(y, y2, true);
|
61 |
ge.enlargeOneCell(); |
62 |
|
63 |
m_Point = ge.getGridCoordsFromWorldCoords(pt); |
64 |
m_Point2 = ge.getGridCoordsFromWorldCoords(pt2); |
65 |
|
66 |
m_DEM.setWindowExtent(ge); |
67 |
|
68 |
calculateLOS(m_Point.getX(), m_Point.getY(), m_Point2.getX(), m_Point2.getY()); |
69 |
|
70 |
return !m_Task.isCanceled();
|
71 |
|
72 |
} |
73 |
|
74 |
|
75 |
@Override
|
76 |
public void defineCharacteristics() { |
77 |
|
78 |
try {
|
79 |
m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true); |
80 |
m_Parameters.addPoint(POINT, Sextante.getText("point") + " 1"); |
81 |
m_Parameters.addPoint(POINT2, Sextante.getText("point") + " 2"); |
82 |
m_Parameters.addNumericalValue(HEIGHT, Sextante.getText("Height_of_point") + " 1", 0, |
83 |
AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE); |
84 |
m_Parameters.addNumericalValue(HEIGHT2, Sextante.getText("Height_of_point") + " 2", 0, |
85 |
AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE); |
86 |
m_Parameters.addNumericalValue(LAMBDA, Sextante.getText("Wavelength"),
|
87 |
AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 0, 0, Double.MAX_VALUE); |
88 |
|
89 |
addOutputChart(GRAPH, Sextante.getText("Line_of_sight"));
|
90 |
} |
91 |
catch (final RepeatedParameterNameException e) { |
92 |
Sextante.addErrorToLog(e); |
93 |
} |
94 |
|
95 |
setName(Sextante.getText("RF_Line_of_sight"));
|
96 |
setGroup(Sextante.getText("Visibility_and_lighting"));
|
97 |
|
98 |
} |
99 |
|
100 |
|
101 |
private void calculateLOS(int x, |
102 |
int y,
|
103 |
final int x2, |
104 |
final int y2) { |
105 |
|
106 |
double dx, dy;
|
107 |
double ix, iy, id, d, dist, z;
|
108 |
double dHeight, dHeight2;
|
109 |
double dAngle;
|
110 |
final XYSeries serie = new XYSeries(""); |
111 |
final XYSeries fresnelSerie = new XYSeries(""); |
112 |
final XYSeries straightlineSerie = new XYSeries(""); |
113 |
|
114 |
m_Dataset.addSeries(serie); |
115 |
m_Dataset.addSeries(straightlineSerie); |
116 |
m_Dataset.addSeries(fresnelSerie); |
117 |
|
118 |
dx = x2 - x; |
119 |
dy = y2 - y; |
120 |
|
121 |
d = Math.abs(dx) > Math.abs(dy) ? Math.abs(dx) : Math.abs(dy); |
122 |
|
123 |
if (d > 0) { |
124 |
dist = Math.sqrt(dx * dx + dy * dy);
|
125 |
|
126 |
dx /= d; |
127 |
dy /= d; |
128 |
|
129 |
d = dist / d; |
130 |
|
131 |
id = 0.0;
|
132 |
ix = x + 0.5;
|
133 |
iy = y + 0.5;
|
134 |
dHeight = m_DEM.getCellValueAsDouble(x, y); |
135 |
dHeight2 = m_DEM.getCellValueAsDouble(x2, y2); |
136 |
|
137 |
if (m_DEM.isNoDataValue(dHeight) || m_DEM.isNoDataValue(dHeight2)) {
|
138 |
return;
|
139 |
} |
140 |
|
141 |
dHeight += m_dHeight; |
142 |
dHeight2 += m_dHeight2; |
143 |
dAngle = Math.atan2(dHeight2 - dHeight, dist * m_DEM.getWindowCellSize());
|
144 |
|
145 |
straightlineSerie.add(0, dHeight);
|
146 |
straightlineSerie.add(dist * m_DEM.getWindowCellSize(), dHeight2); |
147 |
fresnelSerie.add(0, dHeight);
|
148 |
|
149 |
while (id < dist) {
|
150 |
id += d; |
151 |
|
152 |
ix += dx; |
153 |
iy += dy; |
154 |
|
155 |
x = (int) ix;
|
156 |
y = (int) iy;
|
157 |
|
158 |
z = m_DEM.getCellValueAsDouble(x, y); |
159 |
if (!m_DEM.isNoDataValue(z)) {
|
160 |
serie.add(id * m_DEM.getWindowCellSize(), z); |
161 |
final double dDist = id * m_DEM.getWindowCellSize() / Math.cos(dAngle); |
162 |
final double dDist2 = (dist - id) * m_DEM.getWindowCellSize() / Math.cos(dAngle); |
163 |
final Point2D pt = getFresnelZone(dDist, dDist2, dAngle, dHeight); |
164 |
if (!Double.isNaN(pt.getX()) && !Double.isNaN(pt.getY())) { |
165 |
fresnelSerie.add(pt.getX(), pt.getY()); |
166 |
} |
167 |
} |
168 |
} |
169 |
fresnelSerie.add(dist * m_DEM.getWindowCellSize(), dHeight2); |
170 |
|
171 |
final JFreeChart chart = ChartFactory.createXYLineChart(null, null, null, m_Dataset, PlotOrientation.VERTICAL, false, |
172 |
true, true); |
173 |
|
174 |
final ChartPanel jPanelChart = new ChartPanel(chart); |
175 |
jPanelChart.setPreferredSize(new java.awt.Dimension(500, 300)); |
176 |
jPanelChart.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.gray, 1));
|
177 |
addOutputChart("GRAPH", Sextante.getText("Line_of_sight"), jPanelChart); |
178 |
} |
179 |
|
180 |
} |
181 |
|
182 |
|
183 |
private Point2D getFresnelZone(final double dDist, |
184 |
final double dDist2, |
185 |
final double dAngle, |
186 |
final double dHeight) { |
187 |
|
188 |
final double dRadius = Math.sqrt(m_dFrequency * (dDist * dDist2) / (dDist + dDist2)); |
189 |
double y = dHeight + dDist * Math.sin(dAngle); |
190 |
double x = dDist * Math.cos(dAngle); |
191 |
|
192 |
x += (dRadius * Math.sin(dAngle));
|
193 |
y -= (dRadius * Math.cos(dAngle));
|
194 |
|
195 |
System.out.println(dRadius);
|
196 |
|
197 |
|
198 |
return new Point2D.Double(x, y); |
199 |
|
200 |
} |
201 |
|
202 |
} |