001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.gbif.api.model.occurrence; 015 016import org.gbif.api.annotation.Experimental; 017import org.gbif.api.model.common.Classification; 018import org.gbif.api.model.common.Identifier; 019import org.gbif.api.model.common.LinneanClassification; 020import org.gbif.api.model.common.LinneanClassificationKeys; 021import org.gbif.api.model.common.MediaObject; 022import org.gbif.api.util.ClassificationUtils; 023import org.gbif.api.util.IsoDateInterval; 024import org.gbif.api.vocabulary.BasisOfRecord; 025import org.gbif.api.vocabulary.Continent; 026import org.gbif.api.vocabulary.Country; 027import org.gbif.api.vocabulary.GbifRegion; 028import org.gbif.api.vocabulary.License; 029import org.gbif.api.vocabulary.OccurrenceIssue; 030import org.gbif.api.vocabulary.OccurrenceStatus; 031import org.gbif.api.vocabulary.Rank; 032import org.gbif.api.vocabulary.Sex; 033import org.gbif.api.vocabulary.TaxonomicStatus; 034import org.gbif.dwc.terms.DwcTerm; 035import org.gbif.dwc.terms.GbifTerm; 036import org.gbif.dwc.terms.Term; 037import org.gbif.dwc.terms.UnknownTerm; 038 039import java.lang.reflect.Field; 040import java.lang.reflect.Modifier; 041import java.net.URI; 042import java.util.ArrayList; 043import java.util.Arrays; 044import java.util.Collections; 045import java.util.Date; 046import java.util.EnumSet; 047import java.util.HashMap; 048import java.util.List; 049import java.util.Map; 050import java.util.Objects; 051import java.util.Optional; 052import java.util.Set; 053import java.util.stream.Collectors; 054import java.util.stream.Stream; 055 056import javax.annotation.Nullable; 057import javax.validation.constraints.Max; 058import javax.validation.constraints.Min; 059import javax.validation.constraints.NotNull; 060 061import com.fasterxml.jackson.annotation.JsonAnyGetter; 062import com.fasterxml.jackson.annotation.JsonIgnore; 063import com.fasterxml.jackson.annotation.JsonProperty; 064import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 065import com.fasterxml.jackson.databind.annotation.JsonSerialize; 066 067import io.swagger.v3.oas.annotations.ExternalDocumentation; 068import io.swagger.v3.oas.annotations.media.Schema; 069import lombok.EqualsAndHashCode; 070import lombok.ToString; 071 072/** 073 * Represents an Occurrence as interpreted by GBIF, adding typed properties on top of the verbatim ones. 074 */ 075@EqualsAndHashCode 076@ToString 077@SuppressWarnings("unused") 078public class Occurrence extends VerbatimOccurrence implements LinneanClassification, LinneanClassificationKeys { 079 080 public static final String GEO_DATUM = "WGS84"; 081 // keep names of ALL properties of this class in a set for jackson serialization, see #properties() 082 private static final Set<String> PROPERTIES = Collections.unmodifiableSet( 083 Stream.concat( 084 // we need to these JSON properties manually because we have a fixed getter but no field for it 085 Stream.of(DwcTerm.geodeticDatum.simpleName(), "class", DwcTerm.countryCode.simpleName(), GbifTerm.gbifRegion.simpleName(), GbifTerm.publishedByGbifRegion.simpleName()), 086 Stream.concat(Arrays.stream(Occurrence.class.getDeclaredFields()), 087 Arrays.stream(VerbatimOccurrence.class.getDeclaredFields())) 088 .filter(field -> !Modifier.isStatic(field.getModifiers())) 089 .map(Field::getName)).collect(Collectors.toSet())); 090 091 // occurrence fields 092 093 // OpenAPI documentation comes from the enumeration. 094 private BasisOfRecord basisOfRecord; 095 096 @Schema( 097 description = "The number of individuals present at the time of the Occurrence.", 098 externalDocs = @ExternalDocumentation( 099 description = "Darwin Core definition", 100 url = "https://rs.tdwg.org/dwc/terms/individualCount" 101 ) 102 ) 103 private Integer individualCount; 104 105 // OpenAPI documentation comes from the enumeration. 106 private OccurrenceStatus occurrenceStatus; 107 108 // OpenAPI documentation comes from the enumeration. 109 private String sex; 110 111 @Schema( 112 description = "The age class or life stage of the Organism(s) at the time the Occurrence was recorded.\n\n" + 113 "Values are aligned to the [GBIF LifeStage vocabulary](https://registry.gbif.org/vocabulary/LifeStage/concepts)", 114 externalDocs = @ExternalDocumentation( 115 description = "Darwin Core definition", 116 url = "https://rs.tdwg.org/dwc/terms/lifeStage" 117 ) 118 ) 119 private String lifeStage; 120 121 @Schema( 122 description = "Statement about whether an organism or organisms have been introduced to a given place and time " + 123 "through the direct or indirect activity of modern humans.\n\n" + 124 "Values are aligned to the [GBIF EstablishmentMeans vocabulary](https://registry.gbif.org/vocabulary/EstablishmentMeans/concepts)," + 125 "which is derived from the [Darwin Core EstablishmentMeans vocabulary](https://dwc.tdwg.org/em/).", 126 externalDocs = @ExternalDocumentation( 127 description = "Darwin Core definition", 128 url = "https://rs.tdwg.org/dwc/terms/establishmentMeans" 129 ) 130 ) 131 private String establishmentMeans; 132 133 @Schema( 134 description = "The degree to which an Organism survives, reproduces, and expands its range at the given " + 135 "place and time.\n\n" + 136 "Values are aligned to the [GBIF DegreeOfEstablishment vocabulary](https://registry.gbif.org/vocabulary/DegreeOfEstablishment/concepts)," + 137 "which is derived from the [Darwin Core DegreeOfEstablishment vocabulary](https://dwc.tdwg.org/doe/).", 138 externalDocs = @ExternalDocumentation( 139 description = "Darwin Core definition", 140 url = "https://rs.tdwg.org/dwc/terms/degreeOfEstablishment" 141 ) 142 ) 143 private String degreeOfEstablishment; 144 145 @Schema( 146 description = "The process by which an Organism came to be in a given place at a given time.\n\n" + 147 "Values are aligned to the [GBIF Pathway vocabulary](https://registry.gbif.org/vocabulary/Pathway/concepts)," + 148 "which is derived from the [Darwin Core Pathway vocabulary](https://dwc.tdwg.org/pw/).", 149 externalDocs = @ExternalDocumentation( 150 description = "Darwin Core definition", 151 url = "https://rs.tdwg.org/dwc/terms/pathway" 152 ) 153 ) 154 private String pathway; 155 156 157 @Schema( 158 description = "The map of classifications associated with this occurrence keyed by checklistKey.", 159 externalDocs = @ExternalDocumentation( 160 description = "Darwin Core definition", 161 url = "https://rs.tdwg.org/dwc/terms/" 162 ) 163 ) 164 private Map<String, Classification> classifications; 165 166 @Schema( 167 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the most specific " + 168 "(lowest rank) taxon for this occurrence. This could be a synonym, see `acceptedTaxonKey`.", 169 externalDocs = @ExternalDocumentation( 170 description = "Darwin Core definition", 171 url = "https://rs.tdwg.org/dwc/terms/" 172 ) 173 ) 174 @Deprecated 175 private Integer taxonKey; 176 177 @Schema( 178 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the kingdom of this" + 179 "occurrence.", 180 externalDocs = @ExternalDocumentation( 181 description = "Darwin Core definition", 182 url = "https://rs.tdwg.org/dwc/terms/" 183 ) 184 ) 185 @Deprecated 186 private Integer kingdomKey; 187 188 @Schema( 189 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the phylum of this" + 190 "occurrence.", 191 externalDocs = @ExternalDocumentation( 192 description = "Darwin Core definition", 193 url = "https://rs.tdwg.org/dwc/terms/" 194 ) 195 ) 196 @Deprecated 197 private Integer phylumKey; 198 199 @Schema( 200 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the class of this" + 201 "occurrence.", 202 externalDocs = @ExternalDocumentation( 203 description = "Darwin Core definition", 204 url = "https://rs.tdwg.org/dwc/terms/" 205 ) 206 ) 207 @Deprecated 208 private Integer classKey; 209 210 @Schema( 211 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the order of this" + 212 "occurrence.", 213 externalDocs = @ExternalDocumentation( 214 description = "Darwin Core definition", 215 url = "https://rs.tdwg.org/dwc/terms/" 216 ) 217 ) 218 @Deprecated 219 private Integer orderKey; 220 221 @Schema( 222 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the family of this" + 223 "occurrence.", 224 externalDocs = @ExternalDocumentation( 225 description = "Darwin Core definition", 226 url = "https://rs.tdwg.org/dwc/terms/" 227 ) 228 ) 229 @Deprecated 230 private Integer familyKey; 231 232 @Schema( 233 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the genus of this" + 234 "occurrence.", 235 externalDocs = @ExternalDocumentation( 236 description = "Darwin Core definition", 237 url = "https://rs.tdwg.org/dwc/terms/" 238 ) 239 ) 240 @Deprecated 241 private Integer genusKey; 242 243 @Schema( 244 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the subgenus of this" + 245 "occurrence.", 246 externalDocs = @ExternalDocumentation( 247 description = "Darwin Core definition", 248 url = "https://rs.tdwg.org/dwc/terms/" 249 ) 250 ) 251 @Deprecated 252 private Integer subgenusKey; 253 254 @Schema( 255 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the species of this" + 256 "occurrence.", 257 externalDocs = @ExternalDocumentation( 258 description = "Darwin Core definition", 259 url = "https://rs.tdwg.org/dwc/terms/" 260 ) 261 ) 262 @Deprecated 263 private Integer speciesKey; 264 265 @Schema( 266 description = "A taxon key from the [GBIF backbone](https://doi.org/10.15468/39omei) for the accepted taxon of " + 267 "this occurrence.", 268 externalDocs = @ExternalDocumentation( 269 description = "Darwin Core definition", 270 url = "https://rs.tdwg.org/dwc/terms/" 271 ) 272 ) 273 @Deprecated 274 private Integer acceptedTaxonKey; 275 276 // taxonomy as name strings → LinneanClassification 277 278 @Schema( 279 description = "The scientific name (including authorship) for the taxon from the " + 280 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence. This could be a synonym, see " + 281 "also `acceptedScientificName`.", 282 externalDocs = @ExternalDocumentation( 283 description = "Darwin Core definition", 284 url = "https://rs.tdwg.org/dwc/terms/" 285 ) 286 ) 287 private String scientificName; // the interpreted name matching taxonKey 288 289 @Schema( 290 description = "The scientific name authorship for the taxon from the " + 291 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence. This could be a synonym, see " + 292 "also `acceptedScientificName`.", 293 externalDocs = @ExternalDocumentation( 294 description = "Darwin Core definition", 295 url = "https://rs.tdwg.org/dwc/terms/" 296 ) 297 ) 298 private String scientificNameAuthorship; 299 300 @Schema( 301 description = "The accepted scientific name (including authorship) for the taxon from the " + 302 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 303 externalDocs = @ExternalDocumentation( 304 description = "Darwin Core definition", 305 url = "https://rs.tdwg.org/dwc/terms/" 306 ) 307 ) 308 private String acceptedScientificName; 309 310 @Schema( 311 description = "The kingdom name (excluding authorship) for the kingdom from the " + 312 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 313 externalDocs = @ExternalDocumentation( 314 description = "Darwin Core definition", 315 url = "https://rs.tdwg.org/dwc/terms/" 316 ) 317 ) 318 private String kingdom; 319 320 @Schema( 321 description = "The phylum name (excluding authorship) for the phylum from the " + 322 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 323 externalDocs = @ExternalDocumentation( 324 description = "Darwin Core definition", 325 url = "https://rs.tdwg.org/dwc/terms/" 326 ) 327 ) 328 private String phylum; 329 330 @Schema( 331 description = "The class name (excluding authorship) for the class from the " + 332 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 333 externalDocs = @ExternalDocumentation( 334 description = "Darwin Core definition", 335 url = "https://rs.tdwg.org/dwc/terms/" 336 ) 337 ) 338 @JsonProperty("class") 339 private String clazz; 340 341 @Schema( 342 description = "The order name (excluding authorship) for the order from the " + 343 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 344 externalDocs = @ExternalDocumentation( 345 description = "Darwin Core definition", 346 url = "https://rs.tdwg.org/dwc/terms/" 347 ) 348 ) 349 private String order; 350 351 @Schema( 352 description = "The family name (excluding authorship) for the family from the " + 353 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 354 externalDocs = @ExternalDocumentation( 355 description = "Darwin Core definition", 356 url = "https://rs.tdwg.org/dwc/terms/" 357 ) 358 ) 359 private String family; 360 361 @Schema( 362 description = "The genus name (excluding authorship) for the genus from the " + 363 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 364 externalDocs = @ExternalDocumentation( 365 description = "Darwin Core definition", 366 url = "https://rs.tdwg.org/dwc/terms/" 367 ) 368 ) 369 private String genus; 370 371 @Schema( 372 description = "The subgenus name (excluding authorship) for the subgenus from the " + 373 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 374 externalDocs = @ExternalDocumentation( 375 description = "Darwin Core definition", 376 url = "https://rs.tdwg.org/dwc/terms/" 377 ) 378 ) 379 private String subgenus; 380 381 @Schema( 382 description = "The species name (excluding authorship) for the species from the " + 383 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 384 externalDocs = @ExternalDocumentation( 385 description = "Darwin Core definition", 386 url = "https://rs.tdwg.org/dwc/terms/" 387 ) 388 ) 389 private String species; 390 391 // atomised scientific name 392 393 @Schema( 394 description = "The genus name part of the species name from the " + 395 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 396 externalDocs = @ExternalDocumentation( 397 description = "Darwin Core definition", 398 url = "https://rs.tdwg.org/dwc/terms/genericName" 399 ) 400 ) 401 private String genericName; 402 403 @Schema( 404 description = "The specific name part of the species name from the " + 405 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 406 externalDocs = @ExternalDocumentation( 407 description = "Darwin Core definition", 408 url = "https://rs.tdwg.org/dwc/terms/specificEpithet" 409 ) 410 ) 411 private String specificEpithet; 412 413 @Schema( 414 description = "The infraspecific name part of the species name from the " + 415 "[GBIF backbone](https://doi.org/10.15468/39omei) matched to this occurrence.", 416 externalDocs = @ExternalDocumentation( 417 description = "Darwin Core definition", 418 url = "https://rs.tdwg.org/dwc/terms/infraspecificEpithet" 419 ) 420 ) 421 private String infraspecificEpithet; 422 423 @Schema( 424 description = "The taxonomic rank of the most specific name in the scientificName.", 425 externalDocs = @ExternalDocumentation( 426 description = "Darwin Core definition", 427 url = "https://rs.tdwg.org/dwc/terms/taxonRank" 428 ) 429 ) 430 private Rank taxonRank; 431 432 @Schema( 433 description = "The status of the use of the scientificName as a label for a taxon.", 434 externalDocs = @ExternalDocumentation( 435 description = "Darwin Core definition", 436 url = "https://rs.tdwg.org/dwc/terms/taxonomicStatus" 437 ) 438 ) 439 private TaxonomicStatus taxonomicStatus; 440 441 @Schema( 442 description = "The IUCN Red List Category of the taxon of this occurrence.\n\n" + 443 "See the [GBIF vocabulary](https://rs.gbif.org/vocabulary/iucn/threat_status/) for the values and their " + 444 "definitions, and the [IUCN Red List of Threatened Species dataset in GBIF](https://doi.org/10.15468/0qnb58) " + 445 "for the version of the Red List GBIF's interpretation procedures are using.", 446 externalDocs = @ExternalDocumentation( 447 description = "GBIF vocabulary", 448 url = "https://rs.gbif.org/vocabulary/iucn/threat_status/" 449 ) 450 ) 451 private String iucnRedListCategory; 452 453 // identification 454 455 @Schema( 456 description = "The date on which the subject was determined as representing the Taxon.", 457 externalDocs = @ExternalDocumentation( 458 description = "Darwin Core definition", 459 url = "https://rs.tdwg.org/dwc/terms/dateIdentified" 460 ) 461 ) 462 private Date dateIdentified; 463 464 // location 465 466 @Schema( 467 description = "The geographic latitude (in decimal degrees, using the WGS84 datum) of the geographic centre " + 468 "of the location of the occurrence.", 469 externalDocs = @ExternalDocumentation( 470 description = "Darwin Core definition", 471 url = "https://rs.tdwg.org/dwc/terms/decimalLatitude" 472 ) 473 ) 474 private Double decimalLatitude; 475 476 @Schema( 477 description = "The geographic longitude (in decimal degrees, using the WGS84 datum) of the geographic centre " + 478 "of the location of the occurrence.", 479 externalDocs = @ExternalDocumentation( 480 description = "Darwin Core definition", 481 url = "https://rs.tdwg.org/dwc/terms/decimalLongitude" 482 ) 483 ) 484 private Double decimalLongitude; 485 486 //coordinatePrecision and coordinateUncertaintyInMeters should be BigDecimal see POR-2795 487 488 @Schema( 489 description = "A decimal representation of the precision of the coordinates given in the decimalLatitude and decimalLongitude.", 490 externalDocs = @ExternalDocumentation( 491 description = "Darwin Core definition", 492 url = "https://rs.tdwg.org/dwc/terms/coordinatePrecision" 493 ) 494 ) 495 private Double coordinatePrecision; 496 497 @Schema( 498 description = "The horizontal distance (in metres) from the given decimalLatitude and decimalLongitude " + 499 "describing the smallest circle containing the whole of the Location.", 500 externalDocs = @ExternalDocumentation( 501 description = "Darwin Core definition", 502 url = "https://rs.tdwg.org/dwc/terms/coordinateUncertaintyInMeters" 503 ) 504 ) 505 private Double coordinateUncertaintyInMeters; 506 507 @Schema( 508 description = "**Deprecated.** This value is always null. It is an obsolete Darwin Core term.", 509 externalDocs = @ExternalDocumentation( 510 description = "Darwin Core definition", 511 url = "https://rs.tdwg.org/dwc/terms/" 512 ) 513 ) 514 @Deprecated //see getter 515 private Double coordinateAccuracy; 516 517 @Schema( 518 description = "Elevation (altitude) in metres above sea level. This is not a current Darwin Core term." 519 ) 520 private Double elevation; 521 522 @Schema( 523 description = "The value of the potential error associated with the elevation. This is not a current Darwin Core term." 524 ) 525 private Double elevationAccuracy; 526 527 @Schema( 528 description = "Depth in metres below sea level. This is not a current Darwin Core term." 529 ) 530 private Double depth; 531 532 @Schema( 533 description = "The value of the potential error associated with the depth. This is not a current Darwin Core term." 534 ) 535 private Double depthAccuracy; 536 537 // OpenAPI documentation from enumeration 538 private Continent continent; 539 540 @JsonSerialize(using = Country.IsoSerializer.class) 541 @JsonDeserialize(using = Country.IsoDeserializer.class) 542 private Country country; 543 544 @Schema( 545 description = "The name of the next-smaller administrative region than country (state, province, canton, " + 546 "department, region, etc.) in which the occurrence occurs.\n\n" + 547 "This value is unaltered by GBIF's processing; see also the GADM fields.", 548 externalDocs = @ExternalDocumentation( 549 description = "Darwin Core definition", 550 url = "https://rs.tdwg.org/dwc/terms/stateProvince" 551 ) 552 ) 553 private String stateProvince; 554 555 @Schema( 556 description = "The administrative divisions according to the [GADM database](https://gadm.org/).\n\n" + 557 "This value is applied by GBIF's processing without consideration of the `stateProvince`, `county` or `locality` fields." 558 ) 559 private Gadm gadm = new Gadm(); 560 561 @Schema( 562 description = "The name of the water body in which the Location occurs.", 563 externalDocs = @ExternalDocumentation( 564 description = "Darwin Core definition", 565 url = "https://rs.tdwg.org/dwc/terms/waterBody" 566 ) 567 ) 568 private String waterBody; 569 570 @Schema( 571 description = "The distance in metres of the occurrence from a centroid known to be applied to occurrences " + 572 "during georeferencing. This can potentially indicate low-precision georeferencing, check the values of " + 573 "`coordinateUncertaintyInMeters` and `georeferenceRemarks`." 574 ) 575 private Double distanceFromCentroidInMeters; 576 577 @Schema( 578 description = "A list (concatenated and separated) of geographic names less specific than the information captured in the dwc:locality term.", 579 externalDocs = @ExternalDocumentation( 580 description = "Darwin Core definition", 581 url = "https://rs.tdwg.org/dwc/terms/higherGeography" 582 ) 583 ) 584 private String higherGeography; 585 586 @Schema( 587 description = "A list (concatenated and separated) of names of people, groups, or organizations who determined the georeference (spatial representation) for the dcterms:Location.", 588 externalDocs = @ExternalDocumentation( 589 description = "Darwin Core definition", 590 url = "https://rs.tdwg.org/dwc/terms/georeferencedBy" 591 ) 592 ) 593 private String georeferencedBy; 594 595 // recording event 596 597 @Schema( 598 description = "The four-digit year in which the event occurred, according to the Common Era calendar.", 599 externalDocs = @ExternalDocumentation( 600 description = "Darwin Core definition", 601 url = "https://rs.tdwg.org/dwc/terms/year" 602 ) 603 ) 604 private Integer year; 605 606 @Schema( 607 description = "The integer month in which the Event occurred.", 608 externalDocs = @ExternalDocumentation( 609 description = "Darwin Core definition", 610 url = "https://rs.tdwg.org/dwc/terms/month" 611 ) 612 ) 613 private Integer month; 614 615 @Schema( 616 description = "The integer day of the month on which the Event occurred.", 617 externalDocs = @ExternalDocumentation( 618 description = "Darwin Core definition", 619 url = "https://rs.tdwg.org/dwc/terms/day" 620 ) 621 ) 622 private Integer day; 623 624 @Schema( 625 description = "The date-time during which an Event occurred. For occurrences, this is the date-time when the " + 626 "event was recorded. Not suitable for a time in a geological context.", 627 externalDocs = @ExternalDocumentation( 628 description = "Darwin Core definition", 629 url = "https://rs.tdwg.org/dwc/terms/eventDate" 630 ) 631 ) 632 private IsoDateInterval eventDate; 633 634 @Schema( 635 description = "The latest integer day of the year on which the Event occurred (1 for 1 January, 365 for " + 636 "31 December, except in a leap year, in which case it is 366).", 637 externalDocs = @ExternalDocumentation( 638 description = "Darwin Core definition", 639 url = "https://rs.tdwg.org/dwc/terms/endDayOfYear" 640 ) 641 ) 642 private Integer startDayOfYear; 643 644 @Schema( 645 description = "The earliest integer day of the year on which the Event occurred (1 for 1 January, 365 for " + 646 "31 December, except in a leap year, in which case it is 366).", 647 externalDocs = @ExternalDocumentation( 648 description = "Darwin Core definition", 649 url = "https://rs.tdwg.org/dwc/terms/startDayOfYear" 650 ) 651 ) 652 private Integer endDayOfYear; 653 654 @Schema( 655 description = "A list (concatenated and separated) of nomenclatural types (type status, typified scientific name, " + 656 "publication) applied to the occurrence.", 657 externalDocs = @ExternalDocumentation( 658 description = "Darwin Core definition", 659 url = "https://rs.tdwg.org/dwc/terms/typeStatus" 660 ) 661 ) 662 private String typeStatus; 663 664 // extracted from type status, but we should propose a new dwc term for this! 665 // for example: "Paratype of Taeniopteryx metequi Ricker & Ross" is status=Paratype, typifiedName=Taeniopteryx metequi Ricker & Ross 666 @Schema( 667 description = "The scientific name that is based on the type specimen.\n\n" + 668 "This is not yet a Darwin Core term, see the [proposal to add it](https://github.com/tdwg/dwc/issues/28)." 669 ) 670 private String typifiedName; // missing from DwC 671 672 @Schema( 673 description = "A specific interpretation issue found during processing and interpretation of the record.\n\n" + 674 "See the https://links.gbif.org/occurrence-issues[list of occurrence issues] and the " + 675 "https://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/OccurrenceIssue.html[OccurrenceIssue enumeration] " + 676 "for possible values and definitions." 677 ) 678 private Set<OccurrenceIssue> issues = EnumSet.noneOf(OccurrenceIssue.class); 679 680 // record level 681 682 @Schema( 683 description = "The most recent date-time on which the occurrence was changed, according to the publisher.", 684 externalDocs = @ExternalDocumentation( 685 description = "Dublin Core definition", 686 url = "https://purl.org/dc/terms/modified" 687 ) 688 ) 689 private Date modified; // interpreted dc:modified, i.e. date changed in source 690 691 @Schema( 692 description = "The time this occurrence was last processed by GBIF's interpretation system “Pipelines”.\n\n" + 693 "This is the time the record was last changed in GBIF, **not** the time the record was last changed by the " + 694 "publisher. Data is also reprocessed when we changed the taxonomic backbone, geographic data sources or " + 695 "other interpretation procedures.\n\n" + 696 "An earlier interpretation system distinguished between “parsing” and “interpretation”, but in the current " + 697 "system there is only one process — the two dates will always be the same." 698 ) 699 private Date lastInterpreted; 700 701 @Schema( 702 description = "A related resource that is referenced, cited, or otherwise pointed to by the described resource.", 703 externalDocs = @ExternalDocumentation( 704 description = "Dublin Core definition", 705 url = "https://purl.org/dc/terms/references" 706 ) 707 ) 708 private URI references; 709 710 @Schema( 711 description = "A legal document giving official permission to do something with the occurrence.", 712 externalDocs = @ExternalDocumentation( 713 description = "Dublin Core definition", 714 url = "https://purl.org/dc/terms/license" 715 ) 716 ) 717 private License license; 718 719 @Schema( 720 description = "A number or enumeration value for the quantity of organisms.", 721 externalDocs = @ExternalDocumentation( 722 description = "Darwin Core definition", 723 url = "https://rs.tdwg.org/dwc/terms/organismQuantity" 724 ) 725 ) 726 private Double organismQuantity; 727 728 @Schema( 729 description = "The type of quantification system used for the quantity of organisms.", 730 externalDocs = @ExternalDocumentation( 731 description = "Darwin Core definition", 732 url = "https://rs.tdwg.org/dwc/terms/organismQuantityType" 733 ) 734 ) 735 private String organismQuantityType; 736 737 @Schema( 738 description = "The unit of measurement of the size (time duration, length, area, or volume) of a sample in a sampling event.", 739 externalDocs = @ExternalDocumentation( 740 description = "Darwin Core definition", 741 url = "https://rs.tdwg.org/dwc/terms/sampleSizeUnit" 742 ) 743 ) 744 private String sampleSizeUnit; 745 746 @Schema( 747 description = "A numeric value for a measurement of the size (time duration, length, area, or volume) of a sample in a sampling event.", 748 externalDocs = @ExternalDocumentation( 749 description = "Darwin Core definition", 750 url = "https://rs.tdwg.org/dwc/terms/sampleSizeValue" 751 ) 752 ) 753 private Double sampleSizeValue; 754 755 @Schema( 756 description = "The relative measurement of the quantity of the organism (i.e. without absolute units)." 757 ) 758 private Double relativeOrganismQuantity; 759 760 @Schema( 761 description = "Flag occurrence when associatedSequences/extension exists" 762 ) 763 private boolean isSequenced; 764 765 @Schema( 766 description = "A list (concatenated and separated) of identifiers (publication, global unique identifier, URI) " 767 + "of genetic sequence information associated with the material entity.", 768 externalDocs = 769 @ExternalDocumentation( 770 description = "Darwin Core definition", 771 url = "https://rs.tdwg.org/dwc/terms/associatedSequences")) 772 private String associatedSequences; 773 774 // interpreted extension data 775 776 @Schema( 777 description = "Alternative identifiers for the occurrence.", 778 externalDocs = @ExternalDocumentation( 779 description = "GBIF Alternative Identifiers extension", 780 url = "https://rs.gbif.org/terms/1.0/Identifier" 781 ) 782 ) 783 private List<Identifier> identifiers = new ArrayList<>(); 784 785 @Schema( 786 description = "Multimedia related to te occurrence.", 787 externalDocs = @ExternalDocumentation( 788 description = "GBIF Multimedia extension", 789 url = "https://rs.gbif.org/terms/1.0/Multimedia" 790 ) 791 ) 792 private List<MediaObject> media = new ArrayList<>(); 793 794 @Schema( 795 description = "Measurements or facts about the the occurrence.", 796 externalDocs = @ExternalDocumentation( 797 description = "Darwin Core definition", 798 url = "https://rs.tdwg.org/dwc/terms/MeasurementOrFact" 799 ) 800 ) 801 private List<MeasurementOrFact> facts = new ArrayList<>(); 802 803 @Schema( 804 description = "Relationships between occurrences.", 805 externalDocs = @ExternalDocumentation( 806 description = "Darwin Core definition", 807 url = "https://rs.tdwg.org/dwc/terms/ResourceRelationship" 808 ) 809 ) 810 private List<OccurrenceRelation> relations = new ArrayList<>(); 811 812 @Schema( 813 description = "A list of the globally unique identifiers for the person, people, groups, or organizations " + 814 "responsible for recording the original Occurrence.", 815 externalDocs = @ExternalDocumentation( 816 description = "Darwin Core definition", 817 url = "https://rs.tdwg.org/dwc/terms/recordedByID" 818 ) 819 ) 820 @JsonProperty("recordedByIDs") 821 private List<AgentIdentifier> recordedByIds = new ArrayList<>(); 822 823 @Schema( 824 description = "A list of the globally unique identifiers for the person, people, groups, or organizations " + 825 "responsible for assigning the Taxon to the occurrence.", 826 externalDocs = @ExternalDocumentation( 827 description = "Darwin Core definition", 828 url = "https://rs.tdwg.org/dwc/terms/identifiedByID" 829 ) 830 ) 831 @JsonProperty("identifiedByIDs") 832 private List<AgentIdentifier> identifiedByIds = new ArrayList<>(); 833 834 @Schema( 835 description = "**Experimental.** The UUID of the institution holding the specimen occurrence, from GRSciColl." 836 ) 837 @Experimental 838 private String institutionKey; 839 840 @Schema( 841 description = "**Experimental.** The UUID of the collection containing the specimen occurrence, from GRSciColl." 842 ) 843 @Experimental 844 private String collectionKey; 845 846 @Schema( 847 description = "**Experimental.** Whether the occurrence belongs to a machine-calculated cluster of probable " + 848 "duplicate occurrences.", 849 externalDocs = @ExternalDocumentation( 850 description = "GBIF Data Blog", 851 url = "https://data-blog.gbif.org/post/clustering-occurrences/" 852 ) 853 ) 854 @Experimental 855 private boolean isInCluster; 856 857 @Schema( 858 description = "An identifier for the set of data. May be a global unique identifier or an identifier specific to " + 859 "a collection or institution.", 860 externalDocs = @ExternalDocumentation( 861 description = "Darwin Core definition", 862 url = "https://rs.tdwg.org/dwc/terms/datasetID" 863 ) 864 ) 865 private String datasetID; 866 867 @Schema( 868 description = "The name identifying the data set from which the record was derived.", 869 externalDocs = @ExternalDocumentation( 870 description = "Darwin Core definition", 871 url = "https://rs.tdwg.org/dwc/terms/" 872 ) 873 ) 874 private String datasetName; 875 876 @Schema( 877 description = "A list (concatenated and separated) of previous or alternate fully qualified catalogue numbers " + 878 "or other human-used identifiers for the same occurrence, whether in the current or any other data set or collection.", 879 externalDocs = @ExternalDocumentation( 880 description = "Darwin Core definition", 881 url = "https://rs.tdwg.org/dwc/terms/otherCatalogNumbers" 882 ) 883 ) 884 private String otherCatalogNumbers; 885 886 @Schema( 887 description = "The full name of the earliest possible geochronologic eon or lowest chrono-stratigraphic eonothem or the informal name (\"Precambrian\") attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 888 externalDocs = @ExternalDocumentation( 889 description = "Darwin Core definition", 890 url = "https://rs.tdwg.org/dwc/terms/earliestEonOrLowestEonothem" 891 ) 892 ) 893 private String earliestEonOrLowestEonothem; 894 895 @Schema( 896 description = "The full name of the latest possible geochronologic eon or highest chrono-stratigraphic eonothem or the informal name (\"Precambrian\") attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 897 externalDocs = @ExternalDocumentation( 898 description = "Darwin Core definition", 899 url = "https://rs.tdwg.org/dwc/terms/latestEonOrHighestEonothem" 900 ) 901 ) 902 private String latestEonOrHighestEonothem; 903 904 @Schema( 905 description = "The full name of the earliest possible geochronologic era or lowest chronostratigraphic erathem attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 906 externalDocs = @ExternalDocumentation( 907 description = "Darwin Core definition", 908 url = "https://rs.tdwg.org/dwc/terms/earliestEraOrLowestErathem" 909 ) 910 ) 911 private String earliestEraOrLowestErathem; 912 913 @Schema( 914 description = "The full name of the latest possible geochronologic era or highest chronostratigraphic erathem attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 915 externalDocs = @ExternalDocumentation( 916 description = "Darwin Core definition", 917 url = "https://rs.tdwg.org/dwc/terms/latestEraOrHighestErathem" 918 ) 919 ) 920 private String latestEraOrHighestErathem; 921 922 @Schema( 923 description = "The full name of the earliest possible geochronologic period or lowest chronostratigraphic system attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 924 externalDocs = @ExternalDocumentation( 925 description = "Darwin Core definition", 926 url = "https://rs.tdwg.org/dwc/terms/earliestPeriodOrLowestSystem" 927 ) 928 ) 929 private String earliestPeriodOrLowestSystem; 930 931 @Schema( 932 description = "The full name of the latest possible geochronologic period or highest chronostratigraphic system attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 933 externalDocs = @ExternalDocumentation( 934 description = "Darwin Core definition", 935 url = "https://rs.tdwg.org/dwc/terms/latestPeriodOrHighestSystem" 936 ) 937 ) 938 private String latestPeriodOrHighestSystem; 939 940 @Schema( 941 description = "The full name of the earliest possible geochronologic epoch or lowest chronostratigraphic series attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 942 externalDocs = @ExternalDocumentation( 943 description = "Darwin Core definition", 944 url = "https://rs.tdwg.org/dwc/terms/earliestEpochOrLowestSeries" 945 ) 946 ) 947 private String earliestEpochOrLowestSeries; 948 949 @Schema( 950 description = "The full name of the latest possible geochronologic epoch or highest chronostratigraphic series attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 951 externalDocs = @ExternalDocumentation( 952 description = "Darwin Core definition", 953 url = "https://rs.tdwg.org/dwc/terms/latestEpochOrHighestSeries" 954 ) 955 ) 956 private String latestEpochOrHighestSeries; 957 958 @Schema( 959 description = "The full name of the earliest possible geochronologic age or lowest chronostratigraphic stage attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 960 externalDocs = @ExternalDocumentation( 961 description = "Darwin Core definition", 962 url = "https://rs.tdwg.org/dwc/terms/earliestAgeOrLowestStage" 963 ) 964 ) 965 private String earliestAgeOrLowestStage; 966 967 @Schema( 968 description = "The full name of the latest possible geochronologic age or highest chronostratigraphic stage attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 969 externalDocs = @ExternalDocumentation( 970 description = "Darwin Core definition", 971 url = "https://rs.tdwg.org/dwc/terms/latestAgeOrHighestStage" 972 ) 973 ) 974 private String latestAgeOrHighestStage; 975 976 @Schema( 977 description = "The full name of the lowest possible geological biostratigraphic zone of the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 978 externalDocs = @ExternalDocumentation( 979 description = "Darwin Core definition", 980 url = "https://rs.tdwg.org/dwc/terms/lowestBiostratigraphicZone" 981 ) 982 ) 983 private String lowestBiostratigraphicZone; 984 985 @Schema( 986 description = "The full name of the highest possible geological biostratigraphic zone of the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 987 externalDocs = @ExternalDocumentation( 988 description = "Darwin Core definition", 989 url = "https://rs.tdwg.org/dwc/terms/highestBiostratigraphicZone" 990 ) 991 ) 992 private String highestBiostratigraphicZone; 993 994 @Schema( 995 description = "The full name of the lithostratigraphic group from which the dwc:MaterialEntity was collected.", 996 externalDocs = @ExternalDocumentation( 997 description = "Darwin Core definition", 998 url = "https://rs.tdwg.org/dwc/terms/group" 999 ) 1000 ) 1001 private String group; 1002 1003 @Schema( 1004 description = "The full name of the lithostratigraphic formation from which the dwc:MaterialEntity was collected.", 1005 externalDocs = @ExternalDocumentation( 1006 description = "Darwin Core definition", 1007 url = "https://rs.tdwg.org/dwc/terms/formation" 1008 ) 1009 ) 1010 private String formation; 1011 1012 @Schema( 1013 description = "The full name of the lithostratigraphic member from which the dwc:MaterialEntity was collected.", 1014 externalDocs = @ExternalDocumentation( 1015 description = "Darwin Core definition", 1016 url = "https://rs.tdwg.org/dwc/terms/member" 1017 ) 1018 ) 1019 private String member; 1020 1021 @Schema( 1022 description = "The full name of the lithostratigraphic bed from which the dwc:MaterialEntity was collected.", 1023 externalDocs = @ExternalDocumentation( 1024 description = "Darwin Core definition", 1025 url = "https://rs.tdwg.org/dwc/terms/bed" 1026 ) 1027 ) 1028 private String bed; 1029 1030 1031 @Schema( 1032 description = "A person, group, or organization responsible for recording the original occurrence.", 1033 externalDocs = @ExternalDocumentation( 1034 description = "Darwin Core definition", 1035 url = "https://rs.tdwg.org/dwc/terms/recordedBy" 1036 ) 1037 ) 1038 private String recordedBy; 1039 1040 @Schema( 1041 description = "A list (concatenated and separated) of names of people, groups, or organizations who assigned the " + 1042 "Taxon to the occurrence.", 1043 externalDocs = @ExternalDocumentation( 1044 description = "Darwin Core definition", 1045 url = "https://rs.tdwg.org/dwc/terms/identifiedBy" 1046 ) 1047 ) 1048 private String identifiedBy; 1049 1050 @Schema( 1051 description = "A preparation or preservation method for a specimen.", 1052 externalDocs = @ExternalDocumentation( 1053 description = "Darwin Core definition", 1054 url = "https://rs.tdwg.org/dwc/terms/preparations" 1055 ) 1056 ) 1057 private String preparations; 1058 1059 @Schema( 1060 description = "The methods or protocols used during an Event, denoted by an IRI.", 1061 externalDocs = @ExternalDocumentation( 1062 description = "Darwin Core definition", 1063 url = "https://rs.tdwg.org/dwc/terms/samplingProtocol" 1064 ) 1065 ) 1066 private String samplingProtocol; 1067 1068 @Schema( 1069 description = "**Experimental.** The DNA sequence ID of an occurrence." 1070 ) 1071 @Experimental 1072 private List<String> dnaSequenceID = new ArrayList<>(); 1073 1074 public Occurrence() { 1075 1076 } 1077 1078 /** 1079 * Create occurrence instance from existing verbatim one, copying over all data. 1080 */ 1081 public Occurrence(@Nullable VerbatimOccurrence verbatim) { 1082 if (verbatim != null) { 1083 setKey(verbatim.getKey()); 1084 setDatasetKey(verbatim.getDatasetKey()); 1085 setPublishingOrgKey(verbatim.getPublishingOrgKey()); 1086 setPublishingCountry(verbatim.getPublishingCountry()); 1087 setProtocol(verbatim.getProtocol()); 1088 setCrawlId(verbatim.getCrawlId()); 1089 if (verbatim.getLastCrawled() != null) { 1090 setLastCrawled(new Date(verbatim.getLastCrawled().getTime())); 1091 } 1092 if (verbatim.getVerbatimFields() != null) { 1093 getVerbatimFields().putAll(verbatim.getVerbatimFields()); 1094 } 1095 if (verbatim.getLastParsed() != null) { 1096 setLastParsed(verbatim.getLastParsed()); 1097 } 1098 setExtensions(verbatim.getExtensions()); 1099 } 1100 } 1101 1102 @Nullable 1103 public BasisOfRecord getBasisOfRecord() { 1104 return basisOfRecord; 1105 } 1106 1107 public void setBasisOfRecord(BasisOfRecord basisOfRecord) { 1108 this.basisOfRecord = basisOfRecord; 1109 } 1110 1111 @Nullable 1112 public Integer getIndividualCount() { 1113 return individualCount; 1114 } 1115 1116 public void setIndividualCount(Integer individualCount) { 1117 this.individualCount = individualCount; 1118 } 1119 1120 @Nullable 1121 public OccurrenceStatus getOccurrenceStatus() { 1122 return occurrenceStatus; 1123 } 1124 1125 public void setOccurrenceStatus(OccurrenceStatus occurrenceStatus) { 1126 this.occurrenceStatus = occurrenceStatus; 1127 } 1128 1129 @Nullable 1130 public String getSex() { 1131 return sex; 1132 } 1133 1134 public void setSex(String sex) { 1135 this.sex = sex; 1136 } 1137 1138 @Nullable 1139 public String getLifeStage() { 1140 return lifeStage; 1141 } 1142 1143 public void setLifeStage(String lifeStage) { 1144 this.lifeStage = lifeStage; 1145 } 1146 1147 @Nullable 1148 public String getEstablishmentMeans() { 1149 return establishmentMeans; 1150 } 1151 1152 public void setEstablishmentMeans(String establishmentMeans) { 1153 this.establishmentMeans = establishmentMeans; 1154 } 1155 1156 /** 1157 * The best matching, accepted GBIF backbone name usage representing this occurrence. 1158 * In case the verbatim scientific name and its classification can only be matched to a higher rank this will 1159 * represent the lowest matching rank. In the worst case this could just be for example Animalia. 1160 */ 1161 @Nullable 1162 public Integer getTaxonKey() { 1163 return taxonKey; 1164 } 1165 1166 public void setTaxonKey(Integer taxonKey) { 1167 this.taxonKey = taxonKey; 1168 } 1169 1170 @Nullable 1171 @Override 1172 public Integer getKingdomKey() { 1173 return kingdomKey; 1174 } 1175 1176 @Override 1177 public void setKingdomKey(@Nullable Integer kingdomKey) { 1178 this.kingdomKey = kingdomKey; 1179 } 1180 1181 @Nullable 1182 @Override 1183 public Integer getPhylumKey() { 1184 return phylumKey; 1185 } 1186 1187 @Override 1188 public void setPhylumKey(@Nullable Integer phylumKey) { 1189 this.phylumKey = phylumKey; 1190 } 1191 1192 @Nullable 1193 @Override 1194 public Integer getClassKey() { 1195 return classKey; 1196 } 1197 1198 @Override 1199 public void setClassKey(@Nullable Integer classKey) { 1200 this.classKey = classKey; 1201 } 1202 1203 @Nullable 1204 @Override 1205 public Integer getOrderKey() { 1206 return orderKey; 1207 } 1208 1209 @Override 1210 public void setOrderKey(@Nullable Integer orderKey) { 1211 this.orderKey = orderKey; 1212 } 1213 1214 @Nullable 1215 @Override 1216 public Integer getFamilyKey() { 1217 return familyKey; 1218 } 1219 1220 @Override 1221 public void setFamilyKey(@Nullable Integer familyKey) { 1222 this.familyKey = familyKey; 1223 } 1224 1225 @Nullable 1226 @Override 1227 public Integer getGenusKey() { 1228 return genusKey; 1229 } 1230 1231 @Override 1232 public void setGenusKey(@Nullable Integer genusKey) { 1233 this.genusKey = genusKey; 1234 } 1235 1236 @Nullable 1237 @Override 1238 public Integer getSubgenusKey() { 1239 return subgenusKey; 1240 } 1241 1242 @Override 1243 public void setSubgenusKey(@Nullable Integer subgenusKey) { 1244 this.subgenusKey = subgenusKey; 1245 } 1246 1247 @Nullable 1248 @Override 1249 public Integer getHigherRankKey(Rank rank) { 1250 return ClassificationUtils.getHigherRankKey(this, rank); 1251 } 1252 1253 /** 1254 * An ordered map with entries for all higher Linnean ranks excluding the taxonKey itself. 1255 * The map starts with the highest rank, e.g. the kingdom and maps the name usage key to its canonical name. 1256 * 1257 * @return map of higher ranks 1258 */ 1259 @NotNull 1260 @JsonIgnore 1261 public Map<Integer, String> getHigherClassificationMap() { 1262 return taxonKey == null ? ClassificationUtils.getHigherClassificationMap(this) 1263 : ClassificationUtils.getHigherClassificationMap(this, taxonKey, null, null); 1264 } 1265 1266 /** 1267 * The accepted species for this occurrence. In case the taxonKey is of a higher rank than species (e.g. genus) 1268 * speciesKey is null. In case taxonKey represents an infraspecific taxon the speciesKey points to the species 1269 * the infraspecies is classified as. In case of taxonKey being a species the speciesKey is the same. 1270 */ 1271 @Nullable 1272 @Override 1273 public Integer getSpeciesKey() { 1274 return speciesKey; 1275 } 1276 1277 @Override 1278 public void setSpeciesKey(@Nullable Integer speciesKey) { 1279 this.speciesKey = speciesKey; 1280 } 1281 1282 /** 1283 * The accepted taxon key from the GBIF backbone. 1284 */ 1285 @Nullable 1286 public Integer getAcceptedTaxonKey() { 1287 return acceptedTaxonKey; 1288 } 1289 1290 public void setAcceptedTaxonKey(Integer acceptedTaxonKey) { 1291 this.acceptedTaxonKey = acceptedTaxonKey; 1292 } 1293 1294 @Nullable 1295 public String getSpecificEpithet() { 1296 return specificEpithet; 1297 } 1298 1299 public void setSpecificEpithet(String specificEpithet) { 1300 this.specificEpithet = specificEpithet; 1301 } 1302 1303 @Nullable 1304 public String getInfraspecificEpithet() { 1305 return infraspecificEpithet; 1306 } 1307 1308 public void setInfraspecificEpithet(String infraspecificEpithet) { 1309 this.infraspecificEpithet = infraspecificEpithet; 1310 } 1311 1312 @Nullable 1313 public Rank getTaxonRank() { 1314 return taxonRank; 1315 } 1316 1317 public void setTaxonRank(Rank taxonRank) { 1318 this.taxonRank = taxonRank; 1319 } 1320 1321 /** 1322 * The status of the use of the scientificName as a label for a taxon. 1323 * The GBIF recommended controlled value vocabulary can be found at <a href="http://rs.gbif.org/vocabulary/gbif/taxonomic_status.xml">http://rs.gbif.org/vocabulary/gbif/taxonomic_status.xm</a>. 1324 */ 1325 @Nullable 1326 public TaxonomicStatus getTaxonomicStatus() { 1327 return taxonomicStatus; 1328 } 1329 1330 public void setTaxonomicStatus(TaxonomicStatus taxonomicStatus) { 1331 this.taxonomicStatus = taxonomicStatus; 1332 } 1333 1334 /** 1335 * The IUCN Red List Category. 1336 */ 1337 @Nullable 1338 public String getIucnRedListCategory() { 1339 return iucnRedListCategory; 1340 } 1341 1342 public void setIucnRedListCategory(String iucnRedListCategory) { 1343 this.iucnRedListCategory = iucnRedListCategory; 1344 } 1345 1346 /** 1347 * The scientific name for taxonKey from the GBIF backbone. 1348 */ 1349 @Nullable 1350 public String getScientificName() { 1351 return scientificName; 1352 } 1353 1354 public void setScientificName(@Nullable String scientificName) { 1355 this.scientificName = scientificName; 1356 } 1357 1358 /** 1359 * The scientific name authorship for taxonKey from the GBIF backbone. 1360 */ 1361 @Nullable 1362 public String getScientificNameAuthorship() { 1363 return scientificNameAuthorship; 1364 } 1365 1366 public void setScientificNameAuthorship(String scientificNameAuthorship) { 1367 this.scientificNameAuthorship = scientificNameAuthorship; 1368 } 1369 1370 /** 1371 * The verbatim scientific name as provided by the source. 1372 */ 1373 @Nullable 1374 @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) 1375 public String getVerbatimScientificName() { 1376 return getVerbatimField(DwcTerm.scientificName); 1377 } 1378 1379 public void setVerbatimScientificName(String scientificName) { 1380 //DO NOTHING 1381 } 1382 1383 /** 1384 * The accepted scientific name for the acceptedTaxonKey from the GBIF backbone. 1385 */ 1386 @Nullable 1387 public String getAcceptedScientificName() { 1388 return acceptedScientificName; 1389 } 1390 1391 public void setAcceptedScientificName(String acceptedScientificName) { 1392 this.acceptedScientificName = acceptedScientificName; 1393 } 1394 1395 @Nullable 1396 @Override 1397 public String getKingdom() { 1398 return kingdom; 1399 } 1400 1401 @Override 1402 public void setKingdom(@Nullable String kingdom) { 1403 this.kingdom = kingdom; 1404 } 1405 1406 @Nullable 1407 @Override 1408 public String getPhylum() { 1409 return phylum; 1410 } 1411 1412 @Override 1413 public void setPhylum(@Nullable String phylum) { 1414 this.phylum = phylum; 1415 } 1416 1417 @Nullable 1418 @Override 1419 public String getClazz() { 1420 return clazz; 1421 } 1422 1423 @Override 1424 public void setClazz(@Nullable String clazz) { 1425 this.clazz = clazz; 1426 } 1427 1428 @Nullable 1429 @Override 1430 public String getOrder() { 1431 return order; 1432 } 1433 1434 @Override 1435 public void setOrder(@Nullable String order) { 1436 this.order = order; 1437 } 1438 1439 @Nullable 1440 @Override 1441 public String getFamily() { 1442 return family; 1443 } 1444 1445 @Override 1446 public void setFamily(@Nullable String family) { 1447 this.family = family; 1448 } 1449 1450 @Nullable 1451 @Override 1452 public String getGenus() { 1453 return genus; 1454 } 1455 1456 @Override 1457 public void setGenus(@Nullable String genus) { 1458 this.genus = genus; 1459 } 1460 1461 @Nullable 1462 public String getGenericName() { 1463 return genericName; 1464 } 1465 1466 public void setGenericName(String genericName) { 1467 this.genericName = genericName; 1468 } 1469 1470 @Nullable 1471 @Override 1472 public String getSubgenus() { 1473 return subgenus; 1474 } 1475 1476 @Override 1477 public void setSubgenus(@Nullable String subgenus) { 1478 this.subgenus = subgenus; 1479 } 1480 1481 @Nullable 1482 @Override 1483 public String getHigherRank(Rank rank) { 1484 return ClassificationUtils.getHigherRank(this, rank); 1485 } 1486 1487 /** 1488 * The corresponding scientific name of the speciesKey from the GBIF backbone. 1489 */ 1490 @Nullable 1491 @Override 1492 public String getSpecies() { 1493 return species; 1494 } 1495 1496 @Override 1497 public void setSpecies(@Nullable String species) { 1498 this.species = species; 1499 } 1500 1501 @Nullable 1502 public Date getDateIdentified() { 1503 return dateIdentified == null ? null : new Date(dateIdentified.getTime()); 1504 } 1505 1506 public void setDateIdentified(@Nullable Date dateIdentified) { 1507 this.dateIdentified = dateIdentified == null ? null : new Date(dateIdentified.getTime()); 1508 } 1509 1510 /** 1511 * The decimalLongitude in decimal degrees always for the WGS84 datum. If a different geodetic datum was given the verbatim 1512 * coordinates are transformed into WGS84 values. 1513 */ 1514 @Nullable 1515 public Double getDecimalLongitude() { 1516 return decimalLongitude; 1517 } 1518 1519 public void setDecimalLongitude(@Nullable Double decimalLongitude) { 1520 this.decimalLongitude = decimalLongitude; 1521 } 1522 1523 @Nullable 1524 public Double getDecimalLatitude() { 1525 return decimalLatitude; 1526 } 1527 1528 public void setDecimalLatitude(@Nullable Double decimalLatitude) { 1529 this.decimalLatitude = decimalLatitude; 1530 } 1531 1532 /** 1533 * The uncertainty radius for lat/lon in meters. 1534 */ 1535 @Nullable 1536 public Double getCoordinateUncertaintyInMeters() { 1537 return coordinateUncertaintyInMeters; 1538 } 1539 1540 public void setCoordinateUncertaintyInMeters(@Nullable Double coordinateUncertaintyInMeters) { 1541 this.coordinateUncertaintyInMeters = coordinateUncertaintyInMeters; 1542 } 1543 1544 @Nullable 1545 public Double getCoordinatePrecision() { 1546 return coordinatePrecision; 1547 } 1548 1549 public void setCoordinatePrecision(Double coordinatePrecision) { 1550 this.coordinatePrecision = coordinatePrecision; 1551 } 1552 1553 /** 1554 * @deprecated to be removed in the public v2 of the API (see POR-3061) 1555 * The uncertainty for latitude in decimal degrees. 1556 * Note that the longitude degrees have a different accuracy in degrees which changes with latitude and is largest at the poles. 1557 */ 1558 @Nullable 1559 @Deprecated 1560 public Double getCoordinateAccuracy() { 1561 return coordinateAccuracy; 1562 } 1563 1564 public void setCoordinateAccuracy(@Nullable Double coordinateAccuracy) { 1565 this.coordinateAccuracy = coordinateAccuracy; 1566 } 1567 1568 /** 1569 * The geodetic datum for the interpreted decimal coordinates. 1570 * This is always WGS84 if a coordinate exists as we reproject other datums into WGS84. 1571 */ 1572 @Schema( 1573 description = "The geodetic datum for the interpreted decimal coordinates.\n\n" + 1574 "Coordinates are reprojected to WGS84 if they exist, so this field is either null or `WGS84`." 1575 ) 1576 @Nullable 1577 public String getGeodeticDatum() { 1578 if (decimalLatitude != null) { 1579 return GEO_DATUM; 1580 } 1581 return null; 1582 } 1583 1584 /** 1585 * This private method is needed for jackson deserialization only. 1586 */ 1587 private void setGeodeticDatum(String datum) { 1588 // ignore, we have a static WGS84 value 1589 } 1590 1591 /** 1592 * Elevation in meters usually above sea level (altitude). 1593 * </br> 1594 * The elevation is calculated using the equation: (minimumElevationInMeters + maximumElevationInMeters) / 2. 1595 */ 1596 @Nullable 1597 public Double getElevation() { 1598 return elevation; 1599 } 1600 1601 public void setElevation(@Nullable Double elevation) { 1602 this.elevation = elevation; 1603 } 1604 1605 /** 1606 * Elevation accuracy is the uncertainty for the elevation in meters. 1607 * </br> 1608 * The elevation accuracy is calculated using the equation: (maximumElevationInMeters - minimumElevationInMeters) / 2 1609 */ 1610 @Nullable 1611 public Double getElevationAccuracy() { 1612 return elevationAccuracy; 1613 } 1614 1615 public void setElevationAccuracy(@Nullable Double elevationAccuracy) { 1616 this.elevationAccuracy = elevationAccuracy; 1617 } 1618 1619 /** 1620 * Depth in meters below the surface. Complimentary to elevation, the depth can be 10 meters below the surface of a 1621 * lake in 1100m (=elevation). 1622 * </br> 1623 * The depth is calculated using the equation: (minimumDepthInMeters + maximumDepthInMeters) / 2. 1624 */ 1625 @Nullable 1626 public Double getDepth() { 1627 return depth; 1628 } 1629 1630 public void setDepth(@Nullable Double depth) { 1631 this.depth = depth; 1632 } 1633 1634 /** 1635 * Depth accuracy is the uncertainty for the depth in meters. 1636 * </br> 1637 * The depth accuracy is calculated using the equation: (maximumDepthInMeters - minimumDepthInMeters) / 2 1638 */ 1639 @Nullable 1640 public Double getDepthAccuracy() { 1641 return depthAccuracy; 1642 } 1643 1644 public void setDepthAccuracy(@Nullable Double depthAccuracy) { 1645 this.depthAccuracy = depthAccuracy; 1646 } 1647 1648 @Nullable 1649 public Continent getContinent() { 1650 return continent; 1651 } 1652 1653 public void setContinent(@Nullable Continent continent) { 1654 this.continent = continent; 1655 } 1656 1657 @Schema( 1658 description = "The 2-letter country code (as per ISO-3166-1) of the country, territory or area in which the " + 1659 "occurrence was recorded.", 1660 externalDocs = @ExternalDocumentation( 1661 description = "Darwin Core definition", 1662 url = "https://rs.tdwg.org/dwc/terms/countryCode" 1663 ) 1664 ) 1665 @Nullable 1666 @JsonProperty("countryCode") 1667 public Country getCountry() { 1668 return country; 1669 } 1670 1671 public void setCountry(@Nullable Country country) { 1672 this.country = country; 1673 } 1674 1675 @Nullable 1676 @JsonProperty("gbifRegion") 1677 public GbifRegion getGbifRegion() { 1678 return Optional.ofNullable(country).map(Country::getGbifRegion).orElse(null); 1679 } 1680 1681 private void setGbifRegion(String gbifRegion) { 1682 // ignore, setter only to avoid JSON being written into the fields map 1683 } 1684 1685 /** 1686 * Renders the country title as a JSON property country in addition to the ISO 3166 2 letter countryCode being 1687 * serialized by the regular country Java property. 1688 * Made private to use it only for JSON serialization and not within Java code. 1689 */ 1690 @Schema( 1691 description = "The title (as per ISO-3166-1) of the country, territory or area in which the " + 1692 "occurrence was recorded.", 1693 externalDocs = @ExternalDocumentation( 1694 description = "Darwin Core definition", 1695 url = "https://rs.tdwg.org/dwc/terms/country" 1696 ) 1697 ) 1698 @Nullable 1699 @JsonProperty("country") 1700 private String getCountryTitle() { 1701 return country == null ? null : country.getTitle(); 1702 } 1703 1704 private void setCountryTitle(String country) { 1705 // ignore, setter only to avoid JSON being written into the fields map 1706 } 1707 1708 @Nullable 1709 public String getStateProvince() { 1710 return stateProvince; 1711 } 1712 1713 public void setStateProvince(@Nullable String stateProvince) { 1714 this.stateProvince = stateProvince; 1715 } 1716 1717 @Nullable 1718 public String getWaterBody() { 1719 return waterBody; 1720 } 1721 1722 public void setWaterBody(@Nullable String waterBody) { 1723 this.waterBody = waterBody; 1724 } 1725 1726 /** 1727 * The distance in metres from a known centroid, e.g. a country centroid. 1728 */ 1729 public Double getDistanceFromCentroidInMeters() { 1730 return distanceFromCentroidInMeters; 1731 } 1732 1733 public void setDistanceFromCentroidInMeters(Double distanceFromCentroidInMeters) { 1734 this.distanceFromCentroidInMeters = distanceFromCentroidInMeters; 1735 } 1736 1737 @Nullable 1738 public String getHigherGeography() { 1739 return higherGeography; 1740 } 1741 1742 public void setHigherGeography(String higherGeography) { 1743 this.higherGeography = higherGeography; 1744 } 1745 1746 @Nullable 1747 public String getGeoreferencedBy() { 1748 return georeferencedBy; 1749 } 1750 1751 public void setGeoreferencedBy(String georeferencedBy) { 1752 this.georeferencedBy = georeferencedBy; 1753 } 1754 1755 /** 1756 * The full year of the event date. 1757 * 1758 * @return the year of the event date 1759 */ 1760 @Min(1500) 1761 @Max(2030) 1762 @Nullable 1763 public Integer getYear() { 1764 return year; 1765 } 1766 1767 public void setYear(@Nullable Integer year) { 1768 this.year = year; 1769 } 1770 1771 /** 1772 * The month of the year of the event date starting with zero for january following {@link Date}. 1773 * 1774 * @return the month of the event date 1775 */ 1776 @Min(1) 1777 @Max(12) 1778 @Nullable 1779 public Integer getMonth() { 1780 return month; 1781 } 1782 1783 public void setMonth(@Nullable Integer month) { 1784 this.month = month; 1785 } 1786 1787 /** 1788 * The day of the month of the event date. 1789 * 1790 * @return the day of the event date 1791 */ 1792 @Min(1) 1793 @Max(31) 1794 @Nullable 1795 public Integer getDay() { 1796 return day; 1797 } 1798 1799 public void setDay(@Nullable Integer day) { 1800 this.day = day; 1801 } 1802 1803 /** 1804 * The date the occurrence was recorded or collected. 1805 */ 1806 @Nullable 1807 public IsoDateInterval getEventDate() { 1808 return eventDate == null ? null : new IsoDateInterval(eventDate.getFrom(), eventDate.getTo()); 1809 } 1810 1811 public void setEventDate(@Nullable IsoDateInterval eventDate) { 1812 this.eventDate = eventDate == null ? null : new IsoDateInterval(eventDate.getFrom(), eventDate.getTo()); 1813 } 1814 1815 /** 1816 * The earliest integer day of the year of the event. 1817 * 1818 * @return the earliest integer day of the event date 1819 */ 1820 @Min(1) 1821 @Max(366) 1822 @Nullable 1823 public Integer getStartDayOfYear() { 1824 return startDayOfYear; 1825 } 1826 1827 public void setStartDayOfYear(@Nullable Integer startDayOfYear) { 1828 this.startDayOfYear = startDayOfYear; 1829 } 1830 1831 /** 1832 * The latest integer day of the year of the event. 1833 * 1834 * @return the latest integer day of the event date 1835 */ 1836 @Min(1) 1837 @Max(366) 1838 @Nullable 1839 public Integer getEndDayOfYear() { 1840 return endDayOfYear; 1841 } 1842 1843 public void setEndDayOfYear(@Nullable Integer endDayOfYear) { 1844 this.endDayOfYear = endDayOfYear; 1845 } 1846 1847 @Nullable 1848 public String getTypeStatus() { 1849 return typeStatus; 1850 } 1851 1852 public void setTypeStatus(@Nullable String typeStatus) { 1853 this.typeStatus = typeStatus; 1854 } 1855 1856 /** 1857 * The scientific name the type status of this specimen applies to. 1858 */ 1859 @Nullable 1860 public String getTypifiedName() { 1861 return typifiedName; 1862 } 1863 1864 public void setTypifiedName(@Nullable String typifiedName) { 1865 this.typifiedName = typifiedName; 1866 } 1867 1868 /** 1869 * A set of issues found for this occurrence. 1870 */ 1871 @NotNull 1872 public Set<OccurrenceIssue> getIssues() { 1873 return issues; 1874 } 1875 1876 public void setIssues(Set<OccurrenceIssue> issues) { 1877 Objects.requireNonNull(issues, "Issues cannot be null"); 1878 EnumSet<OccurrenceIssue> set = EnumSet.noneOf(OccurrenceIssue.class); 1879 set.addAll(issues); 1880 this.issues = set; 1881 } 1882 1883 public void addIssue(OccurrenceIssue issue) { 1884 Objects.requireNonNull(issue, "Issue needs to be specified"); 1885 issues.add(issue); 1886 } 1887 1888 /** 1889 * The interpreted dc:modified from the verbatim source data. 1890 * Ideally indicating when a record was last modified in the source. 1891 */ 1892 @Nullable 1893 public Date getModified() { 1894 return modified == null ? null : new Date(modified.getTime()); 1895 } 1896 1897 public void setModified(@Nullable Date modified) { 1898 this.modified = modified == null ? null : new Date(modified.getTime()); 1899 } 1900 1901 /** 1902 * The date this occurrence last went through the interpretation phase of the GBIF indexing. 1903 */ 1904 @Nullable 1905 public Date getLastInterpreted() { 1906 return lastInterpreted == null ? null : new Date(lastInterpreted.getTime()); 1907 } 1908 1909 public void setLastInterpreted(@Nullable Date lastInterpreted) { 1910 this.lastInterpreted = lastInterpreted == null ? null : new Date(lastInterpreted.getTime()); 1911 } 1912 1913 /** 1914 * An external link to more details, the records "homepage". 1915 */ 1916 @Nullable 1917 public URI getReferences() { 1918 return references; 1919 } 1920 1921 public void setReferences(URI references) { 1922 this.references = references; 1923 } 1924 1925 /** 1926 * A number or enumeration value for the quantity of organisms. 1927 */ 1928 @Nullable 1929 public Double getOrganismQuantity() { 1930 return organismQuantity; 1931 } 1932 1933 public void setOrganismQuantity(@Nullable Double organismQuantity) { 1934 this.organismQuantity = organismQuantity; 1935 } 1936 1937 /** 1938 * The type of quantification system used for the quantity of organisms. 1939 */ 1940 @Nullable 1941 public String getOrganismQuantityType() { 1942 return organismQuantityType; 1943 } 1944 1945 public void setOrganismQuantityType(@Nullable String organismQuantityType) { 1946 this.organismQuantityType = organismQuantityType; 1947 } 1948 1949 /** 1950 * The unit of measurement of the size (time duration, length, area, or volume) of a sample in a sampling event. 1951 */ 1952 @Nullable 1953 public String getSampleSizeUnit() { 1954 return sampleSizeUnit; 1955 } 1956 1957 public void setSampleSizeUnit(@Nullable String sampleSizeUnit) { 1958 this.sampleSizeUnit = sampleSizeUnit; 1959 } 1960 1961 /** 1962 * A numeric value for a measurement of the size (time duration, length, area, or volume) of a sample in a sampling event. 1963 */ 1964 @Nullable 1965 public Double getSampleSizeValue() { 1966 return sampleSizeValue; 1967 } 1968 1969 public void setSampleSizeValue(@Nullable Double sampleSizeValue) { 1970 this.sampleSizeValue = sampleSizeValue; 1971 } 1972 1973 /** 1974 * Calculated filed organismQuantity / sampleSizeValue, if the type is identical 1975 */ 1976 @Nullable 1977 public Double getRelativeOrganismQuantity() { 1978 return relativeOrganismQuantity; 1979 } 1980 1981 public void setRelativeOrganismQuantity(@Nullable Double relativeOrganismQuantity) { 1982 this.relativeOrganismQuantity = relativeOrganismQuantity; 1983 } 1984 1985 /** 1986 * Flag occurrence when associatedSequences/extension exists 1987 */ 1988 public boolean getIsSequenced() { 1989 return isSequenced; 1990 } 1991 1992 public void setIsSequenced(boolean isSequenced) { 1993 this.isSequenced = isSequenced; 1994 } 1995 1996 /** 1997 * A list (concatenated and separated) of identifiers (publication, global unique identifier, URI) of genetic 1998 * sequence information associated with the material entity. 1999 */ 2000 @Nullable 2001 public String getAssociatedSequences() { 2002 return associatedSequences; 2003 } 2004 2005 public void setAssociatedSequences(String associatedSequences) { 2006 this.associatedSequences = associatedSequences; 2007 } 2008 2009 /** 2010 * Applied license to the occurrence record or dataset to which this record belongs to. 2011 */ 2012 @NotNull 2013 public License getLicense() { 2014 return license; 2015 } 2016 2017 public void setLicense(License license) { 2018 this.license = license; 2019 } 2020 2021 @NotNull 2022 public List<Identifier> getIdentifiers() { 2023 return identifiers; 2024 } 2025 2026 public void setIdentifiers(List<Identifier> identifiers) { 2027 this.identifiers = identifiers; 2028 } 2029 2030 @NotNull 2031 public List<MediaObject> getMedia() { 2032 return media; 2033 } 2034 2035 public void setMedia(List<MediaObject> media) { 2036 this.media = media; 2037 } 2038 2039 @NotNull 2040 public List<MeasurementOrFact> getFacts() { 2041 return facts; 2042 } 2043 2044 public void setFacts(List<MeasurementOrFact> facts) { 2045 this.facts = facts; 2046 } 2047 2048 @NotNull 2049 public List<OccurrenceRelation> getRelations() { 2050 return relations; 2051 } 2052 2053 public void setRelations(List<OccurrenceRelation> relations) { 2054 this.relations = relations; 2055 } 2056 2057 @NotNull 2058 public List<AgentIdentifier> getRecordedByIds() { 2059 return recordedByIds; 2060 } 2061 2062 public void setRecordedByIds(List<AgentIdentifier> recordedByIds) { 2063 this.recordedByIds = recordedByIds; 2064 } 2065 2066 @NotNull 2067 public List<AgentIdentifier> getIdentifiedByIds() { 2068 return identifiedByIds; 2069 } 2070 2071 public void setIdentifiedByIds(List<AgentIdentifier> identifiedByIds) { 2072 this.identifiedByIds = identifiedByIds; 2073 } 2074 2075 @NotNull 2076 public Gadm getGadm() { 2077 return gadm; 2078 } 2079 2080 public void setGadm(Gadm gadm) { 2081 this.gadm = gadm; 2082 } 2083 2084 @Nullable 2085 @Experimental 2086 public String getInstitutionKey() { 2087 return institutionKey; 2088 } 2089 2090 public void setInstitutionKey(String institutionKey) { 2091 this.institutionKey = institutionKey; 2092 } 2093 2094 @Nullable 2095 @Experimental 2096 public String getCollectionKey() { 2097 return collectionKey; 2098 } 2099 2100 public void setCollectionKey(String collectionKey) { 2101 this.collectionKey = collectionKey; 2102 } 2103 2104 public boolean getIsInCluster() { 2105 return isInCluster; 2106 } 2107 2108 public void setIsInCluster(boolean isInCluster) { 2109 this.isInCluster = isInCluster; 2110 } 2111 2112 @Nullable 2113 public String getDegreeOfEstablishment() { 2114 return degreeOfEstablishment; 2115 } 2116 2117 public void setDegreeOfEstablishment(String degreeOfEstablishment) { 2118 this.degreeOfEstablishment = degreeOfEstablishment; 2119 } 2120 2121 @Nullable 2122 public String getPathway() { 2123 return pathway; 2124 } 2125 2126 public void setPathway(String pathway) { 2127 this.pathway = pathway; 2128 } 2129 2130 public String getDatasetID() { 2131 return datasetID; 2132 } 2133 2134 public void setDatasetID(String datasetID) { 2135 this.datasetID = datasetID; 2136 } 2137 2138 public String getDatasetName() { 2139 return datasetName; 2140 } 2141 2142 public void setDatasetName(String datasetName) { 2143 this.datasetName = datasetName; 2144 } 2145 2146 public String getOtherCatalogNumbers() { 2147 return otherCatalogNumbers; 2148 } 2149 2150 public void setOtherCatalogNumbers(String otherCatalogNumbers) { 2151 this.otherCatalogNumbers = otherCatalogNumbers; 2152 } 2153 2154 @Nullable 2155 public String getEarliestEonOrLowestEonothem() { 2156 return earliestEonOrLowestEonothem; 2157 } 2158 2159 public void setEarliestEonOrLowestEonothem(String earliestEonOrLowestEonothem) { 2160 this.earliestEonOrLowestEonothem = earliestEonOrLowestEonothem; 2161 } 2162 2163 @Nullable 2164 public String getLatestEonOrHighestEonothem() { 2165 return latestEonOrHighestEonothem; 2166 } 2167 2168 public void setLatestEonOrHighestEonothem(String latestEonOrHighestEonothem) { 2169 this.latestEonOrHighestEonothem = latestEonOrHighestEonothem; 2170 } 2171 2172 @Nullable 2173 public String getEarliestEraOrLowestErathem() { 2174 return earliestEraOrLowestErathem; 2175 } 2176 2177 public void setEarliestEraOrLowestErathem(String earliestEraOrLowestErathem) { 2178 this.earliestEraOrLowestErathem = earliestEraOrLowestErathem; 2179 } 2180 2181 @Nullable 2182 public String getLatestEraOrHighestErathem() { 2183 return latestEraOrHighestErathem; 2184 } 2185 2186 public void setLatestEraOrHighestErathem(String latestEraOrHighestErathem) { 2187 this.latestEraOrHighestErathem = latestEraOrHighestErathem; 2188 } 2189 2190 @Nullable 2191 public String getEarliestPeriodOrLowestSystem() { 2192 return earliestPeriodOrLowestSystem; 2193 } 2194 2195 public void setEarliestPeriodOrLowestSystem(String earliestPeriodOrLowestSystem) { 2196 this.earliestPeriodOrLowestSystem = earliestPeriodOrLowestSystem; 2197 } 2198 2199 @Nullable 2200 public String getLatestPeriodOrHighestSystem() { 2201 return latestPeriodOrHighestSystem; 2202 } 2203 2204 public void setLatestPeriodOrHighestSystem(String latestPeriodOrHighestSystem) { 2205 this.latestPeriodOrHighestSystem = latestPeriodOrHighestSystem; 2206 } 2207 2208 @Nullable 2209 public String getEarliestEpochOrLowestSeries() { 2210 return earliestEpochOrLowestSeries; 2211 } 2212 2213 public void setEarliestEpochOrLowestSeries(String earliestEpochOrLowestSeries) { 2214 this.earliestEpochOrLowestSeries = earliestEpochOrLowestSeries; 2215 } 2216 2217 @Nullable 2218 public String getLatestEpochOrHighestSeries() { 2219 return latestEpochOrHighestSeries; 2220 } 2221 2222 public void setLatestEpochOrHighestSeries(String latestEpochOrHighestSeries) { 2223 this.latestEpochOrHighestSeries = latestEpochOrHighestSeries; 2224 } 2225 2226 @Nullable 2227 public String getEarliestAgeOrLowestStage() { 2228 return earliestAgeOrLowestStage; 2229 } 2230 2231 public void setEarliestAgeOrLowestStage(String earliestAgeOrLowestStage) { 2232 this.earliestAgeOrLowestStage = earliestAgeOrLowestStage; 2233 } 2234 2235 @Nullable 2236 public String getLatestAgeOrHighestStage() { 2237 return latestAgeOrHighestStage; 2238 } 2239 2240 public void setLatestAgeOrHighestStage(String latestAgeOrHighestStage) { 2241 this.latestAgeOrHighestStage = latestAgeOrHighestStage; 2242 } 2243 2244 @Nullable 2245 public String getLowestBiostratigraphicZone() { 2246 return lowestBiostratigraphicZone; 2247 } 2248 2249 public void setLowestBiostratigraphicZone(String lowestBiostratigraphicZone) { 2250 this.lowestBiostratigraphicZone = lowestBiostratigraphicZone; 2251 } 2252 2253 @Nullable 2254 public String getHighestBiostratigraphicZone() { 2255 return highestBiostratigraphicZone; 2256 } 2257 2258 public void setHighestBiostratigraphicZone(String highestBiostratigraphicZone) { 2259 this.highestBiostratigraphicZone = highestBiostratigraphicZone; 2260 } 2261 2262 @Nullable 2263 public String getGroup() { 2264 return group; 2265 } 2266 2267 public void setGroup(String group) { 2268 this.group = group; 2269 } 2270 2271 @Nullable 2272 public String getFormation() { 2273 return formation; 2274 } 2275 2276 public void setFormation(String formation) { 2277 this.formation = formation; 2278 } 2279 2280 @Nullable 2281 public String getMember() { 2282 return member; 2283 } 2284 2285 public void setMember(String member) { 2286 this.member = member; 2287 } 2288 2289 @Nullable 2290 public String getBed() { 2291 return bed; 2292 } 2293 2294 public void setBed(String bed) { 2295 this.bed = bed; 2296 } 2297 2298 public String getRecordedBy() { 2299 return recordedBy; 2300 } 2301 2302 public void setRecordedBy(String recordedBy) { 2303 this.recordedBy = recordedBy; 2304 } 2305 2306 public String getIdentifiedBy() { 2307 return identifiedBy; 2308 } 2309 2310 public void setIdentifiedBy(String identifiedBy) { 2311 this.identifiedBy = identifiedBy; 2312 } 2313 2314 public String getPreparations() { 2315 return preparations; 2316 } 2317 2318 public void setPreparations(String preparations) { 2319 this.preparations = preparations; 2320 } 2321 2322 public String getSamplingProtocol() { 2323 return samplingProtocol; 2324 } 2325 2326 public void setSamplingProtocol(String samplingProtocol) { 2327 this.samplingProtocol = samplingProtocol; 2328 } 2329 2330 public List<String> getDnaSequenceID() { 2331 return dnaSequenceID; 2332 } 2333 2334 public void setDnaSequenceID(List<String> dnaSequenceID) { 2335 this.dnaSequenceID = dnaSequenceID; 2336 } 2337 2338 public Map<String, Classification> getClassifications() { 2339 return classifications; 2340 } 2341 2342 public void setClassifications(Map<String, Classification> classifications) { 2343 this.classifications = classifications; 2344 } 2345 2346 /** 2347 * Convenience method checking if any spatial validation rule has not passed. 2348 * Primarily used to indicate that the record should not be displayed on a map. 2349 */ 2350 @JsonIgnore 2351 public boolean hasSpatialIssue() { 2352 for (OccurrenceIssue rule : OccurrenceIssue.GEOSPATIAL_RULES) { 2353 if (issues.contains(rule)) { 2354 return true; 2355 } 2356 } 2357 return false; 2358 } 2359 2360 /** 2361 * This private method is only for serialization via jackson and not exposed anywhere else! 2362 * It maps the verbatimField terms into properties with their simple name or qualified names for UnknownTerms. 2363 */ 2364 @JsonAnyGetter 2365 private Map<String, String> jsonVerbatimFields() { 2366 Map<String, String> extendedProps = new HashMap<>(); 2367 for (Map.Entry<Term, String> prop : getVerbatimFields().entrySet()) { 2368 Term t = prop.getKey(); 2369 if (t instanceof UnknownTerm || PROPERTIES.contains(t.simpleName())) { 2370 extendedProps.put(t.qualifiedName(), prop.getValue()); 2371 } else { 2372 // render all terms in controlled enumerations as simple names only - unless we have a property of that name already! 2373 extendedProps.put(t.simpleName(), prop.getValue()); 2374 } 2375 } 2376 return extendedProps; 2377 } 2378}