>
23 | implements PseudoCommand {
24 |
25 | private final D data;
26 |
27 | protected GenericCommand(D dataset) {
28 | this.data = dataset;
29 | }
30 |
31 | /**
32 | * Executes the command on the dataset. This implementation will remember all
33 | * primitives returned by fillModifiedData for restoring them on undo.
34 | *
35 | * The layer should be invalidated after execution so that it can be re-painted.
36 | *
37 | * @return true
38 | */
39 | public abstract boolean executeCommand();
40 |
41 | /**
42 | * Undoes the command.
43 | * It can be assumed that all objects are in the same state they were before.
44 | * It can also be assumed that executeCommand was called exactly once before.
45 | * This implementation undoes all objects stored by a former call to executeCommand.
46 | */
47 | public abstract void undoCommand();
48 |
49 | /**
50 | * Gets the data set this command affects.
51 | *
52 | * @return The data set. May be null
if no layer was set and no edit layer was found.
53 | */
54 | public D getAffectedDataSet() {
55 | return data;
56 | }
57 |
58 | /**
59 | * Return the primitives that take part in this command.
60 | *
61 | * @return primitives that take part in this command
62 | */
63 | public abstract Collection extends O> getParticipatingIPrimitives();
64 |
65 | /**
66 | * Fill collections with modified data
67 | *
68 | * @param modified The modified primitives
69 | * @param deleted The deleted primitives
70 | * @param added The added primitives
71 | */
72 | public abstract void fillModifiedData(Collection modified, Collection deleted, Collection added);
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/data/mapillary/DataType.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.data.mapillary;
3 |
4 | import org.openstreetmap.josm.actions.ExpertToggleAction;
5 | import org.openstreetmap.josm.plugins.mapillary.gui.DeveloperToggleAction;
6 |
7 | /**
8 | * Use for features that should only be shown when expert/developer
9 | */
10 | public enum DataType {
11 | /** Only visible with developer mode and expert mode */
12 | TESTING(true, true),
13 | /** Only visible with expert mode */
14 | PREVIEW(true, false),
15 | /** Always visible */
16 | PRODUCTION(false, false);
17 |
18 | private final boolean expert;
19 | private final boolean developer;
20 |
21 | DataType(boolean expert, boolean developer) {
22 | this.expert = expert;
23 | this.developer = developer;
24 | }
25 |
26 | /**
27 | * Use to determine if something should be visible. Only use dynamically.
28 | *
29 | * @return {@code true} if it should be visible.
30 | */
31 | public boolean shouldBeVisible() {
32 | boolean e = !this.expert || ExpertToggleAction.isExpert();
33 | boolean d = !this.developer || DeveloperToggleAction.isDeveloper();
34 | return e && d;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/data/mapillary/DetectionType.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.data.mapillary;
3 |
4 | /**
5 | * Base detection types for Mapillary object detections
6 | */
7 | public enum DetectionType {
8 | /** Traffic sign type/class */
9 | TRAFFIC_SIGN("signs"),
10 | /** Point object features like fire hydrants */
11 | POINT("objects"),
12 | /** Line object features */
13 | LINE(null),
14 | /** Segmentation features */
15 | SEGMENTATION(null);
16 |
17 | private final String imageLocationString;
18 |
19 | /**
20 | * Create a new detection type
21 | *
22 | * @param imageLocationString {@code "mapillary_sprite_source/package_" + imageLocationString}
23 | */
24 | DetectionType(String imageLocationString) {
25 | this.imageLocationString = imageLocationString == null ? null : "package_" + imageLocationString;
26 | }
27 |
28 | /**
29 | * The directory for the image location
30 | *
31 | * @return A path to be used as a directory when getting an image
32 | */
33 | public String getImageLocationString() {
34 | return this.imageLocationString;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/data/mapillary/ImageMode.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.data.mapillary;
3 |
4 | import jakarta.annotation.Nonnull;
5 |
6 | /**
7 | * Possible image modes
8 | *
9 | * @author Taylor Smock
10 | */
11 | public enum ImageMode {
12 | /** The default mode */
13 | NORMAL,
14 | /** The mode used when walking */
15 | WALK,
16 | /** When smart edits are being done */
17 | SMART_EDIT;
18 |
19 | private static ImageMode currentMode = NORMAL;
20 |
21 | /**
22 | * Get the current mode
23 | *
24 | * @return The current mode
25 | */
26 | public static ImageMode getMode() {
27 | return currentMode;
28 | }
29 |
30 | /**
31 | * Set the mode
32 | *
33 | * @param mode The new mode
34 | */
35 | public static void setMode(@Nonnull ImageMode mode) {
36 | currentMode = mode;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/data/mapillary/VectorDataSelectionListener.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.data.mapillary;
3 |
4 | import org.openstreetmap.josm.data.osm.event.IDataSelectionListener;
5 | import org.openstreetmap.josm.data.vector.VectorDataSet;
6 | import org.openstreetmap.josm.data.vector.VectorNode;
7 | import org.openstreetmap.josm.data.vector.VectorPrimitive;
8 | import org.openstreetmap.josm.data.vector.VectorRelation;
9 | import org.openstreetmap.josm.data.vector.VectorWay;
10 |
11 | /**
12 | * A convenient listener for selection events in vector data
13 | */
14 | public interface VectorDataSelectionListener
15 | extends IDataSelectionListener {
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/data/osm/event/FilterEventListener.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.data.osm.event;
3 |
4 | import java.util.Arrays;
5 | import java.util.List;
6 | import java.util.stream.Collectors;
7 |
8 | import javax.swing.SwingUtilities;
9 | import javax.swing.event.TableModelEvent;
10 | import javax.swing.event.TableModelListener;
11 |
12 | import org.openstreetmap.josm.data.osm.Filter;
13 | import org.openstreetmap.josm.data.osm.FilterMatcher;
14 | import org.openstreetmap.josm.data.osm.FilterWorker;
15 | import org.openstreetmap.josm.data.osm.IFilterablePrimitive;
16 | import org.openstreetmap.josm.data.osm.OsmData;
17 | import org.openstreetmap.josm.data.osm.search.SearchParseError;
18 | import org.openstreetmap.josm.gui.MainApplication;
19 | import org.openstreetmap.josm.gui.layer.Layer;
20 | import org.openstreetmap.josm.plugins.mapillary.gui.dialog.MapillaryExpertFilterDialog;
21 | import org.openstreetmap.josm.tools.Logging;
22 |
23 | /**
24 | * This class allows layers to listen for changes to the filter dialog, and have the filters applied to an arbitrary
25 | * dataset.
26 | *
27 | * @author Taylor Smock
28 | */
29 | public class FilterEventListener implements TableModelListener {
30 | private final Layer layer;
31 | private final OsmData extends IFilterablePrimitive, ?, ?, ?> data;
32 | public final FilterMatcher matcher;
33 |
34 | public FilterEventListener(Layer layer, OsmData extends IFilterablePrimitive, ?, ?, ?> data) {
35 | this.layer = layer;
36 | this.data = data;
37 | matcher = new FilterMatcher();
38 | }
39 |
40 | @Override
41 | public void tableChanged(TableModelEvent e) {
42 | updateAndRunFilters();
43 | }
44 |
45 | public synchronized void updateAndRunFilters() {
46 | matcher.reset();
47 | if (MainApplication.getMap() != null) {
48 | for (List filters : Arrays.asList(
49 | MapillaryExpertFilterDialog.getInstance().getFilterModel().getFilters(),
50 | MainApplication.getMap().filterDialog.getFilterModel().getFilters())) {
51 | for (Filter filter : filters) {
52 | try {
53 | matcher.add(filter);
54 | } catch (SearchParseError e1) {
55 | Logging.error(e1);
56 | }
57 | }
58 | }
59 | }
60 | FilterWorker.executeFilters(
61 | data.allPrimitives().stream().filter(p -> p.getReferrers().isEmpty()).collect(Collectors.toList()),
62 | matcher);
63 | SwingUtilities.invokeLater(layer::invalidate);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/boilerplate/MapillaryButton.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.boilerplate;
3 |
4 | import java.awt.Color;
5 | import java.awt.Graphics;
6 | import java.awt.Graphics2D;
7 | import java.awt.RenderingHints;
8 |
9 | import javax.swing.Action;
10 | import javax.swing.BorderFactory;
11 | import javax.swing.JButton;
12 |
13 | import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryColorScheme;
14 |
15 | public class MapillaryButton extends JButton {
16 | private static final long serialVersionUID = 2619282066157874464L;
17 |
18 | public MapillaryButton(final Action action) {
19 | this(action, false);
20 | }
21 |
22 | public MapillaryButton(final Action action, boolean slim) {
23 | super(action);
24 | setForeground(Color.WHITE);
25 | setBorder(slim ? BorderFactory.createEmptyBorder(3, 4, 3, 4) : BorderFactory.createEmptyBorder(7, 10, 7, 10));
26 | }
27 |
28 | @Override
29 | protected void paintComponent(final Graphics g) {
30 | if (!isEnabled()) {
31 | g.setColor(MapillaryColorScheme.TOOLBAR_DARK_GREY);
32 | } else if (getModel().isPressed()) {
33 | g.setColor(MapillaryColorScheme.MAPILLARY_GREEN.darker().darker());
34 | } else if (getModel().isRollover()) {
35 | g.setColor(MapillaryColorScheme.MAPILLARY_GREEN.darker());
36 | } else {
37 | g.setColor(MapillaryColorScheme.MAPILLARY_GREEN);
38 | }
39 | ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
40 | g.fillRoundRect(0, 0, getWidth(), getHeight(), 3, 3);
41 | super.paintComponent(g);
42 | }
43 |
44 | @Override
45 | public boolean isContentAreaFilled() {
46 | return false;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/dialog/OrganizationListCellRenderer.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.dialog;
3 |
4 | import java.awt.Component;
5 | import java.awt.Image;
6 | import java.util.Map;
7 | import java.util.concurrent.ConcurrentHashMap;
8 |
9 | import javax.swing.DefaultListCellRenderer;
10 | import javax.swing.ImageIcon;
11 | import javax.swing.JLabel;
12 | import javax.swing.JList;
13 |
14 | import org.openstreetmap.josm.plugins.mapillary.data.mapillary.OrganizationRecord;
15 | import org.openstreetmap.josm.tools.ImageProvider;
16 |
17 | /**
18 | * A cell renderer for organization lists
19 | */
20 | public class OrganizationListCellRenderer extends DefaultListCellRenderer {
21 | private static final long serialVersionUID = -1650696801628131389L;
22 | /** Scaled organization icons -- cached for performance */
23 | private static final Map ORGANIZATION_SCALED_ICONS = new ConcurrentHashMap<>(0);
24 |
25 | @Override
26 | public Component getListCellRendererComponent(JList> list, Object value, int index, boolean isSelected,
27 | boolean cellHasFocus) {
28 | JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
29 | if (value instanceof OrganizationRecord) {
30 | OrganizationRecord organization = (OrganizationRecord) value;
31 | if ((organization.niceName() != null && !organization.niceName().isEmpty())
32 | || OrganizationRecord.NULL_RECORD.equals(organization)) {
33 | comp.setText(organization.niceName());
34 | } else {
35 | comp.setText(Long.toString(organization.id()));
36 | }
37 | if (organization.avatar() != null) {
38 | comp.setIcon(ORGANIZATION_SCALED_ICONS.computeIfAbsent(organization,
39 | OrganizationListCellRenderer::scaleOrganizationIcon));
40 | }
41 | }
42 | return comp;
43 | }
44 |
45 | /**
46 | * Scale organization icons
47 | *
48 | * @param organization The organization whose icon needs to be scaled
49 | * @return The scaled icon
50 | */
51 | private static ImageIcon scaleOrganizationIcon(final OrganizationRecord organization) {
52 | final ImageProvider.ImageSizes size = ImageProvider.ImageSizes.DEFAULT;
53 | final Image scaledImage = organization.avatar().getImage().getScaledInstance(size.getAdjustedWidth(),
54 | size.getAdjustedHeight(), Image.SCALE_SMOOTH);
55 | return new ImageIcon(scaledImage);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/dialog/ResetListener.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.dialog;
3 |
4 | /**
5 | * A listener for resetting state
6 | */
7 | public interface ResetListener {
8 | /**
9 | * Reset the implementation to a default state
10 | */
11 | void reset();
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/dialog/UserProfileListCellRenderer.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.dialog;
3 |
4 | import java.awt.Component;
5 |
6 | import javax.swing.DefaultListCellRenderer;
7 | import javax.swing.JLabel;
8 | import javax.swing.JList;
9 |
10 | import org.openstreetmap.josm.plugins.mapillary.model.UserProfile;
11 |
12 | /**
13 | * A renderer for {@link UserProfile} objects
14 | */
15 | class UserProfileListCellRenderer extends DefaultListCellRenderer {
16 | @Override
17 | public Component getListCellRendererComponent(JList> list, Object value, int index, boolean isSelected,
18 | boolean cellHasFocus) {
19 | JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
20 | if (value instanceof UserProfile userProfile) {
21 | if (userProfile.username() != null && !userProfile.username().isBlank()) {
22 | comp.setText(userProfile.username());
23 | } else if (!UserProfile.NONE.equals(userProfile)) {
24 | comp.setText(Long.toString(userProfile.key()));
25 | } else {
26 | comp.setText("");
27 | }
28 | }
29 | return comp;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/imageinfo/MapillaryAction.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.imageinfo;
3 |
4 | import javax.swing.Action;
5 |
6 | import org.openstreetmap.josm.actions.JosmAction;
7 | import org.openstreetmap.josm.tools.Shortcut;
8 |
9 | /**
10 | * A common class for Mapillary actions
11 | */
12 | abstract class MapillaryAction extends JosmAction {
13 | MapillaryAction(String name, String icon, String tooltip, Shortcut shortcut, boolean registerInToolbar,
14 | String toolbarId, boolean installAdapters) {
15 | super(name, icon, tooltip, shortcut, registerInToolbar, toolbarId, installAdapters);
16 | // We don't need the large icon, and it messes with spacing in buttons
17 | this.putValue(Action.LARGE_ICON_KEY, null);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/imageinfo/WebLinkAction.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.imageinfo;
3 |
4 | import static org.openstreetmap.josm.tools.I18n.tr;
5 |
6 | import java.awt.event.ActionEvent;
7 | import java.awt.event.KeyEvent;
8 | import java.io.Serial;
9 | import java.net.URI;
10 | import java.net.URISyntaxException;
11 |
12 | import javax.swing.JOptionPane;
13 |
14 | import org.openstreetmap.josm.gui.Notification;
15 | import org.openstreetmap.josm.tools.I18n;
16 | import org.openstreetmap.josm.tools.Logging;
17 | import org.openstreetmap.josm.tools.OpenBrowser;
18 | import org.openstreetmap.josm.tools.Shortcut;
19 |
20 | /**
21 | * An action to open web links
22 | */
23 | public class WebLinkAction extends MapillaryAction {
24 | @Serial
25 | private static final long serialVersionUID = 2397830510179013823L;
26 |
27 | private URI uri;
28 |
29 | /**
30 | * Create a new action
31 | */
32 | public WebLinkAction() {
33 | super(tr("View in browser"), "link", tr("Open in browser"),
34 | Shortcut.registerShortcut("mapillary:open_in_browser_View_in_browser",
35 | tr("Mapillary: Open image in browser"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE),
36 | false, "mapillary:open_in_browser_View_in_browser", false);
37 | }
38 |
39 | /**
40 | * Set the URL to be opened
41 | *
42 | * @param url the url to set
43 | */
44 | public final void setURI(URI url) {
45 | this.uri = url;
46 | setEnabled(url != null);
47 | }
48 |
49 | /*
50 | * (non-Javadoc)
51 | * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
52 | */
53 | @Override
54 | public void actionPerformed(ActionEvent e) {
55 | try {
56 | if (uri != null) {
57 | OpenBrowser.displayUrl(uri);
58 | } else {
59 | throw new URISyntaxException("‹null›", "The URL is null");
60 | }
61 | } catch (URISyntaxException e1) {
62 | String msg = I18n.tr("Could not open the URL {0} in a browser", "‹null›");
63 | Logging.log(Logging.LEVEL_WARN, msg, e1);
64 | new Notification(msg).setIcon(JOptionPane.WARNING_MESSAGE).show();
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/layer/AdditionalActionPanel.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.layer;
3 |
4 | import java.awt.Color;
5 |
6 | import javax.swing.BorderFactory;
7 | import javax.swing.JButton;
8 | import javax.swing.JPanel;
9 | import javax.swing.UIManager;
10 |
11 | class AdditionalActionPanel extends JPanel {
12 | private boolean hasEnabledActions;
13 |
14 | /**
15 | * Create an additional action panel
16 | *
17 | * @param actionButtons The action buttons
18 | */
19 | public AdditionalActionPanel(JButton... actionButtons) {
20 | this.setBackground(UIManager.getColor("ToolTip.background"));
21 | this.setForeground(UIManager.getColor("ToolTip.foreground"));
22 | this.setFont(UIManager.getFont("ToolTip.font"));
23 | this.setBorder(BorderFactory.createLineBorder(Color.black));
24 | for (JButton button : actionButtons) {
25 | this.add(button);
26 | this.hasEnabledActions = this.hasEnabledActions || button.getAction().isEnabled();
27 | }
28 | }
29 |
30 | /**
31 | * Check if there is content in the layer
32 | *
33 | * @return {@code true} if there is content to show
34 | */
35 | public boolean hasContent() {
36 | return this.hasEnabledActions;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/layer/MapillaryLayerDrawTypes.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.layer;
3 |
4 | /**
5 | * Supported draw types
6 | */
7 | public enum MapillaryLayerDrawTypes {
8 | DEFAULT, VELOCITY_CAR, VELOCITY_BIKE, VELOCITY_FOOT, DIRECTION, DATE;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/package-info.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | /**
3 | * The GUI components that are special to the mapillary plugin.
4 | */
5 | package org.openstreetmap.josm.plugins.mapillary.gui;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/widget/DisableShortcutsOnFocusGainedJSpinner.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.widget;
3 |
4 | import java.util.ArrayList;
5 | import java.util.HashSet;
6 | import java.util.List;
7 | import java.util.Set;
8 |
9 | import javax.swing.Action;
10 | import javax.swing.JSpinner;
11 | import javax.swing.SpinnerModel;
12 |
13 | import org.openstreetmap.josm.actions.JosmAction;
14 | import org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedComponent;
15 | import org.openstreetmap.josm.tools.Pair;
16 | import org.openstreetmap.josm.tools.Shortcut;
17 |
18 | /**
19 | * A JSpinner that disables shortcuts when focus is gained
20 | *
21 | * @author Taylor Smock
22 | */
23 | public class DisableShortcutsOnFocusGainedJSpinner extends JSpinner implements DisableShortcutsOnFocusGainedComponent {
24 | private final Set disabledMenuActions = new HashSet<>();
25 | private final List> unregisteredActionShortcuts = new ArrayList<>();
26 |
27 | public DisableShortcutsOnFocusGainedJSpinner(final SpinnerModel spinnerModel) {
28 | super(spinnerModel);
29 | }
30 |
31 | @Override
32 | public List> getUnregisteredActionShortcuts() {
33 | return this.unregisteredActionShortcuts;
34 | }
35 |
36 | @Override
37 | public Set getDisabledMenuActions() {
38 | return this.disabledMenuActions;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/workers/MapillaryNodesDownloader.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.workers;
3 |
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.Objects;
7 | import java.util.concurrent.ExecutionException;
8 | import java.util.function.Consumer;
9 | import java.util.stream.Collectors;
10 |
11 | import org.openstreetmap.josm.plugins.mapillary.data.mapillary.MapillaryDownloader;
12 | import org.openstreetmap.josm.plugins.mapillary.data.mapillary.MapillaryNode;
13 | import org.openstreetmap.josm.tools.JosmRuntimeException;
14 |
15 | /**
16 | * Download nodes asynchronously
17 | */
18 | public class MapillaryNodesDownloader extends MapillaryUIDownloader, Void> {
19 | private static final List downloadList = new ArrayList<>();
20 | private final Consumer> onFinish;
21 | private final long[] images;
22 |
23 | public MapillaryNodesDownloader(Consumer> onFinish, long... images) {
24 | Objects.requireNonNull(onFinish);
25 | Objects.requireNonNull(images);
26 | downloadList.add(this);
27 | this.onFinish = onFinish;
28 | this.images = images.clone();
29 | }
30 |
31 | @Override
32 | protected List doInBackground() {
33 | return MapillaryDownloader.downloadImages(images).values().stream().flatMap(List::stream)
34 | .collect(Collectors.toList());
35 | }
36 |
37 | @Override
38 | protected void done() {
39 | try {
40 | super.done();
41 | this.onFinish.accept(this.get());
42 | } catch (InterruptedException e) {
43 | Thread.currentThread().interrupt();
44 | throw new JosmRuntimeException(e);
45 | } catch (ExecutionException e) {
46 | throw new JosmRuntimeException(e);
47 | } finally {
48 | downloadList.remove(this);
49 | }
50 | }
51 |
52 | /**
53 | * Kill all download threads
54 | */
55 | public static void killAll() {
56 | // Kill the sequence downloader first -- it may cause nodes to be downloaded
57 | MapillarySequenceDownloader.killAll();
58 | // Kill individual node downloads
59 | MapillaryNodeDownloader.killAll();
60 | for (MapillaryNodesDownloader downloader : downloadList) {
61 | downloader.cancel(true);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/workers/MapillaryUIDownloader.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.gui.workers;
3 |
4 | import javax.swing.SwingWorker;
5 |
6 | /**
7 | * A common class for downloaders
8 | *
9 | * @param The primary return type
10 | * @param The updating type
11 | * @see SwingWorker
12 | */
13 | abstract class MapillaryUIDownloader extends SwingWorker {
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/io/download/TileAddEventSource.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.io.download;
3 |
4 | import org.openstreetmap.gui.jmapviewer.Tile;
5 |
6 | /**
7 | * The source for {@link TileAddListener} events
8 | *
9 | * @param The tile type
10 | */
11 | public interface TileAddEventSource {
12 | /**
13 | * Add a listener
14 | *
15 | * @param listener The listener to add
16 | * @param The listener type
17 | * @return {@code true} if the listener was added
18 | */
19 | > boolean addListener(L listener);
20 |
21 | /**
22 | * Remove a listener
23 | *
24 | * @param listener The listener to remove
25 | * @param The listener type
26 | * @return {@code true} if the listener was removed
27 | */
28 | > boolean removeListener(L listener);
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/io/download/TileAddListener.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.io.download;
3 |
4 | import org.openstreetmap.gui.jmapviewer.Tile;
5 |
6 | /**
7 | * Listen for tile add events
8 | * @param The tile type that we are listening for
9 | */
10 | public interface TileAddListener {
11 | /**
12 | * Called when a tile is added
13 | *
14 | * @param tile The tile added
15 | */
16 | void tileAdded(T tile);
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/io/export/package-info.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | /**
3 | * Classes for exporting images that were downloaded from mapillary.com .
4 | */
5 | package org.openstreetmap.josm.plugins.mapillary.io.export;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/io/package-info.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | /**
3 | * Classes for I/O operations like downloading images and their metadata and exporting them.
4 | */
5 | package org.openstreetmap.josm.plugins.mapillary.io;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/model/KeyIndexedObject.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.model;
3 |
4 | import java.io.Serializable;
5 |
6 | /**
7 | * An object that is identified amongst objects of the same class by a {@link String} key.
8 | *
9 | * @param The key type
10 | */
11 | public interface KeyIndexedObject extends Serializable {
12 | /**
13 | * Get the key for the object
14 | *
15 | * @return the unique key that identifies this object among other instances of the same class
16 | */
17 | T key();
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/model/SpecialImageArea.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.model;
3 |
4 | import java.awt.Shape;
5 | import java.util.Objects;
6 |
7 | import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryProperties;
8 |
9 | /**
10 | * Special image areas
11 | *
12 | * @param The key type
13 | * @param The shape type
14 | */
15 | public class SpecialImageArea implements KeyIndexedObject {
16 | private final S key;
17 | private final S imageKey;
18 | private final T shape;
19 |
20 | protected SpecialImageArea(final T shape, final S imageKey, final S key) {
21 | this.key = key;
22 | this.shape = shape;
23 | this.imageKey = imageKey;
24 | }
25 |
26 | public S getImageKey() {
27 | return imageKey;
28 | }
29 |
30 | public Shape getShape() {
31 | if (Boolean.TRUE.equals(MapillaryProperties.SMART_EDIT.get())) {
32 | return shape.getBounds2D();
33 | }
34 | return shape;
35 | }
36 |
37 | @Override
38 | public S key() {
39 | return this.key;
40 | }
41 |
42 | @Override
43 | public boolean equals(Object object) {
44 | if (super.equals(object) && this.getClass().equals(object.getClass())) {
45 | SpecialImageArea, ?> other = (SpecialImageArea, ?>) object;
46 | return Objects.equals(this.shape, other.shape) && Objects.equals(this.imageKey, other.imageKey);
47 | }
48 | return false;
49 | }
50 |
51 | @Override
52 | public int hashCode() {
53 | return Objects.hash(super.hashCode(), this.imageKey, this.shape);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/oauth/MapillaryLoginListener.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.oauth;
3 |
4 | /**
5 | * This interface should be implemented by components that want to get notified when the user
6 | * logs in or logs out of his Mapillary account.
7 | * Such listeners can be registered e.g. at a {@link OAuthPortListener}.
8 | */
9 | public interface MapillaryLoginListener {
10 | /**
11 | * Should be called whenever the user logs into a mapillary account.
12 | * E.g. for updating the GUI to reflect the login status.
13 | *
14 | * @param username the username that the user is now logged in with
15 | */
16 | void onLogin(final String username);
17 |
18 | /**
19 | * Should be called whenever the user logs out of a mapillary account.
20 | * E.g. for updating the GUI to reflect the login status.
21 | */
22 | void onLogout();
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/oauth/package-info.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | /**
3 | * Everything related to signing users in and out of Mapillary.
4 | * We are using OAuth 2.0 to authenticate the user against the Mapillary API.
5 | * See https://a.mapillary.com/#oauth for more details.
6 | */
7 | package org.openstreetmap.josm.plugins.mapillary.oauth;
8 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/package-info.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | /**
3 | * The main package in which all core-code (so at the moment all code) resides.
4 | */
5 | package org.openstreetmap.josm.plugins.mapillary;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/spi/preferences/ApiKeyReader.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.spi.preferences;
3 |
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | import jakarta.json.Json;
8 | import jakarta.json.JsonObject;
9 | import jakarta.json.JsonReader;
10 | import org.openstreetmap.josm.spi.preferences.Config;
11 | import org.openstreetmap.josm.tools.Logging;
12 | import org.openstreetmap.josm.tools.ResourceProvider;
13 | import org.openstreetmap.josm.tools.Utils;
14 |
15 | /**
16 | * Read api keys from a system property, then JOSM preferences, and finally from an API key file in the jar.
17 | */
18 | public final class ApiKeyReader {
19 | private ApiKeyReader() {
20 | /* Hide constructor */ }
21 |
22 | private static final String API_KEY_FILE = "mapillary_api_keys.json";
23 |
24 | static String readValue(final String key) {
25 | // Prefer system property (this is something that can be changed fairly easily)
26 | if (System.getProperty(key) != null) {
27 | return System.getProperty(key);
28 | }
29 | // Then check if there was something stored in JOSM preferences
30 | if (Config.getPref() != null && !Utils.isStripEmpty(Config.getPref().get("mapillary.api." + key))) {
31 | return Config.getPref().get("mapillary.api." + key);
32 | }
33 | // Then check and see if the api key file has the key
34 | final InputStream fileStream = ResourceProvider.getResourceAsStream(API_KEY_FILE);
35 | if (fileStream != null) {
36 | try (JsonReader reader = Json.createReader(fileStream)) {
37 | final JsonObject object = reader.readObject();
38 | if (object.containsKey(key)) {
39 | return object.getString(key);
40 | }
41 | } finally {
42 | try {
43 | fileStream.close();
44 | } catch (IOException e) {
45 | Logging.error(e);
46 | }
47 | }
48 | }
49 | // Finally, return "test" no value has been found
50 | return "test";
51 | }
52 |
53 | static long readMapillaryClientId() {
54 | try {
55 | final String stringValue = readValue("MAPILLARY_CLIENT_ID");
56 | return Long.parseLong(stringValue);
57 | } catch (NumberFormatException numberFormatException) {
58 | Logging.error(numberFormatException);
59 | }
60 | return 4_280_585_711_960_869L;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/spi/preferences/IMapillaryUrlChange.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.spi.preferences;
3 |
4 | /**
5 | * Used to indicate that urls have changed
6 | *
7 | * @author Taylor Smock
8 | */
9 | public interface IMapillaryUrlChange {
10 | /**
11 | * Called when {@link MapillaryConfig} changes url implementation
12 | *
13 | * @param oldUrls The old instance
14 | * @param newUrls The new instance
15 | */
16 | void urlsChanged(final IMapillaryUrls oldUrls, final IMapillaryUrls newUrls);
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/spi/preferences/MapillaryConfig.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.spi.preferences;
3 |
4 | import org.openstreetmap.josm.spi.preferences.IBaseDirectories;
5 | import org.openstreetmap.josm.tools.ListenerList;
6 |
7 | /**
8 | * A class holding configuration information
9 | *
10 | * @author Taylor Smock
11 | */
12 | public final class MapillaryConfig {
13 | private MapillaryConfig() {
14 | // hide constructor
15 | }
16 |
17 | private static final ListenerList MAPILLARY_URL_CHANGE_LISTENER_LIST = ListenerList.create();
18 |
19 | private static IMapillaryUrls urls;
20 | private static IBaseDirectories pluginDirs;
21 |
22 | /**
23 | * Add a listener for URL changes
24 | *
25 | * @param listener The listener to add
26 | */
27 | public static void addUrlChangeListener(final IMapillaryUrlChange listener) {
28 | if (!MAPILLARY_URL_CHANGE_LISTENER_LIST.containsListener(listener)) {
29 | MAPILLARY_URL_CHANGE_LISTENER_LIST.addListener(listener);
30 | }
31 | }
32 |
33 | /**
34 | * Set the current URL provider
35 | *
36 | * @param urlsProvider The provider to use
37 | */
38 | public static void setUrlsProvider(final IMapillaryUrls urlsProvider) {
39 | final IMapillaryUrls oldUrls = urls;
40 | urls = urlsProvider;
41 | MAPILLARY_URL_CHANGE_LISTENER_LIST.fireEvent(target -> target.urlsChanged(oldUrls, urls));
42 | }
43 |
44 | /**
45 | * The current URL provider
46 | *
47 | * @return get the provider
48 | */
49 | public static IMapillaryUrls getUrls() {
50 | return urls;
51 | }
52 |
53 | /**
54 | * Set the plugin directory provider
55 | *
56 | * @param pluginDirs The plugin directory provider
57 | */
58 | public static void setDirectoriesProvider(IBaseDirectories pluginDirs) {
59 | MapillaryConfig.pluginDirs = pluginDirs;
60 | }
61 |
62 | /**
63 | * Get the base directories for the plugin
64 | *
65 | * @return The base directories
66 | */
67 | public static IBaseDirectories getPluginDirs() {
68 | return pluginDirs;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/spi/preferences/MapillaryUrls.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.spi.preferences;
3 |
4 | import static org.openstreetmap.josm.plugins.mapillary.spi.preferences.ApiKeyReader.readMapillaryClientId;
5 | import static org.openstreetmap.josm.plugins.mapillary.spi.preferences.ApiKeyReader.readValue;
6 |
7 | /**
8 | * The default URL implementation
9 | *
10 | * @author Taylor Smock
11 | */
12 | public class MapillaryUrls implements IMapillaryUrls {
13 | private static final String BASE_URL = "https://www.mapillary.com/";
14 | /**
15 | * The API key for v4
16 | */
17 | private static final String ACCESS_ID = readValue("MAPILLARY_CLIENT_TOKEN");
18 | /**
19 | * This is the client id for the application, used solely for authentication
20 | */
21 | private static final long CLIENT_ID = readMapillaryClientId();
22 |
23 | /**
24 | * This is the client secret for the application, used solely for authentication
25 | */
26 | private static final String CLIENT_SECRET = readValue("MAPILLARY_CLIENT_SECRET");
27 |
28 | /** The base URL to get metadata */
29 | private static final String BASE_META_DATA_URL = "https://graph.mapillary.com/";
30 | /** The base URL for tiles */
31 | private static final String BASE_TILE_URL = "https://tiles.mapillary.com/maps/vtp/";
32 | /** The paint style url */
33 | private static final String PAINT_STYLE_URL = "https://josm.openstreetmap.de/josmfile?page=Styles/MapillaryDetections&zip=1";
34 |
35 | @Override
36 | public String getBaseMetaDataUrl() {
37 | return BASE_META_DATA_URL;
38 | }
39 |
40 | @Override
41 | public String getBaseTileUrl() {
42 | return BASE_TILE_URL;
43 | }
44 |
45 | @Override
46 | public String getPaintStyleUrl() {
47 | return PAINT_STYLE_URL;
48 | }
49 |
50 | @Override
51 | public String getAccessId() {
52 | return ACCESS_ID;
53 | }
54 |
55 | @Override
56 | public long getClientId() {
57 | return CLIENT_ID;
58 | }
59 |
60 | @Override
61 | public String getClientSecret() {
62 | return CLIENT_SECRET;
63 | }
64 |
65 | @Override
66 | public String getBaseUrl() {
67 | return BASE_URL;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/DetectionVerification.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import java.util.Locale;
5 |
6 | import org.openstreetmap.josm.plugins.mapillary.model.ImageDetection;
7 |
8 | /**
9 | * Vote for/against a detection
10 | */
11 | public final class DetectionVerification {
12 | /** The type of vote to make */
13 | public enum TYPE {
14 | /** Approve the detection */
15 | APPROVE,
16 | /** Reject the detection */
17 | REJECT;
18 |
19 | @Override
20 | public String toString() {
21 | return this.name().toLowerCase(Locale.ENGLISH);
22 | }
23 | }
24 |
25 | /**
26 | * Vote for a detection
27 | *
28 | * @param detection The detection to vote for
29 | * @param type The type of vote to make
30 | * @return {@code true} if successful
31 | */
32 | public static boolean vote(ImageDetection> detection, TYPE type) {
33 | throw new UnsupportedOperationException("Mapillary: v4 API does not currently support voting");
34 | }
35 |
36 | private DetectionVerification() {
37 | // Don't instantiate
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/ImageUtil.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import java.awt.Graphics2D;
5 | import java.awt.Image;
6 | import java.awt.geom.AffineTransform;
7 | import java.awt.image.BufferedImage;
8 |
9 | import javax.swing.ImageIcon;
10 |
11 | import org.openstreetmap.josm.tools.Logging;
12 |
13 | public final class ImageUtil {
14 | private ImageUtil() {
15 | // Private constructor to avoid instantiation
16 | }
17 |
18 | /**
19 | * Scales an {@link ImageIcon} to the desired size
20 | *
21 | * @param icon the icon, which should be resized
22 | * @param size the desired length of the longest edge of the icon
23 | * @return the resized {@link ImageIcon}. It is the same object that you put in,
24 | * only the contained {@link Image} is exchanged.
25 | */
26 | public static ImageIcon scaleImageIcon(final ImageIcon icon, int size) {
27 | Logging.debug("Scale icon {0} → {1}", icon.getIconWidth(), size);
28 | return new ImageIcon(icon.getImage().getScaledInstance(
29 | icon.getIconWidth() >= icon.getIconHeight() ? size
30 | : Math.max(1, Math.round(icon.getIconWidth() / (float) icon.getIconHeight() * size)),
31 | icon.getIconHeight() >= icon.getIconWidth() ? size
32 | : Math.max(1, Math.round(icon.getIconHeight() / (float) icon.getIconWidth() * size)),
33 | Image.SCALE_SMOOTH));
34 | }
35 |
36 | public static BufferedImage scale(BufferedImage src, int width, int height) {
37 | BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
38 | Graphics2D g = dest.createGraphics();
39 | AffineTransform at = AffineTransform.getScaleInstance((double) width / src.getWidth(),
40 | (double) height / src.getHeight());
41 | g.drawRenderedImage(src, at);
42 | return dest;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryUserUtils.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | /**
5 | * Keys and utility methods for Mapillary Users
6 | */
7 | public class MapillaryUserUtils {
8 | public static final String KEY = "key";
9 | public static final String ID = "id";
10 | public static final String USER_NAME = "username";
11 | public static final String CREATED_AT = "created_at";
12 |
13 | private MapillaryUserUtils() {
14 | // Don't allow instantiation
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/ReflectionUtils.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import java.lang.reflect.Field;
5 | import java.util.Optional;
6 |
7 | import jakarta.annotation.Nonnull;
8 | import jakarta.annotation.Nullable;
9 | import org.openstreetmap.josm.tools.Logging;
10 |
11 | /**
12 | * A class for getting objects from JOSM code
13 | */
14 | public final class ReflectionUtils {
15 | private ReflectionUtils() {
16 | // Hide constructor
17 | }
18 |
19 | /**
20 | * Get a declared field
21 | *
22 | * @param parentClass The class with the declared field
23 | * @param fieldInParentClass The field to get
24 | * @param objectWithField The object with the field (may be {@code null})
25 | * @param returnClass The return type
26 | * @param The parent class
27 | * @param The class to search
28 | * @param The return class
29 | * @return An optional with the object (may be empty)
30 | */
31 | @Nonnull
32 | public static Optional getDeclaredField(@Nonnull Class parentClass,
33 | @Nonnull String fieldInParentClass, @Nullable C objectWithField, @Nonnull Class returnClass) {
34 | try {
35 | Field tagMenuField = parentClass.getDeclaredField(fieldInParentClass);
36 | org.openstreetmap.josm.tools.ReflectionUtils.setObjectsAccessible(tagMenuField);
37 | final Object object = tagMenuField.get(objectWithField);
38 | if (returnClass.isInstance(object)) {
39 | return Optional.of(returnClass.cast(object));
40 | }
41 | } catch (ReflectiveOperationException e) {
42 | Logging.error(e);
43 | }
44 | return Optional.empty();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/SecurityManagerUtils.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import org.openstreetmap.josm.plugins.mapillary.cache.Caches;
5 | import org.openstreetmap.josm.plugins.mapillary.cache.MapillaryCache;
6 | import org.openstreetmap.josm.tools.Logging;
7 |
8 | /**
9 | * This class exists to help initialize some items that fail when a security manager is installed
10 | *
11 | * @author Taylor Smock
12 | */
13 | public class SecurityManagerUtils {
14 | private SecurityManagerUtils() {
15 | // Don't allow instantiation
16 | }
17 |
18 | /**
19 | * Do initializations that cannot occur in a ForkJoinPool (due to WebStart's security manager)
20 | */
21 | public static void doInitializations() {
22 | if (System.getSecurityManager() != null) {
23 | // Ensure that we aren't initializing the caches in a secure context (specifically, ForkJoin pools)
24 | // -- this fails, and throws exceptions. See JOSM #20951.
25 | // Ensure that the image caches are initialized
26 | if (Caches.FULL_IMAGE_CACHE.hashCode() == 0) {
27 | Logging.trace("Mapillary: FULL_IMAGE_CACHE had a 0 hashCode. This is just a filler message.");
28 | }
29 | // Ensure that the ForkJoin pools are already initialized
30 | MapillaryUtils.getForkJoinPool();
31 | MapillaryUtils.getForkJoinPool(MapillaryCache.class);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/api/JsonSequencesDecoder.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils.api;
3 |
4 | import java.util.Collections;
5 | import java.util.List;
6 | import java.util.Objects;
7 | import java.util.stream.Collectors;
8 |
9 | import jakarta.json.JsonArray;
10 | import jakarta.json.JsonNumber;
11 | import jakarta.json.JsonObject;
12 | import jakarta.json.JsonString;
13 | import jakarta.json.JsonValue;
14 | import org.openstreetmap.josm.data.osm.IWay;
15 | import org.openstreetmap.josm.plugins.mapillary.spi.preferences.IMapillaryUrls;
16 | import org.openstreetmap.josm.tools.Logging;
17 |
18 | /**
19 | * Decodes the JSON returned by {@link IMapillaryUrls} into Java objects.
20 | * Takes a {@link JsonObject} and {@link #decodeSequence(JsonValue)} tries to convert it to a
21 | * {@link IWay}.
22 | */
23 | public final class JsonSequencesDecoder {
24 | private JsonSequencesDecoder() {
25 | // Private constructor to avoid instantiation
26 | }
27 |
28 | /**
29 | * Parses a given {@link JsonObject} as an array of image identifiers into a {@link IWay}.
30 | *
31 | * @param json the {@link JsonObject} to be parsed
32 | * @return a singleton list of {@link IWay} that is parsed from the given {@link JsonObject}. If mandatory
33 | * information is missing from the JSON, or it's not meeting the expecting format in another way,
34 | * an empty list will be returned.
35 | */
36 | public static List decodeSequence(final JsonValue json) {
37 | /*
38 | * The response looks like:
39 | * {"data":[{"id":"0"},{"id":"1"},{"id":"2"},...]}
40 | * We just have the "data" value
41 | */
42 | if (!(json instanceof JsonArray)) {
43 | Logging.error("Mapillary: The sequence endpoint just returns an array of picture ids");
44 | return Collections.emptyList();
45 | }
46 | return ((JsonArray) json).getValuesAs(value -> value instanceof JsonObject ? (JsonObject) value : null).stream()
47 | .filter(Objects::nonNull).filter(image -> image.containsKey("id")).map(image -> image.get("id"))
48 | .filter(jsonObject -> jsonObject instanceof JsonString || jsonObject instanceof JsonNumber)
49 | .map(value -> value instanceof JsonString ? Long.parseLong(((JsonString) value).getString())
50 | : ((JsonNumber) value).longValue())
51 | .distinct().collect(Collectors.toList());
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/api/JsonTagMapDecoder.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils.api;
3 |
4 | import java.util.Map;
5 |
6 | import jakarta.json.JsonObject;
7 | import jakarta.json.JsonString;
8 | import jakarta.json.JsonValue;
9 | import org.openstreetmap.josm.data.osm.TagMap;
10 |
11 | /**
12 | * Convert a properties object into a TagMap
13 | */
14 | public final class JsonTagMapDecoder {
15 | private JsonTagMapDecoder() {
16 | // Utility class, shouldn't be instantiated
17 | }
18 |
19 | /**
20 | * Get a tag map for the values
21 | *
22 | * @param json The json to convert to a tag map (ignores sub arrays and sub objects)
23 | * @return The tagmap
24 | */
25 | public static Map getTagMap(JsonObject json) {
26 | TagMap tags = new TagMap();
27 | for (Map.Entry entry : json.entrySet()) {
28 | JsonValue.ValueType type = entry.getValue().getValueType();
29 | if (type == JsonValue.ValueType.STRING) {
30 | tags.put(entry.getKey(), ((JsonString) entry.getValue()).getString());
31 | } else if (type == JsonValue.ValueType.TRUE) {
32 | tags.put(entry.getKey(), Boolean.TRUE.toString());
33 | } else if (type == JsonValue.ValueType.FALSE) {
34 | tags.put(entry.getKey(), Boolean.FALSE.toString());
35 | } else { // if (type == JsonValue.ValueType.NUMBER) {
36 | tags.put(entry.getKey(), entry.getValue().toString());
37 | }
38 | }
39 | return tags;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/api/JsonUserProfileDecoder.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils.api;
3 |
4 | import java.awt.image.BufferedImage;
5 | import java.io.IOException;
6 | import java.net.URI;
7 |
8 | import javax.imageio.ImageIO;
9 | import javax.swing.ImageIcon;
10 |
11 | import org.openstreetmap.josm.plugins.mapillary.model.UserProfile;
12 | import org.openstreetmap.josm.plugins.mapillary.spi.preferences.IMapillaryUrls;
13 | import org.openstreetmap.josm.tools.ImageProvider;
14 | import org.openstreetmap.josm.tools.Logging;
15 |
16 | import jakarta.json.JsonObject;
17 |
18 | /**
19 | * Decodes the JSON returned by {@link IMapillaryUrls} into Java objects.
20 | * Takes a {@link JsonObject} and {@link #decodeUserProfile(JsonObject)} tries to convert it to a {@link UserProfile}.
21 | */
22 | public final class JsonUserProfileDecoder {
23 | /** The avatar for profiles without an avatar */
24 | private static final ImageIcon FAKE_AVATAR = new ImageProvider("fake-avatar").get();
25 |
26 | private JsonUserProfileDecoder() {
27 | // Private constructor to avoid instantiation
28 | }
29 |
30 | /**
31 | * Decode the user profile
32 | *
33 | * @param json The user profile json object
34 | * @return The decoded profile
35 | */
36 | public static UserProfile decodeUserProfile(JsonObject json) {
37 | if (json == null) {
38 | return null;
39 | }
40 | final var username = json.getString("username", null);
41 | final var key = json.getString("id", null);
42 | if (key == null || username == null) {
43 | return null;
44 | }
45 |
46 | final var avatar = json.getString("avatar", null);
47 | ImageIcon icon = null;
48 | if (avatar != null) {
49 | try {
50 | BufferedImage img = ImageIO.read(URI.create(avatar).toURL());
51 | if (img != null) {
52 | icon = new ImageIcon(img);
53 | }
54 | } catch (IOException e) {
55 | Logging.debug(e);
56 | }
57 | }
58 | if (icon == null) {
59 | icon = FAKE_AVATAR;
60 | }
61 | return new UserProfile(Long.parseLong(key), username, icon);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/org/openstreetmap/josm/plugins/mapillary/utils/package-info.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | /**
3 | * Utility classes for simplifying recurring tasks throughout the project.
4 | * These classes are typically not instantiatable and only have static methods.
5 | */
6 | package org.openstreetmap.josm.plugins.mapillary.utils;
7 |
--------------------------------------------------------------------------------
/src/main/resources/data/ar.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ar.lang
--------------------------------------------------------------------------------
/src/main/resources/data/ast.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ast.lang
--------------------------------------------------------------------------------
/src/main/resources/data/be.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/be.lang
--------------------------------------------------------------------------------
/src/main/resources/data/bg.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/bg.lang
--------------------------------------------------------------------------------
/src/main/resources/data/ca-valencia.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ca-valencia.lang
--------------------------------------------------------------------------------
/src/main/resources/data/ca.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ca.lang
--------------------------------------------------------------------------------
/src/main/resources/data/cs.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/cs.lang
--------------------------------------------------------------------------------
/src/main/resources/data/cy.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/cy.lang
--------------------------------------------------------------------------------
/src/main/resources/data/da.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/da.lang
--------------------------------------------------------------------------------
/src/main/resources/data/de.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/de.lang
--------------------------------------------------------------------------------
/src/main/resources/data/el.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/el.lang
--------------------------------------------------------------------------------
/src/main/resources/data/en.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/en.lang
--------------------------------------------------------------------------------
/src/main/resources/data/en_AU.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/en_AU.lang
--------------------------------------------------------------------------------
/src/main/resources/data/en_CA.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/en_CA.lang
--------------------------------------------------------------------------------
/src/main/resources/data/en_GB.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/en_GB.lang
--------------------------------------------------------------------------------
/src/main/resources/data/eo.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/eo.lang
--------------------------------------------------------------------------------
/src/main/resources/data/es.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/es.lang
--------------------------------------------------------------------------------
/src/main/resources/data/et.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/et.lang
--------------------------------------------------------------------------------
/src/main/resources/data/fa.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/fa.lang
--------------------------------------------------------------------------------
/src/main/resources/data/fi.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/fi.lang
--------------------------------------------------------------------------------
/src/main/resources/data/fo.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/fo.lang
--------------------------------------------------------------------------------
/src/main/resources/data/fr.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/fr.lang
--------------------------------------------------------------------------------
/src/main/resources/data/gl.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/gl.lang
--------------------------------------------------------------------------------
/src/main/resources/data/hu.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/hu.lang
--------------------------------------------------------------------------------
/src/main/resources/data/id.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/id.lang
--------------------------------------------------------------------------------
/src/main/resources/data/is.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/is.lang
--------------------------------------------------------------------------------
/src/main/resources/data/it.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/it.lang
--------------------------------------------------------------------------------
/src/main/resources/data/ja.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ja.lang
--------------------------------------------------------------------------------
/src/main/resources/data/km.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/km.lang
--------------------------------------------------------------------------------
/src/main/resources/data/ko.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ko.lang
--------------------------------------------------------------------------------
/src/main/resources/data/lt.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/lt.lang
--------------------------------------------------------------------------------
/src/main/resources/data/mr.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/mr.lang
--------------------------------------------------------------------------------
/src/main/resources/data/nb.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/nb.lang
--------------------------------------------------------------------------------
/src/main/resources/data/nl.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/nl.lang
--------------------------------------------------------------------------------
/src/main/resources/data/pl.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/pl.lang
--------------------------------------------------------------------------------
/src/main/resources/data/pt.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/pt.lang
--------------------------------------------------------------------------------
/src/main/resources/data/pt_BR.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/pt_BR.lang
--------------------------------------------------------------------------------
/src/main/resources/data/ru.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/ru.lang
--------------------------------------------------------------------------------
/src/main/resources/data/sk.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/sk.lang
--------------------------------------------------------------------------------
/src/main/resources/data/sr-latin.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/sr-latin.lang
--------------------------------------------------------------------------------
/src/main/resources/data/sv.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/sv.lang
--------------------------------------------------------------------------------
/src/main/resources/data/tr.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/tr.lang
--------------------------------------------------------------------------------
/src/main/resources/data/uk.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/uk.lang
--------------------------------------------------------------------------------
/src/main/resources/data/zh_CN.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/zh_CN.lang
--------------------------------------------------------------------------------
/src/main/resources/data/zh_TW.lang:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/data/zh_TW.lang
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-cancel.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-clear.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-download.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-filter-expert.svg:
--------------------------------------------------------------------------------
1 |
2 |
70 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-filter.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-history.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-info.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-main.svg:
--------------------------------------------------------------------------------
1 |
2 |
23 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-restart.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillary-upload.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillaryPause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/dialogs/mapillaryPause.png
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillaryPlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/dialogs/mapillaryPlay.png
--------------------------------------------------------------------------------
/src/main/resources/images/dialogs/mapillaryStop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/dialogs/mapillaryStop.png
--------------------------------------------------------------------------------
/src/main/resources/images/fake-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/fake-avatar.png
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/current-ca.svg:
--------------------------------------------------------------------------------
1 |
2 |
74 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/default-ca-hover.svg:
--------------------------------------------------------------------------------
1 |
2 |
74 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/default-ca.svg:
--------------------------------------------------------------------------------
1 |
2 |
74 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/deleted-ca-hover.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/deleted-ca.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/private-ca-hover.svg:
--------------------------------------------------------------------------------
1 |
2 |
74 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/private-ca.svg:
--------------------------------------------------------------------------------
1 |
2 |
73 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/sequence-ca-hover.svg:
--------------------------------------------------------------------------------
1 |
2 |
74 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/sequence-ca.svg:
--------------------------------------------------------------------------------
1 |
2 |
73 |
--------------------------------------------------------------------------------
/src/main/resources/images/josm-ca/sign-detection.svg:
--------------------------------------------------------------------------------
1 |
2 |
64 |
--------------------------------------------------------------------------------
/src/main/resources/images/link.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/images/mapicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/src/main/resources/images/mapillary-eyedropper.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/main/resources/images/mapillary-logo-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/mapillary-logo-white.png
--------------------------------------------------------------------------------
/src/main/resources/images/mapillary-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/mapmode/mapillary-edit.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/src/main/resources/images/mapmode/mapillary-join.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/mapmode/mapillary-select.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/images/signs/crossing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/crossing.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/intersection_danger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/intersection_danger.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/no_entry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/no_entry.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/no_overtaking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/no_overtaking.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/no_parking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/no_parking.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/no_turn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/no_turn.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/only_straight_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/only_straight_on.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/roundabout_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/roundabout_right.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/speed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/speed.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/stop.png
--------------------------------------------------------------------------------
/src/main/resources/images/signs/uneven.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/src/main/resources/images/signs/uneven.png
--------------------------------------------------------------------------------
/src/main/resources/images/unknown-mapobject-type.svg:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/test/README:
--------------------------------------------------------------------------------
1 |
2 | This directory includes the test resources for the mapillary plugin.
3 |
4 |
5 | unit/ test sources (Unit tests, functional tests)
6 |
7 | config/ configuration files for running tests
8 |
9 | data/ test data
10 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/README.md:
--------------------------------------------------------------------------------
1 | This directory contains example data representative for what the APIv4 typically returns for certain queries.
2 |
3 | The data responses are organized like this:
4 | * graph (for entities)
5 | * entity\_id.json
6 | * coverageTiles (for tiles)
7 | * endpoint (minus commonalities). If there are non coordinate paths after commonalities, they are included as subdirs.
8 | * {z}/{x}/{y}.mvt
9 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3251/6257.mvt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3251/6257.mvt
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3251/6258.mvt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3251/6258.mvt
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3252/6257.mvt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3252/6257.mvt
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3252/6258.mvt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/__files/api/v4/responses/coverageTiles/mly1_public/2/14/3252/6258.mvt
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/104214208486349.json:
--------------------------------------------------------------------------------
1 | {"username":"vorpalblade","id":"104214208486349"}
2 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/104214208486350.json:
--------------------------------------------------------------------------------
1 | {"username":"mapillary_userÄ2!","id":"104214208486349", "comment": "Not an actual user! Don't update!"}
2 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/135511895288847.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1364.617,
3 | "atomic_scale": 0.97891115347587,
4 | "camera_parameters": [
5 | 0.85136388143343,
6 | -6.6499673206348e-05,
7 | -3.8067681992196e-05
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721072184,
11 | "compass_angle": 336.74,
12 | "computed_altitude": 1399.5043095825,
13 | "computed_compass_angle": 1.2865829255371,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57081597085,
18 | 39.068354912098
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.3642214091955,
23 | -0.0019509766093401,
24 | 0.035317244081076
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.57081597222,
31 | 39.068354972222
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 4.546427159383e+18,
39 | "mesh": {
40 | "id": "903987176835273",
41 | "url": "mesh_filler_url"
42 | },
43 | "quality_score": 0.7561310782241,
44 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
45 | "sfm_cluster": {
46 | "id": "306951457725231",
47 | "url": "sfm_cluster_filler_url"
48 | },
49 | "width": 4160,
50 | "id": "135511895288847",
51 | "thumb_original_url": "thumb_original_filler_url",
52 | "detections": {
53 | "data": [
54 | {
55 | "id": "138291978344172"
56 | },
57 | {
58 | "id": "138571594982877"
59 | }
60 | ]
61 | }
62 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/135511895288847/detections.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "created_at": "2021-05-22T15:20:45+0000",
5 | "geometry": "GnZ4AgoGbXB5LW9yKIAgEmcIARgDImEJ5CySK9ICIgRWBE4MDAgYKAxEAn4QXgKcAQY2CBgAJgQWAJoBBQobBLkBAKsBAzUCCwEFBwMACycDIQMJA30PWwHBAQU3ByEDVwUbAwMCMQQNCgkYBzwBEgsUAAwDIgEP",
6 | "image": {
7 | "geometry": {
8 | "type": "Point",
9 | "coordinates": [
10 | -108.57081597222,
11 | 39.068354972222
12 | ]
13 | },
14 | "id": "135511895288847"
15 | },
16 | "value": "object--junction-box",
17 | "id": "138291978344172"
18 | },
19 | {
20 | "created_at": "2021-05-23T00:40:55+0000",
21 | "geometry": "GjgKBm1weS1vchIYEgIAABgDIhAJkCawDRq4BgAAhAO3BgAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==",
22 | "image": {
23 | "geometry": {
24 | "type": "Point",
25 | "coordinates": [
26 | -108.57081597222,
27 | 39.068354972222
28 | ]
29 | },
30 | "id": "135511895288847"
31 | },
32 | "value": "information--general-directions--g1",
33 | "id": "138571594982877"
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/148137757289079.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1365.268,
3 | "atomic_scale": 0.99647293545609,
4 | "camera_parameters": [
5 | 0.84445215999653,
6 | 0.00013121033151786,
7 | -1.9432407137559e-06
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721048460,
11 | "compass_angle": 327.58,
12 | "computed_altitude": 1397.88957371,
13 | "computed_compass_angle": 359.18081230616,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57077016445,
18 | 39.065738749246
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.3810978714822,
23 | -0.027114611384617,
24 | -0.056708179817346
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.57076997222,
31 | 39.065739
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 5.2826592657222e+17,
39 | "mesh": {
40 | "id": "1082942308776704",
41 | "url": "mesh_filler_url"
42 | },
43 | "quality_score": 0.78643410852713,
44 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
45 | "sfm_cluster": {
46 | "id": "511129849910835",
47 | "url": "sfm_cluster_filler_url"
48 | },
49 | "width": 4160,
50 | "id": "148137757289079",
51 | "thumb_original_url": "thumb_original_filler_url",
52 | "detections": {
53 | "data": [
54 | {
55 | "id": "149534623816059"
56 | },
57 | {
58 | "id": "149583247144530"
59 | },
60 | {
61 | "id": "150066420429546"
62 | },
63 | {
64 | "id": "150499680386220"
65 | },
66 | {
67 | "id": "150806497022205"
68 | }
69 | ]
70 | }
71 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/308609047601518.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1363.29,
3 | "atomic_scale": 0.97891115347587,
4 | "camera_parameters": [
5 | 0.85136388143343,
6 | -6.6499673206348e-05,
7 | -3.8067681992196e-05
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721068212,
11 | "compass_angle": 334.28,
12 | "computed_altitude": 1399.4088478871,
13 | "computed_compass_angle": 2.8645135091551,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57081900996,
18 | 39.067959960774
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.3740205373753,
23 | -0.042444898098058,
24 | 0.032009776361988
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.570819,
31 | 39.067959972222
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 4.546427159383e+18,
39 | "quality_score": 0.76024363233666,
40 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
41 | "sfm_cluster": {
42 | "id": "306951457725231",
43 | "url": "sfm_cluster_filler_url"
44 | },
45 | "width": 4160,
46 | "id": "308609047601518",
47 | "thumb_original_url": "thumb_original_filler_url",
48 | "detections": {
49 | "data": [
50 | {
51 | "id": "310373714091718"
52 | },
53 | {
54 | "id": "311423430653413"
55 | },
56 | {
57 | "id": "311503437312079"
58 | },
59 | {
60 | "id": "311542917308131"
61 | },
62 | {
63 | "id": "311618317300591"
64 | }
65 | ]
66 | }
67 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/311681117131457.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1365.438,
3 | "atomic_scale": 1,
4 | "camera_parameters": [
5 | 0.85,
6 | 0,
7 | 0
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721080184,
11 | "compass_angle": 344.66,
12 | "computed_altitude": 1399.4218842061,
13 | "computed_compass_angle": 344.94472689299,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57079697265,
18 | 39.069199998346
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.5608887723115,
23 | 0.20627902216826,
24 | -0.20625267065192
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.57079697222,
31 | 39.0692
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 3.3337991113989e+18,
39 | "quality_score": 0.91282894736842,
40 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
41 | "sfm_cluster": {
42 | "id": "155444533218101",
43 | "url": "sfm_cluster_filler_url"
44 | },
45 | "width": 4160,
46 | "id": "311681117131457",
47 | "thumb_original_url": "thumb_original_filler_url",
48 | "detections": {
49 | "data": [
50 | {
51 | "id": "313159516983617"
52 | }
53 | ]
54 | }
55 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/311681117131457/detections.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "created_at": "2021-05-20T20:30:46+0000",
5 | "geometry": "GjgKBm1weS1vchIYEgIAABgDIhAJvjTKIxrIAwAAvALHAwAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==",
6 | "image": {
7 | "geometry": {
8 | "type": "Point",
9 | "coordinates": [
10 | -108.57079697222,
11 | 39.0692
12 | ]
13 | },
14 | "id": "311681117131457"
15 | },
16 | "value": "information--general-directions--g1",
17 | "id": "313159516983617"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/311799370533334.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1363.049,
3 | "atomic_scale": 0.99647293545609,
4 | "camera_parameters": [
5 | 0.84445215999653,
6 | 0.00013121033151786,
7 | -1.9432407137559e-06
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721051100,
11 | "compass_angle": 343.1,
12 | "computed_altitude": 1398.0575835621,
13 | "computed_compass_angle": 0.77063365372027,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57079091664,
18 | 39.065986975316
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.3806186802315,
23 | -0.050131317819359,
24 | -0.038180974935017
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.57079097222,
31 | 39.065986972222
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 5.2826592657222e+17,
39 | "mesh": {
40 | "id": "2931656060382386",
41 | "url": "mesh_filler_url"
42 | },
43 | "quality_score": 0.74476744186047,
44 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
45 | "sfm_cluster": {
46 | "id": "511129849910835",
47 | "url": "sfm_cluster_filler_url"
48 | },
49 | "width": 4160,
50 | "id": "311799370533334",
51 | "thumb_original_url": "thumb_original_filler_url",
52 | "detections": {
53 | "data": [
54 | {
55 | "id": "313324430380828"
56 | },
57 | {
58 | "id": "313366017043336"
59 | },
60 | {
61 | "id": "313943736985564"
62 | }
63 | ]
64 | }
65 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/311799370533334/detections.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "created_at": "2021-05-20T19:34:30+0000",
5 | "geometry": "GjUKBm1weS1vchIVEgIAABgDIg0Jhh2eLBpkAABiYwAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==",
6 | "image": {
7 | "geometry": {
8 | "type": "Point",
9 | "coordinates": [
10 | -108.57079097222,
11 | 39.065986972222
12 | ]
13 | },
14 | "id": "311799370533334"
15 | },
16 | "value": "information--general-directions--g1",
17 | "id": "313324430380828"
18 | },
19 | {
20 | "created_at": "2021-05-20T21:05:34+0000",
21 | "geometry": "GjgKBm1weS1vchIYEgIAABgDIhAJ3gbKKxqkAQAA1gGjAQAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==",
22 | "image": {
23 | "geometry": {
24 | "type": "Point",
25 | "coordinates": [
26 | -108.57079097222,
27 | 39.065986972222
28 | ]
29 | },
30 | "id": "311799370533334"
31 | },
32 | "value": "regulatory--no-left-turn--g1",
33 | "id": "313366017043336"
34 | },
35 | {
36 | "created_at": "2021-05-21T17:25:13+0000",
37 | "geometry": "GjcKBm1weS1vchIXEgIAABgDIg8JtBuMLRrKAQAAWMkBAA8aBHR5cGUiCQoHcG9seWdvbiiAIHgB",
38 | "image": {
39 | "geometry": {
40 | "type": "Point",
41 | "coordinates": [
42 | -108.57079097222,
43 | 39.065986972222
44 | ]
45 | },
46 | "id": "311799370533334"
47 | },
48 | "value": "information--general-directions--g1",
49 | "id": "313943736985564"
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/338231874314914.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1364.617,
3 | "atomic_scale": 0.97891115347587,
4 | "camera_parameters": [
5 | 0.85136388143343,
6 | -6.6499673206348e-05,
7 | -3.8067681992196e-05
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721072184,
11 | "compass_angle": 336.74,
12 | "computed_altitude": 1399.5043095825,
13 | "computed_compass_angle": 1.2865829255371,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57081597085,
18 | 39.068354912098
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.3642214091955,
23 | -0.0019509766093401,
24 | 0.035317244081076
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.57081597222,
31 | 39.068354972222
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 4.546427159383e+18,
39 | "mesh": {
40 | "id": "903987176835273",
41 | "url": "mesh_filler_url"
42 | },
43 | "quality_score": 0.7561310782241,
44 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
45 | "sfm_cluster": {
46 | "id": "306951457725231",
47 | "url": "sfm_cluster_filler_url"
48 | },
49 | "width": 4160,
50 | "id": "338231874314914",
51 | "thumb_original_url": "thumb_original_filler_url",
52 | "detections": {
53 | "data": []
54 | },
55 | "comment": "This file is pretty much hand written -- the image appears to be borked on Mapillary's end (as of August 17, 2021)"
56 | }
57 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/4235112816526838.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1362.799,
3 | "atomic_scale": 1,
4 | "camera_parameters": [
5 | 0.85,
6 | 0,
7 | 0
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721059027,
11 | "compass_angle": 336.32,
12 | "computed_altitude": 1398.8672037208,
13 | "computed_compass_angle": 335.53765702375,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57081199999,
18 | 39.066878001959
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.5448066712781,
23 | 0.33486840325311,
24 | -0.33486442444208
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.570812,
31 | 39.066878
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 7.4009176193932e+17,
39 | "quality_score": 0.80005636581413,
40 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
41 | "sfm_cluster": {
42 | "id": "183557110205058",
43 | "url": "sfm_cluster_filler_url"
44 | },
45 | "width": 4160,
46 | "id": "4235112816526838",
47 | "thumb_original_url": "thumb_original_filler_url",
48 | "detections": {
49 | "data": [
50 | {
51 | "id": "4239760849395368"
52 | },
53 | {
54 | "id": "4243230999048353"
55 | },
56 | {
57 | "id": "4248247361880050"
58 | },
59 | {
60 | "id": "4248381345199985"
61 | },
62 | {
63 | "id": "4248765325161587"
64 | },
65 | {
66 | "id": "4248842428487210"
67 | },
68 | {
69 | "id": "4249042848467168"
70 | },
71 | {
72 | "id": "4249064551798331"
73 | }
74 | ]
75 | }
76 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/464249047982277.json:
--------------------------------------------------------------------------------
1 | {
2 | "altitude": 1362.421,
3 | "atomic_scale": 1,
4 | "camera_parameters": [
5 | 0.85,
6 | 0,
7 | 0
8 | ],
9 | "camera_type": "perspective",
10 | "captured_at": 1563721062971,
11 | "compass_angle": 335.83,
12 | "computed_altitude": 1399.2187248701,
13 | "computed_compass_angle": 338.04298879857,
14 | "computed_geometry": {
15 | "type": "Point",
16 | "coordinates": [
17 | -108.57081497264,
18 | 39.067357000697
19 | ]
20 | },
21 | "computed_rotation": [
22 | 1.5496206827148,
23 | 0.30062622625581,
24 | -0.30065559861764
25 | ],
26 | "exif_orientation": 1,
27 | "geometry": {
28 | "type": "Point",
29 | "coordinates": [
30 | -108.57081497222,
31 | 39.067357
32 | ]
33 | },
34 | "height": 3120,
35 | "thumb_256_url": "thumb_256_filler_url",
36 | "thumb_1024_url": "thumb_1024_filler_url",
37 | "thumb_2048_url": "thumb_2048_filler_url",
38 | "merge_cc": 4.0138052809816e+18,
39 | "quality_score": 0.95078612716763,
40 | "sequence": "7nfcwfvjdtphz7yj6zat6a",
41 | "sfm_cluster": {
42 | "id": "298750828608649",
43 | "url": "sfm_cluster_filler_url"
44 | },
45 | "width": 4160,
46 | "id": "464249047982277",
47 | "thumb_original_url": "thumb_original_filler_url",
48 | "detections": {
49 | "data": [
50 | {
51 | "id": "465612364512612"
52 | }
53 | ]
54 | }
55 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/464249047982277/detections.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "created_at": "2021-05-21T02:11:27+0000",
5 | "geometry": "GjgKBm1weS1vchIYEgIAABgDIhAJliP0GxqmBgAA8AKlBgAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==",
6 | "image": {
7 | "geometry": {
8 | "type": "Point",
9 | "coordinates": [
10 | -108.57081497222,
11 | 39.067357
12 | ]
13 | },
14 | "id": "464249047982277"
15 | },
16 | "value": "information--general-directions--g1",
17 | "id": "465612364512612"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/496980935069177.json:
--------------------------------------------------------------------------------
1 | {
2 | "first_seen_at": "2017-08-23T21:32:26+0000",
3 | "last_seen_at": "2017-08-23T21:32:26+0000",
4 | "object_value": "complementary--both-directions--g2",
5 | "object_type": "trafficsign",
6 | "geometry": {
7 | "type": "Point",
8 | "coordinates": [
9 | -83.417193328459,
10 | 41.341166490122
11 | ]
12 | },
13 | "images": {
14 | "data": [
15 | {
16 | "geometry": {
17 | "type": "Point",
18 | "coordinates": [
19 | -83.41752502,
20 | 41.34126339
21 | ]
22 | },
23 | "id": "133075088816573"
24 | },
25 | {
26 | "geometry": {
27 | "type": "Point",
28 | "coordinates": [
29 | -83.41764319,
30 | 41.34124814
31 | ]
32 | },
33 | "id": "512146709982392"
34 | },
35 | {
36 | "geometry": {
37 | "type": "Point",
38 | "coordinates": [
39 | -83.41758216,
40 | 41.34124408
41 | ]
42 | },
43 | "id": "828719391332432"
44 | }
45 | ]
46 | },
47 | "id": "496980935069177"
48 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/496980935069177/detections.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "created_at": "2021-05-21T14:59:31+0000",
5 | "geometry": "GjYKBm1weS1vchIWEgIAABgDIg4Jkia4HxpYAACMAVcADxoEdHlwZSIJCgdwb2x5Z29uKIAgeAE=",
6 | "image": {
7 | "geometry": {
8 | "type": "Point",
9 | "coordinates": [
10 | -83.41758216,
11 | 41.34124408
12 | ]
13 | },
14 | "id": "828719391332432"
15 | },
16 | "value": "complementary--both-directions--g2",
17 | "id": "835055007365537"
18 | },
19 | {
20 | "created_at": "2021-05-21T14:59:31+0000",
21 | "geometry": "GjYKBm1weS1vchIWEgIAABgDIg4JwiekHxpoAACeAWcADxoEdHlwZSIJCgdwb2x5Z29uKIAgeAE=",
22 | "image": {
23 | "geometry": {
24 | "type": "Point",
25 | "coordinates": [
26 | -83.41752502,
27 | 41.34126339
28 | ]
29 | },
30 | "id": "133075088816573"
31 | },
32 | "value": "complementary--both-directions--g2",
33 | "id": "139111688212913"
34 | },
35 | {
36 | "created_at": "2021-05-21T14:59:31+0000",
37 | "geometry": "GjUKBm1weS1vchIVEgIAABgDIg0JsCTkHxpSAAB8UQAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==",
38 | "image": {
39 | "geometry": {
40 | "type": "Point",
41 | "coordinates": [
42 | -83.41764319,
43 | 41.34124814
44 | ]
45 | },
46 | "id": "512146709982392"
47 | },
48 | "value": "complementary--both-directions--g2",
49 | "id": "518393049357758"
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/README.md:
--------------------------------------------------------------------------------
1 | # Entity responses
2 | All entity responses are formatted with `jq`. Please keep in mind that the formatting from the server is typically less human readable (i.e., no spacing, no newlines, etc.).
3 |
4 | ## Image
5 | This returns the metadata for an image.
6 |
7 | When used in tests, the output should be appropriately filtered if it is the return from an API call.
8 |
9 | ### Endpoint
10 | * https://graph.mapillary.com/:image\_id
11 |
12 | ### Fields
13 | * altitude
14 | * atomic\_scale
15 | * camera\_parameters
16 | * camera\_parameters
17 | * camera\_type
18 | * captured\_at
19 | * compass\_angle
20 | * computed\_altitude
21 | * computed\_compass\_angle
22 | * computed\_geometry
23 | * computed\_rotation
24 | * exif\_orientation
25 | * geometry
26 | * height
27 | * thumb\_256\_url
28 | * thumb\_1024\_url
29 | * thumb\_2048\_url
30 | * merge\_cc
31 | * mesh
32 | * quality\_score
33 | * sequence
34 | * sfm\_cluster
35 | * width
36 |
37 | ## Sequence
38 | Sequence entities represent a sequence of image IDS ordered by capture time.
39 |
40 | These are stored in image\_ids/:sequence\_id
41 |
42 |
43 | ### Endpoints
44 | * https://graph.mapillary.com/image\_ids?sequence\_id=:sequence\_id -- this is a collection endpoint, so the `data` value is an array.
45 |
46 | ### Fields
47 | * `id`: The identifier for the image in the sequence
48 |
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/application_request_limit_reached.json:
--------------------------------------------------------------------------------
1 | {"error":{"message":"Application request limit reached","type":"MLYApiException","is_transient":true,"code":4,"fbtrace_id":"AFJKU45YcZHFgmaRmycfmQ3"}}
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/image_ids/7nfcwfvjdtphz7yj6zat6a.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "id": "148137757289079"
5 | },
6 | {
7 | "id": "311799370533334"
8 | },
9 | {
10 | "id": "338231874314914"
11 | },
12 | {
13 | "id": "4235112816526838"
14 | },
15 | {
16 | "id": "464249047982277"
17 | },
18 | {
19 | "id": "308609047601518"
20 | },
21 | {
22 | "id": "135511895288847"
23 | },
24 | {
25 | "id": "311681117131457"
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/internal_server_error.json:
--------------------------------------------------------------------------------
1 | {"error":{"message":"Invalid OAuth 2.0 Access Token","type":"MLYApiException","code":190,"error_data":{},"fbtrace_id":"AMN5QfsCEBZg1LNVFA4bpvy"}}
--------------------------------------------------------------------------------
/test/data/__files/api/v4/responses/graph/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 |
--------------------------------------------------------------------------------
/test/data/api/v3/requests/changeset.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "location",
3 | "changes": [
4 | {
5 | "image_key": "7erPn382xDMtmfdh0xtvUw",
6 | "from": {
7 | "type": "Feature",
8 | "properties": {
9 | "ca": 0.0
10 | },
11 | "geometry": {
12 | "type": "Point",
13 | "coordinates": [
14 | 0.0,
15 | 0.0
16 | ]
17 | }
18 | },
19 | "to": {
20 | "geometry": {
21 | "coordinates": [
22 | 13.3328,
23 | 50.44619
24 | ],
25 | "type": "Point"
26 | },
27 | "properties": {
28 | "ca": 0.0
29 | },
30 | "type": "Feature"
31 | }
32 | },
33 | {
34 | "image_key": "invalid image key will be ignored",
35 | "from": {
36 | "type": "Feature",
37 | "properties": {
38 | "ca": 0.0
39 | },
40 | "geometry": {
41 | "type": "Point",
42 | "coordinates": [
43 | 0.0,
44 | 0.0
45 | ]
46 | }
47 | },
48 | "to": {
49 | "geometry": {
50 | "coordinates": [
51 | 0.0,
52 | 0.0
53 | ],
54 | "type": "Point"
55 | },
56 | "properties": {
57 | "ca": 13.4
58 | },
59 | "type": "Feature"
60 | }
61 | },
62 | {
63 | "image_key": "wMAqAFr3xE9072G8Al6WLQ",
64 | "from": {
65 | "type": "Feature",
66 | "properties": {
67 | "ca": 10.0
68 | },
69 | "geometry": {
70 | "coordinates": [
71 | 13.3323,
72 | 50.44612
73 | ],
74 | "type": "Point"
75 | }
76 | },
77 | "to": {
78 | "type": "Feature",
79 | "geometry": {
80 | "coordinates": [
81 | 13.4434,
82 | 50.66834
83 | ],
84 | "type": "Point"
85 | },
86 | "properties": {
87 | "ca": 283.3
88 | }
89 | }
90 | }
91 | ],
92 | "request_comment": "JOSM-created"
93 | }
94 |
--------------------------------------------------------------------------------
/test/data/api/v3/requests/rotation_only_changeset.json:
--------------------------------------------------------------------------------
1 | {
2 | "image_key": "rotationOnlyChangesetImageKey",
3 | "from": {
4 | "type": "Feature",
5 | "properties": {
6 | "ca": 10.0
7 | },
8 | "geometry": {
9 | "type": "Point",
10 | "coordinates": [
11 | 13.3323,
12 | 50.44612
13 | ]
14 | }
15 | },
16 | "to": {
17 | "geometry": {
18 | "coordinates": [
19 | 13.3323,
20 | 50.44612
21 | ],
22 | "type": "Point"
23 | },
24 | "properties": {
25 | "ca": -70.3
26 | },
27 | "type": "Feature"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/data/api/v3/requests/single_image_changeset.json:
--------------------------------------------------------------------------------
1 | {
2 | "image_key": "wMAqAFr3xE9072G8Al6WLQ",
3 | "from": {
4 | "type": "Feature",
5 | "properties": {
6 | "ca": 10.0
7 | },
8 | "geometry": {
9 | "type": "Point",
10 | "coordinates": [
11 | 13.3323,
12 | 50.44612
13 | ]
14 | }
15 | },
16 | "to": {
17 | "geometry": {
18 | "coordinates": [
19 | 13.4434,
20 | 50.66834
21 | ],
22 | "type": "Point"
23 | },
24 | "properties": {
25 | "ca": 283.3
26 | },
27 | "type": "Feature"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/data/api/v3/requests/translation_only_changeset.json:
--------------------------------------------------------------------------------
1 | {
2 | "image_key": "translationOnlyChangesetImageKey",
3 | "from": {
4 | "type": "Feature",
5 | "properties": {
6 | "ca": 10.0
7 | },
8 | "geometry": {
9 | "type": "Point",
10 | "coordinates": [
11 | 13.3323,
12 | 50.44612
13 | ]
14 | }
15 | },
16 | "to": {
17 | "geometry": {
18 | "coordinates": [
19 | 13.4434,
20 | 50.66834
21 | ],
22 | "type": "Point"
23 | },
24 | "properties": {
25 | "ca": 10.0
26 | },
27 | "type": "Feature"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/README.md:
--------------------------------------------------------------------------------
1 | This directory contains example data representative for what the APIv3 typically returns for certain queries.
2 |
3 | The examples are taken from https://www.mapillary.com/developer/api-documentation/ .
4 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/imageDetection.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "Feature",
3 | "properties": {
4 | "area": 0.0015604496002197266,
5 | "image_key": "QhRcdlGS_Rn_a1_HTclefg",
6 | "key": "gn0llgitnnuqonecevbmf52ino",
7 | "layer": "trafficsign",
8 | "score": 0.710661225175,
9 | "shape": {
10 | "type": "Polygon",
11 | "coordinates": [
12 | [
13 | [
14 | 0.330078125,
15 | 0.466064453125
16 | ],
17 | [
18 | 0.3642578125,
19 | 0.466064453125
20 | ],
21 | [
22 | 0.3642578125,
23 | 0.51171875
24 | ],
25 | [
26 | 0.330078125,
27 | 0.51171875
28 | ],
29 | [
30 | 0.330078125,
31 | 0.466064453125
32 | ]
33 | ]
34 | ]
35 | },
36 | "value": "regulatory--no-overtaking-by-heavy-goods-vehicles--g1"
37 | },
38 | "geometry": {
39 | "type": "Point",
40 | "coordinates": [
41 | 10.805287,
42 | 55.321409
43 | ]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/images_LwrHXqFRN_pszCopTKHF_Q.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type": "Feature",
3 | "properties": {
4 | "ca": 323.0319999999999,
5 | "camera_make": "Apple",
6 | "camera_model": "iPhone5,4",
7 | "captured_at": "2016-03-14T13:44:53.860Z",
8 | "key": "LwrHXqFRN_pszCopTKHF_Q",
9 | "pano": false,
10 | "sequence_key": "LMlIPUNhaj24h_q9v4ArNw",
11 | "user_key": "AGfe-07BEJX0-kxpu9J3rA",
12 | "username": "pierregeo",
13 | "quality_score": 4
14 | },
15 | "geometry": {
16 | "type": "Point",
17 | "coordinates": [
18 | 16.432958,
19 | 7.246497
20 | ]
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/mapObject.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "Feature",
3 | "properties": {
4 | "accuracy": 1,
5 | "altitude": 1.7983143,
6 | "first_seen_at": "2016-07-01T12:49:08.553Z",
7 | "key": "9f3tl0z2xanom2inyyks65negx",
8 | "last_seen_at": "2016-07-01T12:49:08.553Z",
9 | "layer": "trafficsign",
10 | "value": "regulatory--no-entry--g1",
11 | "detections": []
12 | },
13 | "geometry": {
14 | "type": "Point",
15 | "coordinates": [
16 | 13.017088890075684,
17 | 55.60746765136719
18 | ]
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/searchImageDetections.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "area": 0.00010585784912109375,
8 | "image_key": "33zgql54_tBVvmIij0zrcA",
9 | "key": "bzqdn10wz1s1xd3lae3hawgja0",
10 | "layer": "trafficsign",
11 | "score": 0.000001,
12 | "shape": {
13 | "type": "Polygon",
14 | "coordinates": [
15 | [
16 | [
17 | 0.42724609375,
18 | 0.69091796875
19 | ],
20 | [
21 | 0.436279296875,
22 | 0.69091796875
23 | ],
24 | [
25 | 0.436279296875,
26 | 0.70263671875
27 | ],
28 | [
29 | 0.42724609375,
30 | 0.70263671875
31 | ],
32 | [
33 | 0.42724609375,
34 | 0.69091796875
35 | ]
36 | ]
37 | ]
38 | },
39 | "value": "information--pedestrians-crossing--g1"
40 | },
41 | "geometry": {
42 | "type": "Point",
43 | "coordinates": [
44 | 12.995127,
45 | 55.550739
46 | ]
47 | }
48 | },
49 | {
50 | "type": "Feature",
51 | "properties": {
52 | "area": 0.00010585784912109375,
53 | "image_key": "33zgql54_tBVvmIij0zrcA",
54 | "key": "uzve1xkyk5qbjwrzaq0do09u1x",
55 | "layer": "trafficsign",
56 | "score": 0.000001,
57 | "shape": {
58 | "type": "Polygon",
59 | "coordinates": [
60 | [
61 | [
62 | 0.42724609375,
63 | 0.69091796875
64 | ],
65 | [
66 | 0.436279296875,
67 | 0.69091796875
68 | ],
69 | [
70 | 0.436279296875,
71 | 0.70263671875
72 | ],
73 | [
74 | 0.42724609375,
75 | 0.70263671875
76 | ],
77 | [
78 | 0.42724609375,
79 | 0.69091796875
80 | ]
81 | ]
82 | ]
83 | },
84 | "value": "information--pedestrians-crossing--g1"
85 | },
86 | "geometry": {
87 | "type": "Point",
88 | "coordinates": [
89 | 12.995127,
90 | 55.550739
91 | ]
92 | }
93 | }
94 | ]
95 | }
96 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/searchImages.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "ca": 232.73019999999997,
8 | "camera_make": "Apple",
9 | "captured_at": "2017-04-10T05:51:30.334Z",
10 | "key": "_yA5uXuSNugmsK5VucU6Bg",
11 | "pano": false,
12 | "user_key": "UtczWn8y3afb0GQVW-AiOQ",
13 | "username": "xtyou"
14 | },
15 | "geometry": {
16 | "type": "Point",
17 | "coordinates": [
18 | 2.215628000000038,
19 | 48.90262200000001
20 | ]
21 | }
22 | },
23 | {
24 | "type": "Feature",
25 | "properties": {
26 | "ca": 237.21129999999994,
27 | "camera_make": "Apple",
28 | "captured_at": "2017-04-10T05:51:26.853Z",
29 | "key": "nmF-Wq4EvVTgAUmBicSCCg",
30 | "pano": false,
31 | "user_key": "UtczWn8y3afb0GQVW-AiOQ",
32 | "username": "xtyou"
33 | },
34 | "geometry": {
35 | "type": "Point",
36 | "coordinates": [
37 | 2.2156680000000506,
38 | 48.90267399999999
39 | ]
40 | }
41 | }
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/searchMapObjects.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "accuracy": 1,
8 | "altitude": 3.688496,
9 | "first_seen_at": "2016-10-16T09:42:56.060Z",
10 | "key": "qpku21qv8rjn7fll1v671732th",
11 | "last_seen_at": "2016-10-16T09:42:56.060Z",
12 | "layer": "trafficsign",
13 | "value": "regulatory--no-parking--g1",
14 | "detections": [
15 | {
16 | "detection_key": "cpatpdftmogffmhihau9792tua",
17 | "image_key": "bsw3H-ajJD42zZSg2P64hA"
18 | }
19 | ]
20 | },
21 | "geometry": {
22 | "type": "Point",
23 | "coordinates": [
24 | 13.005650520324707,
25 | 55.608367919921875
26 | ]
27 | }
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/searchSequences.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "camera_make": "Apple",
8 | "captured_at": "2016-03-14T13:44:53.860Z",
9 | "created_at": "2016-03-17T10:47:53.106Z",
10 | "coordinateProperties": {
11 | "cas": [
12 | 323.0319999999999,
13 | 320.8918,
14 | 333.62239999999997,
15 | 329.94820000000004
16 | ],
17 | "image_keys": [
18 | "LwrHXqFRN_pszCopTKHF_Q",
19 | "Aufjv2hdCKwg9LySWWVSwg",
20 | "QEVZ1tp-PmrwtqhSwdW9fQ",
21 | "G_SIwxNcioYeutZuA8Rurw"
22 | ]
23 | },
24 | "key": "LMlIPUNhaj24h_q9v4ArNw",
25 | "pano": false,
26 | "user_key": "AGfe-07BEJX0-kxpu9J3rA"
27 | },
28 | "geometry": {
29 | "type": "LineString",
30 | "coordinates": [
31 | [
32 | 16.432958,
33 | 7.246497
34 | ],
35 | [
36 | 16.432955,
37 | 7.246567
38 | ],
39 | [
40 | 16.432971,
41 | 7.248372
42 | ],
43 | [
44 | 16.432976,
45 | 7.249027
46 | ]
47 | ]
48 | }
49 | }
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/searchSequencesTicket20211Area1.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type" : "FeatureCollection",
3 | "features" : [
4 | {
5 | "type" : "Feature",
6 | "geometry" : {
7 | "type" : "LineString",
8 | "coordinates" : [
9 | [
10 | -108.560526,
11 | 39.065414
12 | ],
13 | [
14 | -108.561343,
15 | 39.065418
16 | ],
17 | [
18 | -108.562143,
19 | 39.065415
20 | ],
21 | [
22 | -108.563105,
23 | 39.065425
24 | ],
25 | [
26 | -108.563708,
27 | 39.065407
28 | ]
29 | ]
30 | },
31 | "properties" : {
32 | "captured_at" : "2019-07-21T14:56:25.559Z",
33 | "username" : "vorpalblade",
34 | "camera_make" : "Essential Products",
35 | "pano" : false,
36 | "user_key" : "x0hTY8cakpy0m3ui1GaG1A",
37 | "key" : "yqly53hefz24ylz79bwc5x",
38 | "coordinateProperties" : {
39 | "image_keys" : [
40 | "3d3y3_-3jKsAm2khDHLaMQ",
41 | "axRgdZfUfW6I3Pq05GZIEw",
42 | "eYCNyXzan1GEALnFO4A0Ow",
43 | "3hxG2Xi6KEN2zeIKwUu8lQ",
44 | "lz_OmSdoDAaoAEDgQXZ4_w"
45 | ],
46 | "cas" : [
47 | 252.27,
48 | 252.08,
49 | 253.21,
50 | 251.92,
51 | 253.5
52 | ]
53 | },
54 | "created_at" : "2019-07-25T00:46:42.003Z"
55 | }
56 | }
57 | ]
58 | }
59 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/sequence.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "Feature",
3 | "properties": {
4 | "camera_make": "Apple",
5 | "captured_at": "2016-03-14T13:44:37.206Z",
6 | "created_at": "2016-03-15T08:48:40.592Z",
7 | "coordinateProperties": {
8 | "cas": [
9 | 96.71454,
10 | 96.47705000000002
11 | ],
12 | "image_keys": [
13 | "76P0YUrlDD_lF6J7Od3yoA",
14 | "Ap_8E0BwoAqqewhJaEbFyQ"
15 | ]
16 | },
17 | "key": "cHBf9e8n0pG8O0ZVQHGFBQ",
18 | "pano": false,
19 | "user_key": "AGfe-07BEJX0-kxpu9J3rA"
20 | },
21 | "geometry": {
22 | "type": "LineString",
23 | "coordinates": [
24 | [
25 | 16.43279,
26 | 7.246085
27 | ],
28 | [
29 | 16.432799,
30 | 7.246082
31 | ]
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/userProfile.json:
--------------------------------------------------------------------------------
1 | {
2 | "about": "Mapillary and Mapping!",
3 | "avatar": "https://d4vkkeqw582u.cloudfront.net/3f9f044b34b498ddfb9afbb6/profile.png",
4 | "created_at": "2013-09-18T16:52:28.042Z",
5 | "key": "2BJl04nvnfW1y2GNaj7x5w",
6 | "username": "gyllen"
7 | }
8 |
--------------------------------------------------------------------------------
/test/data/api/v3/responses/userProfile2.json:
--------------------------------------------------------------------------------
1 | {
2 | "about": "Having a non-image avatar",
3 | "avatar": "https://example.org",
4 | "created_at": "2016-01-31T01:47:28.000+0500",
5 | "key": "abcdefg1",
6 | "username": "mapillary_userÄ2!"
7 | }
8 |
--------------------------------------------------------------------------------
/test/data/exifTestImages/dateTimeOnly.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/exifTestImages/dateTimeOnly.jpg
--------------------------------------------------------------------------------
/test/data/exifTestImages/dateTimeOnly.metadata.txt:
--------------------------------------------------------------------------------
1 | add Exif.Photo.DateTimeOriginal 2015:12:24 01:02:03
2 |
--------------------------------------------------------------------------------
/test/data/exifTestImages/generateExifTaggedImages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | rm latLonOnly.jpg
3 | rm dateTimeOnly.jpg
4 | rm gpsDirectionOnly.jpg
5 | cp -T untagged.jpg latLonOnly.jpg
6 | cp -T untagged.jpg dateTimeOnly.jpg
7 | cp -T untagged.jpg gpsDirectionOnly.jpg
8 | exiv2 -m latLonOnly.metadata.txt latLonOnly.jpg
9 | exiv2 -m dateTimeOnly.metadata.txt dateTimeOnly.jpg
10 | exiv2 -m gpsDirectionOnly.metadata.txt gpsDirectionOnly.jpg
11 |
--------------------------------------------------------------------------------
/test/data/exifTestImages/gpsDirectionOnly.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/exifTestImages/gpsDirectionOnly.jpg
--------------------------------------------------------------------------------
/test/data/exifTestImages/gpsDirectionOnly.metadata.txt:
--------------------------------------------------------------------------------
1 | add Exif.GPSInfo.GPSImgDirection 4273/100
2 |
--------------------------------------------------------------------------------
/test/data/exifTestImages/latLonOnly.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/exifTestImages/latLonOnly.jpg
--------------------------------------------------------------------------------
/test/data/exifTestImages/latLonOnly.metadata.txt:
--------------------------------------------------------------------------------
1 | add Exif.GPSInfo.GPSLatitude 55/1 36/1 19/1
2 | add Exif.GPSInfo.GPSLatitudeRef N
3 | add Exif.GPSInfo.GPSLongitude 13/1 0/1 1/2
4 | add Exif.GPSInfo.GPSLongitudeRef E
5 |
--------------------------------------------------------------------------------
/test/data/exifTestImages/untagged.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/exifTestImages/untagged.jpg
--------------------------------------------------------------------------------
/test/data/exifTestImages/untagged.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/exifTestImages/untagged.png
--------------------------------------------------------------------------------
/test/data/preferences/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/data/xmpTestImages/xmpProjectionOnly.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/xmpTestImages/xmpProjectionOnly.jpg
--------------------------------------------------------------------------------
/test/data/xmpTestImages/xmpProjectionOnly.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/data/zeroByteFile:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JOSM/Mapillary/5bfeceebe95d8ea8b4a9e14942b1edadd04e8362/test/data/zeroByteFile
--------------------------------------------------------------------------------
/test/resources:
--------------------------------------------------------------------------------
1 | data
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/datepicker/impl/GenericDateImplementationTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.datepicker.impl;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | import java.time.Instant;
8 | import java.time.LocalDate;
9 | import java.time.ZoneOffset;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import java.util.stream.Stream;
13 |
14 | import org.junit.jupiter.params.ParameterizedTest;
15 | import org.junit.jupiter.params.provider.Arguments;
16 | import org.junit.jupiter.params.provider.MethodSource;
17 | import org.openstreetmap.josm.plugins.datepicker.IDatePicker;
18 |
19 | /**
20 | * Test method for date implementations.
21 | * The {@link #getDatePickers} method should be updated when new date pickers are implemented.
22 | */
23 | class GenericDateImplementationTest {
24 | static Stream getDatePickers() {
25 | Calendar minCalendar = Calendar.getInstance();
26 | minCalendar.setTime(new Date(Long.MIN_VALUE));
27 | Calendar maxCalendar = Calendar.getInstance();
28 | maxCalendar.setTime(new Date(Long.MAX_VALUE));
29 | LocalDate zero = LocalDate.of(1, 1, 1);
30 | LocalDate dec = LocalDate.of(1, 12, 31);
31 | LocalDate current = LocalDate.now(ZoneOffset.UTC);
32 | // Don't use LocalDate.MAX and LocalDate.MIN due to conversions between Date and LocalDate
33 | LocalDate max = LocalDate.of(maxCalendar.get(Calendar.YEAR), maxCalendar.get(Calendar.MONTH),
34 | maxCalendar.get(Calendar.DAY_OF_MONTH));
35 | LocalDate min = LocalDate.of(minCalendar.get(Calendar.YEAR), minCalendar.get(Calendar.MONTH),
36 | minCalendar.get(Calendar.DAY_OF_MONTH));
37 | return Stream.of(new DatePickerJDatePicker(), new DatePickerSwing())
38 | .flatMap(datePicker -> Stream.of(Arguments.of(datePicker, min), Arguments.of(datePicker, max),
39 | Arguments.of(datePicker, dec), Arguments.of(datePicker, current), Arguments.of(datePicker, zero),
40 | Arguments.of(datePicker, null)));
41 | }
42 |
43 | @MethodSource("getDatePickers")
44 | @ParameterizedTest
45 | void testSetGetDate(final IDatePicker> datePicker, final LocalDate expected) {
46 | // This check does not test for set text listeners.
47 | final Instant expectedInstant = expected != null ? Instant.from(expected.atStartOfDay(ZoneOffset.UTC))
48 | : Instant.EPOCH;
49 | assertDoesNotThrow(() -> datePicker.setInstant(expectedInstant));
50 | assertEquals(expectedInstant, datePicker.getInstant());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/actions/MapObjectLayerActionTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.actions;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 |
6 | import org.junit.jupiter.api.Test;
7 | import org.openstreetmap.josm.data.osm.DataSet;
8 | import org.openstreetmap.josm.gui.MainApplication;
9 | import org.openstreetmap.josm.gui.layer.OsmDataLayer;
10 | import org.openstreetmap.josm.plugins.mapillary.gui.layer.PointObjectLayer;
11 | import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryURLWireMock;
12 | import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryURLWireMockErrors;
13 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
14 | import org.openstreetmap.josm.testutils.annotations.Main;
15 | import org.openstreetmap.josm.testutils.annotations.Projection;
16 |
17 | @BasicPreferences
18 | @Main
19 | @MapillaryURLWireMock
20 | @Projection
21 | class MapObjectLayerActionTest {
22 | @Test
23 | @MapillaryURLWireMockErrors
24 | void testAction() {
25 | assertEquals(0, MainApplication.getLayerManager().getLayers().size());
26 | new MapObjectLayerAction().actionPerformed(null);
27 | assertEquals(0, MainApplication.getLayerManager().getLayers().size());
28 | MainApplication.getLayerManager().addLayer(new OsmDataLayer(new DataSet(), "Test", null));
29 | new MapObjectLayerAction().actionPerformed(null);
30 | assertEquals(2, MainApplication.getLayerManager().getLayers().size());
31 | new MapObjectLayerAction().actionPerformed(null);
32 | assertEquals(2, MainApplication.getLayerManager().getLayers().size());
33 | MainApplication.getLayerManager()
34 | .setActiveLayer(MainApplication.getLayerManager().getLayersOfType(PointObjectLayer.class).get(0));
35 | new MapObjectLayerAction().actionPerformed(null);
36 | assertEquals(2, MainApplication.getLayerManager().getLayers().size());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/cache/CachesTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.cache;
3 |
4 | import org.junit.jupiter.api.Test;
5 | import org.openstreetmap.josm.plugins.mapillary.utils.TestUtil;
6 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
7 |
8 | /**
9 | * Test class for {@link Caches}
10 | */
11 | // Preferences are needed to get the cache directories
12 | @BasicPreferences
13 | class CachesTest {
14 | @Test
15 | void testUtilityClass() {
16 | TestUtil.testUtilityClass(Caches.class);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/oauth/OAuthPortListenerTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.oauth;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.IOException;
8 | import java.io.InputStreamReader;
9 | import java.net.HttpURLConnection;
10 | import java.net.URL;
11 | import java.nio.charset.StandardCharsets;
12 |
13 | import org.junit.jupiter.api.Test;
14 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
15 | import org.openstreetmap.josm.testutils.annotations.HTTP;
16 |
17 | /**
18 | * Tests the {@link OAuthPortListener} class.
19 | *
20 | * @author nokutu
21 | * @see OAuthPortListener
22 | */
23 | @BasicPreferences
24 | @HTTP
25 | class OAuthPortListenerTest {
26 |
27 | /**
28 | * Test that the threads responds when the browser makes the request.
29 | */
30 | @Test
31 | void responseTest() throws IOException, InterruptedException {
32 | OAuthPortListener t = new OAuthPortListener(null);
33 | t.start();
34 | Thread.sleep(500);
35 | URL url = new URL("http://localhost:" + OAuthPortListener.PORT + "?access_token=access_token");
36 | HttpURLConnection con = (HttpURLConnection) url.openConnection();
37 | try (BufferedReader in = new BufferedReader(
38 | new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
39 | in.readLine();
40 | assertEquals(OAuthPortListener.RESPONSE, in.readLine());
41 | } finally {
42 | t.join();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/testutils/annotations/AwaitThreadFinish.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.testutils.annotations;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertTrue;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 | import java.util.concurrent.ForkJoinPool;
12 | import java.util.concurrent.TimeUnit;
13 | import java.util.concurrent.atomic.AtomicBoolean;
14 |
15 | import org.awaitility.Awaitility;
16 | import org.awaitility.Durations;
17 | import org.junit.jupiter.api.extension.AfterEachCallback;
18 | import org.junit.jupiter.api.extension.BeforeEachCallback;
19 | import org.junit.jupiter.api.extension.ExtendWith;
20 | import org.junit.jupiter.api.extension.ExtensionContext;
21 | import org.openstreetmap.josm.gui.MainApplication;
22 | import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryUtils;
23 | import org.openstreetmap.josm.testutils.annotations.ThreadSync;
24 |
25 | /**
26 | * An annotation that waits for threads to finish before continuing
27 | *
28 | * @author Taylor Smock
29 | */
30 | @Documented
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Target({ ElementType.TYPE, ElementType.METHOD })
33 | @ExtendWith(AwaitThreadFinish.AwaitThreadFinishExtension.class)
34 | @ExtendWith(ThreadSync.ThreadSyncExtension.class)
35 | public @interface AwaitThreadFinish {
36 | /**
37 | * An extension that waits for threads to finish, and then continues
38 | */
39 | class AwaitThreadFinishExtension implements AfterEachCallback, BeforeEachCallback {
40 | @Override
41 | public void afterEach(ExtensionContext context) {
42 | // Wait for everything to finish
43 | final AtomicBoolean workerDone = new AtomicBoolean();
44 | MainApplication.worker.submit(() -> workerDone.set(true));
45 | Awaitility.await().atMost(Durations.FIVE_SECONDS).until(workerDone::get);
46 |
47 | assertTrue(ForkJoinPool.commonPool().awaitQuiescence(5, TimeUnit.SECONDS));
48 | MapillaryUtils.forkJoinPoolsAwaitQuiescence(5, TimeUnit.SECONDS);
49 | }
50 |
51 | @Override
52 | public void beforeEach(ExtensionContext context) {
53 | context.getStore(ExtensionContext.Namespace.create(AwaitThreadFinish.class)).put(Thread.class,
54 | Thread.activeCount());
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/testutils/annotations/GuiWorkersStopper.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.testutils.annotations;
3 |
4 | import java.lang.annotation.Documented;
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 | import java.util.concurrent.atomic.AtomicBoolean;
10 |
11 | import org.awaitility.Awaitility;
12 | import org.awaitility.Durations;
13 | import org.junit.jupiter.api.extension.AfterEachCallback;
14 | import org.junit.jupiter.api.extension.ExtendWith;
15 | import org.junit.jupiter.api.extension.ExtensionContext;
16 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
17 |
18 | @Documented
19 | @Retention(RetentionPolicy.RUNTIME)
20 | @Target({ ElementType.TYPE, ElementType.METHOD })
21 | @BasicPreferences
22 | @ExtendWith(GuiWorkersStopper.MapillaryDownloader.class)
23 | @MapillaryLayerAnnotation
24 | public @interface GuiWorkersStopper {
25 | class MapillaryDownloader implements AfterEachCallback {
26 | @Override
27 | public void afterEach(ExtensionContext context) {
28 | AtomicBoolean done = new AtomicBoolean();
29 | new org.openstreetmap.josm.plugins.mapillary.gui.workers.MapillaryNodesDownloader(nodes -> done.set(true),
30 | 1).execute();
31 | Awaitility.await().atMost(Durations.FIVE_SECONDS).untilTrue(done);
32 | done.set(false);
33 | new org.openstreetmap.josm.plugins.mapillary.gui.workers.MapillarySequenceDownloader("",
34 | chunks -> done.set(true)).execute();
35 | Awaitility.await().atMost(Durations.FIVE_SECONDS).untilTrue(done);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/testutils/annotations/IntegrationTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.testutils.annotations;
3 |
4 | import java.lang.annotation.Documented;
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Inherited;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.RetentionPolicy;
9 | import java.lang.annotation.Target;
10 |
11 | import org.junit.jupiter.api.Tag;
12 |
13 | /**
14 | * Mark tests as integration tests.
15 | *
16 | * @author Taylor Smock
17 | */
18 | @Target({ ElementType.TYPE, ElementType.METHOD })
19 | @Retention(RetentionPolicy.RUNTIME)
20 | @Documented
21 | @Inherited
22 | @Tag(IntegrationTest.TAG)
23 | public @interface IntegrationTest {
24 | /** This is the actual tag string added to the test */
25 | String TAG = "integration";
26 | }
27 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/testutils/annotations/MapillaryLayerAnnotation.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.testutils.annotations;
3 |
4 | import java.lang.annotation.Documented;
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | import org.junit.jupiter.api.extension.AfterEachCallback;
11 | import org.junit.jupiter.api.extension.BeforeEachCallback;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.junit.jupiter.api.extension.ExtensionContext;
14 | import org.openstreetmap.josm.gui.MainApplication;
15 | import org.openstreetmap.josm.plugins.mapillary.gui.layer.MapillaryLayer;
16 | import org.openstreetmap.josm.tools.Logging;
17 |
18 | /**
19 | * Ensure that the MapillaryLayer is cleaned up
20 | */
21 | @Documented
22 | @Retention(RetentionPolicy.RUNTIME)
23 | @Target({ ElementType.TYPE, ElementType.METHOD })
24 | @ExtendWith(MapillaryLayerAnnotation.MapillaryLayerExtension.class)
25 | @MapillaryURLWireMock
26 | public @interface MapillaryLayerAnnotation {
27 | class MapillaryLayerExtension implements AfterEachCallback, BeforeEachCallback {
28 |
29 | @Override
30 | public void afterEach(ExtensionContext context) {
31 | this.beforeEach(context);
32 | }
33 |
34 | @Override
35 | public void beforeEach(ExtensionContext context) {
36 | try {
37 | cleanup();
38 | } catch (IllegalArgumentException illegalArgumentException) {
39 | // This happens when the layer isn't properly destroyed in a previous test
40 | Logging.trace(illegalArgumentException);
41 | }
42 | }
43 |
44 | void cleanup() {
45 | if (MapillaryLayer.hasInstance()) {
46 | final MapillaryLayer layer = MapillaryLayer.getInstance();
47 | if (MainApplication.getLayerManager().containsLayer(layer)) {
48 | MainApplication.getLayerManager().removeLayer(layer);
49 | }
50 | layer.destroy();
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/testutils/annotations/ObjectDetectionsAnnotation.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.testutils.annotations;
3 |
4 | import java.lang.annotation.Documented;
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | import org.junit.jupiter.api.extension.AfterAllCallback;
11 | import org.junit.jupiter.api.extension.BeforeAllCallback;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.junit.jupiter.api.extension.ExtensionContext;
14 | import org.openstreetmap.josm.plugins.mapillary.data.mapillary.ObjectDetections;
15 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
16 | import org.openstreetmap.josm.testutils.annotations.HTTP;
17 | import org.openstreetmap.josm.testutils.annotations.Projection;
18 | import org.openstreetmap.josm.testutils.annotations.TaggingPresets;
19 |
20 | /**
21 | * Annotation for ObjectDetections (ensures they have the appropriate presets)
22 | *
23 | * @author Taylor Smock
24 | */
25 | @Documented
26 | @Target(ElementType.TYPE)
27 | @Retention(RetentionPolicy.RUNTIME)
28 | @BasicPreferences
29 | @HTTP
30 | @Projection
31 | @TaggingPresets
32 | @MapillaryURLWireMock // Needed since updatePresets calls an API endpoint
33 | @ExtendWith(ObjectDetectionsAnnotation.ObjectDetectionsExtension.class)
34 | public @interface ObjectDetectionsAnnotation {
35 | class ObjectDetectionsExtension implements AfterAllCallback, BeforeAllCallback {
36 |
37 | @Override
38 | public void afterAll(ExtensionContext context) {
39 | this.beforeAll(context);
40 | }
41 |
42 | @Override
43 | public void beforeAll(ExtensionContext context) {
44 | ObjectDetections.updatePresets();
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/testutils/annotations/SecurityManagerTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.testutils.annotations;
3 |
4 | import java.security.Permission;
5 |
6 | import org.junit.jupiter.api.extension.AfterEachCallback;
7 | import org.junit.jupiter.api.extension.BeforeEachCallback;
8 | import org.junit.jupiter.api.extension.ExtendWith;
9 | import org.junit.jupiter.api.extension.ExtensionContext;
10 |
11 | /**
12 | * Used to indicate a security manager should be installed for a test.
13 | * This is mostly useful for non-regression tests for WebStart related issues.
14 | *
15 | * @author Taylor Smock
16 | */
17 | @ExtendWith(SecurityManagerTest.SecurityManagerExtension.class)
18 | public @interface SecurityManagerTest {
19 | class SecurityManagerExtension implements AfterEachCallback, BeforeEachCallback {
20 | private static class TestSecurityManager extends SecurityManager {
21 | @Override
22 | public void checkPermission(Permission perm) {
23 | if (perm instanceof RuntimePermission && "setSecurityManager".equals(perm.getName())) {
24 | StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[1];
25 | if (SecurityManagerTest.SecurityManagerExtension.class.getCanonicalName()
26 | .equals(stackTrace.getClassName())) {
27 | return;
28 | }
29 | }
30 | super.checkPermission(perm);
31 | }
32 | }
33 |
34 | @Override
35 | public void afterEach(ExtensionContext context) {
36 | SecurityManager sm = System.getSecurityManager();
37 | if (sm instanceof TestSecurityManager) {
38 | System.setSecurityManager(null);
39 | }
40 | }
41 |
42 | @Override
43 | public void beforeEach(ExtensionContext context) {
44 | if (System.getSecurityManager() == null) {
45 | TestSecurityManager securityManager = new TestSecurityManager();
46 | System.setSecurityManager(securityManager);
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/ImageMetaDataUtilTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertTrue;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.nio.file.Files;
10 | import java.nio.file.Paths;
11 |
12 | import org.junit.jupiter.api.Test;
13 | import org.openstreetmap.josm.TestUtils;
14 |
15 | class ImageMetaDataUtilTest {
16 | @Test
17 | void testXmpXmlParse() throws IOException {
18 | boolean pano = ImageMetaDataUtil.checkXmpProjectionType(
19 | Files.readString(Paths.get(TestUtils.getTestDataRoot(), "xmpTestImages", "xmpProjectionOnly.xml")),
20 | "equirectangular");
21 | assertTrue(pano);
22 | }
23 |
24 | @Test
25 | void testImageFileXMP() {
26 | final File xmpImageFile = Paths.get(TestUtils.getTestDataRoot(), "xmpTestImages", "xmpProjectionOnly.jpg")
27 | .toFile();
28 | boolean pano = ImageMetaDataUtil.isPanorama(xmpImageFile);
29 | assertTrue(pano);
30 | }
31 |
32 | @Test
33 | void testImageStreamingXMP() throws IOException {
34 | try (InputStream xmpImageStream = Files
35 | .newInputStream(Paths.get(TestUtils.getTestDataRoot(), "xmpTestImages", "xmpProjectionOnly.jpg"))) {
36 | boolean pano = ImageMetaDataUtil.isPanorama(xmpImageStream);
37 | assertTrue(pano);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/ImageUtilTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 |
6 | import java.awt.image.BufferedImage;
7 |
8 | import javax.swing.ImageIcon;
9 |
10 | import org.junit.jupiter.api.Test;
11 |
12 | class ImageUtilTest {
13 |
14 | @Test
15 | void testUtilityClass() {
16 | TestUtil.testUtilityClass(ImageUtil.class);
17 | }
18 |
19 | @Test
20 | void testScaleImageIcon() {
21 | ImageIcon largeLandscape = new ImageIcon(new BufferedImage(72, 60, BufferedImage.TYPE_4BYTE_ABGR));
22 | ImageIcon largePortrait = new ImageIcon(new BufferedImage(56, 88, BufferedImage.TYPE_4BYTE_ABGR));
23 | ImageIcon smallLandscape = ImageUtil.scaleImageIcon(largeLandscape, 24);
24 | ImageIcon smallPortrait = ImageUtil.scaleImageIcon(largePortrait, 22);
25 |
26 | assertEquals(24, smallLandscape.getIconWidth());
27 | assertEquals(20, smallLandscape.getIconHeight());
28 |
29 | assertEquals(22, smallPortrait.getIconHeight());
30 | assertEquals(14, smallPortrait.getIconWidth());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryColorSchemeTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5 |
6 | import javax.swing.JComponent;
7 |
8 | import org.junit.jupiter.api.Test;
9 |
10 | class MapillaryColorSchemeTest {
11 |
12 | @Test
13 | void testUtilityClass() {
14 | TestUtil.testUtilityClass(MapillaryColorScheme.class);
15 | }
16 |
17 | @Test
18 | void testStyleAsDefaultPanel() {
19 | assertDoesNotThrow(() -> {
20 | MapillaryColorScheme.styleAsDefaultPanel();
21 | MapillaryColorScheme.styleAsDefaultPanel((JComponent[]) null);
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryPropertiesTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils;
3 |
4 | import org.junit.jupiter.api.Test;
5 |
6 | class MapillaryPropertiesTest {
7 | @Test
8 | void test() {
9 | TestUtil.testUtilityClass(MapillaryProperties.class);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/api/JsonDecoderTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils.api;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertArrayEquals;
5 |
6 | import java.io.ByteArrayInputStream;
7 | import java.io.IOException;
8 | import java.io.UncheckedIOException;
9 | import java.nio.charset.StandardCharsets;
10 | import java.util.function.Function;
11 |
12 | import jakarta.json.Json;
13 | import jakarta.json.JsonReader;
14 | import jakarta.json.JsonValue;
15 | import org.junit.jupiter.api.Test;
16 | import org.openstreetmap.josm.plugins.mapillary.utils.TestUtil;
17 |
18 | class JsonDecoderTest {
19 |
20 | @Test
21 | void testUtilityClass() {
22 | TestUtil.testUtilityClass(JsonDecoder.class);
23 | }
24 |
25 | @Test
26 | void testDecodeDoublePair() {
27 | assertArrayEquals(new double[0], JsonDecoder.decodeDoublePair(null));
28 | }
29 |
30 | /**
31 | * Convert a series of strings to JSON
32 | *
33 | * @param parts The string parts to convert
34 | * @return A json value
35 | */
36 | static JsonValue stringToJsonValue(final String... parts) {
37 | return stringToJsonValue(JsonReader::readValue, parts);
38 | }
39 |
40 | /**
41 | * Convert a series of strings to JSON
42 | *
43 | * @param parts The string parts to convert
44 | * @param function The conversion function
45 | * @param The type to return
46 | * @return A json value
47 | */
48 | static T stringToJsonValue(final Function function, final String... parts) {
49 | try (
50 | ByteArrayInputStream stream = new ByteArrayInputStream(
51 | String.join(" ", parts).getBytes(StandardCharsets.UTF_8));
52 | JsonReader reader = Json.createReader(stream)) {
53 | return function.apply(reader);
54 | } catch (IOException e) {
55 | throw new UncheckedIOException(e);
56 | }
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/api/JsonImageDetectionDecoderTest.java:
--------------------------------------------------------------------------------
1 | // License: GPL. For details, see LICENSE file.
2 | package org.openstreetmap.josm.plugins.mapillary.utils.api;
3 |
4 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5 |
6 | import java.io.ByteArrayInputStream;
7 | import java.nio.charset.StandardCharsets;
8 |
9 | import jakarta.json.Json;
10 | import jakarta.json.JsonReader;
11 | import org.junit.jupiter.params.ParameterizedTest;
12 | import org.junit.jupiter.params.provider.ValueSource;
13 | import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryCaches;
14 | import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryURLWireMock;
15 |
16 | @MapillaryCaches
17 | @MapillaryURLWireMock
18 | class JsonImageDetectionDecoderTest {
19 |
20 | /**
21 | * This is a non-regression test for JOSM #21254
22 | *
23 | * @param geometry The geometry to check
24 | */
25 | @ParameterizedTest
26 | @ValueSource(strings = { "GiB4AgoGbXB5LW9yKIAgEhEYAwgBIgsJxheqLxIEFQAeDw==" })
27 | void testDecodeImageDetectionGeometryNonRegression21254(final String geometry) {
28 | final String jsonString = "{\"value\":\"construction--barrier--concrete-block\",\"id\":\"1\",\"geometry\":\""
29 | + geometry + "\",\"image\":{\"id\":\"1\"}}";
30 | try (JsonReader jsonReader = Json
31 | .createReader(new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8)))) {
32 | assertDoesNotThrow(() -> JsonImageDetectionDecoder.decodeImageDetection(jsonReader.read(), null));
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------