Statistics
| Revision:

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
}