Ticket #11265: measure-areas.diff

File measure-areas.diff, 3.3 KB (added by me@…, 11 years ago)

Measure areas made by several adjacent ways

  • src/org/openstreetmap/josm/plugins/measurement/MeasurementDialog.java

    diff --git a/src/org/openstreetmap/josm/plugins/measurement/MeasurementDialog.java b/src/org/openstreetmap/josm/plugins/measurement/MeasurementDialog.java
    index 18eed7b..eed7529 100644
    a b import java.awt.event.KeyEvent;  
    1010import java.text.DecimalFormat;
    1111import java.util.Arrays;
    1212import java.util.Collection;
     13import java.util.Iterator;
    1314
    1415import javax.swing.AbstractAction;
    1516import javax.swing.JLabel;
    public class MeasurementDialog extends ToggleDialog implements SelectionChangedL  
    177178            }
    178179        } else {
    179180            nodes = null;
     181            Node areaStartNode = null;
     182            double wayArea = 0.0;
    180183            for (Way w : ways) {
    181                 Node lastN = null;
    182                 double wayArea = 0.0;
    183                 for (Node n: w.getNodes()) {
    184                     if (lastN != null && lastN.getCoor() != null && n.getCoor() != null) {
    185                         length += lastN.getCoor().greatCircleDistance(n.getCoor());
    186                         //http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
    187                         wayArea += (MeasurementLayer.calcX(n.getCoor()) * MeasurementLayer.calcY(lastN.getCoor()))
    188                                  - (MeasurementLayer.calcY(n.getCoor()) * MeasurementLayer.calcX(lastN.getCoor()));
    189                         segAngle = MeasurementLayer.angleBetween(lastN.getCoor(), n.getCoor());
     184                Iterator<Node> nIter = w.getNodes().iterator();
     185
     186                if(!nIter.hasNext()) {
     187                    // Empty way
     188                    continue;
     189                }
     190
     191                // First node of this way
     192                Node n = nIter.next();
     193                if (areaStartNode == null || n != lastNode) {
     194                    // Starting new possible area (none started, or this way not joined to last way)
     195                    areaStartNode = n;
     196                    wayArea = 0.0;
     197                }
     198                lastNode = n;
     199
     200                // Subsequent nodes
     201                while (nIter.hasNext()) {
     202                    n = nIter.next();
     203                    if (lastNode.getCoor() != null && n.getCoor() != null) {
     204                        length += lastNode.getCoor().greatCircleDistance(n.getCoor());
     205                        // http://www.mathopenref.com/coordpolygonarea2.html
     206                        wayArea += (MeasurementLayer.calcX(n.getCoor()) * MeasurementLayer.calcY(lastNode.getCoor()))
     207                                 - (MeasurementLayer.calcY(n.getCoor()) * MeasurementLayer.calcX(lastNode.getCoor()));
     208                        segAngle = MeasurementLayer.angleBetween(lastNode.getCoor(), n.getCoor());
    190209                    }
    191                     lastN = n;
     210                    lastNode = n;
     211                }
     212
     213                // Found closed loop
     214                if (lastNode != null && lastNode == areaStartNode) {
     215                    area += Math.abs(wayArea / 2);
     216                    areaStartNode = null;
    192217                }
    193                 if (lastN != null && lastN == w.getNodes().iterator().next())
    194                     wayArea = Math.abs(wayArea / 2);
    195                 else
    196                     wayArea = 0;
    197                 area += wayArea;
    198218            }
    199219        }
    200220