001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.Date; 005import java.util.List; 006import java.util.Map; 007 008import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor; 009import org.openstreetmap.josm.tools.LanguageInfo; 010 011/** 012 * IPrimitive captures the common functions of {@link OsmPrimitive} and {@link PrimitiveData}. 013 * @since 4098 014 */ 015public interface IPrimitive extends Tagged, PrimitiveId, Stylable, Comparable<IPrimitive> { 016 017 /** 018 * Replies <code>true</code> if the object has been modified since it was loaded from 019 * the server. In this case, on next upload, this object will be updated. 020 * 021 * Deleted objects are deleted from the server. If the objects are added (id=0), 022 * the modified is ignored and the object is added to the server. 023 * 024 * @return <code>true</code> if the object has been modified since it was loaded from 025 * the server 026 */ 027 boolean isModified(); 028 029 /** 030 * Marks this primitive as being modified. 031 * 032 * @param modified true, if this primitive is to be modified 033 */ 034 void setModified(boolean modified); 035 036 /** 037 * Checks if object is known to the server. 038 * Replies true if this primitive is either unknown to the server (i.e. its id 039 * is 0) or it is known to the server and it hasn't be deleted on the server. 040 * Replies false, if this primitive is known on the server and has been deleted 041 * on the server. 042 * 043 * @return <code>true</code>, if the object is visible on server. 044 * @see #setVisible(boolean) 045 */ 046 boolean isVisible(); 047 048 /** 049 * Sets whether this primitive is visible, i.e. whether it is known on the server 050 * and not deleted on the server. 051 * @param visible {@code true} if this primitive is visible 052 * 053 * @throws IllegalStateException if visible is set to false on an primitive with id==0 054 * @see #isVisible() 055 */ 056 void setVisible(boolean visible); 057 058 /** 059 * Replies <code>true</code>, if the object has been deleted. 060 * 061 * @return <code>true</code>, if the object has been deleted. 062 * @see #setDeleted(boolean) 063 */ 064 boolean isDeleted(); 065 066 /** 067 * Sets whether this primitive is deleted or not. 068 * 069 * Also marks this primitive as modified if deleted is true. 070 * 071 * @param deleted true, if this primitive is deleted; false, otherwise 072 */ 073 void setDeleted(boolean deleted); 074 075 /** 076 * Determines if this primitive is incomplete. 077 * @return {@code true} if this primitive is incomplete, {@code false} otherwise 078 */ 079 boolean isIncomplete(); 080 081 /** 082 * Replies <code>true</code> if the object has been deleted on the server and was undeleted by the user. 083 * @return <code>true</code> if the object has been undeleted 084 */ 085 boolean isUndeleted(); 086 087 /** 088 * Replies <code>true</code>, if the object is usable 089 * (i.e. complete and not deleted). 090 * 091 * @return <code>true</code>, if the object is usable. 092 * @see #setDeleted(boolean) 093 */ 094 boolean isUsable(); 095 096 /** 097 * Determines if this primitive is new or undeleted. 098 * @return True if primitive is new or undeleted 099 * @see #isNew() 100 * @see #isUndeleted() 101 */ 102 boolean isNewOrUndeleted(); 103 104 /** 105 * Replies true, if this primitive is disabled. (E.g. a filter applies) 106 * @return {@code true} if this object has the "disabled" flag enabled 107 * @since 13662 108 */ 109 default boolean isDisabled() { 110 return false; 111 } 112 113 /** 114 * Replies true, if this primitive is disabled and marked as completely hidden on the map. 115 * @return {@code true} if this object has both the "disabled" and "hide if disabled" flags enabled 116 * @since 13662 117 */ 118 default boolean isDisabledAndHidden() { 119 return false; 120 } 121 122 /** 123 * Replies true, if this primitive is preserved from filtering. 124 * @return {@code true} if this object has the "preserved" flag enabled 125 * @since 13764 126 */ 127 default boolean isPreserved() { 128 return false; 129 } 130 131 /** 132 * Determines if this object is selectable. 133 * <p> 134 * A primitive can be selected if all conditions are met: 135 * <ul> 136 * <li>it is drawable 137 * <li>it is not disabled (greyed out) by a filter. 138 * </ul> 139 * @return {@code true} if this object is selectable 140 * @since 13664 141 */ 142 default boolean isSelectable() { 143 return true; 144 } 145 146 /** 147 * Determines if this object is drawable. 148 * <p> 149 * A primitive is drawable if all conditions are met: 150 * <ul> 151 * <li>type and id is known 152 * <li>tags are known 153 * <li>it is not deleted 154 * <li>it is not hidden by a filter 155 * <li>for nodes: lat/lon are known 156 * <li>for ways: all nodes are known and complete 157 * <li>for relations: all members are known and complete 158 * </ul> 159 * @return {@code true} if this object is drawable 160 * @since 13664 161 */ 162 default boolean isDrawable() { 163 return true; 164 } 165 166 /** 167 * Determines whether the primitive is selected 168 * @return whether the primitive is selected 169 * @since 13664 170 */ 171 default boolean isSelected() { 172 return false; 173 } 174 175 /** 176 * Determines if this primitive is a member of a selected relation. 177 * @return {@code true} if this primitive is a member of a selected relation, {@code false} otherwise 178 * @since 13664 179 */ 180 default boolean isMemberOfSelected() { 181 return false; 182 } 183 184 /** 185 * Determines if this primitive is an outer member of a selected multipolygon relation. 186 * @return {@code true} if this primitive is an outer member of a selected multipolygon relation, {@code false} otherwise 187 * @since 13664 188 */ 189 default boolean isOuterMemberOfSelected() { 190 return false; 191 } 192 193 /** 194 * Replies the id of this primitive. 195 * 196 * @return the id of this primitive. 197 */ 198 long getId(); 199 200 /** 201 * Replies the OSM id of this primitive. 202 * By default, returns the same value as {@link #getId}. 203 * Can be overidden by primitive implementations handling an internal id different from the OSM one. 204 * 205 * @return the OSM id of this primitive. 206 * @since 13924 207 */ 208 default long getOsmId() { 209 return getId(); 210 } 211 212 /** 213 * Replies the OSM primitive id for this primitive. 214 * 215 * @return the OSM primitive id for this primitive 216 * @see #getOsmId 217 * @since 13924 218 */ 219 default PrimitiveId getOsmPrimitiveId() { 220 return new SimplePrimitiveId(getOsmId(), getType()); 221 } 222 223 /** 224 * Replies the unique primitive id for this primitive. 225 * 226 * @return the unique primitive id for this primitive 227 * @see #getUniqueId 228 */ 229 default PrimitiveId getPrimitiveId() { 230 return new SimplePrimitiveId(getUniqueId(), getType()); 231 } 232 233 /** 234 * Replies the version number as returned by the API. The version is 0 if the id is 0 or 235 * if this primitive is incomplete. 236 * @return the version number as returned by the API 237 * 238 * @see PrimitiveData#setVersion(int) 239 */ 240 int getVersion(); 241 242 /** 243 * Sets the id and the version of this primitive if it is known to the OSM API. 244 * 245 * Since we know the id and its version it can't be incomplete anymore. incomplete 246 * is set to false. 247 * 248 * @param id the id. > 0 required 249 * @param version the version > 0 required 250 * @throws IllegalArgumentException if id <= 0 251 * @throws IllegalArgumentException if version <= 0 252 * @throws DataIntegrityProblemException if id is changed and primitive was already added to the dataset 253 */ 254 void setOsmId(long id, int version); 255 256 /** 257 * Replies the user who has last touched this object. May be null. 258 * 259 * @return the user who has last touched this object. May be null. 260 */ 261 User getUser(); 262 263 /** 264 * Sets the user who has last touched this object. 265 * 266 * @param user the user 267 */ 268 void setUser(User user); 269 270 /** 271 * Time of last modification to this object. This is not set by JOSM but 272 * read from the server and delivered back to the server unmodified. It is 273 * used to check against edit conflicts. 274 * 275 * @return date of last modification 276 * @see #setTimestamp 277 */ 278 Date getTimestamp(); 279 280 /** 281 * Time of last modification to this object. This is not set by JOSM but 282 * read from the server and delivered back to the server unmodified. It is 283 * used to check against edit conflicts. 284 * 285 * @return last modification as timestamp 286 * @see #setRawTimestamp 287 */ 288 int getRawTimestamp(); 289 290 /** 291 * Sets time of last modification to this object 292 * @param timestamp date of last modification 293 * @see #getTimestamp 294 */ 295 void setTimestamp(Date timestamp); 296 297 /** 298 * Sets time of last modification to this object 299 * @param timestamp date of last modification 300 * @see #getRawTimestamp 301 */ 302 void setRawTimestamp(int timestamp); 303 304 /** 305 * Determines if this primitive has no timestamp information. 306 * @return {@code true} if this primitive has no timestamp information 307 * @see #getTimestamp 308 * @see #getRawTimestamp 309 */ 310 boolean isTimestampEmpty(); 311 312 /** 313 * Replies the id of the changeset this primitive was last uploaded to. 314 * 0 if this primitive wasn't uploaded to a changeset yet or if the 315 * changeset isn't known. 316 * 317 * @return the id of the changeset this primitive was last uploaded to. 318 */ 319 int getChangesetId(); 320 321 /** 322 * Sets the changeset id of this primitive. Can't be set on a new primitive. 323 * 324 * @param changesetId the id. >= 0 required. 325 * @throws IllegalStateException if this primitive is new. 326 * @throws IllegalArgumentException if id < 0 327 */ 328 void setChangesetId(int changesetId); 329 330 /** 331 * Makes the given visitor visit this primitive. 332 * @param visitor visitor 333 */ 334 void accept(PrimitiveVisitor visitor); 335 336 /** 337 * <p>Visits {@code visitor} for all referrers.</p> 338 * 339 * @param visitor the visitor. Ignored, if null. 340 * @since 13806 341 */ 342 void visitReferrers(PrimitiveVisitor visitor); 343 344 /** 345 * Replies the name of this primitive. The default implementation replies the value 346 * of the tag <code>name</code> or null, if this tag is not present. 347 * 348 * @return the name of this primitive 349 */ 350 default String getName() { 351 return get("name"); 352 } 353 354 /** 355 * Replies a localized name for this primitive given by the value of the name tags 356 * accessed from very specific (language variant) to more generic (default name). 357 * 358 * @return the name of this primitive, <code>null</code> if no name exists 359 * @see LanguageInfo#getLanguageCodes 360 */ 361 default String getLocalName() { 362 for (String s : LanguageInfo.getLanguageCodes(null)) { 363 String val = get("name:" + s); 364 if (val != null) 365 return val; 366 } 367 368 return getName(); 369 } 370 371 /** 372 * Replies the display name of a primitive formatted by <code>formatter</code> 373 * @param formatter formatter to use 374 * 375 * @return the display name 376 * @since 13564 377 */ 378 String getDisplayName(NameFormatter formatter); 379 380 /** 381 * Gets the type this primitive is displayed at 382 * @return A {@link OsmPrimitiveType} 383 * @since 13564 384 */ 385 default OsmPrimitiveType getDisplayType() { 386 return getType(); 387 } 388 389 /** 390 * Updates the highlight flag for this primitive. 391 * @param highlighted The new highlight flag. 392 * @since 13664 393 */ 394 void setHighlighted(boolean highlighted); 395 396 /** 397 * Checks if the highlight flag for this primitive was set 398 * @return The highlight flag. 399 * @since 13664 400 */ 401 boolean isHighlighted(); 402 403 /** 404 * Determines if this object is considered "tagged". To be "tagged", an object 405 * must have one or more "interesting" tags. "created_by" and "source" 406 * are typically considered "uninteresting" and do not make an object "tagged". 407 * @return true if this object is considered "tagged" 408 * @since 13662 409 */ 410 boolean isTagged(); 411 412 /** 413 * Determines if this object is considered "annotated". To be "annotated", an object 414 * must have one or more "work in progress" tags, such as "note" or "fixme". 415 * @return true if this object is considered "annotated" 416 * @since 13662 417 */ 418 boolean isAnnotated(); 419 420 /** 421 * Determines if this object is a relation and behaves as a multipolygon. 422 * @return {@code true} if it is a real multipolygon or a boundary relation 423 * @since 13667 424 */ 425 default boolean isMultipolygon() { 426 return false; 427 } 428 429 /** 430 * true if this object has direction dependent tags (e.g. oneway) 431 * @return {@code true} if this object has direction dependent tags 432 * @since 13662 433 */ 434 boolean hasDirectionKeys(); 435 436 /** 437 * true if this object has the "reversed direction" flag enabled 438 * @return {@code true} if this object has the "reversed direction" flag enabled 439 * @since 13662 440 */ 441 boolean reversedDirection(); 442 443 /** 444 * Fetches the bounding box of the primitive. 445 * @return Bounding box of the object 446 * @since 13764 447 */ 448 BBox getBBox(); 449 450 /** 451 * Gets a list of all primitives in the current dataset that reference this primitive. 452 * @return The referrers 453 * @since 13764 454 */ 455 default List<? extends IPrimitive> getReferrers() { 456 return getReferrers(false); 457 } 458 459 /** 460 * Find primitives that reference this primitive. Returns only primitives that are included in the same 461 * dataset as this primitive. <br> 462 * 463 * For example following code will add wnew as referer to all nodes of existingWay, but this method will 464 * not return wnew because it's not part of the dataset <br> 465 * 466 * <code>Way wnew = new Way(existingWay)</code> 467 * 468 * @param allowWithoutDataset If true, method will return empty list if primitive is not part of the dataset. If false, 469 * exception will be thrown in this case 470 * 471 * @return a collection of all primitives that reference this primitive. 472 * @since 13808 473 */ 474 List<? extends IPrimitive> getReferrers(boolean allowWithoutDataset); 475 476 /** 477 * Returns the parent data set of this primitive. 478 * @return OsmData this primitive is part of. 479 * @since 13807 480 */ 481 OsmData<?, ?, ?, ?> getDataSet(); 482 483 /** 484 * Returns {@link #getKeys()} for which {@code key} does not fulfill uninteresting criteria. 485 * @return A map of interesting tags 486 * @since 13809 487 */ 488 Map<String, String> getInterestingTags(); 489 490 /** 491 * Replies true if other isn't null and has the same interesting tags (key/value-pairs) as this. 492 * 493 * @param other the other object primitive 494 * @return true if other isn't null and has the same interesting tags (key/value-pairs) as this. 495 * @since 13809 496 */ 497 default boolean hasSameInterestingTags(IPrimitive other) { 498 return (!hasKeys() && !other.hasKeys()) 499 || getInterestingTags().equals(other.getInterestingTags()); 500 } 501}