Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.fmap.control / src / main / java / org / gvsig / fmap / mapcontrol / AreaAndPerimeterCalculator.java @ 43644

History | View | Annotate | Download (7.39 KB)

1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.fmap.mapcontrol;
7

    
8
import com.vividsolutions.jts.algorithm.CGAlgorithms;
9
import com.vividsolutions.jts.geom.Coordinate;
10
import com.vividsolutions.jts.geom.CoordinateList;
11
import java.awt.geom.PathIterator;
12
import java.awt.geom.Point2D;
13
import java.util.ArrayList;
14
import org.cresques.cts.GeoCalc;
15
import org.cresques.cts.IProjection;
16
import org.gvsig.fmap.geom.GeometryLocator;
17
import org.gvsig.fmap.geom.GeometryManager;
18
import org.gvsig.fmap.mapcontext.MapContext;
19

    
20
public class AreaAndPerimeterCalculator {
21

    
22
    public double perimeter(org.gvsig.fmap.geom.Geometry geom, IProjection proj, int distanceUnits) {
23
        ArrayList parts = getXY(geom);
24
        double perimeter = 0;
25
        for (int j = 0; j < parts.size(); j++) {
26
            Double[][] xsys = (Double[][]) parts.get(j);
27
            double dist;
28
            double distAll = 0;
29

    
30
            for (int i = 0; i < (xsys[0].length - 1); i++) {
31
                Point2D p = new Point2D.Double(xsys[0][i], xsys[1][i]);
32
                Point2D p2 = new Point2D.Double(xsys[0][i + 1], xsys[1][i + 1]);
33
                dist = distanceWorld(p, p2,proj,distanceUnits);
34
                distAll += dist;
35
            }
36
            perimeter += distAll / MapContext.getDistanceTrans2Meter()[distanceUnits];
37
        }
38
        return perimeter;        
39
    }
40
    
41
    public double area(org.gvsig.fmap.geom.Geometry geom, IProjection proj, int areaUnits) {
42
        ArrayList parts = getXY(geom);
43
        double area = 0;
44
        for( int i = 0; i < parts.size(); i++ ) {
45
            Double[][] xsys = (Double[][]) parts.get(i);
46
            Double[] xs = xsys[0];
47
            Double[] ys = xsys[1];
48
            if( isCCW(xs, ys) ) {
49
                if( proj.isProjected() ) {
50
                    area -= returnCoordsArea(
51
                        xs,
52
                        ys,
53
                        new Point2D.Double(xs[xs.length - 1], ys[ys.length - 1]),
54
                        areaUnits
55
                    );
56
                } else {
57
                    area -= returnGeoCArea(xs, ys);
58
                }
59
            } else {
60
                if( proj.isProjected() ) {
61
                    area += returnCoordsArea(
62
                        xs,
63
                        ys,
64
                        new Point2D.Double(xs[xs.length - 1], ys[ys.length - 1]),
65
                        areaUnits
66
                    );
67
                } else {
68
                    area += returnGeoCArea(xs, ys);
69
                }
70
            }
71
        }
72
        return area;
73
    }
74

    
75
    public double distanceWorld(Point2D pt1, Point2D pt2, IProjection proj, int distanceUnits) {
76

    
77
      double dist;
78
      if (proj.isProjected()) {
79
        dist = pt1.distance(pt2);
80
        dist = dist * MapContext.getDistanceTrans2Meter()[distanceUnits];
81
      }
82
      else {
83
        GeoCalc geocalc = new GeoCalc(proj);
84
        dist = geocalc.distanceVincenty(pt1, pt2);
85
      }
86
      return dist;
87
    }
88

    
89
    public boolean isCCW(Double[] xs, Double[] ys) {
90
        CoordinateList coordList = new CoordinateList();
91
        for( int i = 0; i < ys.length; i++ ) {
92
            Coordinate coord = new Coordinate(xs[i], ys[i]);
93
            coordList.add(coord);
94
        }
95
        if( coordList.isEmpty() ) {
96
            return true;
97
        }
98
        return CGAlgorithms.isCCW(coordList.toCoordinateArray());
99
    }
100

    
101
    private double returnGeoCArea(Double[] xs, Double[] ys) {
102
        double[] lat = new double[xs.length];
103
        double[] lon = new double[xs.length];
104
        for( int K = 0; K < xs.length; K++ ) {
105
            lon[K] = xs[K] / org.gvsig.fmap.mapcontrol.tools.geo.Geo.Degree;
106
            lat[K] = ys[K] / org.gvsig.fmap.mapcontrol.tools.geo.Geo.Degree;
107
        }
108
        return (org.gvsig.fmap.mapcontrol.tools.geo.Geo.sphericalPolyArea(lat, lon, xs.length - 1) * org.gvsig.fmap.mapcontrol.tools.geo.Geo.SqM);
109
    }
110

    
111
    /**
112
     * Calcula el ?rea.
113
     *
114
     * @param xs
115
     * @param ys
116
     * @param point
117
     * @param areaUnits
118
     *
119
     * @return ?rea.
120
     */
121
    public double returnCoordsArea(Double[] xs, Double[] ys, Point2D point, int areaUnits) {
122
        Point2D aux = point;
123
        double elArea = 0.0;
124
        Point2D pPixel;
125
        Point2D p;// = new Point2D.Double();
126
        Point2D.Double pAnt = new Point2D.Double();
127
        for( int pos = 0; pos < xs.length - 1; pos++ ) {
128
            pPixel = new Point2D.Double(xs[pos], ys[pos]);
129
            p = pPixel;
130
            if( pos == 0 ) {
131
                pAnt.x = aux.getX();
132
                pAnt.y = aux.getY();
133
            }
134
            elArea = elArea + ((pAnt.x - p.getX()) * (pAnt.y + p.getY()));
135
            pAnt.setLocation(p);
136
        }
137

    
138
        elArea = elArea + ((pAnt.x - aux.getX()) * (pAnt.y + aux.getY()));
139
        elArea = Math.abs(elArea / 2.0);
140
        return (elArea / (Math.pow(MapContext.getAreaTrans2Meter()[areaUnits], 2)));
141
    }
142

    
143
    public ArrayList getXY(org.gvsig.fmap.geom.Geometry geometry) {
144
        ArrayList xs = new ArrayList();
145
        ArrayList ys = new ArrayList();
146
        ArrayList parts = new ArrayList();
147
        double[] theData = new double[6];
148

    
149
        //double[] aux = new double[6];
150
        PathIterator theIterator;
151
        int theType;
152
        int numParts = 0;
153
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
154
        theIterator = geometry.getPathIterator(null, geomManager.getFlatness()); //, flatness);
155
        boolean isClosed = false;
156
        while( !theIterator.isDone() ) {
157
            theType = theIterator.currentSegment(theData);
158

    
159
            switch( theType ) {
160
            case PathIterator.SEG_MOVETO:
161
                if( numParts == 0 ) {
162
                    xs.add(theData[0]);
163
                    ys.add(theData[1]);
164
                } else {
165
                    if( !isClosed ) {
166
                        Double[] x = (Double[]) xs.toArray(new Double[0]);
167
                        Double[] y = (Double[]) ys.toArray(new Double[0]);
168
                        parts.add(new Double[][]{x,
169
                            y});
170
                        xs.clear();
171
                        ys.clear();
172
                    }
173
                    xs.add(theData[0]);
174
                    ys.add(theData[1]);
175
                }
176
                numParts++;
177
                isClosed = false;
178
                break;
179
            case PathIterator.SEG_LINETO:
180
                isClosed = false;
181
                xs.add(theData[0]);
182
                ys.add(theData[1]);
183
                break;
184
            case PathIterator.SEG_CLOSE:
185
                isClosed = true;
186
                xs.add(theData[0]);
187
                ys.add(theData[1]);
188
                Double[] x = (Double[]) xs.toArray(new Double[0]);
189
                Double[] y = (Double[]) ys.toArray(new Double[0]);
190
                parts.add(new Double[][]{x,
191
                    y});
192
                xs.clear();
193
                ys.clear();
194
                break;
195
            } //end switch
196

    
197
            theIterator.next();
198
        } //end while loop
199

    
200
        if( !isClosed ) {
201
//                isClosed=true;
202
            xs.add(theData[0]);
203
            ys.add(theData[1]);
204
            Double[] x = (Double[]) xs.toArray(new Double[0]);
205
            Double[] y = (Double[]) ys.toArray(new Double[0]);
206
            parts.add(new Double[][]{x,
207
                y});
208
            xs.clear();
209
            ys.clear();
210
        }
211
        return parts;
212

    
213
    }
214

    
215
}