kopia lustrzana https://github.com/JOSM/MapWithAI
Fix some potential issues from pmd/spotbugs and update some gradle packages
Signed-off-by: Taylor Smock <taylor.smock@kaart.com>pull/1/head
rodzic
6c0d8ae241
commit
2520e1b0ea
|
@ -12,9 +12,9 @@ plugins {
|
|||
id "maven-publish"
|
||||
id "pmd"
|
||||
id "com.github.ben-manes.versions" version "0.27.0"
|
||||
id "com.github.spotbugs" version "2.0.0"
|
||||
id "com.github.spotbugs" version "2.0.1"
|
||||
id "org.openstreetmap.josm" version "0.6.4"
|
||||
id "net.ltgt.errorprone" version "1.1.0"
|
||||
id "net.ltgt.errorprone" version "1.1.1"
|
||||
//id 'de.aaschmid.cpd' version '2.0'
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ def versions = [
|
|||
pmd: "6.18.0",
|
||||
spotbugs: "4.0.0-beta4",
|
||||
wiremock: "2.25.1",
|
||||
findsecbugs: "1.10.0",
|
||||
findsecbugs: "1.10.1",
|
||||
]
|
||||
|
||||
repositories {
|
||||
|
|
|
@ -40,6 +40,7 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
|
|||
private final JSpinner maximumAdditionSpinner;
|
||||
private final ReplacementPreferenceTable table;
|
||||
private final List<PrefEntry> displayData;
|
||||
private static final int MAX_SELECTED_TO_EDIT = 1;
|
||||
|
||||
public MapWithAIPreferences() {
|
||||
possibleMapWithAIApiUrl = new JComboBox<>();
|
||||
|
@ -53,8 +54,8 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
|
|||
}
|
||||
|
||||
private static void fillDisplayData(List<PrefEntry> list) {
|
||||
Map<String, String> current = new TreeMap<>(MapWithAIPreferenceHelper.getReplacementTags());
|
||||
for (Entry<String, String> entry : current.entrySet()) {
|
||||
final Map<String, String> current = new TreeMap<>(MapWithAIPreferenceHelper.getReplacementTags());
|
||||
for (final Entry<String, String> entry : current.entrySet()) {
|
||||
list.add(new PrefEntry(entry.getKey(), new StringSetting(entry.getValue()), new StringSetting(null), false));
|
||||
}
|
||||
}
|
||||
|
@ -99,15 +100,15 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
|
|||
|
||||
final JPanel expert = new JPanel(new GridBagLayout());
|
||||
expert.add(Box.createHorizontalGlue(), GBC.std().fill(GridBagConstraints.HORIZONTAL));
|
||||
JScrollPane scroll = new JScrollPane(table);
|
||||
final JScrollPane scroll = new JScrollPane(table);
|
||||
expert.add(scroll, GBC.eol().fill(GridBagConstraints.BOTH));
|
||||
scroll.setPreferredSize(new Dimension(400, 200));
|
||||
|
||||
JButton add = new JButton(tr("Add"));
|
||||
final JButton add = new JButton(tr("Add"));
|
||||
expert.add(Box.createHorizontalGlue(), GBC.std().fill(GridBagConstraints.HORIZONTAL));
|
||||
expert.add(add, GBC.std().insets(0, 5, 0, 0));
|
||||
add.addActionListener(e -> {
|
||||
PrefEntry pe = table.addPreference(gui);
|
||||
final PrefEntry pe = table.addPreference(gui);
|
||||
if (pe != null && pe.getValue() instanceof StringSetting) {
|
||||
displayData.add(pe);
|
||||
Collections.sort(displayData);
|
||||
|
@ -115,19 +116,19 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
|
|||
}
|
||||
});
|
||||
|
||||
JButton edit = new JButton(tr("Edit"));
|
||||
final JButton edit = new JButton(tr("Edit"));
|
||||
expert.add(edit, GBC.std().insets(5, 5, 0, 0));
|
||||
edit.addActionListener(e -> {
|
||||
List<PrefEntry> toEdit = table.getSelectedItems();
|
||||
if (toEdit.size() == 1) {
|
||||
final List<PrefEntry> toEdit = table.getSelectedItems();
|
||||
if (toEdit.size() == MAX_SELECTED_TO_EDIT) {
|
||||
table.editPreference(gui);
|
||||
}
|
||||
});
|
||||
|
||||
JButton delete = new JButton(tr("Delete"));
|
||||
final JButton delete = new JButton(tr("Delete"));
|
||||
expert.add(delete, GBC.std().insets(5, 5, 0, 0));
|
||||
delete.addActionListener(e -> {
|
||||
List<PrefEntry> toRemove = table.getSelectedItems();
|
||||
final List<PrefEntry> toRemove = table.getSelectedItems();
|
||||
if (!toRemove.isEmpty()) {
|
||||
displayData.removeAll(toRemove);
|
||||
}
|
||||
|
@ -136,7 +137,7 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
|
|||
|
||||
ExpertToggleAction.addVisibilitySwitcher(expert);
|
||||
|
||||
JPanel pane = new JPanel(new GridBagLayout());
|
||||
final JPanel pane = new JPanel(new GridBagLayout());
|
||||
pane.add(nonExpert, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
|
||||
pane.add(expert);
|
||||
|
||||
|
@ -156,7 +157,7 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
|
|||
}
|
||||
|
||||
private static Map<String, String> convertPrefToMap(List<PrefEntry> displayData) {
|
||||
Map<String, String> returnMap = displayData.isEmpty() ? Collections.emptyMap() : new TreeMap<>();
|
||||
final Map<String, String> returnMap = displayData.isEmpty() ? Collections.emptyMap() : new TreeMap<>();
|
||||
displayData.forEach(entry -> returnMap.put(entry.getKey(), entry.getValue().getValue().toString()));
|
||||
return returnMap;
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@ public class ReplacementPreferenceTable extends PreferencesTable {
|
|||
|
||||
@Override
|
||||
public PrefEntry addPreference(final JComponent gui) {
|
||||
JPanel p = new JPanel(new GridBagLayout());
|
||||
final JPanel p = new JPanel(new GridBagLayout());
|
||||
p.add(new JLabel(tr("Original Tag")), GBC.std().insets(0, 0, 5, 0));
|
||||
JosmTextField tkey = new JosmTextField("", 50);
|
||||
final JosmTextField tkey = new JosmTextField("", 50);
|
||||
p.add(tkey, GBC.eop().insets(5, 0, 0, 0).fill(GridBagConstraints.HORIZONTAL));
|
||||
p.add(new JLabel(tr("Replacement Tag")), GBC.std().insets(0, 0, 5, 0));
|
||||
JosmTextField tValue = new JosmTextField("", 50);
|
||||
final JosmTextField tValue = new JosmTextField("", 50);
|
||||
p.add(tValue, GBC.eop().insets(5, 0, 0, 0).fill(GridBagConstraints.HORIZONTAL));
|
||||
|
||||
PrefEntry pe = null;
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -47,6 +48,9 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
private static final int MAX_NUMBER_OF_BBOXES_TO_PROCESS = 1;
|
||||
private static final String SERVER_ID_KEY = "server_id";
|
||||
|
||||
/**
|
||||
* @param bbox The initial bbox to get data from (don't reduce beforehand --
|
||||
* it will be reduced here)
|
||||
|
@ -67,17 +71,14 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
super();
|
||||
this.bbox = new ArrayList<>(bbox);
|
||||
this.dataSet = dataSet;
|
||||
if (monitor == null) {
|
||||
monitor = NullProgressMonitor.INSTANCE;
|
||||
}
|
||||
this.monitor = monitor;
|
||||
this.monitor = Optional.ofNullable(monitor).orElse(NullProgressMonitor.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet compute() {
|
||||
final List<BBox> bboxes = MapWithAIDataUtils.reduceBBoxSize(bbox);
|
||||
monitor.beginTask(tr("Downloading {0} data", MapWithAIPlugin.NAME), bboxes.size() - 1);
|
||||
if (bboxes.size() == 1) {
|
||||
if (bboxes.size() == MAX_NUMBER_OF_BBOXES_TO_PROCESS) {
|
||||
final DataSet temporaryDataSet = getDataReal(bboxes.get(0));
|
||||
synchronized (GetDataRunnable.class) {
|
||||
dataSet.mergeFrom(temporaryDataSet);
|
||||
|
@ -108,11 +109,11 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
|
||||
/**
|
||||
* Replace tags in a dataset with a set of replacement tags
|
||||
*
|
||||
*
|
||||
* @param dataSet The dataset with primitives to change
|
||||
*/
|
||||
public static void replaceTags(DataSet dataSet) {
|
||||
Map<Tag, Tag> replaceTags = MapWithAIPreferenceHelper.getReplacementTags().entrySet().parallelStream()
|
||||
final Map<Tag, Tag> replaceTags = MapWithAIPreferenceHelper.getReplacementTags().entrySet().parallelStream()
|
||||
.map(entry -> new Pair<>(Tag.ofString(entry.getKey()), Tag.ofString(entry.getValue())))
|
||||
.collect(Collectors.toMap(pair -> pair.a, pair -> pair.b));
|
||||
replaceTags.forEach((orig, replace) -> dataSet.allNonDeletedPrimitives().parallelStream()
|
||||
|
@ -121,13 +122,13 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
|
||||
private static void cleanupDataSet(DataSet dataSet) {
|
||||
Map<OsmPrimitive, String> origIds = dataSet.allPrimitives().parallelStream()
|
||||
.filter(prim -> prim.hasKey("orig_id")).distinct()
|
||||
.collect(Collectors.toMap(prim -> prim, prim -> prim.get("orig_id")));
|
||||
Map<OsmPrimitive, String> serverIds = dataSet.allPrimitives().parallelStream()
|
||||
.filter(prim -> prim.hasKey("server_id")).distinct()
|
||||
.collect(Collectors.toMap(prim -> prim, prim -> prim.get("server_id")));
|
||||
.filter(prim -> prim.hasKey(MergeDuplicateWays.ORIG_ID)).distinct()
|
||||
.collect(Collectors.toMap(prim -> prim, prim -> prim.get(MergeDuplicateWays.ORIG_ID)));
|
||||
final Map<OsmPrimitive, String> serverIds = dataSet.allPrimitives().parallelStream()
|
||||
.filter(prim -> prim.hasKey(SERVER_ID_KEY)).distinct()
|
||||
.collect(Collectors.toMap(prim -> prim, prim -> prim.get(SERVER_ID_KEY)));
|
||||
|
||||
List<OsmPrimitive> toDelete = origIds.entrySet().parallelStream()
|
||||
final List<OsmPrimitive> toDelete = origIds.entrySet().parallelStream()
|
||||
.filter(entry -> serverIds.containsValue(entry.getValue())).map(Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
if (!toDelete.isEmpty()) {
|
||||
|
@ -135,8 +136,8 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
}
|
||||
origIds = origIds.entrySet().parallelStream().filter(entry -> !toDelete.contains(entry.getKey()))
|
||||
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
||||
serverIds.forEach((prim, str) -> prim.remove("server_id"));
|
||||
origIds.forEach((prim, str) -> prim.remove("orig_id"));
|
||||
serverIds.forEach((prim, str) -> prim.remove(SERVER_ID_KEY));
|
||||
origIds.forEach((prim, str) -> prim.remove(MergeDuplicateWays.ORIG_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,8 +148,8 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
public static void removeCommonTags(DataSet dataSet) {
|
||||
dataSet.allPrimitives().parallelStream().filter(prim -> prim.hasKey(MergeDuplicateWays.ORIG_ID))
|
||||
.forEach(prim -> prim.remove(MergeDuplicateWays.ORIG_ID));
|
||||
dataSet.getNodes().parallelStream().forEach(node -> node.remove("server_id"));
|
||||
List<Node> emptyNodes = dataSet.getNodes().parallelStream().distinct().filter(node -> !node.isDeleted())
|
||||
dataSet.getNodes().parallelStream().forEach(node -> node.remove(SERVER_ID_KEY));
|
||||
final List<Node> emptyNodes = dataSet.getNodes().parallelStream().distinct().filter(node -> !node.isDeleted())
|
||||
.filter(node -> node.getReferrers().isEmpty() && !node.hasKeys()).collect(Collectors.toList());
|
||||
if (!emptyNodes.isEmpty()) {
|
||||
new DeleteCommand(emptyNodes).executeCommand();
|
||||
|
@ -156,18 +157,18 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
}
|
||||
|
||||
private static void mergeNodes(DataSet dataSet) {
|
||||
List<Node> nodes = dataSet.getNodes().parallelStream().filter(node -> !node.isDeleted())
|
||||
final List<Node> nodes = dataSet.getNodes().parallelStream().filter(node -> !node.isDeleted())
|
||||
.collect(Collectors.toList());
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
Node n1 = nodes.get(i);
|
||||
BBox bbox = new BBox();
|
||||
final Node n1 = nodes.get(i);
|
||||
final BBox bbox = new BBox();
|
||||
bbox.addPrimitive(n1, 0.001);
|
||||
List<Node> nearbyNodes = dataSet.searchNodes(bbox).parallelStream()
|
||||
.filter(node -> !node.isDeleted() && node != n1
|
||||
&& n1.getCoor().greatCircleDistance(node.getCoor()) < MapWithAIPreferenceHelper
|
||||
.getMaxNodeDistance())
|
||||
final List<Node> nearbyNodes = dataSet.searchNodes(bbox).parallelStream()
|
||||
.filter(node -> !node.isDeleted() && !node.equals(n1)
|
||||
&& n1.getCoor().greatCircleDistance(node.getCoor()) < MapWithAIPreferenceHelper
|
||||
.getMaxNodeDistance())
|
||||
.collect(Collectors.toList());
|
||||
Command mergeCommand = MergeNodesAction.mergeNodes(nearbyNodes, n1);
|
||||
final Command mergeCommand = MergeNodesAction.mergeNodes(nearbyNodes, n1);
|
||||
if (mergeCommand != null) {
|
||||
mergeCommand.executeCommand();
|
||||
nodes.removeAll(nearbyNodes);
|
||||
|
|
|
@ -52,7 +52,7 @@ public final class MapWithAIAvailability {
|
|||
private MapWithAIAvailability() {
|
||||
try (CachedFile cachedRapidReleases = new CachedFile(rapidReleases);
|
||||
JsonParser parser = Json.createParser(cachedRapidReleases.getContentReader())) {
|
||||
cachedRapidReleases.setMaxAge(604800);
|
||||
cachedRapidReleases.setMaxAge(604_800);
|
||||
parser.next();
|
||||
final Stream<Entry<String, JsonValue>> entries = parser.getObjectStream();
|
||||
final Optional<Entry<String, JsonValue>> objects = entries
|
||||
|
@ -87,16 +87,11 @@ public final class MapWithAIAvailability {
|
|||
|
||||
private static Map<String, Map<String, Boolean>> parseForCountries(JsonArray countries) {
|
||||
final Map<String, Map<String, Boolean>> returnCountries = new TreeMap<>();
|
||||
Territories.initialize();
|
||||
final DataSet territories = Territories.getDataSet();
|
||||
for (int i = 0; i < countries.size(); i++) {
|
||||
final JsonObject country = countries.getJsonObject(i).getJsonObject("properties");
|
||||
final String countryName = cornerCaseNames(country.getString("Country"));
|
||||
DataSet territories;
|
||||
try {
|
||||
territories = Territories.getDataSet();
|
||||
} catch (NullPointerException e) {
|
||||
Territories.initialize();
|
||||
territories = Territories.getDataSet();
|
||||
}
|
||||
final Optional<OsmPrimitive> realCountry = territories.allPrimitives().parallelStream()
|
||||
.filter(primitive -> countryName.equalsIgnoreCase(primitive.get("name:en")))
|
||||
.findFirst();
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
@ -35,7 +36,7 @@ import org.openstreetmap.josm.tools.Utils;
|
|||
*
|
||||
*/
|
||||
public final class MapWithAIDataUtils {
|
||||
public static final int MAXIMUM_SIDE_DIMENSIONS = 10000; // RapiD is about 1km, max is 10km
|
||||
public static final int MAXIMUM_SIDE_DIMENSIONS = 10_000; // RapiD is about 1km, max is 10km
|
||||
private static ForkJoinPool forkJoinPool;
|
||||
static final Object LAYER_LOCK = new Object();
|
||||
|
||||
|
@ -48,7 +49,7 @@ public final class MapWithAIDataUtils {
|
|||
*/
|
||||
public static void addMapWithAIPaintStyles() {
|
||||
// Remove old url's that were automatically added -- remove after Jan 01, 2020
|
||||
List<String> oldUrls = Arrays.asList(
|
||||
final List<String> oldUrls = Arrays.asList(
|
||||
"https://gitlab.com/gokaart/JOSM_MapWithAI/raw/master/src/resources/styles/standard/mapwithai.mapcss",
|
||||
"https://gitlab.com/smocktaylor/rapid/raw/master/src/resources/styles/standard/rapid.mapcss");
|
||||
MapPaintStyles.getStyles().getStyleSources().parallelStream().filter(style -> oldUrls.contains(style.url))
|
||||
|
@ -56,7 +57,7 @@ public final class MapWithAIDataUtils {
|
|||
|
||||
if (MapPaintStyles.getStyles().getStyleSources().parallelStream()
|
||||
.noneMatch(source -> "resource://styles/standard/mapwithai.mapcss".equals(source.url))) {
|
||||
MapCSSStyleSource style = new MapCSSStyleSource("resource://styles/standard/mapwithai.mapcss",
|
||||
final MapCSSStyleSource style = new MapCSSStyleSource("resource://styles/standard/mapwithai.mapcss",
|
||||
MapWithAIPlugin.NAME, "MapWithAI");
|
||||
MapPaintStyles.addStyle(style);
|
||||
}
|
||||
|
@ -67,8 +68,8 @@ public final class MapWithAIDataUtils {
|
|||
*/
|
||||
public static void removeMapWithAIPaintStyles() {
|
||||
MapPaintStyles.getStyles().getStyleSources().parallelStream()
|
||||
.filter(source -> "resource://styles/standard/mapwithai.mapcss".equals(source.url))
|
||||
.forEach(MapPaintStyles::removeStyle);
|
||||
.filter(source -> "resource://styles/standard/mapwithai.mapcss".equals(source.url))
|
||||
.forEach(MapPaintStyles::removeStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,6 +193,17 @@ public final class MapWithAIDataUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for MapWithAI
|
||||
*
|
||||
* @param layer A pre-existing {@link MapWithAILayer}
|
||||
* @param osmLayer The osm datalayer with a set of bounds
|
||||
*/
|
||||
public static void getMapWithAIData(MapWithAILayer layer, OsmDataLayer osmLayer) {
|
||||
getMapWithAIData(layer,
|
||||
osmLayer.getDataSet().getDataSourceBounds().stream().map(Bounds::toBBox).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for MapWithAI
|
||||
*
|
||||
|
@ -229,23 +241,23 @@ public final class MapWithAIDataUtils {
|
|||
}
|
||||
|
||||
private static List<BBox> reduceBBox(List<BBox> alreadyDownloaded, List<BBox> wantToDownload) {
|
||||
List<BBox> alreadyDownloadedReduced = new ArrayList<>(alreadyDownloaded);
|
||||
final List<BBox> alreadyDownloadedReduced = new ArrayList<>(alreadyDownloaded);
|
||||
int aDRSize = -1;
|
||||
do {
|
||||
aDRSize = alreadyDownloadedReduced.size();
|
||||
for (int i = 0; i < alreadyDownloadedReduced.size(); i++) {
|
||||
BBox bbox1 = alreadyDownloadedReduced.get(i);
|
||||
final BBox bbox1 = alreadyDownloadedReduced.get(i);
|
||||
for (int j = 0; j < alreadyDownloadedReduced.size(); j++) {
|
||||
BBox bbox2 = alreadyDownloadedReduced.get(j);
|
||||
if (bbox1 != bbox2 && bboxesShareSide(bbox1, bbox2)) {
|
||||
final BBox bbox2 = alreadyDownloadedReduced.get(j);
|
||||
if (!bbox1.equals(bbox2) && bboxesShareSide(bbox1, bbox2)) {
|
||||
bbox1.add(bbox2);
|
||||
alreadyDownloadedReduced.remove(bbox2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (aDRSize != alreadyDownloadedReduced.size());
|
||||
for (BBox bbox : wantToDownload) {
|
||||
for (BBox downloaded : alreadyDownloaded) {
|
||||
for (final BBox bbox : wantToDownload) {
|
||||
for (final BBox downloaded : alreadyDownloaded) {
|
||||
if (bboxesAreFunctionallyEqual(bbox, downloaded, null)) {
|
||||
Logging.debug("YEP");
|
||||
}
|
||||
|
@ -253,43 +265,31 @@ public final class MapWithAIDataUtils {
|
|||
}
|
||||
return wantToDownload.parallelStream()
|
||||
.filter(bbox1 -> alreadyDownloadedReduced.parallelStream()
|
||||
.noneMatch(bbox2 -> bboxesAreFunctionallyEqual(bbox1, bbox2, 0.00002)))
|
||||
.noneMatch(bbox2 -> bboxesAreFunctionallyEqual(bbox1, bbox2, 0.000_02)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// TODO replace with {@link BBox.bboxesAreFunctionallyEqual} when version bumped to >r15483
|
||||
private static boolean bboxesAreFunctionallyEqual(BBox bbox1, BBox bbox2, Double maxDifference) {
|
||||
if (maxDifference == null) {
|
||||
maxDifference = LatLon.MAX_SERVER_PRECISION;
|
||||
}
|
||||
return (bbox1 != null && bbox2 != null)
|
||||
&& (Math.abs(bbox1.getBottomRightLat() - bbox2.getBottomRightLat()) < maxDifference
|
||||
&& Math.abs(bbox1.getBottomRightLon() - bbox2.getBottomRightLon()) < maxDifference
|
||||
&& Math.abs(bbox1.getTopLeftLat() - bbox2.getTopLeftLat()) < maxDifference
|
||||
&& Math.abs(bbox1.getTopLeftLon() - bbox2.getTopLeftLon()) < maxDifference);
|
||||
final double diff = Optional.ofNullable(maxDifference).orElse(LatLon.MAX_SERVER_PRECISION);
|
||||
return (bbox1 != null && bbox2 != null && Math.abs(bbox1.getBottomRightLat() - bbox2.getBottomRightLat()) < diff
|
||||
&& Math.abs(bbox1.getBottomRightLon() - bbox2.getBottomRightLon()) < diff
|
||||
&& Math.abs(bbox1.getTopLeftLat() - bbox2.getTopLeftLat()) < diff
|
||||
&& Math.abs(bbox1.getTopLeftLon() - bbox2.getTopLeftLon()) < diff);
|
||||
}
|
||||
|
||||
private static boolean bboxesShareSide(BBox bbox1, BBox bbox2) {
|
||||
List<Double> bbox1Lons = Arrays.asList(bbox1.getTopLeftLon(), bbox1.getBottomRightLon());
|
||||
List<Double> bbox1Lats = Arrays.asList(bbox1.getTopLeftLat(), bbox1.getBottomRightLat());
|
||||
List<Double> bbox2Lons = Arrays.asList(bbox2.getTopLeftLon(), bbox2.getBottomRightLon());
|
||||
List<Double> bbox2Lats = Arrays.asList(bbox2.getTopLeftLat(), bbox2.getBottomRightLat());
|
||||
Long lonDupeCount = bbox1Lons.parallelStream().filter(lon -> bbox2Lons.parallelStream().anyMatch(lon2 -> Double.compare(lon, lon2) == 0)).count();
|
||||
Long latDupeCount = bbox1Lats.parallelStream().filter(lat -> bbox2Lats.parallelStream().anyMatch(lat2 -> Double.compare(lat, lat2) == 0)).count();
|
||||
final List<Double> bbox1Lons = Arrays.asList(bbox1.getTopLeftLon(), bbox1.getBottomRightLon());
|
||||
final List<Double> bbox1Lats = Arrays.asList(bbox1.getTopLeftLat(), bbox1.getBottomRightLat());
|
||||
final List<Double> bbox2Lons = Arrays.asList(bbox2.getTopLeftLon(), bbox2.getBottomRightLon());
|
||||
final List<Double> bbox2Lats = Arrays.asList(bbox2.getTopLeftLat(), bbox2.getBottomRightLat());
|
||||
final Long lonDupeCount = bbox1Lons.parallelStream()
|
||||
.filter(lon -> bbox2Lons.parallelStream().anyMatch(lon2 -> Double.compare(lon, lon2) == 0)).count();
|
||||
final Long latDupeCount = bbox1Lats.parallelStream()
|
||||
.filter(lat -> bbox2Lats.parallelStream().anyMatch(lat2 -> Double.compare(lat, lat2) == 0)).count();
|
||||
return (lonDupeCount + latDupeCount) > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for MapWithAI
|
||||
*
|
||||
* @param layer A pre-existing {@link MapWithAILayer}
|
||||
* @param osmLayer The osm datalayer with a set of bounds
|
||||
*/
|
||||
public static void getMapWithAIData(MapWithAILayer layer, OsmDataLayer osmLayer) {
|
||||
getMapWithAIData(layer,
|
||||
osmLayer.getDataSet().getDataSourceBounds().stream().map(Bounds::toBBox).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public static double getWidth(BBox bbox) {
|
||||
// Lat is y, Lon is x
|
||||
final LatLon bottomRight = bbox.getBottomRight();
|
||||
|
|
|
@ -47,10 +47,7 @@ public class MapWithAILayer extends OsmDataLayer {
|
|||
|
||||
// @Override TODO remove comment on 2020-01-01
|
||||
public String getChangesetSourceTag() {
|
||||
if (MapWithAIDataUtils.getAddedObjects() > 0) {
|
||||
return "MapWithAI";
|
||||
}
|
||||
return null;
|
||||
return MapWithAIDataUtils.getAddedObjects() > 0 ? "MapWithAI" : null;
|
||||
}
|
||||
|
||||
public void setMaximumAddition(Integer max) {
|
||||
|
@ -114,6 +111,7 @@ public class MapWithAILayer extends OsmDataLayer {
|
|||
private boolean dataSetLocked;
|
||||
|
||||
public MapLock() {
|
||||
super();
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
|
|
@ -50,11 +50,13 @@ public class MapWithAIObject implements CommandQueueListener, Destroyable {
|
|||
|
||||
private void setText() {
|
||||
final Long addedObjects = MapWithAIDataUtils.getAddedObjects();
|
||||
if (addedObjects != 0L) {
|
||||
if (addedObjects == 0L) {
|
||||
mapWithAIObjects.setVisible(false);
|
||||
mapWithAIObjects.setVisible(true);
|
||||
mapWithAIObjects.setText(tr("{0} Objects Added: {1}", MapWithAIPlugin.NAME, addedObjects));
|
||||
} else {
|
||||
mapWithAIObjects.setVisible(false);
|
||||
mapWithAIObjects.setVisible(true);
|
||||
mapWithAIObjects.setText(tr("{0} Objects Added: {1}", MapWithAIPlugin.NAME, addedObjects));
|
||||
}
|
||||
final int maxAdd = MapWithAIPreferenceHelper.getMaximumAddition();
|
||||
if (addedObjects == 0) {
|
||||
|
|
|
@ -38,14 +38,14 @@ public final class MapWithAIPreferenceHelper {
|
|||
public static String getMapWithAIUrl() {
|
||||
final MapWithAILayer layer = MapWithAIDataUtils.getLayer(false);
|
||||
String url = Config.getPref().get(MapWithAIPlugin.NAME.concat(".current_api"), DEFAULT_MAPWITHAI_API);
|
||||
if (layer != null && layer.getMapWithAIUrl() != null) {
|
||||
url = layer.getMapWithAIUrl();
|
||||
} else {
|
||||
if (layer == null || layer.getMapWithAIUrl() == null) {
|
||||
final List<String> urls = getMapWithAIURLs();
|
||||
if (!urls.contains(url)) {
|
||||
url = DEFAULT_MAPWITHAI_API;
|
||||
setMapWithAIUrl(DEFAULT_MAPWITHAI_API, true);
|
||||
}
|
||||
} else {
|
||||
url = layer.getMapWithAIUrl();
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
@ -140,10 +140,10 @@ public final class MapWithAIPreferenceHelper {
|
|||
public static void setMaximumAddition(int max, boolean permanent) {
|
||||
final MapWithAILayer mapWithAILayer = MapWithAIDataUtils.getLayer(false);
|
||||
if (permanent) {
|
||||
if (getDefaultMaximumAddition() != max) {
|
||||
Config.getPref().putInt(MAXIMUMSELECTION, max);
|
||||
} else {
|
||||
if (getDefaultMaximumAddition() == max) {
|
||||
Config.getPref().put(MAXIMUMSELECTION, null);
|
||||
} else {
|
||||
Config.getPref().putInt(MAXIMUMSELECTION, max);
|
||||
}
|
||||
} else if (mapWithAILayer != null) {
|
||||
mapWithAILayer.setMaximumAddition(max);
|
||||
|
@ -159,10 +159,10 @@ public final class MapWithAIPreferenceHelper {
|
|||
*/
|
||||
public static void setMergeBuildingAddress(boolean selected, boolean permanent) {
|
||||
if (permanent) {
|
||||
if (!selected) {
|
||||
Config.getPref().putBoolean(MERGEBUILDINGADDRESSES, selected);
|
||||
} else {
|
||||
if (selected) {
|
||||
Config.getPref().put(MERGEBUILDINGADDRESSES, null);
|
||||
} else {
|
||||
Config.getPref().putBoolean(MERGEBUILDINGADDRESSES, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,10 +177,10 @@ public final class MapWithAIPreferenceHelper {
|
|||
public static void setSwitchLayers(boolean selected, boolean permanent) {
|
||||
final MapWithAILayer layer = MapWithAIDataUtils.getLayer(false);
|
||||
if (permanent) {
|
||||
if (!selected) {
|
||||
Config.getPref().putBoolean(AUTOSWITCHLAYERS, selected);
|
||||
} else {
|
||||
if (selected) {
|
||||
Config.getPref().put(AUTOSWITCHLAYERS, null);
|
||||
} else {
|
||||
Config.getPref().putBoolean(AUTOSWITCHLAYERS, selected);
|
||||
}
|
||||
} else if (layer != null) {
|
||||
layer.setSwitchLayers(selected);
|
||||
|
@ -200,8 +200,8 @@ public final class MapWithAIPreferenceHelper {
|
|||
* @return A map of tags to replacement tags (use {@link Tag.ofString} to parse)
|
||||
*/
|
||||
public static Map<String, String> getReplacementTags() {
|
||||
Map<String, String> defaultMap = Collections.emptyMap();
|
||||
List<Map<String, String>> listOfMaps = Config.getPref()
|
||||
final Map<String, String> defaultMap = Collections.emptyMap();
|
||||
final List<Map<String, String>> listOfMaps = Config.getPref()
|
||||
.getListOfMaps(MapWithAIPlugin.NAME.concat(".replacementtags"), Arrays.asList(defaultMap));
|
||||
return listOfMaps.isEmpty() ? defaultMap : listOfMaps.get(0);
|
||||
}
|
||||
|
@ -210,7 +210,8 @@ public final class MapWithAIPreferenceHelper {
|
|||
* @param tagsToReplace set the tags to replace
|
||||
*/
|
||||
public static void setReplacementTags(Map<String, String> tagsToReplace) {
|
||||
List<Map<String, String>> tags = tagsToReplace.isEmpty() ? null : Arrays.asList(new TreeMap<>(tagsToReplace));
|
||||
final List<Map<String, String>> tags = tagsToReplace.isEmpty() ? null
|
||||
: Arrays.asList(new TreeMap<>(tagsToReplace));
|
||||
Config.getPref().putListOfMaps(MapWithAIPlugin.NAME.concat(".replacementtags"), tags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class MergeDuplicateWaysAction extends JosmAction {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<Way> ways = new ArrayList<>(MainApplication.getLayerManager().getActiveDataSet().getSelectedWays());
|
||||
final List<Way> ways = new ArrayList<>(MainApplication.getLayerManager().getActiveDataSet().getSelectedWays());
|
||||
Command command = null;
|
||||
int i = 0;
|
||||
do {
|
||||
|
|
|
@ -22,14 +22,15 @@ import org.openstreetmap.josm.io.OsmReader;
|
|||
public class OsmReaderCustom extends OsmReader {
|
||||
protected OsmReaderCustom(boolean convertUnknownToTags) {
|
||||
// Restricts visibility
|
||||
super();
|
||||
// TODO when we update to r15470 this.convertUnknownToTags =
|
||||
// convertUnknownToTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OsmPrimitive buildPrimitive(PrimitiveData pd) {
|
||||
Long serverId = pd.getUniqueId();
|
||||
OsmPrimitive p = super.buildPrimitive(pd);
|
||||
final Long serverId = pd.getUniqueId();
|
||||
final OsmPrimitive p = super.buildPrimitive(pd);
|
||||
p.put("server_id", Long.toString(serverId));
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@ import org.openstreetmap.josm.tools.Utils;
|
|||
public class CreateConnectionsCommand extends Command {
|
||||
private final Collection<OsmPrimitive> primitives;
|
||||
private Command command = null;
|
||||
private static final List<Class<? extends AbstractConflationCommand>> conflationCommands = new ArrayList<>();
|
||||
private static final List<Class<? extends AbstractConflationCommand>> CONFLATION_COMMANDS = new ArrayList<>();
|
||||
static {
|
||||
conflationCommands.add(ConnectedCommand.class);
|
||||
conflationCommands.add(DuplicateCommand.class);
|
||||
conflationCommands.add(MergeAddressBuildings.class);
|
||||
CONFLATION_COMMANDS.add(ConnectedCommand.class);
|
||||
CONFLATION_COMMANDS.add(DuplicateCommand.class);
|
||||
CONFLATION_COMMANDS.add(MergeAddressBuildings.class);
|
||||
}
|
||||
|
||||
public CreateConnectionsCommand(DataSet data, Collection<OsmPrimitive> primitives) {
|
||||
|
@ -71,7 +71,7 @@ public class CreateConnectionsCommand extends Command {
|
|||
SequenceCommand returnSequence = null;
|
||||
final Collection<OsmPrimitive> realPrimitives = collection.stream().map(dataSet::getPrimitiveById)
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
for (Class<? extends AbstractConflationCommand> abstractCommandClass : getConflationCommands()) {
|
||||
for (final Class<? extends AbstractConflationCommand> abstractCommandClass : getConflationCommands()) {
|
||||
final AbstractConflationCommand abstractCommand;
|
||||
try {
|
||||
abstractCommand = abstractCommandClass.getConstructor(DataSet.class).newInstance(dataSet);
|
||||
|
@ -115,13 +115,13 @@ public class CreateConnectionsCommand extends Command {
|
|||
* @param command A command to run when copying data from the MapWithAI layer
|
||||
*/
|
||||
public static void addConflationCommand(Class<? extends AbstractConflationCommand> command) {
|
||||
conflationCommands.add(command);
|
||||
CONFLATION_COMMANDS.add(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A set of commands to run when copying data from the MapWithAI layer
|
||||
*/
|
||||
public static List<Class<? extends AbstractConflationCommand>> getConflationCommands() {
|
||||
return Collections.unmodifiableList(conflationCommands);
|
||||
return Collections.unmodifiableList(CONFLATION_COMMANDS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@ import org.openstreetmap.josm.tools.Pair;
|
|||
public class MergeDuplicateWays extends Command {
|
||||
public static final String ORIG_ID = "orig_id";
|
||||
|
||||
private Way way1;
|
||||
private Way way2;
|
||||
private final Way way1;
|
||||
private final Way way2;
|
||||
|
||||
private List<Command> commands;
|
||||
private final List<Command> commands;
|
||||
|
||||
public MergeDuplicateWays(DataSet data) {
|
||||
this(data, null, null);
|
||||
|
@ -69,14 +69,14 @@ public class MergeDuplicateWays extends Command {
|
|||
} else if (way1 == null) {
|
||||
checkForDuplicateWays(way2, commands);
|
||||
} else {
|
||||
Command command = checkForDuplicateWays(way1, way2);
|
||||
final Command command = checkForDuplicateWays(way1, way2);
|
||||
if (command != null) {
|
||||
commands.add(command);
|
||||
command.executeCommand();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Command command : commands) {
|
||||
for (final Command command : commands) {
|
||||
command.executeCommand();
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public class MergeDuplicateWays extends Command {
|
|||
|
||||
@Override
|
||||
public void undoCommand() {
|
||||
for (Command tCommand : commands) {
|
||||
for (final Command tCommand : commands) {
|
||||
tCommand.undoCommand();
|
||||
}
|
||||
}
|
||||
|
@ -94,13 +94,13 @@ public class MergeDuplicateWays extends Command {
|
|||
final List<Way> ways = new ArrayList<>(
|
||||
dataSet.getWays().parallelStream().filter(prim -> !prim.isIncomplete()).collect(Collectors.toList()));
|
||||
for (int i = 0; i < ways.size(); i++) {
|
||||
Way way1 = ways.get(i);
|
||||
Collection<Way> nearbyWays = dataSet.searchWays(way1.getBBox()).parallelStream()
|
||||
final Way way1 = ways.get(i);
|
||||
final Collection<Way> nearbyWays = dataSet.searchWays(way1.getBBox()).parallelStream()
|
||||
.filter(way -> !way.isDeleted()).collect(Collectors.toList());
|
||||
nearbyWays.remove(way1);
|
||||
for (Way way2 : nearbyWays) {
|
||||
Command command = checkForDuplicateWays(way1, way2);
|
||||
Collection<OsmPrimitive> deletedWays = new ArrayList<>();
|
||||
for (final Way way2 : nearbyWays) {
|
||||
final Command command = checkForDuplicateWays(way1, way2);
|
||||
final Collection<OsmPrimitive> deletedWays = new ArrayList<>();
|
||||
if (command != null) {
|
||||
commands.add(command);
|
||||
command.executeCommand();
|
||||
|
@ -121,11 +121,11 @@ public class MergeDuplicateWays extends Command {
|
|||
* @return non-null command if there are duplicate ways
|
||||
*/
|
||||
public static void checkForDuplicateWays(Way way, List<Command> commands) {
|
||||
Collection<Way> nearbyWays = way.getDataSet().searchWays(way.getBBox());
|
||||
final Collection<Way> nearbyWays = way.getDataSet().searchWays(way.getBBox());
|
||||
nearbyWays.remove(way);
|
||||
for (Way way2 : nearbyWays) {
|
||||
for (final Way way2 : nearbyWays) {
|
||||
if (!way2.isDeleted()) {
|
||||
Command tCommand = checkForDuplicateWays(way, way2);
|
||||
final Command tCommand = checkForDuplicateWays(way, way2);
|
||||
if (tCommand != null) {
|
||||
commands.add(tCommand);
|
||||
tCommand.executeCommand();
|
||||
|
@ -145,8 +145,8 @@ public class MergeDuplicateWays extends Command {
|
|||
public static Command checkForDuplicateWays(Way way1, Way way2) {
|
||||
Command returnCommand = null;
|
||||
final Map<Pair<Integer, Node>, Map<Integer, Node>> duplicateNodes = getDuplicateNodes(way1, way2);
|
||||
Set<Entry<Pair<Integer, Node>, Map<Integer, Node>>> duplicateEntrySet = duplicateNodes.entrySet();
|
||||
Set<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> compressed = duplicateNodes.entrySet().stream()
|
||||
final Set<Entry<Pair<Integer, Node>, Map<Integer, Node>>> duplicateEntrySet = duplicateNodes.entrySet();
|
||||
final Set<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> compressed = duplicateNodes.entrySet().stream()
|
||||
.map(entry -> new Pair<Pair<Integer, Node>, Pair<Integer, Node>>(entry.getKey(),
|
||||
new Pair<Integer, Node>(entry.getValue().entrySet().iterator().next().getKey(),
|
||||
entry.getValue().entrySet().iterator().next().getValue())))
|
||||
|
@ -180,8 +180,8 @@ public class MergeDuplicateWays extends Command {
|
|||
Command command = null;
|
||||
if (compressed.size() > 1 || (way1.hasKey(ORIG_ID) && way1.get(ORIG_ID).equals(way2.get(ORIG_ID)))) {
|
||||
Set<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> realSet = new LinkedHashSet<>(compressed);
|
||||
boolean sameDirection = checkDirection(realSet);
|
||||
List<Node> way2Nodes = way2.getNodes();
|
||||
final boolean sameDirection = checkDirection(realSet);
|
||||
final List<Node> way2Nodes = way2.getNodes();
|
||||
if (!sameDirection) {
|
||||
Collections.reverse(way2Nodes);
|
||||
realSet = realSet.stream().map(pair -> {
|
||||
|
@ -189,12 +189,12 @@ public class MergeDuplicateWays extends Command {
|
|||
return pair;
|
||||
}).collect(Collectors.toSet());
|
||||
}
|
||||
int last = realSet.stream().mapToInt(pair -> pair.b.a).max().orElse(way2Nodes.size());
|
||||
int first = realSet.stream().mapToInt(pair -> pair.b.a).min().orElse(0);
|
||||
List<Node> before = new ArrayList<>();
|
||||
List<Node> after = new ArrayList<>();
|
||||
for (Node node : way2Nodes) {
|
||||
int position = way2Nodes.indexOf(node);
|
||||
final int last = realSet.stream().mapToInt(pair -> pair.b.a).max().orElse(way2Nodes.size());
|
||||
final int first = realSet.stream().mapToInt(pair -> pair.b.a).min().orElse(0);
|
||||
final List<Node> before = new ArrayList<>();
|
||||
final List<Node> after = new ArrayList<>();
|
||||
for (final Node node : way2Nodes) {
|
||||
final int position = way2Nodes.indexOf(node);
|
||||
if (position < first) {
|
||||
before.add(node);
|
||||
} else if (position > last) {
|
||||
|
@ -202,7 +202,7 @@ public class MergeDuplicateWays extends Command {
|
|||
}
|
||||
}
|
||||
Collections.reverse(before);
|
||||
Way newWay = new Way(way1);
|
||||
final Way newWay = new Way(way1);
|
||||
List<Command> commands = new ArrayList<>();
|
||||
before.forEach(node -> newWay.addNode(0, node));
|
||||
after.forEach(newWay::addNode);
|
||||
|
@ -229,7 +229,7 @@ public class MergeDuplicateWays extends Command {
|
|||
*/
|
||||
public static Node nodeInCompressed(Node node, Set<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> compressed) {
|
||||
Node returnNode = node;
|
||||
for (Pair<Pair<Integer, Node>, Pair<Integer, Node>> pair : compressed) {
|
||||
for (final Pair<Pair<Integer, Node>, Pair<Integer, Node>> pair : compressed) {
|
||||
if (node.equals(pair.a.b)) {
|
||||
returnNode = pair.b.b;
|
||||
} else if (node.equals(pair.b.b)) {
|
||||
|
@ -252,16 +252,16 @@ public class MergeDuplicateWays extends Command {
|
|||
* @return true if the node pairs increment in the same direction
|
||||
*/
|
||||
public static boolean checkDirection(Set<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> compressed) {
|
||||
Iterator<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> iterator = compressed.iterator();
|
||||
final Iterator<Pair<Pair<Integer, Node>, Pair<Integer, Node>>> iterator = compressed.iterator();
|
||||
boolean returnValue = false;
|
||||
if (compressed.size() > 1) {
|
||||
Pair<Pair<Integer, Node>, Pair<Integer, Node>> first = iterator.next();
|
||||
Pair<Pair<Integer, Node>, Pair<Integer, Node>> second = iterator.next();
|
||||
boolean way1Forward = first.a.a < second.a.a;
|
||||
boolean way2Forward = first.b.a < second.b.a;
|
||||
final Pair<Pair<Integer, Node>, Pair<Integer, Node>> first = iterator.next();
|
||||
final Pair<Pair<Integer, Node>, Pair<Integer, Node>> second = iterator.next();
|
||||
final boolean way1Forward = first.a.a < second.a.a;
|
||||
final boolean way2Forward = first.b.a < second.b.a;
|
||||
returnValue = way1Forward == way2Forward;
|
||||
} else if (compressed.size() == 1) {
|
||||
Pair<Pair<Integer, Node>, Pair<Integer, Node>> first = iterator.next();
|
||||
final Pair<Pair<Integer, Node>, Pair<Integer, Node>> first = iterator.next();
|
||||
returnValue = (first.a.a == 0 && first.b.a != 0) || (first.a.a != 0 && first.b.a == 0);
|
||||
}
|
||||
return returnValue;
|
||||
|
@ -323,7 +323,7 @@ public class MergeDuplicateWays extends Command {
|
|||
@Override
|
||||
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
|
||||
Collection<OsmPrimitive> added) {
|
||||
for (Command command : commands) {
|
||||
for (final Command command : commands) {
|
||||
command.fillModifiedData(modified, deleted, added);
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue