source: josm/trunk/src/org/openstreetmap/josm/tools/OsmPrimitiveImageProvider.java@ 17335

Last change on this file since 17335 was 16848, checked in by simon04, 4 years ago

see #19622 - Java warning

File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2
3package org.openstreetmap.josm.tools;
4
5import java.util.Collection;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.EnumSet;
9import java.util.Objects;
10import java.util.Optional;
11
12import javax.swing.ImageIcon;
13
14import org.openstreetmap.josm.data.coor.LatLon;
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.INode;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
19import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
20import org.openstreetmap.josm.gui.mappaint.Range;
21import org.openstreetmap.josm.gui.mappaint.StyleElementList;
22import org.openstreetmap.josm.gui.mappaint.styleelement.MapImage;
23import org.openstreetmap.josm.gui.mappaint.styleelement.NodeElement;
24import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
25import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
26import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
27
28/**
29 * An {@link ImageProvider} for {@link org.openstreetmap.josm.data.osm.OsmPrimitive}
30 *
31 * @since 16838 (extracted from ImageProvider)
32 */
33public final class OsmPrimitiveImageProvider {
34
35 private OsmPrimitiveImageProvider() {
36 // private constructor
37 }
38
39 /**
40 * Returns an {@link ImageIcon} for the given OSM object, at the specified size.
41 * This is a slow operation.
42 * @param primitive Object for which an icon shall be fetched. The icon is chosen based on tags.
43 * @param options zero or more {@linkplain Options options}.
44 * @return Icon for {@code primitive} that fits in cell or {@code null}.
45 * @since 15889
46 */
47 public static ImageResource getResource(OsmPrimitive primitive, Collection<Options> options) {
48 // Check if the current styles have special icon for tagged objects.
49 if (primitive.isTagged()) {
50 ImageResource icon = getResourceFromMapPaintStyles(primitive, options);
51 if (icon != null) {
52 return icon;
53 }
54 }
55
56 // Check if the presets have icons for nodes/relations.
57 if (primitive.isTagged() && (!options.contains(Options.NO_WAY_PRESETS) || OsmPrimitiveType.WAY != primitive.getType())) {
58 final Optional<ImageResource> icon = TaggingPresets.getMatchingPresets(primitive).stream()
59 .sorted(Comparator.comparing(p -> (p.iconName != null && p.iconName.contains("multipolygon"))
60 || p.types == null || p.types.isEmpty() ? Integer.MAX_VALUE : p.types.size()))
61 .map(TaggingPreset::getImageResource)
62 .filter(Objects::nonNull)
63 .findFirst();
64 if (icon.isPresent()) {
65 return icon.get();
66 }
67 }
68
69 // Use generic default icon.
70 return options.contains(Options.NO_DEFAULT)
71 ? null
72 : new ImageProvider("data", primitive.getDisplayType().getAPIName()).getResource();
73 }
74
75 /**
76 * Computes a new padded icon for the given tagged primitive, using map paint styles.
77 * This is a slow operation.
78 * @param primitive tagged OSM primitive
79 * @param options zero or more {@linkplain Options options}.
80 * @return a new padded icon for the given tagged primitive, or null
81 */
82 private static ImageResource getResourceFromMapPaintStyles(OsmPrimitive primitive, Collection<Options> options) {
83 Pair<StyleElementList, Range> nodeStyles;
84 DataSet ds = primitive.getDataSet();
85 if (ds != null) {
86 ds.getReadLock().lock();
87 }
88 try {
89 nodeStyles = MapPaintStyles.getStyles().generateStyles(primitive, 100, false);
90 } finally {
91 if (ds != null) {
92 ds.getReadLock().unlock();
93 }
94 }
95 for (StyleElement style : nodeStyles.a) {
96 if (style instanceof NodeElement) {
97 NodeElement nodeStyle = (NodeElement) style;
98 MapImage icon = nodeStyle.mapImage;
99 if (icon != null && icon.getImageResource() != null &&
100 (icon.name == null || !options.contains(Options.NO_DEPRECATED) || !icon.name.contains("deprecated"))) {
101 return icon.getImageResource();
102 }
103 }
104 }
105 return null;
106 }
107
108 /**
109 * Searches for an icon for the given key/value and primitiveType
110 * @param key The tag key
111 * @param value The tag value
112 * @param primitiveType The type of the primitive
113 * @return an icon for the given key/value and primitiveType
114 */
115 public static Optional<ImageResource> getResource(String key, String value, OsmPrimitiveType primitiveType) {
116 final OsmPrimitive virtual = primitiveType
117 .newInstance(0, false);
118 if (virtual instanceof INode) {
119 ((INode) virtual).setCoor(LatLon.ZERO);
120 }
121 virtual.put(key, value);
122 try {
123 final ImageResource padded = getResource(virtual, EnumSet.of(Options.NO_DEFAULT, Options.NO_DEPRECATED));
124 return Optional.ofNullable(padded);
125 } catch (Exception e) {
126 Logging.warn("Failed to find icon for {0} {1}={2}", virtual.getType(), key, value);
127 Logging.warn(e);
128 return Optional.empty();
129 }
130 }
131
132 /**
133 * Options used in {@link #getResource(OsmPrimitive, Collection)}.
134 * @since 15889
135 */
136 public enum Options {
137 /**
138 * Exclude icon indicating deprecated tag usage.
139 */
140 NO_DEPRECATED,
141 /**
142 * Exclude default icon for {@link OsmPrimitiveType} from {@link ImageProvider#get(OsmPrimitiveType)}
143 */
144 NO_DEFAULT,
145 /**
146 * Exclude tagging preset icons.
147 */
148 NO_PRESETS,
149 /**
150 * Exclude tagging preset icons for {@linkplain OsmPrimitiveType#WAY ways}.
151 */
152 NO_WAY_PRESETS;
153
154 static final Collection<Options> DEFAULT = Collections.singleton(Options.NO_WAY_PRESETS);
155 }
156}
Note: See TracBrowser for help on using the repository browser.