Package org.openstreetmap.josm.actions
Class JoinAreasAction
- java.lang.Object
-
- javax.swing.AbstractAction
-
- org.openstreetmap.josm.actions.JosmAction
-
- org.openstreetmap.josm.actions.JoinAreasAction
-
- All Implemented Interfaces:
java.awt.event.ActionListener
,java.io.Serializable
,java.lang.Cloneable
,java.util.EventListener
,javax.swing.Action
,Destroyable
public class JoinAreasAction extends JosmAction
Join Areas (i.e. closed ways and multipolygons).- Since:
- 2575
- See Also:
- Serialized Form
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
JoinAreasAction.AssembledMultipolygon
A multipolygon with a list of inner ways and an assembled polygon for the outer waystatic class
JoinAreasAction.AssembledPolygon
This helper class describes a polygon, assembled from several ways.private static class
JoinAreasAction.JoinAreaCommand
static class
JoinAreasAction.JoinAreasResult
This helper class describes join areas action result.static class
JoinAreasAction.Multipolygon
A record class to store how a multipolygon is constructed(package private) static class
JoinAreasAction.PolygonLevel
Helper storage class for finding findOuterWaysprivate static class
JoinAreasAction.RelationRole
static class
JoinAreasAction.WayInPolygon
HelperClass - saves a way and the "inside" side.private static class
JoinAreasAction.WayTraverser
This helper class implements algorithm traversing through connected ways.-
Nested classes/interfaces inherited from class org.openstreetmap.josm.actions.JosmAction
JosmAction.ActiveLayerChangeAdapter, JosmAction.LayerChangeAdapter, JosmAction.SelectionChangeAdapter
-
-
Field Summary
Fields Modifier and Type Field Description private java.util.List<Relation>
addedRelations
private boolean
addUndoRedo
private java.util.LinkedList<Command>
cmds
private DataSet
ds
private java.util.LinkedList<Command>
executedCmds
-
Fields inherited from class org.openstreetmap.josm.actions.JosmAction
sc
-
-
Constructor Summary
Constructors Constructor Description JoinAreasAction()
Constructs a newJoinAreasAction
.JoinAreasAction(boolean addShortcutToolbarAdapters)
Constructs a newJoinAreasAction
with optional shortcut and adapters.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
actionPerformed(java.awt.event.ActionEvent e)
Gets called whenever the shortcut is pressed or the menu entry is selected.private JoinAreasAction.RelationRole
addOwnMultipolygonRelation(java.util.Collection<Way> inner)
Will add own multipolygon relation to the "previously existing" relations.private static java.util.List<java.util.List<Node>>
buildNodeChunks(Way way, java.util.Collection<Node> splitNodes)
Simple chunking version.private void
clearFields()
static java.util.List<JoinAreasAction.Multipolygon>
collectMultipolygons(java.util.Collection<Way> selectedWays)
This method analyzes multipolygon relationships of given ways and collects addition inner ways to consider.private void
commitCommand(Command c)
private void
commitCommands(java.lang.String description)
Commits the command list with a descriptionprivate void
commitExecuted()
Add all executed commands as one command to the undo stack without executing them again.static java.util.List<JoinAreasAction.AssembledPolygon>
findBoundaryPolygons(java.util.Collection<JoinAreasAction.WayInPolygon> multigonWays, java.util.List<Way> discardedResult)
Finds all ways that form inner or outer boundaries.private static java.util.List<JoinAreasAction.PolygonLevel>
findOuterWaysImpl(int level, java.util.Collection<JoinAreasAction.AssembledPolygon> boundaryWays)
Collects outer way and corresponding inner ways from all boundaries.private static java.util.List<JoinAreasAction.AssembledMultipolygon>
findPolygons(java.util.Collection<JoinAreasAction.AssembledPolygon> boundaries)
This method finds which ways are outer and which are inner.private void
fixRelations(java.util.List<JoinAreasAction.RelationRole> rels, Way outer, JoinAreasAction.RelationRole ownMultipol, java.util.Set<Relation> relationsToDelete)
Adds the previously removed relations again to the outer way.static java.util.List<JoinAreasAction.AssembledPolygon>
fixTouchingPolygons(java.util.List<JoinAreasAction.AssembledPolygon> polygons)
This method checks if polygons have several touching parts and splits them in several polygons.void
join(java.util.Collection<Way> ways)
Joins the given ways.private JoinAreasAction.JoinAreasResult
joinAreas(java.util.List<JoinAreasAction.Multipolygon> areas)
Will join two or more overlapping areasprivate Way
joinOrientedWays(java.util.List<JoinAreasAction.WayInPolygon> ways)
Joins a list of ways (using CombineWayAction and ReverseWayAction as specified in WayInPath)private JoinAreasAction.Multipolygon
joinPolygon(JoinAreasAction.AssembledMultipolygon polygon)
Joins the lists of ways.private Way
joinWays(java.util.List<JoinAreasAction.WayInPolygon> ways)
Joins the outer ways and deletes all short ways that can't be part of a multipolygon anyway.private Way
keepOlder(Way way, java.util.Map<Node,Way> oldestWayMap, java.util.List<Way> discardedWays)
Create copy of given way using an older id so that we don't create a new way instead of a modified old one.private static java.util.List<JoinAreasAction.WayInPolygon>
markWayInsideSide(java.util.List<Way> parts, boolean isInner)
This method analyzes the way and assigns each part what direction polygon "inside" is.private boolean
removeDuplicateNodes(java.util.List<Way> ways)
This method removes duplicate points (if any) from the input ways.private java.util.List<JoinAreasAction.RelationRole>
removeFromAllRelations(OsmPrimitive osm)
Removes a given OsmPrimitive from all relations.private boolean
resolveTagConflicts(java.util.List<JoinAreasAction.Multipolygon> polygons)
Checks if tags of two given ways differ, and presents the user a dialog to solve conflictsprivate static void
revertDuplicateTwoNodeWays(java.util.List<JoinAreasAction.WayInPolygon> parts)
Correct possible error in markWayInsideSide result when splitting a self-intersecting way.private java.util.List<Way>
splitWayOnNodes(Way way, java.util.Set<Node> nodes, java.util.Map<Node,Way> oldestWayMap)
This is a method that splits way into smaller parts, using the prepared nodes list as split points.private void
stripTags(java.util.Collection<Way> ways)
Remove all tags from the all the wayprivate boolean
testJoin(java.util.List<JoinAreasAction.Multipolygon> areas)
Tests if the areas have some intersections to join.private void
tryUndo()
protected void
updateEnabledState()
Override in subclasses to update the enabled state of the action when something in the JOSM state changes, i.e.protected void
updateEnabledState(java.util.Collection<? extends OsmPrimitive> selection)
Override in subclasses to update the enabled state of the action if the collection of selected primitives changes.static boolean
wayInsideWay(JoinAreasAction.AssembledPolygon inside, JoinAreasAction.AssembledPolygon outside)
Tests if way is inside other way-
Methods inherited from class org.openstreetmap.josm.actions.JosmAction
buildActiveLayerChangeAdapter, buildLayerChangeAdapter, checkAndConfirmOutlyingOperation, destroy, getLayerManager, getShortcut, initEnabledState, installAdapters, listenToLayerChange, listenToSelectionChange, setHelpId, setToolbarId, setTooltip, updateEnabledStateOnCurrentSelection, updateEnabledStateOnCurrentSelection, updateEnabledStateOnModifiableSelection, waitFuture
-
Methods inherited from class javax.swing.AbstractAction
addPropertyChangeListener, clone, firePropertyChange, getKeys, getPropertyChangeListeners, getValue, isEnabled, putValue, removePropertyChangeListener, setEnabled
-
-
-
-
Field Detail
-
executedCmds
private final transient java.util.LinkedList<Command> executedCmds
-
addedRelations
private final transient java.util.List<Relation> addedRelations
-
addUndoRedo
private final boolean addUndoRedo
-
-
Constructor Detail
-
JoinAreasAction
public JoinAreasAction()
Constructs a newJoinAreasAction
.
-
JoinAreasAction
public JoinAreasAction(boolean addShortcutToolbarAdapters)
Constructs a newJoinAreasAction
with optional shortcut and adapters.- Parameters:
addShortcutToolbarAdapters
- controls whether the shortcut should be registered or not, as for toolbar registration, adapters creation and undo/redo integration- Since:
- 11611
-
-
Method Detail
-
actionPerformed
public void actionPerformed(java.awt.event.ActionEvent e)
Gets called whenever the shortcut is pressed or the menu entry is selected. Checks whether the selected objects are suitable to join and joins them if so.
-
clearFields
private void clearFields()
-
join
public void join(java.util.Collection<Way> ways)
Joins the given ways.- Parameters:
ways
- Ways to join- Since:
- 7534
-
tryUndo
private void tryUndo()
-
testJoin
private boolean testJoin(java.util.List<JoinAreasAction.Multipolygon> areas)
Tests if the areas have some intersections to join.- Parameters:
areas
- Areas to test- Returns:
true
if areas are joinable
-
joinAreas
private JoinAreasAction.JoinAreasResult joinAreas(java.util.List<JoinAreasAction.Multipolygon> areas) throws UserCancelException
Will join two or more overlapping areas- Parameters:
areas
- list of areas to join- Returns:
- new area formed.
- Throws:
UserCancelException
- if user cancels the operation- Since:
- 15852 : visibility changed from public to private
-
keepOlder
private Way keepOlder(Way way, java.util.Map<Node,Way> oldestWayMap, java.util.List<Way> discardedWays)
Create copy of given way using an older id so that we don't create a new way instead of a modified old one.- Parameters:
way
- the way to checkoldestWayMap
- nodes from old waysdiscardedWays
- collection of ways which will be deleted (modified)- Returns:
- a copy of the way with an older id or the way itself
-
resolveTagConflicts
private boolean resolveTagConflicts(java.util.List<JoinAreasAction.Multipolygon> polygons)
Checks if tags of two given ways differ, and presents the user a dialog to solve conflicts- Parameters:
polygons
- ways to check- Returns:
true
if all conflicts are resolved,false
if conflicts remain.
-
removeDuplicateNodes
private boolean removeDuplicateNodes(java.util.List<Way> ways)
This method removes duplicate points (if any) from the input ways.- Parameters:
ways
- the ways to process- Returns:
true
if any changes where made
-
commitCommands
private void commitCommands(java.lang.String description)
Commits the command list with a description- Parameters:
description
- The description of what the commands do
-
commitCommand
private void commitCommand(Command c)
-
commitExecuted
private void commitExecuted()
Add all executed commands as one command to the undo stack without executing them again.
-
markWayInsideSide
private static java.util.List<JoinAreasAction.WayInPolygon> markWayInsideSide(java.util.List<Way> parts, boolean isInner)
This method analyzes the way and assigns each part what direction polygon "inside" is.- Parameters:
parts
- the split parts of the wayisInner
- - if true, reverts the direction (for multipolygon islands)- Returns:
- list of parts, marked with the inside orientation.
- Throws:
java.lang.IllegalArgumentException
- if parts is empty or not circular
-
revertDuplicateTwoNodeWays
private static void revertDuplicateTwoNodeWays(java.util.List<JoinAreasAction.WayInPolygon> parts)
Correct possible error in markWayInsideSide result when splitting a self-intersecting way. If we have two ways with the same two nodes and the same direction there must be a self intersection. Change the direction flag for the latter of the two ways. The result is that difference between the number of ways with insideToTheRight =true
and those with insideToTheRight =false
differs by 0 or 1, not more.See #10511
- Parameters:
parts
- the parts of a single closed way
-
splitWayOnNodes
private java.util.List<Way> splitWayOnNodes(Way way, java.util.Set<Node> nodes, java.util.Map<Node,Way> oldestWayMap)
This is a method that splits way into smaller parts, using the prepared nodes list as split points. UsesSplitWayCommand.splitWay(org.openstreetmap.josm.data.osm.Way, java.util.List<java.util.List<org.openstreetmap.josm.data.osm.Node>>, java.util.Collection<? extends org.openstreetmap.josm.data.osm.OsmPrimitive>)
for the heavy lifting.- Parameters:
way
- way to splitnodes
- split pointsoldestWayMap
- nodes from old ways (modified here)- Returns:
- list of split ways (or original way if no splitting is done).
-
buildNodeChunks
private static java.util.List<java.util.List<Node>> buildNodeChunks(Way way, java.util.Collection<Node> splitNodes)
Simple chunking version. Does not care about circular ways and result being proper, we will glue it all back together later on.- Parameters:
way
- the way to chunksplitNodes
- the places where to cut.- Returns:
- list of node paths to produce.
-
findPolygons
private static java.util.List<JoinAreasAction.AssembledMultipolygon> findPolygons(java.util.Collection<JoinAreasAction.AssembledPolygon> boundaries)
This method finds which ways are outer and which are inner.- Parameters:
boundaries
- list of joined boundaries to search in- Returns:
- outer ways
-
findOuterWaysImpl
private static java.util.List<JoinAreasAction.PolygonLevel> findOuterWaysImpl(int level, java.util.Collection<JoinAreasAction.AssembledPolygon> boundaryWays)
Collects outer way and corresponding inner ways from all boundaries.- Parameters:
level
- depth levelboundaryWays
- list of joined boundaries to search in- Returns:
- the outermost Way.
-
findBoundaryPolygons
public static java.util.List<JoinAreasAction.AssembledPolygon> findBoundaryPolygons(java.util.Collection<JoinAreasAction.WayInPolygon> multigonWays, java.util.List<Way> discardedResult)
Finds all ways that form inner or outer boundaries.- Parameters:
multigonWays
- A list of (splitted) ways that form a multigon and share common end nodes on intersections.discardedResult
- this list is filled with ways that are to be discarded- Returns:
- A list of ways that form the outer and inner boundaries of the multigon.
-
fixTouchingPolygons
public static java.util.List<JoinAreasAction.AssembledPolygon> fixTouchingPolygons(java.util.List<JoinAreasAction.AssembledPolygon> polygons)
This method checks if polygons have several touching parts and splits them in several polygons.- Parameters:
polygons
- the polygons to process.- Returns:
- the resulting list of polygons
-
wayInsideWay
public static boolean wayInsideWay(JoinAreasAction.AssembledPolygon inside, JoinAreasAction.AssembledPolygon outside)
Tests if way is inside other way- Parameters:
outside
- outer polygon descriptioninside
- inner polygon description- Returns:
true
if inner is inside outer
-
joinPolygon
private JoinAreasAction.Multipolygon joinPolygon(JoinAreasAction.AssembledMultipolygon polygon) throws UserCancelException
Joins the lists of ways.- Parameters:
polygon
- The list of outer ways that belong to that multipolygon.- Returns:
- The newly created outer way
- Throws:
UserCancelException
- if user cancels the operation
-
joinWays
private Way joinWays(java.util.List<JoinAreasAction.WayInPolygon> ways) throws UserCancelException
Joins the outer ways and deletes all short ways that can't be part of a multipolygon anyway.- Parameters:
ways
- The list of outer ways that belong to that multigon.- Returns:
- The newly created outer way
- Throws:
UserCancelException
- if user cancels the operation
-
joinOrientedWays
private Way joinOrientedWays(java.util.List<JoinAreasAction.WayInPolygon> ways) throws UserCancelException
Joins a list of ways (using CombineWayAction and ReverseWayAction as specified in WayInPath)- Parameters:
ways
- The list of ways to join and reverse- Returns:
- The newly created way
- Throws:
UserCancelException
- if user cancels the operation
-
collectMultipolygons
public static java.util.List<JoinAreasAction.Multipolygon> collectMultipolygons(java.util.Collection<Way> selectedWays)
This method analyzes multipolygon relationships of given ways and collects addition inner ways to consider.- Parameters:
selectedWays
- the selected ways- Returns:
- list of polygons, or null if too complex relation encountered.
-
addOwnMultipolygonRelation
private JoinAreasAction.RelationRole addOwnMultipolygonRelation(java.util.Collection<Way> inner)
Will add own multipolygon relation to the "previously existing" relations. Fixup is done by fixRelations- Parameters:
inner
- List of already closed inner ways- Returns:
- The list of relation with roles to add own relation to
-
removeFromAllRelations
private java.util.List<JoinAreasAction.RelationRole> removeFromAllRelations(OsmPrimitive osm)
Removes a given OsmPrimitive from all relations.- Parameters:
osm
- Element to remove from all relations- Returns:
- List of relations with roles the primitives was part of
-
fixRelations
private void fixRelations(java.util.List<JoinAreasAction.RelationRole> rels, Way outer, JoinAreasAction.RelationRole ownMultipol, java.util.Set<Relation> relationsToDelete)
Adds the previously removed relations again to the outer way. If there are multiple multipolygon relations where the joined areas were in "outer" role a new relation is created instead with all members of both. This function depends on multigon relations to be valid already, it won't fix them.- Parameters:
rels
- List of relations with roles the (original) ways were part ofouter
- The newly created outer area/wayownMultipol
- elements to directly add as outerrelationsToDelete
- set of relations to delete.
-
stripTags
private void stripTags(java.util.Collection<Way> ways)
Remove all tags from the all the way- Parameters:
ways
- The List of Ways to remove all tags from
-
updateEnabledState
protected void updateEnabledState()
Description copied from class:JosmAction
Override in subclasses to update the enabled state of the action when something in the JOSM state changes, i.e. when a layer is removed or added. SeeJosmAction.updateEnabledState(Collection)
to respond to changes in the collection of selected primitives. Default behavior is empty.- Overrides:
updateEnabledState
in classJosmAction
- See Also:
JosmAction.updateEnabledState(Collection)
,JosmAction.initEnabledState()
,JosmAction.listenToLayerChange()
-
updateEnabledState
protected void updateEnabledState(java.util.Collection<? extends OsmPrimitive> selection)
Description copied from class:JosmAction
Override in subclasses to update the enabled state of the action if the collection of selected primitives changes. This method is called with the new selection.- Overrides:
updateEnabledState
in classJosmAction
- Parameters:
selection
- the collection of selected primitives; may be empty, but not null- See Also:
JosmAction.updateEnabledState()
,JosmAction.initEnabledState()
,JosmAction.listenToSelectionChange()
-
-