Ignore:
Timestamp:
2019-07-07T16:09:02+02:00 (5 years ago)
Author:
donvip
Message:

see #josm11265 - measure area of multipolygons

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/measurement/src/org/openstreetmap/josm/plugins/measurement/MeasurementDialog.java

    r34529 r35047  
    1111import java.util.Arrays;
    1212import java.util.Collection;
     13import java.util.Objects;
    1314
    1415import javax.swing.AbstractAction;
     
    2223import org.openstreetmap.josm.data.osm.Node;
    2324import org.openstreetmap.josm.data.osm.OsmPrimitive;
     25import org.openstreetmap.josm.data.osm.Relation;
    2426import org.openstreetmap.josm.data.osm.Way;
    2527import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
     
    3739import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
    3840import org.openstreetmap.josm.gui.help.HelpUtil;
     41import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
     42import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
     43import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
     44import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
     45import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3946import org.openstreetmap.josm.gui.util.GuiHelper;
     47import org.openstreetmap.josm.tools.Geometry;
    4048import org.openstreetmap.josm.tools.ImageProvider;
    4149import org.openstreetmap.josm.tools.Shortcut;
     
    4755 * @author ramack
    4856 */
    49 public class MeasurementDialog extends ToggleDialog implements DataSelectionListener, DataSetListener, SoMChangeListener {
     57public class MeasurementDialog extends ToggleDialog implements DataSelectionListener, DataSetListener, SoMChangeListener, LayerChangeListener {
    5058    private static final long serialVersionUID = 4708541586297950021L;
    5159
     
    8290    private DataSet ds;
    8391
     92    private Collection<Relation> relations;
    8493    private Collection<Way> ways;
    8594    private Collection<Node> nodes;
     
    143152        }));
    144153
     154        MainApplication.getLayerManager().addLayerChangeListener(this);
    145155        SelectionEventManager.getInstance().addSelectionListener(this);
    146156        SystemOfMeasurement.addSoMChangeListener(this);
     
    185195        if (ways.isEmpty()) {
    186196            nodes = new SubclassFilteredCollection<>(selection, Node.class::isInstance);
    187             for (Node n : nodes) {
    188                 if (n.getCoor() != null) {
    189                     if (lastNode == null) {
    190                         lastNode = n;
    191                     } else {
    192                         length += lastNode.getCoor().greatCircleDistance(n.getCoor());
    193                         segAngle = MeasurementLayer.angleBetween(lastNode.getCoor(), n.getCoor());
    194                         lastNode = n;
     197            if (nodes.isEmpty()) {
     198                relations = new SubclassFilteredCollection<>(selection, Relation.class::isInstance);
     199                for (Relation r : relations) {
     200                    if (r.isMultipolygon()) {
     201                        area += Geometry.multipolygonArea(r);
     202                    }
     203                }
     204            } else {
     205                for (Node n : nodes) {
     206                    if (n.getCoor() != null) {
     207                        if (lastNode == null) {
     208                            lastNode = n;
     209                        } else {
     210                            length += lastNode.getCoor().greatCircleDistance(n.getCoor());
     211                            segAngle = MeasurementLayer.angleBetween(lastNode.getCoor(), n.getCoor());
     212                            lastNode = n;
     213                        }
    195214                    }
    196215                }
     
    264283        SystemOfMeasurement.removeSoMChangeListener(this);
    265284        SelectionEventManager.getInstance().removeSelectionListener(this);
     285        MainApplication.getLayerManager().removeLayerChangeListener(this);
     286        clear();
     287    }
     288
     289    private void clear() {
    266290        if (ds != null) {
    267291            ds.removeDataSetListener(this);
    268292            ds = null;
    269293        }
    270     }
    271 
    272     private boolean waysContain(Node n) {
    273         if (ways != null) {
    274             for (Way w : ways) {
    275                 if (w.containsNode(n)) {
    276                     return true;
    277                 }
    278             }
    279         }
    280         return false;
     294        clear(relations);
     295        clear(ways);
     296        clear(nodes);
     297    }
     298
     299    private static void clear(Collection<?> collection) {
     300        if (collection != null) {
     301            collection.clear();
     302        }
     303    }
     304
     305    private boolean parentsContain(Way w) {
     306        return w.getReferrers().stream()
     307                .anyMatch(ref -> ref instanceof Relation && relations != null && relations.contains(ref));
     308    }
     309
     310    private boolean parentsContain(Node n) {
     311        return n.getReferrers().stream()
     312                .anyMatch(ref
     313                        -> (ref instanceof Way && ((ways != null && ways.contains(ref)) || parentsContain((Way) ref)))
     314                        || (ref instanceof Relation && relations != null && relations.contains(ref)));
    281315    }
    282316
     
    284318        Node n = event.getNode();
    285319        // Refresh selection if a node belonging to a selected member has moved (example: scale action)
    286         if ((nodes != null && nodes.contains(n)) || waysContain(n)) {
     320        if ((nodes != null && nodes.contains(n)) || parentsContain(n)) {
    287321            refresh(event.getDataset().getSelected());
    288322        }
     
    290324
    291325    @Override public void wayNodesChanged(WayNodesChangedEvent event) {
    292         if (ways.contains(event.getChangedWay())) {
     326        Way w = event.getChangedWay();
     327        if ((ways != null && ways.contains(w)) || parentsContain(w)) {
     328            refresh(event.getDataset().getSelected());
     329        }
     330    }
     331
     332    @Override public void relationMembersChanged(RelationMembersChangedEvent event) {
     333        if (relations != null && relations.contains(event.getRelation())) {
    293334            refresh(event.getDataset().getSelected());
    294335        }
     
    298339    @Override public void primitivesRemoved(PrimitivesRemovedEvent event) {}
    299340    @Override public void tagsChanged(TagsChangedEvent event) {}
    300     @Override public void relationMembersChanged(RelationMembersChangedEvent event) {}
    301341    @Override public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
    302342    @Override public void dataChanged(DataChangedEvent event) {}
     
    310350        }
    311351    }
     352
     353    @Override public void layerOrderChanged(LayerOrderChangeEvent e) {}
     354    @Override public void layerAdded(LayerAddEvent e) {}
     355
     356    @Override
     357    public void layerRemoving(LayerRemoveEvent e) {
     358        if (e.getRemovedLayer() instanceof OsmDataLayer && Objects.equals(ds, ((OsmDataLayer) e.getRemovedLayer()).getDataSet())) {
     359            clear();
     360        }
     361    }
    312362}
Note: See TracChangeset for help on using the changeset viewer.