kopia lustrzana https://github.com/JOSM/MapWithAI
Add a check and cleanup for overnoded ways
Also switch layers to the appropriate data layer (for UI) for OverNodedWays/MissingConnectionTags. Signed-off-by: Taylor Smock <taylor.smock@kaart.com>pull/1/head
rodzic
3d43ee1434
commit
779c862cea
|
@ -30,6 +30,8 @@ import org.openstreetmap.josm.data.validation.tests.CrossingWays;
|
|||
import org.openstreetmap.josm.data.validation.tests.DuplicateNode;
|
||||
import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
|
||||
import org.openstreetmap.josm.gui.MainApplication;
|
||||
import org.openstreetmap.josm.gui.layer.AbstractOsmDataLayer;
|
||||
import org.openstreetmap.josm.gui.layer.Layer;
|
||||
import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
|
||||
import org.openstreetmap.josm.gui.util.GuiHelper;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.AbstractConflationCommand;
|
||||
|
@ -45,7 +47,8 @@ import org.openstreetmap.josm.tools.Utils;
|
|||
* @author Taylor Smock
|
||||
*/
|
||||
public class MissingConnectionTags extends AbstractConflationCommand {
|
||||
private double precision = Config.getPref().getDouble("validator.duplicatenodes.precision", 0.);
|
||||
private double precision;
|
||||
private static final String HIGHWAY = "highway";
|
||||
|
||||
public MissingConnectionTags(DataSet data) {
|
||||
super(data);
|
||||
|
@ -64,11 +67,22 @@ public class MissingConnectionTags extends AbstractConflationCommand {
|
|||
@Override
|
||||
public String getKey() {
|
||||
// For now, we assume that only highways are at issue.
|
||||
return "highway";
|
||||
return HIGHWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command getRealCommand() {
|
||||
precision = Config.getPref().getDouble("validator.duplicatenodes.precision", 0.);
|
||||
Layer current = MainApplication.getLayerManager().getActiveLayer();
|
||||
Collection<Way> ways = Utils.filteredCollection(possiblyAffectedPrimitives, Way.class);
|
||||
if (!ways.isEmpty()) {
|
||||
DataSet ds = this.getAffectedDataSet();
|
||||
Layer toSwitch = MainApplication.getLayerManager().getLayersOfType(AbstractOsmDataLayer.class).stream()
|
||||
.filter(d -> ds.equals(d.getDataSet())).findAny().orElse(null);
|
||||
if (toSwitch != null) {
|
||||
MainApplication.getLayerManager().setActiveLayer(toSwitch);
|
||||
}
|
||||
}
|
||||
// precision is in meters
|
||||
precision = precision == 0 ? 1 : precision;
|
||||
String prefKey = "mapwithai.conflation.missingconflationtags";
|
||||
|
@ -79,6 +93,9 @@ public class MissingConnectionTags extends AbstractConflationCommand {
|
|||
fixErrors(prefKey, commands, findDuplicateNodes(possiblyAffectedPrimitives));
|
||||
fixErrors(prefKey, commands, findCrossingWaysAtNodes(possiblyAffectedPrimitives));
|
||||
ConditionalOptionPaneUtil.endBulkOperation(prefKey);
|
||||
if (current != null) {
|
||||
MainApplication.getLayerManager().setActiveLayer(current);
|
||||
}
|
||||
GuiHelper.runInEDT(() -> getAffectedDataSet().setSelected(selection));
|
||||
commands.forEach(Command::undoCommand);
|
||||
return commands.isEmpty() ? null : new SequenceCommand(tr("Perform missing conflation steps"), commands);
|
||||
|
@ -149,7 +166,9 @@ public class MissingConnectionTags extends AbstractConflationCommand {
|
|||
way.getDataSet().searchWays(way.getBBox()).forEach(crossingWays::visit);
|
||||
crossingWays.endTest();
|
||||
for (TestError error : crossingWays.getErrors()) {
|
||||
if (seenFix.containsAll(error.getPrimitives())) {
|
||||
if (seenFix.containsAll(error.getPrimitives())
|
||||
|| error.getPrimitives().stream().filter(Way.class::isInstance).map(Way.class::cast)
|
||||
.filter(w -> w.hasKey(HIGHWAY)).count() == 0L) {
|
||||
continue;
|
||||
}
|
||||
TestError.Builder fixError = TestError.builder(error.getTester(), error.getSeverity(), error.getCode())
|
||||
|
@ -164,11 +183,9 @@ public class MissingConnectionTags extends AbstractConflationCommand {
|
|||
}
|
||||
|
||||
private Supplier<Command> createIntersectionCommandSupplier(TestError error, Way way) {
|
||||
Collection<Node> nodes = Geometry
|
||||
.addIntersections(
|
||||
error.getPrimitives().stream().filter(Way.class::isInstance).map(Way.class::cast)
|
||||
.filter(w -> w.hasKey("highway")).collect(Collectors.toList()),
|
||||
false, new ArrayList<>());
|
||||
Collection<Node> nodes = Geometry.addIntersections(error.getPrimitives().stream().filter(Way.class::isInstance)
|
||||
.map(Way.class::cast).filter(w -> w.hasKey(HIGHWAY)).collect(Collectors.toList()), false,
|
||||
new ArrayList<>());
|
||||
if (nodes.stream().anyMatch(n -> way.getNodes().stream().filter(MissingConnectionTags::noConflationKey)
|
||||
.anyMatch(wn -> n.getCoor().greatCircleDistance(wn.getCoor()) < precision))) {
|
||||
return () -> createIntersectionCommand(way,
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.cleanup;
|
||||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.openstreetmap.josm.actions.AutoScaleAction;
|
||||
import org.openstreetmap.josm.actions.SimplifyWayAction;
|
||||
import org.openstreetmap.josm.command.Command;
|
||||
import org.openstreetmap.josm.command.SequenceCommand;
|
||||
import org.openstreetmap.josm.data.osm.DataSet;
|
||||
import org.openstreetmap.josm.data.osm.Node;
|
||||
import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
||||
import org.openstreetmap.josm.data.osm.Way;
|
||||
import org.openstreetmap.josm.gui.MainApplication;
|
||||
import org.openstreetmap.josm.gui.layer.AbstractOsmDataLayer;
|
||||
import org.openstreetmap.josm.gui.layer.Layer;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.AbstractConflationCommand;
|
||||
import org.openstreetmap.josm.spi.preferences.Config;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
public class OverNodedWays extends AbstractConflationCommand {
|
||||
|
||||
private double threshold;
|
||||
private int acceptableRemovalPercentage;
|
||||
|
||||
public OverNodedWays(DataSet data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescriptionText() {
|
||||
return tr("Fix overnoded ways");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends OsmPrimitive>> getInterestedTypes() {
|
||||
return Collections.singleton(Way.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
// Currently only interested in highways
|
||||
return "highway";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command getRealCommand() {
|
||||
threshold = Config.getPref().getDouble("mapwithai.conflation.simplifyway", 0.5);
|
||||
acceptableRemovalPercentage = Config.getPref().getInt("mapwithai.conflation.simplifywaynodepercentagerequired",
|
||||
20);
|
||||
Layer current = MainApplication.getLayerManager().getActiveLayer();
|
||||
Collection<Way> ways = Utils.filteredCollection(possiblyAffectedPrimitives, Way.class);
|
||||
if (!ways.isEmpty()) {
|
||||
DataSet ds = this.getAffectedDataSet();
|
||||
Layer toSwitch = MainApplication.getLayerManager().getLayersOfType(AbstractOsmDataLayer.class).stream()
|
||||
.filter(d -> ds.equals(d.getDataSet())).findAny().orElse(null);
|
||||
if (toSwitch != null) {
|
||||
MainApplication.getLayerManager().setActiveLayer(toSwitch);
|
||||
}
|
||||
}
|
||||
Collection<Command> commands = new ArrayList<>();
|
||||
for (Way way : ways) {
|
||||
Command command = SimplifyWayAction.createSimplifyCommand(way, threshold);
|
||||
if (command == null) {
|
||||
continue;
|
||||
}
|
||||
int count = Utils.filteredCollection(new ArrayList<>(command.getParticipatingPrimitives()), Node.class)
|
||||
.size();
|
||||
if ((count / (double) way.getNodesCount()) * 100 > this.acceptableRemovalPercentage) {
|
||||
AutoScaleAction.zoomTo(Collections.singleton(way));
|
||||
double length = SimplifyWayAction.askSimplifyWays(
|
||||
tr("You are about to simplify {0} way with a total length of {1}.", 1, way.getLength()), true);
|
||||
commands.add(SimplifyWayAction.createSimplifyCommand(way, length));
|
||||
}
|
||||
}
|
||||
if (current != null) {
|
||||
MainApplication.getLayerManager().setActiveLayer(current);
|
||||
}
|
||||
if (commands.size() == 1) {
|
||||
return commands.iterator().next();
|
||||
} else if (!commands.isEmpty()) {
|
||||
return new SequenceCommand(tr("Simplify ways"), commands);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowUndo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyShouldNotExistInOSM() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -29,6 +29,7 @@ import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.Dupl
|
|||
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.MergeAddressBuildings;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.MergeBuildingAddress;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.cleanup.MissingConnectionTags;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.cleanup.OverNodedWays;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
|
@ -43,6 +44,7 @@ public class CreateConnectionsCommand extends Command {
|
|||
CONFLATION_COMMANDS.add(MergeAddressBuildings.class);
|
||||
CONFLATION_COMMANDS.add(MergeBuildingAddress.class);
|
||||
CONFLATION_COMMANDS.add(MissingConnectionTags.class);
|
||||
CONFLATION_COMMANDS.add(OverNodedWays.class);
|
||||
}
|
||||
|
||||
public CreateConnectionsCommand(DataSet data, Collection<PrimitiveData> primitives) {
|
||||
|
|
Ładowanie…
Reference in New Issue