001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.List; 007import java.util.concurrent.locks.Lock; 008import java.util.function.Predicate; 009 010import org.openstreetmap.josm.data.Data; 011import org.openstreetmap.josm.data.DataSource; 012import org.openstreetmap.josm.data.ProjectionBounds; 013import org.openstreetmap.josm.data.osm.event.SelectionEventManager; 014import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 015import org.openstreetmap.josm.tools.SubclassFilteredCollection; 016 017/** 018 * Abstraction of {@link DataSet}. 019 * This class holds OSM data but does not rely on implementation types, 020 * allowing plugins to define their own representation of OSM data if needed. 021 * @param <O> the base type of OSM primitives 022 * @param <N> type representing OSM nodes 023 * @param <W> type representing OSM ways 024 * @param <R> type representing OSM relations 025 * @since 13764 026 */ 027public interface OsmData<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Data, Lockable { 028 029 // -------------- 030 // Metadata 031 // -------------- 032 033 /** 034 * Replies the API version this dataset was created from. May be null. 035 * @return the API version this dataset was created from. May be null. 036 */ 037 String getVersion(); 038 039 /** 040 * Returns the name of this data set (optional). 041 * @return the name of this data set. Can be {@code null} 042 * @since 12718 043 */ 044 String getName(); 045 046 /** 047 * Sets the name of this data set. 048 * @param name the new name of this data set. Can be {@code null} to reset it 049 * @since 12718 050 */ 051 void setName(String name); 052 053 // -------------------- 054 // OSM primitives 055 // -------------------- 056 057 /** 058 * Adds a primitive. 059 * @param primitive the primitive 060 */ 061 void addPrimitive(O primitive); 062 063 /** 064 * Removes all primitives. 065 */ 066 void clear(); 067 068 /** 069 * Searches for nodes in the given bounding box. 070 * @param bbox the bounding box 071 * @return List of nodes in the given bbox. Can be empty but not null 072 */ 073 List<N> searchNodes(BBox bbox); 074 075 /** 076 * Determines if the given node can be retrieved in the data set through its bounding box. Useful for dataset consistency test. 077 * @param n The node to search 078 * @return {@code true} if {@code n} can be retrieved in this data set, {@code false} otherwise 079 */ 080 boolean containsNode(N n); 081 082 /** 083 * Searches for ways in the given bounding box. 084 * @param bbox the bounding box 085 * @return List of ways in the given bbox. Can be empty but not null 086 */ 087 List<W> searchWays(BBox bbox); 088 089 /** 090 * Determines if the given way can be retrieved in the data set through its bounding box. Useful for dataset consistency test. 091 * @param w The way to search 092 * @return {@code true} if {@code w} can be retrieved in this data set, {@code false} otherwise 093 */ 094 boolean containsWay(W w); 095 096 /** 097 * Searches for relations in the given bounding box. 098 * @param bbox the bounding box 099 * @return List of relations in the given bbox. Can be empty but not null 100 */ 101 List<R> searchRelations(BBox bbox); 102 103 /** 104 * Determines if the given relation can be retrieved in the data set through its bounding box. Useful for dataset consistency test. 105 * @param r The relation to search 106 * @return {@code true} if {@code r} can be retrieved in this data set, {@code false} otherwise 107 */ 108 boolean containsRelation(R r); 109 110 /** 111 * Returns a primitive with a given id from the data set. null, if no such primitive exists 112 * 113 * @param id uniqueId of the primitive. Might be < 0 for newly created primitives 114 * @param type the type of the primitive. Must not be null. 115 * @return the primitive 116 * @throws NullPointerException if type is null 117 */ 118 default O getPrimitiveById(long id, OsmPrimitiveType type) { 119 return getPrimitiveById(new SimplePrimitiveId(id, type)); 120 } 121 122 /** 123 * Returns a primitive with a given id from the data set. null, if no such primitive exists 124 * 125 * @param primitiveId type and uniqueId of the primitive. Might be < 0 for newly created primitives 126 * @return the primitive 127 */ 128 O getPrimitiveById(PrimitiveId primitiveId); 129 130 /** 131 * Gets a filtered collection of primitives matching the given predicate. 132 * @param <T> The primitive type. 133 * @param predicate The predicate to match 134 * @return The list of primtives. 135 * @since 10590 136 */ 137 <T extends O> Collection<T> getPrimitives(Predicate<? super O> predicate); 138 139 /** 140 * Replies an unmodifiable collection of nodes in this dataset 141 * 142 * @return an unmodifiable collection of nodes in this dataset 143 */ 144 Collection<N> getNodes(); 145 146 /** 147 * Replies an unmodifiable collection of ways in this dataset 148 * 149 * @return an unmodifiable collection of ways in this dataset 150 */ 151 Collection<W> getWays(); 152 153 /** 154 * Replies an unmodifiable collection of relations in this dataset 155 * 156 * @return an unmodifiable collection of relations in this dataset 157 */ 158 Collection<R> getRelations(); 159 160 /** 161 * Returns a collection containing all primitives of the dataset. 162 * @return A collection containing all primitives of the dataset. Data is not ordered 163 */ 164 default Collection<O> allPrimitives() { 165 return getPrimitives(o -> true); 166 } 167 168 /** 169 * Returns a collection containing all not-deleted primitives. 170 * @return A collection containing all not-deleted primitives. 171 * @see OsmPrimitive#isDeleted 172 */ 173 default Collection<O> allNonDeletedPrimitives() { 174 return getPrimitives(p -> !p.isDeleted()); 175 } 176 177 /** 178 * Returns a collection containing all not-deleted complete primitives. 179 * @return A collection containing all not-deleted complete primitives. 180 * @see OsmPrimitive#isDeleted 181 * @see OsmPrimitive#isIncomplete 182 */ 183 default Collection<O> allNonDeletedCompletePrimitives() { 184 return getPrimitives(primitive -> !primitive.isDeleted() && !primitive.isIncomplete()); 185 } 186 187 /** 188 * Returns a collection containing all not-deleted complete physical primitives. 189 * @return A collection containing all not-deleted complete physical primitives (nodes and ways). 190 * @see OsmPrimitive#isDeleted 191 * @see OsmPrimitive#isIncomplete 192 */ 193 default Collection<O> allNonDeletedPhysicalPrimitives() { 194 return getPrimitives( 195 primitive -> !primitive.isDeleted() && !primitive.isIncomplete() && !(primitive instanceof IRelation)); 196 } 197 198 /** 199 * Returns a collection containing all modified primitives. 200 * @return A collection containing all modified primitives. 201 * @see OsmPrimitive#isModified 202 */ 203 default Collection<O> allModifiedPrimitives() { 204 return getPrimitives(IPrimitive::isModified); 205 } 206 207 /** 208 * Returns a collection containing all primitives preserved from filtering. 209 * @return A collection containing all primitives preserved from filtering. 210 * @see OsmPrimitive#isPreserved 211 * @since 13309 212 */ 213 default Collection<O> allPreservedPrimitives() { 214 return getPrimitives(IPrimitive::isPreserved); 215 } 216 217 // -------------- 218 // Policies 219 // -------------- 220 221 /** 222 * Get the download policy. 223 * @return the download policy 224 * @see #setDownloadPolicy(DownloadPolicy) 225 * @since 13453 226 */ 227 DownloadPolicy getDownloadPolicy(); 228 229 /** 230 * Sets the download policy. 231 * @param downloadPolicy the download policy. Must not be null 232 * @see #getUploadPolicy() 233 * @since 13453 234 */ 235 void setDownloadPolicy(DownloadPolicy downloadPolicy); 236 237 /** 238 * Get the upload policy. 239 * @return the upload policy 240 * @see #setUploadPolicy(UploadPolicy) 241 */ 242 UploadPolicy getUploadPolicy(); 243 244 /** 245 * Sets the upload policy. 246 * @param uploadPolicy the upload policy. Must not be null 247 * @see #getUploadPolicy() 248 */ 249 void setUploadPolicy(UploadPolicy uploadPolicy); 250 251 // -------------- 252 // Locks 253 // -------------- 254 255 /** 256 * Returns the lock used for reading. 257 * @return the lock used for reading 258 */ 259 Lock getReadLock(); 260 261 // --------------- 262 // Highlight 263 // --------------- 264 265 /** 266 * Returns an unmodifiable collection of *WaySegments* whose virtual 267 * nodes should be highlighted. WaySegments are used to avoid having 268 * to create a VirtualNode class that wouldn't have much purpose otherwise. 269 * 270 * @return unmodifiable collection of WaySegments 271 */ 272 Collection<WaySegment> getHighlightedVirtualNodes(); 273 274 /** 275 * Returns an unmodifiable collection of WaySegments that should be highlighted. 276 * 277 * @return unmodifiable collection of WaySegments 278 */ 279 Collection<WaySegment> getHighlightedWaySegments(); 280 281 /** 282 * clear all highlights of virtual nodes 283 */ 284 default void clearHighlightedVirtualNodes() { 285 setHighlightedVirtualNodes(new ArrayList<WaySegment>()); 286 } 287 288 /** 289 * clear all highlights of way segments 290 */ 291 default void clearHighlightedWaySegments() { 292 setHighlightedWaySegments(new ArrayList<WaySegment>()); 293 } 294 295 /** 296 * set what virtual nodes should be highlighted. Requires a Collection of 297 * *WaySegments* to avoid a VirtualNode class that wouldn't have much use otherwise. 298 * @param waySegments Collection of way segments 299 */ 300 void setHighlightedVirtualNodes(Collection<WaySegment> waySegments); 301 302 /** 303 * set what virtual ways should be highlighted. 304 * @param waySegments Collection of way segments 305 */ 306 void setHighlightedWaySegments(Collection<WaySegment> waySegments); 307 308 /** 309 * Adds a listener that gets notified whenever way segment / virtual nodes highlights change. 310 * @param listener The Listener 311 * @since 12014 312 */ 313 void addHighlightUpdateListener(HighlightUpdateListener listener); 314 315 /** 316 * Removes a listener that was added with {@link #addHighlightUpdateListener(HighlightUpdateListener)} 317 * @param listener The Listener 318 * @since 12014 319 */ 320 void removeHighlightUpdateListener(HighlightUpdateListener listener); 321 322 // --------------- 323 // Selection 324 // --------------- 325 326 /** 327 * Replies an unmodifiable collection of primitives currently selected 328 * in this dataset, except deleted ones. May be empty, but not null. 329 * 330 * When iterating through the set it is ordered by the order in which the primitives were added to the selection. 331 * 332 * @return unmodifiable collection of primitives 333 */ 334 default Collection<O> getSelected() { 335 return new SubclassFilteredCollection<>(getAllSelected(), p -> !p.isDeleted()); 336 } 337 338 /** 339 * Replies an unmodifiable collection of primitives currently selected 340 * in this dataset, including deleted ones. May be empty, but not null. 341 * 342 * When iterating through the set it is ordered by the order in which the primitives were added to the selection. 343 * 344 * @return unmodifiable collection of primitives 345 */ 346 Collection<O> getAllSelected(); 347 348 /** 349 * Returns selected nodes. 350 * @return selected nodes 351 */ 352 default Collection<N> getSelectedNodes() { 353 return new SubclassFilteredCollection<>(getSelected(), Node.class::isInstance); 354 } 355 356 /** 357 * Returns selected ways. 358 * @return selected ways 359 */ 360 default Collection<W> getSelectedWays() { 361 return new SubclassFilteredCollection<>(getSelected(), Way.class::isInstance); 362 } 363 364 /** 365 * Returns selected relations. 366 * @return selected relations 367 */ 368 default Collection<R> getSelectedRelations() { 369 return new SubclassFilteredCollection<>(getSelected(), Relation.class::isInstance); 370 } 371 372 /** 373 * Determines whether the selection is empty or not 374 * @return whether the selection is empty or not 375 */ 376 boolean selectionEmpty(); 377 378 /** 379 * Determines whether the given primitive is selected or not 380 * @param osm the primitive 381 * @return whether {@code osm} is selected or not 382 */ 383 boolean isSelected(O osm); 384 385 /** 386 * Toggles the selected state of the given collection of primitives. 387 * @param osm The primitives to toggle 388 */ 389 void toggleSelected(Collection<? extends PrimitiveId> osm); 390 391 /** 392 * Toggles the selected state of the given collection of primitives. 393 * @param osm The primitives to toggle 394 */ 395 void toggleSelected(PrimitiveId... osm); 396 397 /** 398 * Sets the current selection to the primitives in <code>selection</code> 399 * and notifies all {@link DataSelectionListener}. 400 * 401 * @param selection the selection 402 */ 403 void setSelected(Collection<? extends PrimitiveId> selection); 404 405 /** 406 * Sets the current selection to the primitives in <code>osm</code> 407 * and notifies all {@link DataSelectionListener}. 408 * 409 * @param osm the primitives to set. <code>null</code> values are ignored for now, but this may be removed in the future. 410 */ 411 void setSelected(PrimitiveId... osm); 412 413 /** 414 * Adds the primitives in <code>selection</code> to the current selection 415 * and notifies all {@link DataSelectionListener}. 416 * 417 * @param selection the selection 418 */ 419 void addSelected(Collection<? extends PrimitiveId> selection); 420 421 /** 422 * Adds the primitives in <code>osm</code> to the current selection 423 * and notifies all {@link DataSelectionListener}. 424 * 425 * @param osm the primitives to add 426 */ 427 void addSelected(PrimitiveId... osm); 428 429 /** 430 * Removes the selection from every value in the collection. 431 * @param osm The collection of ids to remove the selection from. 432 */ 433 void clearSelection(PrimitiveId... osm); 434 435 /** 436 * Removes the selection from every value in the collection. 437 * @param list The collection of ids to remove the selection from. 438 */ 439 void clearSelection(Collection<? extends PrimitiveId> list); 440 441 /** 442 * Clears the current selection. 443 */ 444 void clearSelection(); 445 446 /** 447 * Add a listener that listens to selection changes in this specific data set. 448 * @param listener The listener. 449 * @see #removeSelectionListener(DataSelectionListener) 450 * @see SelectionEventManager#addSelectionListener(DataSelectionListener) 451 * To add a global listener. 452 */ 453 void addSelectionListener(DataSelectionListener listener); 454 455 /** 456 * Remove a listener that listens to selection changes in this specific data set. 457 * @param listener The listener. 458 * @see #addSelectionListener(DataSelectionListener) 459 */ 460 void removeSelectionListener(DataSelectionListener listener); 461 462 // ------------------- 463 // Miscellaneous 464 // ------------------- 465 466 /** 467 * Returns the data sources bounding box. 468 * @return the data sources bounding box 469 */ 470 default ProjectionBounds getDataSourceBoundingBox() { 471 BoundingXYVisitor bbox = new BoundingXYVisitor(); 472 for (DataSource source : getDataSources()) { 473 bbox.visit(source.bounds); 474 } 475 if (bbox.hasExtend()) { 476 return bbox.getBounds(); 477 } 478 return null; 479 } 480 481 /** 482 * Clear the mappaint cache for this DataSet. 483 * @since 13420 484 */ 485 void clearMappaintCache(); 486 487 /** 488 * Replies true if there is at least one primitive in this dataset with 489 * {@link IPrimitive#isModified()} == <code>true</code>. 490 * 491 * @return true if there is at least one primitive in this dataset with 492 * {@link IPrimitive#isModified()} == <code>true</code>. 493 */ 494 default boolean isModified() { 495 return false; 496 } 497}