kopia lustrzana https://github.com/JOSM/MapWithAI
Fix many SonarLint issues, mostly documentation
Signed-off-by: Taylor Smock <tsmock@meta.com>pull/8/head
rodzic
0fcc9e8ee0
commit
9a61f34d7f
|
@ -56,6 +56,9 @@ import org.openstreetmap.josm.spi.preferences.Config;
|
|||
import org.openstreetmap.josm.tools.Destroyable;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
|
||||
/**
|
||||
* The POJO entry point for the plugin
|
||||
*/
|
||||
public final class MapWithAIPlugin extends Plugin implements Destroyable {
|
||||
/** The name of the plugin */
|
||||
public static final String NAME = "MapWithAI";
|
||||
|
|
|
@ -29,6 +29,9 @@ import org.openstreetmap.josm.tools.Logging;
|
|||
import org.openstreetmap.josm.tools.Territories;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Check for data availability in an area
|
||||
*/
|
||||
public class DataAvailability {
|
||||
/** A map of tag -> message of possible data types */
|
||||
static final Map<String, String> POSSIBLE_DATA_POINTS = new TreeMap<>();
|
||||
|
@ -67,7 +70,7 @@ public class DataAvailability {
|
|||
*/
|
||||
private static void initialize() {
|
||||
try (CachedFile jsonFile = new CachedFile(MapWithAIConfig.getUrls().getMapWithAISourcesJson());
|
||||
JsonParser jsonParser = Json.createParser(jsonFile.getContentReader());) {
|
||||
JsonParser jsonParser = Json.createParser(jsonFile.getContentReader())) {
|
||||
jsonFile.setMaxAge(SEVEN_DAYS_IN_SECONDS);
|
||||
jsonParser.next();
|
||||
JsonObject jsonObject = jsonParser.getObject();
|
||||
|
|
|
@ -27,6 +27,11 @@ public final class DownloadListener implements DataSourceListener, Destroyable {
|
|||
private static final double BBOX_SIMILARITY_DEGREES = 0.001;
|
||||
private static final Collection<DownloadListener> LISTENERS = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Listen to downloads in a dataset
|
||||
*
|
||||
* @param dataSet The dataset to listen to
|
||||
*/
|
||||
public DownloadListener(DataSet dataSet) {
|
||||
Objects.requireNonNull(dataSet, "DataSet cannot be null");
|
||||
ds = new WeakReference<>(dataSet);
|
||||
|
|
|
@ -34,10 +34,16 @@ import org.openstreetmap.josm.tools.Logging;
|
|||
import org.openstreetmap.josm.tools.Utils;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Download data from MapWithAI
|
||||
*/
|
||||
public class DownloadMapWithAITask extends DownloadOsmTask {
|
||||
private final List<MapWithAIInfo> urls;
|
||||
|
||||
private static class Notifications {
|
||||
/**
|
||||
* Show common notifications/issues
|
||||
*/
|
||||
private static final class Notifications {
|
||||
private Notifications() {
|
||||
// Hide constructor
|
||||
}
|
||||
|
@ -72,6 +78,9 @@ public class DownloadMapWithAITask extends DownloadOsmTask {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new download task
|
||||
*/
|
||||
public DownloadMapWithAITask() {
|
||||
urls = MapWithAILayerInfo.getInstance().getLayers();
|
||||
MapWithAILayerInfo.getInstance().save(); // Save preferences between downloads.
|
||||
|
@ -96,7 +105,7 @@ public class DownloadMapWithAITask extends DownloadOsmTask {
|
|||
items.add(tr("OSM Server URL:") + ' ' + url.getHost());
|
||||
items.add(tr("Command") + ": " + url.getPath());
|
||||
if (url.getQuery() != null) {
|
||||
items.add(tr("Request details: {0}", url.getQuery().replaceAll(",\\s*", ", ")));
|
||||
items.add(tr("Request details: {0}", url.getQuery().replaceAll(",\\p{IsWhite_Space}*", ", ")));
|
||||
}
|
||||
return Utils.joinAsHtmlUnorderedList(items);
|
||||
}
|
||||
|
|
|
@ -172,6 +172,8 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
public static final String SOURCE_TAG_KEY = "source";
|
||||
|
||||
/**
|
||||
* Get data in the background
|
||||
*
|
||||
* @param bbox The initial bbox to get data from (don't reduce beforehand --
|
||||
* it will be reduced here)
|
||||
* @param dataSet The dataset to add the data to
|
||||
|
@ -182,6 +184,8 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get data in the background
|
||||
*
|
||||
* @param bbox The initial bboxes to get data from (don't reduce beforehand
|
||||
* -- it will be reduced here)
|
||||
* @param dataSet The dataset to add the data to
|
||||
|
@ -567,7 +571,6 @@ public class GetDataRunnable extends RecursiveTask<DataSet> {
|
|||
bbox.addPrimitive(way1, DEGREE_BUFFER);
|
||||
for (Way nearbyWay : dataSet.searchWays(bbox)) {
|
||||
if (nearbyWay.getNodes().stream().filter(way1::containsNode).count() > 1) {
|
||||
// way1.getNodePairs(false);
|
||||
for (Map.Entry<IWaySegment<Node, Way>, List<IWaySegment<Node, Way>>> entry : checkWayDuplications(
|
||||
way1, nearbyWay).entrySet()) {
|
||||
GetDataRunnable.addMissingElement(entry);
|
||||
|
|
|
@ -5,6 +5,9 @@ import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
|
|||
import static org.openstreetmap.josm.tools.I18n.marktr;
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
|
@ -14,9 +17,6 @@ import java.util.Objects;
|
|||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.openstreetmap.josm.actions.AbstractMergeAction;
|
||||
import org.openstreetmap.josm.actions.JosmAction;
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
|
@ -28,12 +28,18 @@ import org.openstreetmap.josm.gui.layer.OsmDataLayer;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
|
||||
import org.openstreetmap.josm.tools.Shortcut;
|
||||
|
||||
/**
|
||||
* Create or download MapWithAI data
|
||||
*/
|
||||
public class MapWithAIAction extends JosmAction {
|
||||
/** UID */
|
||||
private static final long serialVersionUID = 8886705479253246588L;
|
||||
private static final String DOWNLOAD_DATA = marktr("{0}: Download Data");
|
||||
private static final String SWITCH_LAYERS = marktr("{0}: Switch Layers");
|
||||
|
||||
/**
|
||||
* Create the action
|
||||
*/
|
||||
public MapWithAIAction() {
|
||||
super(tr(DOWNLOAD_DATA, MapWithAIPlugin.NAME), "mapwithai", tr("Get data from {0}", MapWithAIPlugin.NAME),
|
||||
Shortcut.registerShortcut("data:mapWithAI", tr("Data: {0}", MapWithAIPlugin.NAME), KeyEvent.VK_R,
|
||||
|
|
|
@ -192,10 +192,9 @@ public final class MapWithAIDataUtils {
|
|||
final String notificationMessage;
|
||||
if (e.getCause() instanceof IllegalDataException) {
|
||||
notificationMessage = tr("MapWithAI servers may be down.");
|
||||
} else if (!Utils.isBlank(e.getLocalizedMessage())) {
|
||||
notificationMessage = e.getLocalizedMessage();
|
||||
Logging.trace(e);
|
||||
} else {
|
||||
notificationMessage = e.getMessage();
|
||||
throw e;
|
||||
}
|
||||
Notification notification = new Notification();
|
||||
GuiHelper.runInEDT(() -> notification.setContent(notificationMessage));
|
||||
|
@ -227,6 +226,11 @@ public final class MapWithAIDataUtils {
|
|||
null, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.YES_OPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user confirmed the download
|
||||
*
|
||||
* @return {@code true} if the user wants to continue
|
||||
*/
|
||||
public boolean confirmed() {
|
||||
return bool;
|
||||
}
|
||||
|
|
|
@ -292,7 +292,11 @@ public class MapWithAILayer extends OsmDataLayer implements ActiveLayerChangeLis
|
|||
GuiHelper.runInEDT(badData::show);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare OsmPrimitives in a custom manner
|
||||
*/
|
||||
private static class OsmComparator implements Comparator<OsmPrimitive>, Serializable {
|
||||
private static final long serialVersionUID = 594813918562412160L;
|
||||
final Collection<OsmPrimitive> previousSelection;
|
||||
|
||||
public OsmComparator(Collection<OsmPrimitive> previousSelection) {
|
||||
|
@ -337,6 +341,11 @@ public class MapWithAILayer extends OsmDataLayer implements ActiveLayerChangeLis
|
|||
private static final long serialVersionUID = -3528632887550700527L;
|
||||
private final transient MapWithAILayer layer;
|
||||
|
||||
/**
|
||||
* Create a new continuous download toggle
|
||||
*
|
||||
* @param layer the layer to toggle continuous download for
|
||||
*/
|
||||
public ContinuousDownloadAction(MapWithAILayer layer) {
|
||||
super(tr("Continuous download"));
|
||||
new ImageProvider("download").getResource().attachImageIcon(this, true);
|
||||
|
|
|
@ -30,6 +30,9 @@ import org.openstreetmap.josm.plugins.mapwithai.commands.MapWithAIAddCommand;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.tools.BlacklistUtils;
|
||||
import org.openstreetmap.josm.tools.Shortcut;
|
||||
|
||||
/**
|
||||
* Move data between the MapWithAI layer and an OSM data layer
|
||||
*/
|
||||
public class MapWithAIMoveAction extends JosmAction {
|
||||
/** UID for abstract action */
|
||||
private static final long serialVersionUID = 319374598;
|
||||
|
@ -37,6 +40,9 @@ public class MapWithAIMoveAction extends JosmAction {
|
|||
/** The maximum number of objects is this times the maximum add */
|
||||
public static final long MAX_ADD_MULTIPLIER = 10;
|
||||
|
||||
/**
|
||||
* Create a new action
|
||||
*/
|
||||
public MapWithAIMoveAction() {
|
||||
super(tr("{0}: Add selected data", MapWithAIPlugin.NAME), "mapwithai",
|
||||
tr("Add data from {0}", MapWithAIPlugin.NAME), obtainShortcut(), true, "mapwithai:movedata", true);
|
||||
|
|
|
@ -26,6 +26,9 @@ public class MapWithAIObject implements CommandQueueListener, Destroyable {
|
|||
private final JosmTextField mapWithAIObjects;
|
||||
private final List<MapStatus> statusLines;
|
||||
|
||||
/**
|
||||
* Create a new status line for added objects
|
||||
*/
|
||||
public MapWithAIObject() {
|
||||
mapWithAIObjects = new JosmTextField(null, null, "MapWithAI Objects Added: 1000".length() - 10, false);
|
||||
mapWithAIObjects.setBackground(MapStatus.PROP_BACKGROUND_COLOR.get());
|
||||
|
|
|
@ -17,6 +17,9 @@ import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAILayerInfo;
|
||||
import org.openstreetmap.josm.spi.preferences.Config;
|
||||
|
||||
/**
|
||||
* Helper for MapWithAI preferences
|
||||
*/
|
||||
public final class MapWithAIPreferenceHelper {
|
||||
private static final String AUTOSWITCHLAYERS = MapWithAIPlugin.NAME.concat(".autoswitchlayers");
|
||||
private static final String MERGEBUILDINGADDRESSES = MapWithAIPlugin.NAME.concat(".mergebuildingaddresses");
|
||||
|
|
|
@ -16,6 +16,9 @@ import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
|
||||
|
||||
/**
|
||||
* Download MapWithAI data using remote control
|
||||
*/
|
||||
public class MapWithAIRemoteControl extends RequestHandler.RawURLParseRequestHandler {
|
||||
|
||||
private static final PermissionPrefWithDefault PERMISSION_PREF_WITH_DEFAULT = new PermissionPrefWithDefault(
|
||||
|
@ -35,10 +38,6 @@ public class MapWithAIRemoteControl extends RequestHandler.RawURLParseRequestHan
|
|||
private static final String URL_STRING = "url";
|
||||
private static final String SOURCE_STRING = "source";
|
||||
|
||||
public MapWithAIRemoteControl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateRequest() throws RequestHandlerBadRequestException {
|
||||
if (args != null) {
|
||||
|
@ -171,7 +170,10 @@ public class MapWithAIRemoteControl extends RequestHandler.RawURLParseRequestHan
|
|||
@Override
|
||||
public String[] getUsageExamples() {
|
||||
return new String[] { "/mapwithai", "/mapwithai?bbox=-108.4625421,39.0621223,-108.4594728,39.0633059",
|
||||
"/mapwithai?url=https://www.mapwith.ai/maps/ml_roads?conflate_with_osm=true&theme=ml_road_vector&collaborator=josm&token=ASb3N5o9HbX8QWn8G_NtHIRQaYv3nuG2r7_f3vnGld3KhZNCxg57IsaQyssIaEw5rfRNsPpMwg4TsnrSJtIJms5m&hash=ASawRla3rBcwEjY4HIY&bbox={bbox}",
|
||||
"/mapwithai?url=https://www.mapwith.ai/maps/ml_roads?conflate_with_osm=true"
|
||||
+ "&theme=ml_road_vector&collaborator=josm"
|
||||
+ "&token=ASb3N5o9HbX8QWn8G_NtHIRQaYv3nuG2r7_f3vnGld3KhZNCxg57IsaQyssIaEw5rfRNsPpMwg4TsnrSJtIJms5m"
|
||||
+ "&hash=ASawRla3rBcwEjY4HIY&bbox={bbox}",
|
||||
"/mapwithai?bbox=-108.4625421,39.0621223,-108.4594728,39.0633059&max_obj=1",
|
||||
"/mapwithai?bbox=-108.4625421,39.0621223,-108.4594728,39.0633059&switch_layer=false",
|
||||
"/mapwithai?crop_bbox=-108.4625421,39.0621223,-108.4594728,39.0633059" };
|
||||
|
|
|
@ -18,6 +18,11 @@ import org.openstreetmap.josm.tools.Destroyable;
|
|||
public class MapWithAIUploadHook implements UploadHook, Destroyable {
|
||||
private final String version;
|
||||
|
||||
/**
|
||||
* Create the upload hook
|
||||
*
|
||||
* @param info The info to get version information from
|
||||
*/
|
||||
public MapWithAIUploadHook(PluginInformation info) {
|
||||
version = info.localversion;
|
||||
UploadAction.registerUploadHook(this);
|
||||
|
|
|
@ -31,6 +31,9 @@ public class MergeDuplicateWaysAction extends JosmAction {
|
|||
*/
|
||||
private static final int COMPARE_WAYS_NUMBER = 2;
|
||||
|
||||
/**
|
||||
* Create a new action
|
||||
*/
|
||||
public MergeDuplicateWaysAction() {
|
||||
super(tr("{0}: ".concat(DESCRIPTION), MapWithAIPlugin.NAME), "mapwithai", tr(DESCRIPTION),
|
||||
Shortcut.registerShortcut("data:attemptmergeway", tr(DESCRIPTION), KeyEvent.VK_EXCLAMATION_MARK,
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.openstreetmap.josm.plugins.mapwithai.commands;
|
|||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -17,7 +16,11 @@ import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
|||
import org.openstreetmap.josm.data.osm.Way;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelper;
|
||||
import org.openstreetmap.josm.tools.Geometry;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
|
||||
/**
|
||||
* Add a node to a way
|
||||
*/
|
||||
public class AddNodeToWayCommand extends Command {
|
||||
private final Node toAddNode;
|
||||
private final Way way;
|
||||
|
@ -50,12 +53,13 @@ public class AddNodeToWayCommand extends Command {
|
|||
IWaySegment.forNodePair(getWay(), getFirstNode(), getSecondNode());
|
||||
index = Math.max(getWay().getNodes().indexOf(getFirstNode()), getWay().getNodes().indexOf(getSecondNode()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.trace(e);
|
||||
// OK, someone has added a node between the two nodes since calculation
|
||||
Way tWay = new Way();
|
||||
tWay.setNodes(Arrays.asList(getFirstNode(), getSecondNode()));
|
||||
List<Node> relevantNodes = new ArrayList<>(getWay().getNodes().stream()
|
||||
List<Node> relevantNodes = getWay().getNodes().stream()
|
||||
.filter(node -> Geometry.getDistance(tWay, node) < MapWithAIPreferenceHelper.getMaxNodeDistance())
|
||||
.collect(Collectors.toList()));
|
||||
.collect(Collectors.toList());
|
||||
for (int i = 0; i < relevantNodes.size() - 1; i++) {
|
||||
Way tWay2 = new Way();
|
||||
tWay2.setNodes(Arrays.asList(relevantNodes.get(i), relevantNodes.get(i + 1)));
|
||||
|
|
|
@ -4,8 +4,8 @@ package org.openstreetmap.josm.plugins.mapwithai.commands;
|
|||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -21,6 +21,9 @@ import org.openstreetmap.josm.data.projection.ProjectionRegistry;
|
|||
import org.openstreetmap.josm.tools.Geometry;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
|
||||
/**
|
||||
* Connect a way to another way (in between nodes)
|
||||
*/
|
||||
public class ConnectedCommand extends AbstractConflationCommand {
|
||||
public static final String KEY = "conn";
|
||||
|
||||
|
@ -87,7 +90,7 @@ public class ConnectedCommand extends AbstractConflationCommand {
|
|||
|
||||
@Override
|
||||
public Collection<Class<? extends OsmPrimitive>> getInterestedTypes() {
|
||||
return Arrays.asList(Node.class);
|
||||
return Collections.singletonList(Node.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,6 +28,9 @@ import org.openstreetmap.josm.plugins.mapwithai.commands.cleanup.OverNodedWays;
|
|||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Create connections
|
||||
*/
|
||||
public class CreateConnectionsCommand extends Command {
|
||||
private final Collection<PrimitiveData> primitives;
|
||||
private Command command;
|
||||
|
@ -43,6 +46,12 @@ public class CreateConnectionsCommand extends Command {
|
|||
CONFLATION_COMMANDS.add(AlreadyConflatedCommand.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new command
|
||||
*
|
||||
* @param data The dataset
|
||||
* @param primitives The primitives to connect
|
||||
*/
|
||||
public CreateConnectionsCommand(DataSet data, Collection<PrimitiveData> primitives) {
|
||||
super(data);
|
||||
this.primitives = primitives;
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.openstreetmap.josm.plugins.mapwithai.commands;
|
|||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -21,6 +20,9 @@ import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
|
|||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Connect duplicate nodes
|
||||
*/
|
||||
public class DuplicateCommand extends AbstractConflationCommand {
|
||||
public static final String KEY = "dupe";
|
||||
|
||||
|
@ -68,7 +70,7 @@ public class DuplicateCommand extends AbstractConflationCommand {
|
|||
public static Command replaceNode(Node original, Node newNode) {
|
||||
Command tCommand = null;
|
||||
if (original.getCoor().equalsEpsilon(newNode.getCoor())) {
|
||||
tCommand = MergeNodesAction.mergeNodes(Arrays.asList(original), newNode, newNode);
|
||||
tCommand = MergeNodesAction.mergeNodes(Collections.singletonList(original), newNode, newNode);
|
||||
}
|
||||
return tCommand;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,9 @@ import org.openstreetmap.josm.tools.Logging;
|
|||
import org.openstreetmap.josm.tools.Pair;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Add data from the MapWithAI layer to the OSM data layer
|
||||
*/
|
||||
public class MapWithAIAddCommand extends Command implements Runnable {
|
||||
private final DataSet editable;
|
||||
private final DataSet mapWithAI;
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.openstreetmap.josm.plugins.mapwithai.commands;
|
|||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -31,7 +33,9 @@ public final class MergeBuildingNodeCommand {
|
|||
*
|
||||
* @param subjectNode node to be replaced
|
||||
* @param referenceObject object with greater spatial quality
|
||||
* @return The command that updates the node to a way/relation
|
||||
*/
|
||||
@Nullable
|
||||
public static Command buildUpgradeNodeCommand(Node subjectNode, OsmPrimitive referenceObject) {
|
||||
boolean keepNode = !subjectNode.isNew();
|
||||
if (keepNode) {
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.openstreetmap.josm.plugins.mapwithai.commands;
|
|||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -31,6 +34,9 @@ import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelpe
|
|||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Pair;
|
||||
|
||||
/**
|
||||
* Merge duplicate ways
|
||||
*/
|
||||
public class MergeDuplicateWays extends Command {
|
||||
public static final String ORIG_ID = "orig_id";
|
||||
|
||||
|
@ -41,22 +47,51 @@ public class MergeDuplicateWays extends Command {
|
|||
|
||||
private Bounds bound;
|
||||
|
||||
/**
|
||||
* Merge duplicate ways
|
||||
*
|
||||
* @param data Merge all duplicate ways in the dataset
|
||||
*/
|
||||
public MergeDuplicateWays(DataSet data) {
|
||||
this(data, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge duplicate ways
|
||||
*
|
||||
* @param way1 The way to merge duplicates to
|
||||
*/
|
||||
public MergeDuplicateWays(Way way1) {
|
||||
this(way1.getDataSet(), way1, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge duplicate ways
|
||||
*
|
||||
* @param way1 The way to merge duplicates to
|
||||
* @param way2 The way to merge from
|
||||
*/
|
||||
public MergeDuplicateWays(Way way1, Way way2) {
|
||||
this(way1.getDataSet(), way1, way2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge duplicate ways
|
||||
*
|
||||
* @param data The originating dataset
|
||||
* @param way1 The first way to check against
|
||||
* @param way2 The second way
|
||||
*/
|
||||
public MergeDuplicateWays(DataSet data, Way way1, Way way2) {
|
||||
this(data, Stream.of(way1, way2).filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge duplicate ways
|
||||
*
|
||||
* @param data The originating dataset
|
||||
* @param ways The ways to merge. If empty, the entire dataset will be checked.
|
||||
*/
|
||||
public MergeDuplicateWays(DataSet data, List<Way> ways) {
|
||||
super(data);
|
||||
this.ways = ways.stream().filter(MergeDuplicateWays::nonDeletedWay).collect(Collectors.toList());
|
||||
|
@ -118,7 +153,15 @@ public class MergeDuplicateWays extends Command {
|
|||
this.bound = bound;
|
||||
}
|
||||
|
||||
public static void filterDataSet(DataSet dataSet, List<Command> commands, Bounds bound) {
|
||||
/**
|
||||
* Look for duplicates in the dataset
|
||||
*
|
||||
* @param dataSet The dataset to look through
|
||||
* @param commands The command list to add to
|
||||
* @param bound The bounds to look at, may be {@code null}
|
||||
*/
|
||||
public static void filterDataSet(@Nonnull DataSet dataSet, @Nonnull List<Command> commands,
|
||||
@Nullable Bounds bound) {
|
||||
final List<Way> ways = (bound == null ? dataSet.getWays() : dataSet.searchWays(bound.toBBox())).stream()
|
||||
.filter(prim -> !prim.isIncomplete() && !prim.isDeleted())
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
|
|
|
@ -39,6 +39,13 @@ import org.openstreetmap.josm.tools.bugreport.ReportedException;
|
|||
public class MovePrimitiveDataSetCommand extends Command {
|
||||
private Command command;
|
||||
|
||||
/**
|
||||
* Move primitives from one dataset to another
|
||||
*
|
||||
* @param to The destination dataset
|
||||
* @param from The originating dataset
|
||||
* @param primitives The primitives to move
|
||||
*/
|
||||
public MovePrimitiveDataSetCommand(DataSet to, DataSet from, Collection<OsmPrimitive> primitives) {
|
||||
super(to);
|
||||
if (from == null || to.isLocked() || from.isLocked() || to.equals(from)) {
|
||||
|
@ -48,6 +55,15 @@ public class MovePrimitiveDataSetCommand extends Command {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move primitives from one dataset to another
|
||||
*
|
||||
* @param to The destination dataset
|
||||
* @param from The originating dataset
|
||||
* @param primitives The primitives to move
|
||||
* @param primitiveData A collection to be add the primitive data to (important
|
||||
* if any positive ids are available)
|
||||
*/
|
||||
public MovePrimitiveDataSetCommand(DataSet to, DataSet from, Collection<OsmPrimitive> primitives,
|
||||
Collection<PrimitiveData> primitiveData) {
|
||||
super(to);
|
||||
|
|
|
@ -22,6 +22,9 @@ import org.openstreetmap.josm.plugins.mapwithai.commands.AbstractConflationComma
|
|||
import org.openstreetmap.josm.spi.preferences.Config;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Look for ways that have too many nodes
|
||||
*/
|
||||
public class OverNodedWays extends AbstractConflationCommand {
|
||||
|
||||
private class PostponedOverNodedWayCommand extends Command {
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.openstreetmap.josm.plugins.mapwithai.data.mapwithai;
|
|||
|
||||
import static org.openstreetmap.josm.tools.I18n.marktr;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -10,8 +13,6 @@ import java.util.EnumMap;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.openstreetmap.josm.data.sources.ISourceCategory;
|
||||
import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
|
||||
import org.openstreetmap.josm.tools.ImageProvider;
|
||||
|
@ -23,7 +24,7 @@ import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
|
|||
* @author Taylor Smock
|
||||
*
|
||||
*/
|
||||
public enum MapWithAICategory implements ISourceCategory<MapWithAICategory>, Serializable {
|
||||
public enum MapWithAICategory implements ISourceCategory<MapWithAICategory> {
|
||||
|
||||
BUILDING("data/closedway", "buildings", marktr("Buildings")),
|
||||
HIGHWAY("presets/transport/way/way_road", "highways", marktr("Roads")),
|
||||
|
@ -61,6 +62,13 @@ public enum MapWithAICategory implements ISourceCategory<MapWithAICategory>, Ser
|
|||
.computeIfAbsent(this, x -> ImageProvider.get(x.icon, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the category from a string
|
||||
*
|
||||
* @param s The string to get the category from
|
||||
* @return The category, if found, else {@link #OTHER}
|
||||
*/
|
||||
@Nonnull
|
||||
public static MapWithAICategory fromString(String s) {
|
||||
for (MapWithAICategory category : MapWithAICategory.values()) {
|
||||
if (category.getCategoryString().equals(s)) {
|
||||
|
@ -85,7 +93,12 @@ public enum MapWithAICategory implements ISourceCategory<MapWithAICategory>, Ser
|
|||
return OTHER;
|
||||
}
|
||||
|
||||
public static class DescriptionComparator implements Comparator<MapWithAICategory> {
|
||||
/**
|
||||
* Compare two MapWithAI categories
|
||||
*/
|
||||
public static class DescriptionComparator implements Comparator<MapWithAICategory>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 9131636715279880580L;
|
||||
|
||||
@Override
|
||||
public int compare(MapWithAICategory o1, MapWithAICategory o2) {
|
||||
|
|
|
@ -13,6 +13,9 @@ import org.openstreetmap.josm.plugins.mapwithai.io.mapwithai.ConflationSourceRea
|
|||
import org.openstreetmap.josm.plugins.mapwithai.spi.preferences.MapWithAIConfig;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
|
||||
/**
|
||||
* The conflation category
|
||||
*/
|
||||
public final class MapWithAIConflationCategory {
|
||||
private static final Map<MapWithAICategory, List<String>> CONFLATION_URLS = new EnumMap<>(MapWithAICategory.class);
|
||||
private static final String EMPTY_URL = "";
|
||||
|
@ -20,6 +23,9 @@ public final class MapWithAIConflationCategory {
|
|||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the {@link #CONFLATION_URLS}
|
||||
*/
|
||||
public static void initialize() {
|
||||
CONFLATION_URLS.clear();
|
||||
try (ConflationSourceReader reader = new ConflationSourceReader(
|
||||
|
|
|
@ -35,6 +35,9 @@ import org.openstreetmap.josm.tools.CheckParameterUtil;
|
|||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* The information needed to download external data
|
||||
*/
|
||||
public class MapWithAIInfo extends
|
||||
SourceInfo<MapWithAICategory, MapWithAIType, ImageryInfo.ImageryBounds, MapWithAIInfo.MapWithAIPreferenceEntry> {
|
||||
|
||||
|
@ -146,8 +149,13 @@ public class MapWithAIInfo extends
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare MapWithAI info
|
||||
*/
|
||||
public static class MapWithAIInfoCategoryComparator implements Comparator<MapWithAIInfo>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7992892476979310835L;
|
||||
|
||||
@Override
|
||||
public int compare(MapWithAIInfo o1, MapWithAIInfo o2) {
|
||||
return (Objects.nonNull(o1.getCategory()) || Objects.nonNull(o2.getCategory()) ? 1
|
||||
|
@ -156,18 +164,39 @@ public class MapWithAIInfo extends
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple info object
|
||||
*/
|
||||
public MapWithAIInfo() {
|
||||
this((String) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple info object
|
||||
*
|
||||
* @param name The name of the source
|
||||
*/
|
||||
public MapWithAIInfo(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple info object
|
||||
*
|
||||
* @param name The name of the source
|
||||
* @param baseUrl The URL of the source
|
||||
*/
|
||||
public MapWithAIInfo(String name, String baseUrl) {
|
||||
this(name, baseUrl, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple info object
|
||||
*
|
||||
* @param name The name of the source
|
||||
* @param baseUrl The URL of the source
|
||||
* @param id The unique ID of the source
|
||||
*/
|
||||
public MapWithAIInfo(String name, String baseUrl, String id) {
|
||||
super();
|
||||
setName(name);
|
||||
|
@ -201,6 +230,11 @@ public class MapWithAIInfo extends
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an info object from a preference entry
|
||||
*
|
||||
* @param e The preference entry to copy from
|
||||
*/
|
||||
public MapWithAIInfo(MapWithAIPreferenceEntry e) {
|
||||
this(e.name, e.url, e.id);
|
||||
CheckParameterUtil.ensureParameterNotNull(e.name, "name");
|
||||
|
@ -267,6 +301,11 @@ public class MapWithAIInfo extends
|
|||
alreadyConflatedKey = e.alreadyConflatedKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy from another info object
|
||||
*
|
||||
* @param i The object to copy from
|
||||
*/
|
||||
public MapWithAIInfo(MapWithAIInfo i) {
|
||||
this(i.name, i.url, i.id);
|
||||
this.alreadyConflatedKey = i.alreadyConflatedKey;
|
||||
|
@ -313,6 +352,12 @@ public class MapWithAIInfo extends
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this equals the other object as far as the preferences go
|
||||
*
|
||||
* @param other The other object to check against
|
||||
* @return {@code true} if the object is effectively equal
|
||||
*/
|
||||
public boolean equalsPref(MapWithAIInfo other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
|
|
|
@ -262,6 +262,7 @@ public class MapWithAILayerInfo {
|
|||
*/
|
||||
class DefaultEntryLoader extends RecursiveTask<List<MapWithAIInfo>> {
|
||||
|
||||
private static final long serialVersionUID = 12550342142551680L;
|
||||
private final boolean clearCache;
|
||||
private final boolean fastFail;
|
||||
private final List<MapWithAIInfo> newLayers = new ArrayList<>();
|
||||
|
@ -301,8 +302,6 @@ public class MapWithAILayerInfo {
|
|||
}
|
||||
loadSource(source);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logging.error(e);
|
||||
} finally {
|
||||
if (preferences != null) {
|
||||
// saveOnPut is pretty much always true
|
||||
|
@ -629,11 +628,21 @@ public class MapWithAILayerInfo {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a data source
|
||||
*
|
||||
* @param info The source to add
|
||||
*/
|
||||
public static void addLayer(MapWithAIInfo info) {
|
||||
instance.add(info);
|
||||
instance.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple data sources
|
||||
*
|
||||
* @param infos The sources to add
|
||||
*/
|
||||
public static void addLayers(Collection<MapWithAIInfo> infos) {
|
||||
infos.forEach(instance::add);
|
||||
instance.save();
|
||||
|
@ -667,6 +676,9 @@ public class MapWithAILayerInfo {
|
|||
return layerIds.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for the data source info to finish downloading
|
||||
*/
|
||||
public interface FinishListener {
|
||||
/**
|
||||
* Called when information is finished loading
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.data.mapwithai;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.openstreetmap.josm.data.sources.ISourceType;
|
||||
|
||||
/**
|
||||
|
@ -22,13 +24,20 @@ public enum MapWithAIType implements ISourceType<MapWithAIType> {
|
|||
return typeString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type from a string
|
||||
*
|
||||
* @param s The string to parse
|
||||
* @return The type
|
||||
*/
|
||||
@Nonnull
|
||||
public static MapWithAIType fromString(String s) {
|
||||
for (MapWithAIType type : MapWithAIType.values()) {
|
||||
if (type.getTypeString().equals(s)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return MapWithAIType.THIRD_PARTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,6 +31,9 @@ public class PreConflatedDataUtils implements PreferenceChangedListener, Destroy
|
|||
*/
|
||||
private static final String CONFLATED_KEY = "mapwithai:conflated";
|
||||
|
||||
/**
|
||||
* Create a new util object
|
||||
*/
|
||||
public PreConflatedDataUtils() {
|
||||
Config.getPref().addKeyPreferenceChangeListener(PREF_KEY, this);
|
||||
Config.getPref().addKeyPreferenceChangeListener(PREF_KEY_FULL, this);
|
||||
|
|
|
@ -31,9 +31,12 @@ import org.openstreetmap.josm.tools.Logging;
|
|||
* @author Taylor Smock
|
||||
*/
|
||||
public class ConnectingNodeInformationTest extends Test {
|
||||
private static final int ERROR_CODE = 827277536;
|
||||
private static final int ERROR_CODE = 827_277_536;
|
||||
Map<String, String> badTags;
|
||||
|
||||
/**
|
||||
* Create a new test instance
|
||||
*/
|
||||
public ConnectingNodeInformationTest() {
|
||||
super(tr("Left over conflation information (MapWithAI)"),
|
||||
tr("Checks conflation keys that should not exist in OpenStreetMap."));
|
||||
|
@ -73,7 +76,7 @@ public class ConnectingNodeInformationTest extends Test {
|
|||
|
||||
private void checkTags(OsmPrimitive prim) {
|
||||
DataSet ds = prim.getDataSet();
|
||||
if (!UploadPolicy.BLOCKED.equals(ds.getUploadPolicy()) && !DownloadPolicy.BLOCKED.equals(ds.getDownloadPolicy())
|
||||
if (UploadPolicy.BLOCKED != ds.getUploadPolicy() && DownloadPolicy.BLOCKED != ds.getDownloadPolicy()
|
||||
&& prim.hasKey(badTags.keySet().toArray(new String[0]))) {
|
||||
errors.add(TestError.builder(this, Severity.ERROR, ERROR_CODE).primitives(prim)
|
||||
.message(tr("Don''t leave conflation keys in the data {0}",
|
||||
|
|
|
@ -34,9 +34,15 @@ import org.openstreetmap.josm.tools.Geometry;
|
|||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Pair;
|
||||
|
||||
/**
|
||||
* Check the street address order
|
||||
*/
|
||||
public class StreetAddressOrder extends Test {
|
||||
private static final SharpAngles ANGLES_TEST = new SharpAngles();
|
||||
|
||||
/**
|
||||
* Create a new test object
|
||||
*/
|
||||
public StreetAddressOrder() {
|
||||
super(tr("Address order ({0})", MapWithAIPlugin.NAME), tr("Check that street address order makes sense"));
|
||||
}
|
||||
|
@ -127,9 +133,17 @@ public class StreetAddressOrder extends Test {
|
|||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the error to show the user
|
||||
*
|
||||
* @param potentialBadAddress The potential bad address
|
||||
* @param surroundingAddresses The surrounding addresses that make the
|
||||
* potentialBadAddress bad
|
||||
*/
|
||||
public void createError(IPrimitive potentialBadAddress, Collection<IPrimitive> surroundingAddresses) {
|
||||
if (potentialBadAddress instanceof OsmPrimitive) {
|
||||
errors.add(TestError.builder(this, Severity.OTHER, 58542100).primitives((OsmPrimitive) potentialBadAddress)
|
||||
errors.add(TestError.builder(this, Severity.OTHER, 58_542_100)
|
||||
.primitives((OsmPrimitive) potentialBadAddress)
|
||||
.highlight(surroundingAddresses.stream().filter(OsmPrimitive.class::isInstance)
|
||||
.map(OsmPrimitive.class::cast).collect(Collectors.toSet()))
|
||||
.message(tr("{0} (experimental)", MapWithAIPlugin.NAME), marktr("Potential bad address")).build());
|
||||
|
|
|
@ -31,6 +31,9 @@ import org.openstreetmap.josm.spi.preferences.Config;
|
|||
import org.openstreetmap.josm.tools.Geometry;
|
||||
import org.openstreetmap.josm.tools.Pair;
|
||||
|
||||
/**
|
||||
* Check for addr:street and street name mismatches
|
||||
*/
|
||||
public class StreetAddressTest extends Test {
|
||||
/** Standard bbox expansion */
|
||||
public static final double BBOX_EXPANSION = 0.002;
|
||||
|
@ -45,6 +48,9 @@ public class StreetAddressTest extends Test {
|
|||
"motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link",
|
||||
"tertiary", "tertiary_link", "unclassified", "residential", "living_street", "service", "road"));
|
||||
|
||||
/**
|
||||
* Create a new test object
|
||||
*/
|
||||
public StreetAddressTest() {
|
||||
super(tr("Mismatched street/street addresses ({0})", MapWithAIPlugin.NAME),
|
||||
tr("Check for addr:street/street name mismatches"));
|
||||
|
@ -73,14 +79,20 @@ public class StreetAddressTest extends Test {
|
|||
namePrimitiveMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the error
|
||||
*
|
||||
* @param addrStreet The addr:street tag
|
||||
* @param primitives The bad primitives
|
||||
*/
|
||||
public void createError(String addrStreet, List<OsmPrimitive> primitives) {
|
||||
errors.add(TestError.builder(this, Severity.WARNING, 2136232)
|
||||
errors.add(TestError.builder(this, Severity.WARNING, 2_136_232)
|
||||
.message(tr("{0} (experimental)", MapWithAIPlugin.NAME),
|
||||
marktr("Addresses are not nearby a matching road ({0})"), addrStreet)
|
||||
.primitives(primitives).build());
|
||||
}
|
||||
|
||||
public void realVisit(OsmPrimitive primitive) {
|
||||
private void realVisit(OsmPrimitive primitive) {
|
||||
if (primitive.isUsable() && hasStreetAddressTags(primitive) && !primitive.isOutsideDownloadArea()) {
|
||||
Collection<Way> surroundingWays = getSurroundingHighways(primitive);
|
||||
Collection<String> names = getWayNames(surroundingWays);
|
||||
|
@ -90,7 +102,7 @@ public class StreetAddressTest extends Test {
|
|||
}
|
||||
}
|
||||
|
||||
public static Collection<String> getWayNames(Collection<Way> ways) {
|
||||
private static Collection<String> getWayNames(Collection<Way> ways) {
|
||||
return ways.stream().flatMap(w -> w.getInterestingTags().entrySet().stream())
|
||||
.filter(e -> (e.getKey().contains("name") || e.getKey().contains("ref"))
|
||||
&& !e.getKey().contains("tiger"))
|
||||
|
@ -98,7 +110,7 @@ public class StreetAddressTest extends Test {
|
|||
.filter(s -> !s.isEmpty()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Collection<Way> getSurroundingHighways(OsmPrimitive address) {
|
||||
private static Collection<Way> getSurroundingHighways(OsmPrimitive address) {
|
||||
Objects.requireNonNull(address.getDataSet(), "Node must be part of a dataset");
|
||||
DataSet ds = address.getDataSet();
|
||||
BBox addrBox = expandBBox(new BBox(address.getBBox()), BBOX_EXPANSION);
|
||||
|
|
|
@ -24,6 +24,9 @@ import org.openstreetmap.josm.gui.progress.ProgressMonitor;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
|
||||
import org.openstreetmap.josm.spi.preferences.Config;
|
||||
|
||||
/**
|
||||
* Look for short ("stub") ends
|
||||
*/
|
||||
public class StubEndsTest extends Test {
|
||||
private static final String HIGHWAY = "highway";
|
||||
private static final List<String> BAD_HIGHWAYS = Arrays.asList("services", "rest_area");
|
||||
|
@ -32,6 +35,9 @@ public class StubEndsTest extends Test {
|
|||
// Initialize for use with just a `visit` statement
|
||||
private double maxLength = Config.getPref().getDouble(MapWithAIPlugin.NAME + ".stubendlength", DEFAULT_MAX_LENGTH);
|
||||
|
||||
/**
|
||||
* Create a new test object
|
||||
*/
|
||||
public StubEndsTest() {
|
||||
super(tr("Stub Ends ({0})", MapWithAIPlugin.NAME), tr("Look for short ends on ways"));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ package org.openstreetmap.josm.plugins.mapwithai.gui.download;
|
|||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
|
@ -10,10 +14,6 @@ import java.beans.PropertyChangeEvent;
|
|||
import java.beans.PropertyChangeListener;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
import org.openstreetmap.josm.gui.bbox.BBoxChooser;
|
||||
import org.openstreetmap.josm.gui.download.DownloadDialog;
|
||||
|
@ -32,6 +32,9 @@ public class MapWithAIDownloadOptions extends JPanel implements DownloadSelectio
|
|||
private DownloadDialog iGui;
|
||||
private final MapWithAIProvidersPanel mapwithaiProvidersPanel;
|
||||
|
||||
/**
|
||||
* Create a new options panel
|
||||
*/
|
||||
public MapWithAIDownloadOptions() {
|
||||
optionPanel = new JPanel(new GridBagLayout());
|
||||
JPanel infoHeader = new JPanel();
|
||||
|
|
|
@ -19,6 +19,9 @@ import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAILayerInfo;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAILayerInfo.LayerChangeListener;
|
||||
|
||||
/**
|
||||
* Adds the MapWithAI download checkbox to the JOSM download UI
|
||||
*/
|
||||
public class MapWithAIDownloadSourceType implements IDownloadSourceType, LayerChangeListener {
|
||||
static final BooleanProperty IS_ENABLED = new BooleanProperty("download.mapwithai.data", false);
|
||||
JCheckBox cbDownloadMapWithAIData;
|
||||
|
|
|
@ -41,6 +41,9 @@ import org.openstreetmap.josm.tools.GBC;
|
|||
import org.openstreetmap.josm.tools.ImageProvider;
|
||||
import org.openstreetmap.josm.tools.OpenBrowser;
|
||||
|
||||
/**
|
||||
* The MapWithAI preference pane
|
||||
*/
|
||||
public class MapWithAIPreferences extends DefaultTabPreferenceSetting {
|
||||
private final JCheckBox switchLayerCheckBox;
|
||||
private final JCheckBox mergeBuildingAddressCheckBox;
|
||||
|
@ -49,6 +52,9 @@ public class MapWithAIPreferences extends DefaultTabPreferenceSetting {
|
|||
private final List<PrefEntry> replacementTableDisplayData;
|
||||
private static final int MAX_SELECTED_TO_EDIT = 1;
|
||||
|
||||
/**
|
||||
* Create the preference panel
|
||||
*/
|
||||
public MapWithAIPreferences() {
|
||||
super("mapwithai", tr("MapWithAI preferences"), tr("Modify MapWithAI preferences"), false, new JTabbedPane());
|
||||
|
||||
|
@ -95,11 +101,12 @@ public class MapWithAIPreferences extends DefaultTabPreferenceSetting {
|
|||
switchLayer.setToolTipText(
|
||||
tr("If checked, automatically switch from the {0} layer to the OSM layer when objects are added",
|
||||
MapWithAIPlugin.NAME));
|
||||
maximumAddition.setToolTipText(tr(
|
||||
"This is the maximum number of complete OSM objects that can be added from the {0} layer, child objects do not count to this limit",
|
||||
MapWithAIPlugin.NAME));
|
||||
mergeBuildingWithAddress.setToolTipText(tr(
|
||||
"If checked, automatically merge address nodes onto added buildings, if and only if one address is within the building boundary"));
|
||||
maximumAddition.setToolTipText(
|
||||
tr("This is the maximum number of complete OSM objects that can be added from the {0} layer, "
|
||||
+ "child objects do not count to this limit", MapWithAIPlugin.NAME));
|
||||
mergeBuildingWithAddress
|
||||
.setToolTipText(tr("If checked, automatically merge address nodes onto added buildings, "
|
||||
+ "if and only if one address is within the building boundary"));
|
||||
|
||||
switchLayerCheckBox.setSelected(MapWithAIPreferenceHelper.isSwitchLayers());
|
||||
switchLayerCheckBox.setToolTipText(switchLayer.getToolTipText());
|
||||
|
|
|
@ -84,6 +84,9 @@ import org.openstreetmap.josm.tools.OpenBrowser;
|
|||
*/
|
||||
public class MapWithAIProvidersPanel extends JPanel {
|
||||
|
||||
/**
|
||||
* The options for the panel
|
||||
*/
|
||||
public enum Options {
|
||||
/** Hide the active table */
|
||||
SHOW_ACTIVE
|
||||
|
@ -127,8 +130,16 @@ public class MapWithAIProvidersPanel extends JPanel {
|
|||
/** Options that were passed to the constructor */
|
||||
private final Options[] options;
|
||||
|
||||
/**
|
||||
* Listen for area updates
|
||||
*/
|
||||
protected interface AreaListener {
|
||||
|
||||
/**
|
||||
* Update the area
|
||||
*
|
||||
* @param area The bounds to update
|
||||
*/
|
||||
void updateArea(Bounds area);
|
||||
}
|
||||
|
||||
|
@ -211,7 +222,6 @@ public class MapWithAIProvidersPanel extends JPanel {
|
|||
return label;
|
||||
}
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
@Override
|
||||
public void updateArea(Bounds area) {
|
||||
this.area = area;
|
||||
|
|
|
@ -14,6 +14,11 @@ import org.openstreetmap.josm.io.CachedFile;
|
|||
import org.openstreetmap.josm.tools.HttpClient;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Read sources for MapWithAI
|
||||
*
|
||||
* @param <T> The expected type
|
||||
*/
|
||||
public abstract class CommonSourceReader<T> implements AutoCloseable {
|
||||
private final String source;
|
||||
private CachedFile cachedFile;
|
||||
|
|
|
@ -14,6 +14,9 @@ import java.util.stream.Collectors;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory;
|
||||
import org.openstreetmap.josm.tools.Pair;
|
||||
|
||||
/**
|
||||
* Read conflation entries from JSON
|
||||
*/
|
||||
public class ConflationSourceReader extends CommonSourceReader<Map<MapWithAICategory, List<String>>>
|
||||
implements Closeable {
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ public class ESRISourceReader {
|
|||
MapWithAIInfo newInfo = new MapWithAIInfo(source);
|
||||
newInfo.setId(feature.getString("id"));
|
||||
ForkJoinTask<MapWithAIInfo> future;
|
||||
if (feature.getString("type", "").equals("Feature Service")) {
|
||||
if ("Feature Service".equals(feature.getString("type", ""))) {
|
||||
future = ForkJoinTask.adapt(() -> newInfo.setUrl(featureService(newInfo, feature.getString("url"))),
|
||||
newInfo);
|
||||
} else {
|
||||
|
@ -208,11 +208,6 @@ public class ESRISourceReader {
|
|||
@Nullable
|
||||
private static String getJsonString(@Nonnull final String url, final long defaultMaxAge, final boolean fastFail) {
|
||||
String jsonString = SOURCE_CACHE.get(url);
|
||||
if (Config.getPref() != null) {
|
||||
// TODO FIXME remove sometime after January 2022 (give it a chance to cleanup
|
||||
// directories)
|
||||
CachedFile.cleanup(url);
|
||||
}
|
||||
if (jsonString == null) {
|
||||
HttpClient client = null;
|
||||
try {
|
||||
|
|
|
@ -8,6 +8,7 @@ import javax.json.JsonValue;
|
|||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -21,7 +22,6 @@ import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.CountryUtils;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIType;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Territories;
|
||||
|
||||
/**
|
||||
|
@ -124,21 +124,15 @@ public class MapWithAISourceReader extends CommonSourceReader<List<MapWithAIInfo
|
|||
|
||||
private static List<ImageryInfo.ImageryBounds> getBounds(JsonValue countries) {
|
||||
if (JsonValue.ValueType.OBJECT == countries.getValueType()) {
|
||||
Set<String> codes;
|
||||
try {
|
||||
codes = Territories.getKnownIso3166Codes();
|
||||
List<ImageryBounds> bounds = new ArrayList<>();
|
||||
for (Map.Entry<String, JsonValue> country : countries.asJsonObject().entrySet()) {
|
||||
if (codes.contains(country.getKey())) {
|
||||
CountryUtils.getCountryShape(country.getKey()).ifPresent(bounds::add);
|
||||
}
|
||||
Set<String> codes = Territories.getKnownIso3166Codes();
|
||||
List<ImageryBounds> bounds = new ArrayList<>();
|
||||
for (Map.Entry<String, JsonValue> country : countries.asJsonObject().entrySet()) {
|
||||
if (codes.contains(country.getKey())) {
|
||||
CountryUtils.getCountryShape(country.getKey()).ifPresent(bounds::add);
|
||||
}
|
||||
return bounds;
|
||||
} catch (NullPointerException e) {
|
||||
Logging.error(e);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(bounds);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.spi.preferences;
|
||||
|
||||
public class MapWithAIUrls implements IMapWithAIUrls {
|
||||
/**
|
||||
* Store the MapWithAI URLs
|
||||
*/
|
||||
public final class MapWithAIUrls implements IMapWithAIUrls {
|
||||
/** The base url */
|
||||
private static final String BASE_URL = "https://josm.github.io/MapWithAI/";
|
||||
/** The default url for additional conflation servers */
|
||||
|
|
|
@ -42,6 +42,9 @@ import org.openstreetmap.josm.plugins.mapwithai.spi.preferences.MapWithAIConfig;
|
|||
import org.openstreetmap.josm.tools.ColorHelper;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
|
||||
/**
|
||||
* Utils for the MapWithAI paint style
|
||||
*/
|
||||
public final class MapPaintUtils {
|
||||
/** The default url for the MapWithAI paint style */
|
||||
private static final Pattern TEST_PATTERN = Pattern
|
||||
|
@ -53,11 +56,16 @@ public final class MapPaintUtils {
|
|||
private static final String MAPWITHAI_MAPCSS_ZIP_NAME = "Styles_MapWithAI-style.mapcss";
|
||||
private static final double CRC_DIVIDE_TO_TEN_K_MAX = 429496.7296;
|
||||
|
||||
/**
|
||||
* Safe colors
|
||||
*/
|
||||
public enum SafeColors {
|
||||
RED(Color.RED), ORANGE(Color.ORANGE), GOLD(ColorHelper.html2color("#ffd700")),
|
||||
LIME(ColorHelper.html2color("#00ff00")), CYAN(Color.CYAN), DODGER_BLUE(ColorHelper.html2color("#1e90ff")),
|
||||
AI_MAGENTA(ColorHelper.html2color("#ff26d4")), PINK(Color.PINK), LIGHT_GREY(ColorHelper.html2color("#d3d3d3")),
|
||||
LINEN(ColorHelper.html2color("#faf0e6"));
|
||||
RED(Color.RED), ORANGE(Color.ORANGE), GOLD(Objects.requireNonNull(ColorHelper.html2color("#ffd700"))),
|
||||
LIME(Objects.requireNonNull(ColorHelper.html2color("#00ff00"))), CYAN(Color.CYAN),
|
||||
DODGER_BLUE(Objects.requireNonNull(ColorHelper.html2color("#1e90ff"))),
|
||||
AI_MAGENTA(Objects.requireNonNull(ColorHelper.html2color("#ff26d4"))), PINK(Color.PINK),
|
||||
LIGHT_GREY(Objects.requireNonNull(ColorHelper.html2color("#d3d3d3"))),
|
||||
LINEN(Objects.requireNonNull(ColorHelper.html2color("#faf0e6")));
|
||||
|
||||
private final Color color;
|
||||
|
||||
|
@ -85,8 +93,9 @@ public final class MapPaintUtils {
|
|||
*/
|
||||
public static synchronized StyleSource addMapWithAIPaintStyles() {
|
||||
// Remove old url's that were automatically added -- remove after Jan 01, 2020
|
||||
final List<Pattern> oldUrls = Arrays.asList(Pattern.compile(
|
||||
"https://gitlab.com/(gokaart/JOSM_MapWithAI|smocktaylor/rapid)/raw/master/src/resources/styles/standard/(mapwithai|rapid).mapcss"),
|
||||
final List<Pattern> oldUrls = Arrays.asList(
|
||||
Pattern.compile("https://gitlab.com/(gokaart/JOSM_MapWithAI|smocktaylor/rapid)"
|
||||
+ "/raw/master/src/resources/styles/standard/(mapwithai|rapid).mapcss"),
|
||||
TEST_PATTERN, Pattern.compile("resource://styles/standard/mapwithai.mapcss"));
|
||||
new ArrayList<>(MapPaintStyles.getStyles().getStyleSources()).stream()
|
||||
.filter(style -> oldUrls.stream().anyMatch(p -> p.matcher(style.url).matches()))
|
||||
|
@ -100,6 +109,11 @@ public final class MapPaintUtils {
|
|||
return getMapWithAIPaintStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the paint style exists
|
||||
*
|
||||
* @return {@code true} if the paint style exists
|
||||
*/
|
||||
public static synchronized boolean checkIfMapWithAIPaintStyleExists() {
|
||||
return MapPaintStyles.getStyles().getStyleSources().stream().filter(MapCSSStyleSource.class::isInstance)
|
||||
.map(MapCSSStyleSource.class::cast)
|
||||
|
@ -171,10 +185,11 @@ public final class MapPaintUtils {
|
|||
try (ZipFile zipFile = new ZipFile(file.getAbsolutePath())) {
|
||||
writeZipData(zipFile, group, sources);
|
||||
} catch (ZipException e) {
|
||||
Logging.trace(e);
|
||||
// Assume that it is a standard file, not a zip file.
|
||||
try (OutputStream out = Files.newOutputStream(Paths.get(file.getName() + ".tmp"));
|
||||
BufferedReader bufferedReader = new BufferedReader(
|
||||
new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8));) {
|
||||
new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) {
|
||||
writeData(out, bufferedReader, group, sources);
|
||||
}
|
||||
Files.move(new File(file.getName() + ".tmp").toPath(), new File(file.getName()).toPath(),
|
||||
|
|
|
@ -42,7 +42,7 @@ class MapWithAIInfoTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideMapWithAIInfoInitializers")
|
||||
void assertInitializersWorked(MapWithAIInfo i, String name, String url, String id, MapWithAIType type) {
|
||||
void testInitializersWorked(MapWithAIInfo i, String name, String url, String id, MapWithAIType type) {
|
||||
assertEquals(name, i.getName());
|
||||
assertEquals(id, i.getId());
|
||||
assertEquals(url, i.getUrl());
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.ArrayList;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openstreetmap.josm.TestUtils;
|
||||
import org.openstreetmap.josm.gui.preferences.advanced.PrefEntry;
|
||||
import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
|
||||
import org.openstreetmap.josm.testutils.mockers.WindowMocker;
|
||||
|
||||
|
@ -60,11 +59,11 @@ class ReplacementPreferenceTableTest {
|
|||
void setUp() {
|
||||
TestUtils.assumeWorkingJMockit();
|
||||
new WindowMocker();
|
||||
test = new ReplacementPreferenceTable(new ArrayList<PrefEntry>());
|
||||
test = new ReplacementPreferenceTable(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
void testReplacementPreferenceTable() {
|
||||
new ReplacementPreferenceTableMock(true);
|
||||
assertNotNull(test.addPreference(new JPanel()));
|
||||
new ReplacementPreferenceTableMock(false);
|
||||
|
|
|
@ -35,7 +35,7 @@ class AddMapWithAIPanelTest {
|
|||
JOSMTestRules rule = new MapWithAITestRules().territories().projection().assertionsInEDT();
|
||||
|
||||
@Test
|
||||
void test() throws ReflectiveOperationException {
|
||||
void testAddMapWithAIPanel() throws ReflectiveOperationException {
|
||||
new WindowMocker();
|
||||
MapWithAIInfo oldInfo = new MapWithAIInfo();
|
||||
AddMapWithAIPanel panel = new AddMapWithAIPanel(oldInfo);
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.openstreetmap.josm.plugins.mapwithai.io.mapwithai;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -26,6 +25,7 @@ import org.openstreetmap.josm.plugins.mapwithai.testutils.MapWithAITestRules;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.testutils.annotations.Wiremock;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
import org.openstreetmap.josm.testutils.annotations.BasicWiremock;
|
||||
import org.openstreetmap.josm.tools.JosmRuntimeException;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
|
||||
|
@ -67,9 +67,8 @@ class ESRISourceReaderTest {
|
|||
try {
|
||||
return future.get();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
fail(e);
|
||||
throw new JosmRuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}).collect(Collectors.toList());
|
||||
Future<?> workerQueue = MainApplication.worker.submit(() -> {
|
||||
/* Sync threads */});
|
||||
|
|
Ładowanie…
Reference in New Issue