├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── rocketchat-notifications-feedback-requests.yml ├── .gitignore ├── .idea └── checkstyle-idea.xml ├── CHANGELOG.md ├── CITATION.cff ├── CONTRIBUTING.md ├── COPYING ├── COPYING.LESSER ├── Jenkinsfile ├── README.md ├── config └── ide │ ├── README.md │ ├── eclipse-java-google-style.xml │ └── intellij-java-google-style.xml ├── data ├── test-data-without-keytables.mv.db └── test-data.mv.db ├── documentation ├── README.md ├── first-steps │ ├── BuildingAreaHeidelberg.png │ ├── OSHDBApiTutorial.java │ ├── README.md │ └── example-pom.xml └── manual │ ├── README.md │ ├── aggregation.md │ ├── api.md │ ├── data-model.md │ ├── data-model.svg │ ├── database-backends.md │ ├── filters.md │ ├── geometries.md │ ├── helpers │ ├── OSHDBApplication.md │ ├── OSHDBDriver.md │ └── README.md │ ├── installation.md │ ├── map-reduce.md │ └── views.md ├── oshdb-api-ignite ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── api │ │ ├── db │ │ └── OSHDBIgnite.java │ │ ├── ignite │ │ └── util │ │ │ └── OSHDBToIgnite.java │ │ └── mapreducer │ │ └── backend │ │ ├── MapReducerIgniteAffinityCall.java │ │ ├── MapReducerIgniteLocalPeek.java │ │ ├── MapReducerIgniteScanQuery.java │ │ └── OSHDBIgniteMapReduceComputeTask.java │ └── test │ └── java │ └── org │ └── heigit │ └── ohsome │ └── oshdb │ └── api │ └── tests │ ├── MapReduceOSHDBIgniteAffinityCallTest.java │ ├── MapReduceOSHDBIgniteLocalPeekTest.java │ ├── MapReduceOSHDBIgniteMissingCacheTest.java │ ├── MapReduceOSHDBIgniteScanQueryTest.java │ └── MapReduceOSHDBIgniteTest.java ├── oshdb-api ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── api │ │ ├── db │ │ ├── H2Support.java │ │ ├── OSHDBDatabase.java │ │ ├── OSHDBH2.java │ │ ├── OSHDBJdbc.java │ │ └── package-info.java │ │ ├── generic │ │ ├── NumberUtils.java │ │ ├── OSHDBCombinedIndex.java │ │ ├── WeightedValue.java │ │ └── package-info.java │ │ ├── mapreducer │ │ ├── FilterFunction.java │ │ ├── GeometrySplitter.java │ │ ├── MapAggregatable.java │ │ ├── MapAggregator.java │ │ ├── MapFunction.java │ │ ├── MapReducer.java │ │ ├── MapReducerAggregations.java │ │ ├── MapReducerSettings.java │ │ ├── Mappable.java │ │ ├── MutableWeightedDouble.java │ │ ├── OSMContributionView.java │ │ ├── OSMEntitySnapshotView.java │ │ ├── TdigestReducer.java │ │ ├── backend │ │ │ ├── Kernels.java │ │ │ ├── MapReducerJdbc.java │ │ │ ├── MapReducerJdbcMultithread.java │ │ │ ├── MapReducerJdbcSinglethread.java │ │ │ └── package-info.java │ │ └── package-info.java │ │ ├── object │ │ ├── OSMContributionImpl.java │ │ ├── OSMEntitySnapshotImpl.java │ │ └── package-info.java │ │ └── package-info.java │ └── test │ ├── java │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── api │ │ └── tests │ │ ├── CollectTest.java │ │ ├── FlatMapAggregateGroupedByEntityTest.java │ │ ├── FlatMapAggregateTest.java │ │ ├── FlatMapReduceGroupedByEntityOSHDBH2MultithreadTest.java │ │ ├── FlatMapReduceGroupedByEntityOSHDBH2SinglethreadTest.java │ │ ├── FlatMapReduceGroupedByEntityTest.java │ │ ├── FlatMapReduceTest.java │ │ ├── ForEachTest.java │ │ ├── HelpersOSMContributionViewTest.java │ │ ├── HelpersOSMEntitySnapshotViewTest.java │ │ ├── LambdaFilterTest.java │ │ ├── MapAggregateByGeometryTest.java │ │ ├── MapAggregateByIndexTest.java │ │ ├── MapAggregateByTimestampTest.java │ │ ├── MapReduceOSHDBH2MultithreadTest.java │ │ ├── MapReduceOSHDBH2SinglethreadTest.java │ │ ├── MapReduceOSHDBJdbcMissingTablesTest.java │ │ ├── MapReduceTest.java │ │ ├── OSHDBFilterTest.java │ │ ├── OSMContributionGetContributorUserIdTest.java │ │ ├── OSMDataFiltersTest.java │ │ ├── QuantilesTest.java │ │ ├── StreamTest.java │ │ ├── TestAutoAggregation.java │ │ └── TestMapReducerTimestamps.java │ └── resources │ └── log4j.properties ├── oshdb-filter ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── filter │ │ ├── AndOperator.java │ │ ├── BinaryOperator.java │ │ ├── ChangesetIdFilterEquals.java │ │ ├── ChangesetIdFilterEqualsAnyOf.java │ │ ├── ChangesetIdFilterRange.java │ │ ├── ConstantFilter.java │ │ ├── ContributorUserIdFilterEquals.java │ │ ├── ContributorUserIdFilterEqualsAnyOf.java │ │ ├── ContributorUserIdFilterRange.java │ │ ├── Filter.java │ │ ├── FilterExpression.java │ │ ├── FilterParser.java │ │ ├── GeometryFilter.java │ │ ├── GeometryFilterArea.java │ │ ├── GeometryFilterInnerRings.java │ │ ├── GeometryFilterLength.java │ │ ├── GeometryFilterOuterRings.java │ │ ├── GeometryFilterPerimeter.java │ │ ├── GeometryFilterRoundness.java │ │ ├── GeometryFilterSquareness.java │ │ ├── GeometryFilterVertices.java │ │ ├── GeometryTypeFilter.java │ │ ├── IdFilterEquals.java │ │ ├── IdFilterEqualsAnyOf.java │ │ ├── IdFilterNotEquals.java │ │ ├── IdFilterRange.java │ │ ├── IdRange.java │ │ ├── NegatableFilter.java │ │ ├── OrOperator.java │ │ ├── TagFilter.java │ │ ├── TagFilterAnyOf.java │ │ ├── TagFilterEquals.java │ │ ├── TagFilterEqualsAny.java │ │ ├── TagFilterEqualsAnyOf.java │ │ ├── TagFilterNotEquals.java │ │ ├── TagFilterNotEqualsAny.java │ │ ├── TagFilterNotEqualsAnyOf.java │ │ └── TypeFilter.java │ └── test │ ├── java │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── filter │ │ ├── ApplyOSHTest.java │ │ ├── ApplyOSMContributionTest.java │ │ ├── ApplyOSMEntitySnapshotTest.java │ │ ├── ApplyOSMGeometryTest.java │ │ ├── ApplyOSMTest.java │ │ ├── FilterByTest.java │ │ ├── FilterTest.java │ │ ├── NegateTest.java │ │ ├── NormalizeTest.java │ │ └── ParseTest.java │ └── resources │ └── log4j.properties ├── oshdb-helpers ├── oshdb-application-template │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── helpers │ │ └── applicationtemplate │ │ ├── OSHDBApplication.java │ │ └── PropsUtil.java ├── oshdb-database-driver │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── heigit │ │ │ └── ohsome │ │ │ └── oshdb │ │ │ └── helpers │ │ │ └── db │ │ │ ├── OSHDBConnection.java │ │ │ ├── OSHDBDriver.java │ │ │ └── Util.java │ │ └── test │ │ └── java │ │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── helpers │ │ └── db │ │ └── OSHDBDriverH2Test.java └── pom.xml ├── oshdb-oshpbf-parser ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── heigit │ └── ohsome │ └── oshpbf │ └── parser │ ├── osm │ └── v06 │ │ ├── CommonEntityData.java │ │ ├── Entity.java │ │ ├── Node.java │ │ ├── Relation.java │ │ ├── RelationMember.java │ │ ├── Tag.java │ │ ├── TagText.java │ │ └── Way.java │ ├── pbf │ ├── BlobToOSHIterator.java │ ├── OsmPrimitveBlockIterator.java │ ├── PbfBlob.java │ └── PosContainer.java │ ├── rx │ ├── Osh.java │ ├── OshMerger.java │ └── RxOshPbfReader.java │ └── util │ └── ByteBufferBackedInputStream.java ├── oshdb-tool └── pom.xml ├── oshdb-util ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── heigit │ │ │ └── ohsome │ │ │ └── oshdb │ │ │ └── util │ │ │ ├── TableNames.java │ │ │ ├── celliterator │ │ │ ├── CellIterator.java │ │ │ ├── ContributionType.java │ │ │ ├── LazyEvaluatedContributionTypes.java │ │ │ ├── LazyEvaluatedObject.java │ │ │ └── OSHEntitySource.java │ │ │ ├── exceptions │ │ │ ├── OSHDBException.java │ │ │ ├── OSHDBInvalidTimestampException.java │ │ │ ├── OSHDBKeytablesNotFoundException.java │ │ │ ├── OSHDBNotImplementedException.java │ │ │ ├── OSHDBTableNotFoundException.java │ │ │ └── OSHDBTimeoutException.java │ │ │ ├── function │ │ │ ├── OSHEntityFilter.java │ │ │ ├── OSMEntityFilter.java │ │ │ ├── SerializableBiConsumer.java │ │ │ ├── SerializableBiFunction.java │ │ │ ├── SerializableBiPredicate.java │ │ │ ├── SerializableBinaryOperator.java │ │ │ ├── SerializableConsumer.java │ │ │ ├── SerializableFunction.java │ │ │ ├── SerializablePredicate.java │ │ │ ├── SerializableSupplier.java │ │ │ ├── SerializableToDoubleFunction.java │ │ │ └── package-info.java │ │ │ ├── geometry │ │ │ ├── Geo.java │ │ │ ├── OSHDBGeometryBuilder.java │ │ │ ├── OSHDBGeometryBuilderInternal.java │ │ │ └── fip │ │ │ │ ├── FastBboxInPolygon.java │ │ │ │ ├── FastBboxOutsidePolygon.java │ │ │ │ ├── FastInPolygon.java │ │ │ │ ├── FastPointInPolygon.java │ │ │ │ └── FastPolygonOperations.java │ │ │ ├── mappable │ │ │ ├── OSHDBMapReducible.java │ │ │ ├── OSMContribution.java │ │ │ ├── OSMEntitySnapshot.java │ │ │ └── package-info.java │ │ │ ├── osh │ │ │ └── OSHEntityTimeUtils.java │ │ │ ├── taginterpreter │ │ │ ├── BaseTagInterpreter.java │ │ │ ├── DefaultTagInterpreter.java │ │ │ ├── InvertedHashSet.java │ │ │ └── TagInterpreter.java │ │ │ ├── tagtranslator │ │ │ ├── CachedTagTranslator.java │ │ │ ├── ClosableSqlArray.java │ │ │ ├── JdbcTagTranslator.java │ │ │ ├── OSMRole.java │ │ │ ├── OSMTag.java │ │ │ ├── OSMTagInterface.java │ │ │ ├── OSMTagKey.java │ │ │ └── TagTranslator.java │ │ │ └── time │ │ │ ├── IsoDateTimeParser.java │ │ │ ├── OSHDBTimestampException.java │ │ │ ├── OSHDBTimestampIllegalArgumentException.java │ │ │ ├── OSHDBTimestampInterval.java │ │ │ ├── OSHDBTimestampList.java │ │ │ ├── OSHDBTimestampParseException.java │ │ │ └── OSHDBTimestamps.java │ └── resources │ │ └── json │ │ ├── polygon-features.json │ │ └── uninterestingTags.json │ └── test │ ├── java │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ └── util │ │ ├── celliterator │ │ ├── IterateByContributionNodesTest.java │ │ ├── IterateByContributionNotOsmTypeSpecificTest.java │ │ ├── IterateByContributionRelationsTest.java │ │ ├── IterateByContributionTest.java │ │ ├── IterateByContributionTypeNotMultipolygonTest.java │ │ ├── IterateByContributionWaysTest.java │ │ ├── IterateByTimestampNotOsmTypeSpecificTest.java │ │ ├── IterateByTimestampsNodesTest.java │ │ ├── IterateByTimestampsRelationsTest.java │ │ ├── IterateByTimestampsWaysTest.java │ │ └── helpers │ │ │ └── GridOSHFactory.java │ │ ├── geometry │ │ ├── GeoTest.java │ │ ├── OSHDBGeometryBuilderInternalTest.java │ │ ├── OSHDBGeometryBuilderTest.java │ │ ├── OSHDBGeometryTest.java │ │ ├── fip │ │ │ ├── FastBboxInPolygonTest.java │ │ │ ├── FastBboxOutsidePolygonTest.java │ │ │ ├── FastPointInPolygonTest.java │ │ │ └── FastPolygonOperationsTest.java │ │ ├── helpers │ │ │ ├── FakeTagInterpreter.java │ │ │ ├── FakeTagInterpreterAreaAlways.java │ │ │ ├── FakeTagInterpreterAreaMultipolygonAllOuters.java │ │ │ ├── FakeTagInterpreterAreaNever.java │ │ │ ├── OSMXmlReaderTagInterpreter.java │ │ │ └── TimestampParser.java │ │ ├── incomplete │ │ │ ├── OSHDBGeometryBuilderTestPolygonIncompleteDataTest.java │ │ │ └── OSHDBGeometryBuilderTestWayIncompleteDataTest.java │ │ ├── osmhistorytestdata │ │ │ ├── OSHDBGeometryBuilderTestOsmHistoryTestDataNodesTest.java │ │ │ ├── OSHDBGeometryBuilderTestOsmHistoryTestDataRelationNotMultipolygonTest.java │ │ │ ├── OSHDBGeometryBuilderTestOsmHistoryTestDataRelationTest.java │ │ │ └── OSHDBGeometryBuilderTestOsmHistoryTestDataWaysTest.java │ │ ├── osmtestdata │ │ │ ├── OSHDBGeometryBuilderTestOsmTestData1xxTest.java │ │ │ ├── OSHDBGeometryBuilderTestOsmTestData3xxTest.java │ │ │ └── OSHDBGeometryBuilderTestOsmTestData7xxTest.java │ │ └── relations │ │ │ ├── OSHDBGeometryBuilderMultipolygonInvalidInnersTest.java │ │ │ ├── OSHDBGeometryBuilderMultipolygonInvalidOutersTest.java │ │ │ ├── OSHDBGeometryBuilderRelationOuterDirectionsTest.java │ │ │ └── OSHDBGeometryBuilderRelationTypeNotMultipolygonTest.java │ │ ├── osh │ │ └── TestOSHEntityTimeUtils.java │ │ ├── tagtranslator │ │ ├── AbstractTagTranslatorTest.java │ │ ├── CachedTagTranslatorTest.java │ │ └── JdbcTagTranslatorTest.java │ │ ├── time │ │ ├── IsoDateTimeParserTest.java │ │ ├── OSHDBTimestampIntervalTest.java │ │ └── OSHDBTimestampsTest.java │ │ └── xmlreader │ │ ├── MutableOSMEntity.java │ │ ├── MutableOSMNode.java │ │ ├── MutableOSMRelation.java │ │ ├── MutableOSMWay.java │ │ └── OSMXmlReader.java │ └── resources │ ├── different-timestamps │ ├── node.osm │ ├── not-osm-type-specific.osm │ ├── polygon.osm │ ├── type-not-multipolygon.osm │ └── way.osm │ ├── geometryBuilder.osh │ ├── incomplete-osm │ ├── polygon.osm │ └── way.osm │ ├── log4j.properties │ ├── osm-testdata │ ├── all.osm │ └── readme.md.txt │ └── relations │ ├── invalid-inner-rings.osm │ ├── invalid-outer-ring.osm │ ├── multipolygonShellsShareNode.osm │ ├── outer-directions.osm │ └── relationTypeNotMultipolygon.osm ├── oshdb ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ ├── OSHDB.java │ │ ├── OSHDBBoundable.java │ │ ├── OSHDBBoundingBox.java │ │ ├── OSHDBRole.java │ │ ├── OSHDBTag.java │ │ ├── OSHDBTags.java │ │ ├── OSHDBTemporal.java │ │ ├── OSHDBTimestamp.java │ │ ├── grid │ │ ├── GridOSHEntity.java │ │ ├── GridOSHNodes.java │ │ ├── GridOSHRelations.java │ │ ├── GridOSHWays.java │ │ └── package-info.java │ │ ├── impl │ │ └── osh │ │ │ ├── OSHEntityImpl.java │ │ │ ├── OSHNodeImpl.java │ │ │ ├── OSHRelationImpl.java │ │ │ └── OSHWayImpl.java │ │ ├── index │ │ ├── Grid.java │ │ ├── XYGrid.java │ │ ├── XYGridTree.java │ │ └── package-info.java │ │ ├── osh │ │ ├── OSHEntities.java │ │ ├── OSHEntity.java │ │ ├── OSHNode.java │ │ ├── OSHRelation.java │ │ ├── OSHWay.java │ │ └── package-info.java │ │ ├── osm │ │ ├── OSM.java │ │ ├── OSMCoordinates.java │ │ ├── OSMEntity.java │ │ ├── OSMMember.java │ │ ├── OSMNode.java │ │ ├── OSMRelation.java │ │ ├── OSMType.java │ │ ├── OSMWay.java │ │ └── package-info.java │ │ ├── package-info.java │ │ └── util │ │ ├── CellId.java │ │ ├── OSHDBTagKey.java │ │ ├── bytearray │ │ ├── ByteArrayOutputWrapper.java │ │ ├── ByteArrayWrapper.java │ │ └── OSHDBByteArrayOutputStream.java │ │ └── package-info.java │ └── test │ ├── java │ └── org │ │ └── heigit │ │ └── ohsome │ │ └── oshdb │ │ ├── OSHDBRoleTest.java │ │ ├── OSHDBTagTest.java │ │ ├── OSHDBTagsTest.java │ │ ├── grid │ │ ├── GridOSHNodesTest.java │ │ ├── GridOSHRelationsTest.java │ │ └── GridOSHWaysTest.java │ │ ├── index │ │ ├── XYGridTest.java │ │ └── XYGridTreeTest.java │ │ ├── osh │ │ ├── OSHEntityTest.java │ │ ├── OSHNodeTest.java │ │ ├── OSHRelationTest.java │ │ └── OSHWayTest.java │ │ ├── osm │ │ ├── OSMMemberTest.java │ │ ├── OSMNodeTest.java │ │ ├── OSMRelationTest.java │ │ └── OSMWayTest.java │ │ └── util │ │ ├── CellIdTest.java │ │ ├── OSHDBBoundableTest.java │ │ ├── OSHDBBoundingBoxTest.java │ │ ├── OSHDBTemporalTest.java │ │ └── bytearray │ │ └── ByteArrayOutputWrapperTest.java │ └── resources │ └── log4j.properties ├── pipeline_config.groovy └── pom.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Handle line endings automatically for files detected as text 2 | # and leave all files detected as binary untouched. 3 | * text=auto 4 | 5 | # 6 | # The above will handle all files NOT found below 7 | # 8 | # These files are text and should be normalized (Convert crlf => lf) 9 | *.css text 10 | *.df text 11 | *.htm text 12 | *.html text 13 | *.java text 14 | *.js text 15 | *.json text 16 | *.jsp text 17 | *.jspf text 18 | *.jspx text 19 | *.properties text 20 | *.sh text 21 | *.tld text 22 | *.txt text 23 | *.tag text 24 | *.tagx text 25 | *.xml text 26 | *.yml text 27 | 28 | # These files are binary and should be left untouched 29 | # (binary is a macro for -text -diff) 30 | *.class binary 31 | *.dll binary 32 | *.ear binary 33 | *.gif binary 34 | *.ico binary 35 | *.jar binary 36 | *.jpg binary 37 | *.jpeg binary 38 | *.png binary 39 | *.so binary 40 | *.war binary 41 | 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve the project. 4 | title: '' 5 | labels: 'bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Bug Description 11 | A clear and concise description of what the bug is. 12 | 13 | ### How to Reproduce 14 | Steps to reproduce the behaviour: 15 | 1. Go to '...' 16 | 2. Execute code '...' 17 | 3. See error 18 | 19 | ### Expected behaviour 20 | A clear and concise description of what you expected to happen. 21 | 22 | ### Further Information 23 | #### Error messages, logs, screenshots 24 | If applicable, add printed error messages, log files or screenshots to help explain your problem. 25 | 26 | #### Additional Context 27 | Add any other context about the problem here. 28 | 29 | ### System information 30 | Please complete the following information: 31 | - OS: [e.g. Ubuntu 20.04 LTS] 32 | - Java Version: [e.g. openjdk version "11.0.9.1"] 33 | - OSHDB Version: [e.g. 1.2.3] 34 | - Maven version: [e.g. 3.6.3] 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea or enhancement to this project. 4 | title: '' 5 | labels: 'feature request' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Problem Description 11 | Is your feature request related to a problem? Please add a clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | ### Expected Solution 14 | Describe the solution you'd like 15 | 16 | ### Alternative Solutions 17 | Describe alternatives you've considered 18 | 19 | ### Additional Context 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please add the **type of change** as label. If your PR is not ready for review and merge, please add `🚧` to the PR title. 2 | 3 | ### Description 4 | Please add a clear and concise description of what your PR solves. 5 | 6 | ### Corresponding issue 7 | Closes # 8 | 9 | ### New or changed dependencies 10 | - 11 | 12 | ### Checklist 13 | - [ ] My code follows the [code-style](https://github.com/GIScience/oshdb/blob/main/CONTRIBUTING.md) rules, and I have checked on the [static analyses](https://jenkins.ohsome.org/job/oshdb/view/change-requests/) and [benchmark](https://reports.ohsome.org/oshdb-benchmarks/) (if applicable) results 14 | - [ ] I have commented my code 15 | - [ ] I have written javadoc (required for public classes and methods) 16 | - [ ] I have added sufficient unit tests 17 | - [ ] I have made corresponding changes to the [documentation](https://github.com/GIScience/oshdb/tree/main/documentation) 18 | - [ ] I have updated the [CHANGELOG.md](https://github.com/GIScience/oshdb/blob/main/CHANGELOG.md) 19 | - [ ] I have adjusted the [examples](https://gitlab.gistools.geog.uni-heidelberg.de/giscience/big-data/ohsome/oshdb-examples) or [created an issue](https://gitlab.gistools.geog.uni-heidelberg.de/giscience/big-data/ohsome/oshdb-examples/-/issues/new) in the corresponding repository 20 | - [ ] I have adjusted the [benchmark](https://reports.ohsome.org/oshdb-benchmarks/) or [created an issue](https://gitlab.gistools.geog.uni-heidelberg.de/giscience/big-data/ohsome/oshdb-benchmarks/-/issues/new) in the corresponding repository 21 | 22 | Please check all finished tasks. If some tasks do not apply to your PR, please cross their text out (by using `~...~`) and remove their checkboxes. 23 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.3 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - family-names: "Raifer" 5 | given-names: "Martin" 6 | orcid: "https://orcid.org/0000-0002-2106-8560" 7 | - family-names: "Troilo" 8 | given-names: "Rafael" 9 | - family-names: "Mocnik" 10 | given-names: "Franz-Benjamin" 11 | orcid: "https://orcid.org/0000-0002-1759-6336" 12 | - family-names: "Schott" 13 | given-names: "Moritz" 14 | title: "OSHDB - OpenStreetMap History Data Analysis" 15 | version: 1.2.3 16 | doi: 10.5281/zenodo.4146990 17 | date-released: 2021-07-22 18 | url: "https://github.com/GIScience/oshdb" 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Code Style 2 | 3 | We're using the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html) for the source code. With the [exception](https://google.github.io/styleguide/javaguide.html#s5.3-camel-case) that the abbreviations `OSM`, `OSH` and `OSHDB` are allowed to be used in method and class names. For some popular IDEs and code linting tools you can find settings-files of the used code style in [config/ide](/config/ide/). 4 | -------------------------------------------------------------------------------- /config/ide/README.md: -------------------------------------------------------------------------------- 1 | Here are some suggestions for how to set up your IDE and code linting tools to use the OSHDB code style. 2 | 3 | # IDE Settings 4 | 5 | ## IntelliJ 6 | 7 | Please follow this [guide](https://www.jetbrains.com/help/idea/settings-code-style.html) using this [intellij-java-google-style.xml](/config/ide/intellij-java-google-style.xml). 8 | 9 | ## Eclipse 10 | 11 | Please use this [guide](https://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fpreferences%2Fjava%2Fcodestyle%2Fref-preferences-formatter.htm) to import the dedicated [eclipse-java-google-style.xml](/config/ide/eclipse-java-google-style.xml). 12 | 13 | # Checkstyle 14 | 15 | [Checkstyle](http://checkstyle.sourceforge.net/) can check if Java code complies to a given set of code style rules. It can be used standalone, but there are also plugins for IDEs like [intelliJ](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea) and [eclipse](http://checkstyle.org/eclipse-cs/), or for build tools like [maven](https://maven.apache.org/plugins/maven-checkstyle-plugin/). 16 | 17 | For checkstyle, use our dedicated [checkstyle-google-ohsome.xml](https://gitlab.gistools.geog.uni-heidelberg.de/giscience/big-data/ohsome/parent/-/blob/master/ohsome-codestyle/src/main/resources/checkstyle-google-ohsome.xml) configuration file. 18 | -------------------------------------------------------------------------------- /data/test-data-without-keytables.mv.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GIScience/oshdb/a196cc990a75fa35841ca0908f323c3c9fc06b9a/data/test-data-without-keytables.mv.db -------------------------------------------------------------------------------- /data/test-data.mv.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GIScience/oshdb/a196cc990a75fa35841ca0908f323c3c9fc06b9a/data/test-data.mv.db -------------------------------------------------------------------------------- /documentation/README.md: -------------------------------------------------------------------------------- 1 | # OSHDB Documentation 2 | 3 | Here you find OSHDB related documentation material: 4 | 5 | * [First Steps Tutorial](first-steps/README.md)
6 | This tutorial teaches how to use the OSHDB-API in Java. 7 | * [OSHDB Manual](manual/README.md)
8 | Explains the design of the OSHDB data model and shows the different features of the OSHDB API and how they can be used to efficiently query the OSM history data. 9 | * [Examples](https://gitlab.gistools.geog.uni-heidelberg.de/giscience/big-data/ohsome/oshdb-examples)
10 | Contains some example code for how to use the OSHDB to analyze the OSM history data. 11 | * [org.heigit.ohsome Javadoc](https://javadoc.io/doc/org.heigit.ohsome)
12 | This lists all methods offered by the various OSHDB modules, packages and classes. 13 | -------------------------------------------------------------------------------- /documentation/first-steps/BuildingAreaHeidelberg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GIScience/oshdb/a196cc990a75fa35841ca0908f323c3c9fc06b9a/documentation/first-steps/BuildingAreaHeidelberg.png -------------------------------------------------------------------------------- /documentation/first-steps/OSHDBApiTutorial.java: -------------------------------------------------------------------------------- 1 | package org.example.oshdb.api.tutorial; 2 | 3 | import java.util.SortedMap; 4 | import org.heigit.ohsome.oshdb.OSHDBBoundingBox; 5 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 6 | import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; 7 | import org.heigit.ohsome.oshdb.api.db.OSHDBH2; 8 | import org.heigit.ohsome.oshdb.util.geometry.Geo; 9 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshotView; 10 | import org.heigit.ohsome.oshdb.util.time.OSHDBTimestamps.Interval; 11 | 12 | public class OSHDBApiTutorial { 13 | public static void main(String[] args) throws Exception { 14 | OSHDBDatabase oshdb = new OSHDBH2("path/to/extract.oshdb"); 15 | // calculates the total area of all osm ways tagged as "building" that are not larger than 16 | // 1000 m² for the timestamp 2019-01-01 17 | Number result = OSMEntitySnapshotView.on(oshdb) 18 | .areaOfInterest(OSHDBBoundingBox.bboxWgs84Coordinates(8.6634,49.3965,8.7245,49.4268)) 19 | .timestamps("2021-01-01") 20 | .filter("type:way and building=*") 21 | .map(snapshot -> Geo.areaOf(snapshot.getGeometry())) 22 | .filter(area -> area < 1000.0) 23 | .sum(); 24 | System.out.println(result); 25 | 26 | // calculates the total area of all osm ways tagged as "building" that are not larger than 27 | // 1000 m² for yearly timestamps between 2012-01-01 and 2019-01-01 28 | SortedMap result2 = OSMEntitySnapshotView.on(oshdb) 29 | .areaOfInterest(OSHDBBoundingBox.bboxWgs84Coordinates(8.6634,49.3965,8.7245,49.4268)) 30 | .timestamps("2012-01-01", "2021-01-01", Interval.YEARLY) 31 | .filter("type:way and building=*") 32 | .map(snapshot -> Geo.areaOf(snapshot.getGeometry())) 33 | .filter(area -> area < 1000.0) 34 | .aggregateByTimestamp() 35 | .sum(); 36 | System.out.println(result2); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /documentation/first-steps/example-pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.example.oshdb-api-tutorial 4 | oshdb-first-steps 5 | 0.0.1-SNAPSHOT 6 | 7 | 8 | 9 | org.heigit.ohsome 10 | oshdb-api 11 | 1.2.3 12 | 13 | 14 | 15 | 16 | 11 17 | 11 18 | 19 | 20 | -------------------------------------------------------------------------------- /documentation/manual/README.md: -------------------------------------------------------------------------------- 1 | OSHDB User Manual 2 | ================= 3 | 4 | Background 5 | ---------- 6 | 7 | The OSHDB was initiated as a project to make it easier for researchers to investigate data quality aspects of the OpenStreetMap (OSM) data though analysing its history. 8 | 9 | OSM is a rich resource of freely available geographic information. Analysing historical OSM data provides great insight into the evolution of the map, and supports assessing OSM data quality intrinsically, i.e., without the need for external reference data sets. However, the possibilities for analysing the OSM history data on a global scale are limited because of the large amount of resources needed and the lack of easy to use analytics software. That is, OSM’s huge information treasure for researchers, journalists, community members and other interested people is kept hidden. 10 | 11 | The central idea of the OSHDB is to make this data treasure available for a larger public and to develop further analysis functionality, e.g. for intrinsic data quality analytics. 12 | 13 | Contents 14 | -------- 15 | 16 | * [OSHDB API Manual](api.md)
17 | Shows the different features of the OSHDB API and how they can be used to efficiently query the OSM history data. 18 | * [Data Views](views.md) 19 | * [OSM Feature Geometries](geometries.md) 20 | * [Filtering of OSM data](filters.md) 21 | * [Map and Reduce](map-reduce.md) 22 | * [Data Aggregation](aggregation.md) 23 | * [Database Backends](database-backends.md)
24 | Lists the available database backends and how they are used. 25 | * [Data Model Manual](data-model.md)
26 | Explains the design of the OSHDB data model. 27 | * [Installation](installation.md)
28 | A guide for how to install the OSHDB from sources. 29 | * [Helpers](helpers)
30 | Documentation for helpers that reduce complexity in connection setup for OSHDB. 31 | 32 | See also 33 | -------- 34 | 35 | * [first steps tutorial](../first-steps) 36 | * [examples repository](https://gitlab.gistools.geog.uni-heidelberg.de/giscience/big-data/ohsome/oshdb-examples) -------------------------------------------------------------------------------- /documentation/manual/api.md: -------------------------------------------------------------------------------- 1 | OSHDB Application Programming Interface 2 | ======================================= 3 | 4 | The OSHDB API provides a library that can be used to write custom analysis queries of OSM history data. It is based on the [MapReduce](https://en.wikipedia.org/wiki/MapReduce) programming model, which is also offered by the [Stream](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html) class in Java. 5 | 6 | The [first steps tutorial](../first-steps) explains the main components of the OSHDB API and how they can be used to perform a simple analysis query. On the following sub-pages, the different parts of the API are described in more detail. 7 | 8 | * [Data Views](views.md) 9 | * [OSM Feature Geometries](geometries.md) 10 | * [Filtering of OSM data](filters.md) 11 | * [Map and Reduce](map-reduce.md) 12 | * [Data Aggregation](aggregation.md) 13 | 14 | -------------------------------------------------------------------------------- /documentation/manual/helpers/OSHDBDriver.md: -------------------------------------------------------------------------------- 1 | # OSHDBDriver 2 | ## Installation 3 | 4 | Replace your OSHDB dependency with the following: 5 | 6 | ```xml 7 | 8 | org.heigit.ohsome 9 | oshdb-database-driver 10 | 1.2.3 11 | 12 | ``` 13 | 14 | ## Usage 15 | 16 | To connect to the OSHDB using the OSHDBDriver you first have to define the configuration like: 17 | 18 | ```java 19 | Properties props = new Properties(); 20 | // For H2: 21 | props.setProperty("oshdb", "h2:PATH_TO_H2"); 22 | // Or for Ignite: 23 | props.setProperty("oshdb","ignite:PATH_TO_CFG"); 24 | props.setProperty("keytables","jdbc:postgresql://localhost/keytables-${prefix}?user=ohsome&password=secret"); 25 | ``` 26 | 27 | Alternatively you can read-in a `….properties` file with this information e.g. like so: 28 | 29 | ```java 30 | Properties props = new Properties(); 31 | try(Reader reader = new FileReader("oshdb.properties")){ 32 | props.load(reader); 33 | } 34 | ``` 35 | 36 | Then connect to OSHDB using the driver like: 37 | 38 | ```java 39 | OSHDBDriver.connect(props, (OSHDBConnection oshdb) -> { 40 | // your oshdb code goes here 41 | return 0; 42 | }); 43 | ``` 44 | 45 | ## Example 46 | 47 | ```java 48 | package mypackage; 49 | 50 | import java.util.Properties; 51 | import org.heigit.ohsome.oshdb.OSHDBBoundingBox; 52 | import org.heigit.ohsome.oshdb.helpers.db.OSHDBDriver; 53 | 54 | public class OSHDBDriverExample { 55 | 56 | public static void main(String[] args) throws Exception { 57 | Properties props = new Properties(); 58 | // For H2: 59 | props.setProperty("oshdb", "h2:PATH_TO_H2"); 60 | // Or for Ignite: 61 | props.setProperty("oshdb", "ignite:PATH_TO_CFG"); 62 | props.setProperty("keytables", "jdbc:postgresql://localhost/keytables-global?user=ohsome&password=secret"); 63 | 64 | OSHDBDriver.connect(props, oshdb -> { 65 | OSHDBBoundingBox bbox = OSHDBBoundingBox.bboxWgs84Coordinates(8.651133, 49.387611, 8.6561, 49.390513); 66 | 67 | Integer result = oshdb.getSnapshotView() 68 | .areaOfInterest(bbox) 69 | .filter("type:node") 70 | .timestamps("2018-05-01") 71 | .count(); 72 | 73 | System.out.println(result); 74 | return 0; 75 | }); 76 | } 77 | 78 | } 79 | ``` 80 | -------------------------------------------------------------------------------- /documentation/manual/helpers/README.md: -------------------------------------------------------------------------------- 1 | # OSHDB Helpers 2 | 3 | Simple OSHDB connection helpers that automatically open an Ignite or H2 connection, depending on the input. 4 | 5 | Two functionalities are available: 6 | 7 | - The [OSHDBApplication](OSHDBApplication.md) (recommended usage) provides a full [Spring boot](https://spring.io/projects/spring-boot)-like application including a CLI. "Just add" your OSHDB functionality to create a usage-ready application. 8 | - The [OSHDBDriver](OSHDBDriver.md) provides a static method that exhibits an OSHDB connection to a respective `Consumer`. It leaves you with all setup work for your application and will only handle the OSHDB connection part. 9 | 10 | 11 | ## Configuration 12 | 13 | Both functionalities will need the following configuration options. The details how to specify them will be discussed in the respective subsection. 14 | 15 | - `oshdb` 16 | - for a connection to an H2-file this is the absolute path to the H2-file prefixed by `h2:` like `h2:/path/to/file.oshdb.mv.db` 17 | - for a connection to an Ignite cluster this is the absolute path to an ignite-config.xml file prefixed by `ignite:` like `ignite:/path/to/file.xml` 18 | - `prefix` (optional) 19 | - a string prefixed to database objects to allow multiple data versions to co-exist in the backend. It is (only) necessary if you want to access a legacy OSHDB ignite cluster. You will be notified about this once you get access to an H2-file or the Ignite cluster. 20 | - `keytables` (optional for H2) 21 | - a JDBC string defining a connection to the [keytables](../data-model.md#keytables) linked to the targeted OSHDB. H2 files normally self contain the keytables where the tools are able to find them. 22 | - `multithreading` (optional for H2) 23 | - a boolean parameter for jdbc based connections (i.e. H2) if multithreading should be enabled during processing. 24 | 25 | Note that any `${some-property}` (e.g. `${prefix}`) within these property strings will be automatically replaced by the respective property value. So you can safely include these placeholders into your keytables URL (or any other property), if needed. 26 | -------------------------------------------------------------------------------- /documentation/manual/installation.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | ## Configuring Java Version 5 | 6 | Compiling software that includes the OSHDB currently requires Java 17 or newer. Because maven projects use Java 1.5 by default, it is necessary to either configure your IDE accordingly or add the following compiler version to the properties section of your pom.xml file: 7 | 8 | ```xml 9 | 10 | 17 11 | 17 12 | 13 | ``` 14 | 15 | ## Option 1: Adding the OSHDB as a maven dependency 16 | 17 | Simply add the OSHDB as a dependency to your `pom.xml` file. For most use cases this would be the [`oshdb-api`](api.md): 18 | 19 | ```xml 20 | 21 | 22 | org.heigit.ohsome 23 | oshdb-api 24 | 1.2.3 25 | 26 | 27 | ``` 28 | 29 | Advanced users may also be interested in other packages like the `oshdb` package for raw data access. 30 | 31 | ## Option 2: Building from Source 32 | 33 | Alternatively, you may build OSHDB from source using maven. This option is more involved and requires more knowledge of building software with maven. 34 | 35 | The basic steps are to clone this repository: 36 | 37 | ``` 38 | git clone https://github.com/GIScience/oshdb.git 39 | ``` 40 | 41 | and to build it with: 42 | 43 | ``` 44 | cd ./oshdb 45 | mvn clean install 46 | ``` 47 | 48 | After that, the binaries will be available in the local maven directory. A new OSHDB-Project can be set up directly by defining the dependency as explained in the previous section [option 1](#option-1-adding-the-oshdb-as-a-maven-dependency), step 2. 49 | -------------------------------------------------------------------------------- /oshdb-api-ignite/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBIgniteAffinityCallTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import static org.heigit.ohsome.oshdb.api.db.OSHDBIgnite.ComputeMode.AFFINITY_CALL; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import java.util.Set; 7 | import java.util.stream.Collectors; 8 | import org.heigit.ohsome.oshdb.util.time.OSHDBTimestamps; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * {@inheritDoc} 13 | * 14 | *

Runs the tests using the "affinity call" Ignite backend.

15 | */ 16 | class MapReduceOSHDBIgniteAffinityCallTest extends MapReduceOSHDBIgniteTest { 17 | /** 18 | * Creates the test runner using the ignite affinitycall backend. 19 | * 20 | * @throws Exception if something goes wrong 21 | */ 22 | MapReduceOSHDBIgniteAffinityCallTest() throws Exception { 23 | super(oshdb -> oshdb.computeMode(AFFINITY_CALL)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oshdb-api-ignite/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBIgniteLocalPeekTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import static org.heigit.ohsome.oshdb.api.db.OSHDBIgnite.ComputeMode.LOCAL_PEEK; 4 | 5 | /** 6 | * {@inheritDoc} 7 | * 8 | *

Runs the tests using the "local peek" Ignite backend.

9 | */ 10 | class MapReduceOSHDBIgniteLocalPeekTest extends MapReduceOSHDBIgniteTest { 11 | /** 12 | * Creates the test runner using the ignite localpeak backend. 13 | * 14 | * @throws Exception if something goes wrong 15 | */ 16 | MapReduceOSHDBIgniteLocalPeekTest() throws Exception { 17 | super(oshdb -> oshdb.computeMode(LOCAL_PEEK)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oshdb-api-ignite/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBIgniteMissingCacheTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertThrows; 4 | 5 | import org.heigit.ohsome.oshdb.util.exceptions.OSHDBTableNotFoundException; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * Tests for proper error messages is caches are not pnt on ignite. 10 | */ 11 | class MapReduceOSHDBIgniteMissingCacheTest extends MapReduceOSHDBIgniteTest { 12 | /** 13 | * Creates the test runner using an Ignite backend. 14 | * 15 | * @throws Exception if something goes wrong 16 | */ 17 | MapReduceOSHDBIgniteMissingCacheTest() throws Exception { 18 | super("", KEYTABLES, oshdb -> {}); 19 | } 20 | 21 | @Override 22 | @Test() 23 | void testOSMContributionView() { 24 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMContributionView); 25 | } 26 | 27 | @Override 28 | @Test() 29 | void testOSMEntitySnapshotView() { 30 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMEntitySnapshotView); 31 | } 32 | 33 | @Override 34 | @Test() 35 | void testOSMContributionViewStream() { 36 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMContributionViewStream); 37 | } 38 | 39 | @Override 40 | @Test() 41 | void testOSMEntitySnapshotViewStream() { 42 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMEntitySnapshotViewStream); 43 | } 44 | 45 | @Override 46 | @Test() 47 | void testTimeoutMapReduce() { 48 | assertThrows(OSHDBTableNotFoundException.class, this::timeoutMapReduce); 49 | } 50 | 51 | @Override 52 | @Test() 53 | void testTimeoutStream() { 54 | assertThrows(OSHDBTableNotFoundException.class, this::timeoutStream); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /oshdb-api-ignite/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBIgniteScanQueryTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import static org.heigit.ohsome.oshdb.api.db.OSHDBIgnite.ComputeMode.SCAN_QUERY; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * {@inheritDoc} 10 | * 11 | *

Runs the tests using the "scan query" Ignite backend.

12 | */ 13 | class MapReduceOSHDBIgniteScanQueryTest extends MapReduceOSHDBIgniteTest { 14 | /** 15 | * Creates the test runner using the ignite scanquery backend. 16 | * 17 | * @throws Exception if something goes wrong 18 | */ 19 | MapReduceOSHDBIgniteScanQueryTest() throws Exception { 20 | super(oshdb -> oshdb.computeMode(SCAN_QUERY)); 21 | } 22 | 23 | @Override 24 | @Test 25 | void testTimeoutStream() { 26 | // ignore this test -> scanquery backend currently doesn't support timeouts for stream() 27 | assertTrue(true); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/db/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * API-Implementations of the informative OSHDB-Base-Class. 3 | */ 4 | package org.heigit.ohsome.oshdb.api.db; 5 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/generic/NumberUtils.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.generic; 2 | 3 | import java.io.Serializable; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | /** 7 | * A utility class for common numeric operations on arbitrary number types. 8 | */ 9 | public class NumberUtils implements Serializable { 10 | private NumberUtils() {} 11 | 12 | /** 13 | * Add two numeric values and return the sum in the smallest common type. 14 | * 15 | *

Supports Integer, Float and Double values

16 | * 17 | * @param x a numeric value 18 | * @param y a numeric value 19 | * @param a numeric data type 20 | * @return the sum of x and y 21 | */ 22 | @SuppressWarnings("unchecked") // manual type checking is performed in method body 23 | @NotNull 24 | public static T add(T x, T y) { 25 | if (x instanceof Integer && y instanceof Integer) { 26 | return (T) (Integer) (x.intValue() + y.intValue()); 27 | } else if (x instanceof Float && (y instanceof Float || y instanceof Integer)) { 28 | return (T) (Float) (x.floatValue() + y.floatValue()); 29 | } else { 30 | return (T) (Double) (x.doubleValue() + y.doubleValue()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/generic/WeightedValue.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.generic; 2 | 3 | /** 4 | * Immutable object that stores a numeric value and an associated weight. 5 | * Used to specify data input for the calculation of weighted averages. 6 | */ 7 | public class WeightedValue { 8 | private final Number value; 9 | private final double weight; 10 | 11 | public WeightedValue(Number value, double weight) { 12 | this.value = value; 13 | this.weight = weight; 14 | } 15 | 16 | /** 17 | * Returns the stored numeric value. 18 | * 19 | * @return the stored numeric value 20 | */ 21 | public Number getValue() { 22 | return value; 23 | } 24 | 25 | /** 26 | * Returns the stored weight. 27 | * 28 | * @return the value's associated weight 29 | */ 30 | public double getWeight() { 31 | return weight; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/generic/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Generics of the JAVA-API. 3 | */ 4 | package org.heigit.ohsome.oshdb.api.generic; 5 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/FilterFunction.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import java.util.Collections; 4 | import org.heigit.ohsome.oshdb.util.function.SerializablePredicate; 5 | 6 | /** 7 | * A special map function that represents a filter. 8 | * 9 | *

Note that this class is using raw types on purpose because MapReducer's "map functions" 10 | * are designed to input and output arbitrary data types. The necessary type checks are performed 11 | * at at runtime in the respective setters.

12 | */ 13 | @SuppressWarnings({"rawtypes", "unchecked"}) // see javadoc above 14 | class FilterFunction extends MapFunction { 15 | private final SerializablePredicate filter; 16 | 17 | FilterFunction(SerializablePredicate filter) { 18 | super((x, ignored) -> filter.test(x) 19 | ? Collections.singletonList(x) 20 | : Collections.emptyList(), 21 | true); 22 | this.filter = filter; 23 | } 24 | 25 | public boolean test(Object root) { 26 | return this.filter.test(root); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/MapAggregatable.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import java.io.Serializable; 4 | import org.heigit.ohsome.oshdb.util.function.SerializableFunction; 5 | 6 | /** 7 | * Interface for MapReducers or MapAggregators that can be aggregated by an arbitrary index. 8 | * 9 | * @param the resulting class of the aggregateBy operation 10 | * @param the data type the index function is supplied with 11 | */ 12 | interface MapAggregatable { 13 | /** 14 | * Sets a custom aggregation function that is used to (further) group output results into. 15 | * 16 | * @param indexer a function that will be called for each input element and returns a value that 17 | * will be used to group the results by 18 | * @param data type of the values used to aggregate the output. has to be a comparable type 19 | * @return a MapAggregator object with the equivalent state (settings, filters, map function, 20 | * etc.) of the current MapReducer object 21 | */ 22 | & Serializable> M aggregateBy(SerializableFunction indexer); 23 | } 24 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/MapFunction.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import org.heigit.ohsome.oshdb.util.function.SerializableBiFunction; 4 | 5 | /** 6 | * A function that has a flag: isFlatMapper. 7 | * 8 | *

Note that this class is using raw types on purpose because MapReducer's "map functions" 9 | * are designed to input and output arbitrary data types. The necessary type checks are performed 10 | * at at runtime in the respective setters.

11 | */ 12 | @SuppressWarnings({"rawtypes", "unchecked"}) // see javadoc above 13 | class MapFunction implements SerializableBiFunction { 14 | private final SerializableBiFunction mapper; 15 | private final boolean isFlatMapper; 16 | 17 | MapFunction(SerializableBiFunction mapper, boolean isFlatMapper) { 18 | this.mapper = mapper; 19 | this.isFlatMapper = isFlatMapper; 20 | } 21 | 22 | boolean isFlatMapper() { 23 | return this.isFlatMapper; 24 | } 25 | 26 | @Override 27 | public Object apply(Object o, Object root) { 28 | return this.mapper.apply(o, root); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/Mappable.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import org.heigit.ohsome.oshdb.util.function.SerializableFunction; 4 | import org.heigit.ohsome.oshdb.util.function.SerializablePredicate; 5 | import org.jetbrains.annotations.Contract; 6 | 7 | /** 8 | * Interface for common "monadic" methods in {@link MapReducer} and {@link MapAggregator}. 9 | * 10 | * @param the (arbitrary) data type which is used as the input of the interface's methods. 11 | */ 12 | public interface Mappable { 13 | /** 14 | * Set an arbitrary `map` transformation function. 15 | * 16 | * @param mapper function that will be applied to each data entry (osm entity 17 | * snapshot or contribution) 18 | * @param an arbitrary data type which is the return type of the 19 | * transformation `map` function 20 | * @return a modified copy of the current "Mappable" object operating on the 21 | * transformed type (<R>) 22 | */ 23 | @Contract(pure = true) 24 | Mappable map(SerializableFunction mapper); 25 | 26 | /** 27 | * Set an arbitrary `flatMap` transformation function, which returns list with 28 | * an arbitrary number of results per input data entry. The results of this 29 | * function will be "flattened", meaning that they can be for example 30 | * transformed again by setting additional `map` functions. 31 | * 32 | * @param flatMapper function that will be applied to each data entry (osm 33 | * entity snapshot or contribution) and returns a list of results 34 | * @param an arbitrary data type which is the return type of the 35 | * transformation `map` function 36 | * @return a modified copy of the current "Mappable" object operating on the 37 | * transformed type (<R>) 38 | */ 39 | @Contract(pure = true) 40 | Mappable flatMap(SerializableFunction> flatMapper); 41 | 42 | /** 43 | * Adds a custom arbitrary filter that gets executed in the current 44 | * transformation chain. 45 | * 46 | * @param f the filter function that determines if the respective data should 47 | * be passed on (when f returns true) or discarded (when f returns false) 48 | * @return a modified copy of this "Mappable" (can be used to chain multiple 49 | * commands together) 50 | */ 51 | @Contract(pure = true) 52 | Mappable filter(SerializablePredicate f); 53 | } 54 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/MutableWeightedDouble.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import java.io.Serializable; 4 | import org.heigit.ohsome.oshdb.api.generic.WeightedValue; 5 | 6 | /** 7 | * Mutable version of WeightedValue type. 8 | * 9 | *

For internal use to do faster aggregation during reduce operations.

10 | */ 11 | class MutableWeightedDouble implements Serializable { 12 | double num; 13 | double weight; 14 | 15 | private MutableWeightedDouble(double num, double weight) { 16 | this.num = num; 17 | this.weight = weight; 18 | } 19 | 20 | static MutableWeightedDouble identitySupplier() { 21 | return new MutableWeightedDouble(0.0, 0.0); 22 | } 23 | 24 | static MutableWeightedDouble accumulator( 25 | MutableWeightedDouble acc, 26 | WeightedValue cur) { 27 | acc.num = acc.num + cur.getValue().doubleValue() * cur.getWeight(); 28 | acc.weight += cur.getWeight(); 29 | return acc; 30 | } 31 | 32 | static MutableWeightedDouble combiner( 33 | MutableWeightedDouble a, 34 | MutableWeightedDouble b) { 35 | return new MutableWeightedDouble(a.num + b.num, a.weight + b.weight); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/OSMContributionView.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; 4 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 5 | 6 | /** 7 | * Returns all modifications to OSM elements within a given time period. 8 | */ 9 | public class OSMContributionView { 10 | private OSMContributionView() {} 11 | 12 | public static MapReducer on(OSHDBDatabase oshdb) { 13 | return oshdb.createMapReducer(OSMContribution.class); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/OSMEntitySnapshotView.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; 4 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 5 | 6 | /** 7 | * Returns the state of OSM elements at specific given points in time. 8 | */ 9 | public class OSMEntitySnapshotView { 10 | private OSMEntitySnapshotView() {} 11 | 12 | public static MapReducer on(OSHDBDatabase oshdb) { 13 | return oshdb.createMapReducer(OSMEntitySnapshot.class); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/TdigestReducer.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.mapreducer; 2 | 3 | import com.tdunning.math.stats.MergingDigest; 4 | import com.tdunning.math.stats.TDigest; 5 | import java.util.Arrays; 6 | 7 | class TdigestReducer { 8 | private TdigestReducer() {} 9 | 10 | /** 11 | * A COMPRESSION parameter of 1000 should provide relatively precise results, while not being 12 | * too demanding on memory usage. See page 20 in the paper [1]: 13 | * 14 | * 15 | * > Compression parameter (1/δ) was […] 1000 in order to reliably achieve 0.1% accuracy 16 | * 17 | * 18 | *
  • 19 | * [1] https://raw.githubusercontent.com/tdunning/t-digest/master/docs/t-digest-paper/histo.pdf 20 | *
21 | */ 22 | private static final int COMPRESSION = 1000; 23 | 24 | static TDigest identitySupplier() { 25 | return new MergingDigest(COMPRESSION); 26 | } 27 | 28 | static TDigest accumulator(TDigest acc, R cur) { 29 | acc.add(cur.doubleValue(), 1); 30 | return acc; 31 | } 32 | 33 | static TDigest combiner(TDigest a, TDigest b) { 34 | if (a.size() == 0) { 35 | return b; 36 | } else if (b.size() == 0) { 37 | return a; 38 | } 39 | MergingDigest r = new MergingDigest(COMPRESSION); 40 | r.add(Arrays.asList(a, b)); 41 | return r; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/backend/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Specialised MapReducers. 3 | */ 4 | package org.heigit.ohsome.oshdb.api.mapreducer.backend; 5 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/mapreducer/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Central front-end of the API. OSMContributionViews' and OSMEntitySnapshotViews' produce 3 | * MapReducer that can then be transferred to MapAggregators' wich in turn deliver the results. 4 | */ 5 | package org.heigit.ohsome.oshdb.api.mapreducer; 6 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/object/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * API-Objects used within map, aggregate and reduce steps. 3 | */ 4 | package org.heigit.ohsome.oshdb.api.object; 5 | -------------------------------------------------------------------------------- /oshdb-api/src/main/java/org/heigit/ohsome/oshdb/api/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java-api for optimised data access. 3 | */ 4 | package org.heigit.ohsome.oshdb.api; 5 | -------------------------------------------------------------------------------- /oshdb-api/src/test/java/org/heigit/ohsome/oshdb/api/tests/FlatMapReduceGroupedByEntityOSHDBH2MultithreadTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import org.heigit.ohsome.oshdb.api.db.OSHDBH2; 4 | 5 | /** 6 | * {@inheritDoc} 7 | * 8 | *

Runs the tests using the multithreaded H2 backend.

9 | */ 10 | class FlatMapReduceGroupedByEntityOSHDBH2MultithreadTest extends 11 | FlatMapReduceGroupedByEntityTest { 12 | /** 13 | * Creates the test runner using the multithreaded H2 backend. 14 | * 15 | * @throws Exception if something goes wrong 16 | */ 17 | FlatMapReduceGroupedByEntityOSHDBH2MultithreadTest() throws Exception { 18 | super( 19 | (new OSHDBH2("../data/test-data")).multithreading(true) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /oshdb-api/src/test/java/org/heigit/ohsome/oshdb/api/tests/FlatMapReduceGroupedByEntityOSHDBH2SinglethreadTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import org.heigit.ohsome.oshdb.api.db.OSHDBH2; 4 | 5 | /** 6 | * {@inheritDoc} 7 | * 8 | *

Runs the tests using the singlethreaded H2 backend.

9 | */ 10 | class FlatMapReduceGroupedByEntityOSHDBH2SinglethreadTest extends 11 | FlatMapReduceGroupedByEntityTest { 12 | /** 13 | * Creates the test runner using the singlethreaded "dummy" H2 backend. 14 | * 15 | * @throws Exception if something goes wrong 16 | */ 17 | FlatMapReduceGroupedByEntityOSHDBH2SinglethreadTest() throws Exception { 18 | super( 19 | (new OSHDBH2("../data/test-data")).multithreading(false) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /oshdb-api/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBH2MultithreadTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import org.heigit.ohsome.oshdb.api.db.OSHDBH2; 4 | 5 | /** 6 | * {@inheritDoc} 7 | * 8 | *

Runs the tests using the multithreaded H2 backend.

9 | */ 10 | class MapReduceOSHDBH2MultithreadTest extends MapReduceTest { 11 | /** 12 | * Creates the test runner using the multithreaded H2 backend. 13 | * 14 | * @throws Exception if something goes wrong 15 | */ 16 | MapReduceOSHDBH2MultithreadTest() throws Exception { 17 | super( 18 | (new OSHDBH2("../data/test-data")).multithreading(true) 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oshdb-api/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBH2SinglethreadTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import org.heigit.ohsome.oshdb.api.db.OSHDBH2; 4 | 5 | /** 6 | * {@inheritDoc} 7 | * 8 | *

Runs the tests using the singlethreaded H2 backend.

9 | */ 10 | class MapReduceOSHDBH2SinglethreadTest extends MapReduceTest { 11 | /** 12 | * Creates the test runner using the singlethreaded "dummy" H2 backend. 13 | * 14 | * @throws Exception if something goes wrong 15 | */ 16 | MapReduceOSHDBH2SinglethreadTest() throws Exception { 17 | super( 18 | (new OSHDBH2("../data/test-data")).multithreading(false) 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oshdb-api/src/test/java/org/heigit/ohsome/oshdb/api/tests/MapReduceOSHDBJdbcMissingTablesTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.api.tests; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertThrows; 4 | 5 | import org.heigit.ohsome.oshdb.api.db.OSHDBH2; 6 | import org.heigit.ohsome.oshdb.util.exceptions.OSHDBTableNotFoundException; 7 | import org.junit.jupiter.api.Test; 8 | 9 | /** 10 | * Tests for proper error messages if tables are not present on H2. 11 | */ 12 | class MapReduceOSHDBJdbcMissingTablesTest extends MapReduceTest { 13 | /** 14 | * Creates the test runner using an H2 backend. 15 | * 16 | * @throws Exception if something goes wrong 17 | */ 18 | MapReduceOSHDBJdbcMissingTablesTest() throws Exception { 19 | super(new OSHDBH2("../data/test-data-without-keytables")); 20 | } 21 | 22 | @Override 23 | @Test() 24 | void testOSMContributionView() { 25 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMContributionView); 26 | } 27 | 28 | @Override 29 | @Test() 30 | void testOSMEntitySnapshotView() { 31 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMEntitySnapshotView); 32 | } 33 | 34 | @Override 35 | @Test() 36 | void testOSMContributionViewStream() { 37 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMContributionViewStream); 38 | } 39 | 40 | @Override 41 | @Test() 42 | void testOSMEntitySnapshotViewStream() { 43 | assertThrows(OSHDBTableNotFoundException.class, super::testOSMEntitySnapshotViewStream); 44 | } 45 | 46 | @Override 47 | @Test() 48 | void testTimeoutMapReduce() { 49 | assertThrows(OSHDBTableNotFoundException.class, this::timeoutMapReduce); 50 | } 51 | 52 | @Override 53 | @Test() 54 | void testTimeoutStream() { 55 | assertThrows(OSHDBTableNotFoundException.class, this::timeoutStream); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /oshdb-api/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=WARN, stderr 3 | 4 | # Redirect log messages to console 5 | log4j.appender.stderr=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stderr.Target=System.err 7 | log4j.appender.stderr.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stderr.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 9 | -------------------------------------------------------------------------------- /oshdb-filter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.heigit.ohsome 7 | oshdb-parent 8 | 1.3.0-SNAPSHOT 9 | 10 | 11 | oshdb-filter 12 | OSHDB filter 13 | A flexible filtering library for OSM entities. Formerly known as "ohsome-filter". 14 | 15 | 16 | 3.1 17 | 18 | 19 | 20 | 21 | 22 | ${project.groupId} 23 | oshdb 24 | ${project.version} 25 | 26 | 27 | 28 | ${project.groupId} 29 | oshdb-util 30 | ${project.version} 31 | 32 | 33 | 34 | 35 | org.jparsec 36 | jparsec 37 | ${jparsec.version} 38 | 39 | 40 | 41 | 42 | org.jetbrains 43 | annotations 44 | ${jetbrainsannotations.version} 45 | 46 | 47 | 48 | 49 | com.h2database 50 | h2 51 | ${h2.version} 52 | test 53 | 54 | 55 | 56 | 57 | org.slf4j 58 | slf4j-log4j12 59 | test 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/AndOperator.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.function.Supplier; 4 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 6 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 7 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 8 | import org.locationtech.jts.geom.Geometry; 9 | 10 | /** 11 | * A boolean "and" of two sub-expressions. 12 | */ 13 | public class AndOperator extends BinaryOperator { 14 | AndOperator(FilterExpression op1, FilterExpression op2) { 15 | super(op1, op2); 16 | } 17 | 18 | @Override 19 | public boolean applyOSM(OSMEntity entity) { 20 | return op1.applyOSM(entity) && op2.applyOSM(entity); 21 | } 22 | 23 | @Override 24 | public boolean applyOSH(OSHEntity entity) { 25 | return op1.applyOSH(entity) && op2.applyOSH(entity); 26 | } 27 | 28 | @Override 29 | public boolean applyOSMGeometry(OSMEntity entity, Supplier geometrySupplier) { 30 | return op1.applyOSMGeometry(entity, geometrySupplier) 31 | && op2.applyOSMGeometry(entity, geometrySupplier); 32 | } 33 | 34 | @Override 35 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot snapshot) { 36 | return op1.applyOSMEntitySnapshot(snapshot) && op2.applyOSMEntitySnapshot(snapshot); 37 | } 38 | 39 | @Override 40 | public boolean applyOSMContribution(OSMContribution contribution) { 41 | return op1.applyOSMContribution(contribution) && op2.applyOSMContribution(contribution); 42 | } 43 | 44 | @Override 45 | public FilterExpression negate() { 46 | return new OrOperator(op1.negate(), op2.negate()); 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | String op1String = op1 instanceof OrOperator ? "(" + op1.toString() + ")" : op1.toString(); 52 | String op2String = op2 instanceof OrOperator ? "(" + op2.toString() + ")" : op2.toString(); 53 | return op1String + " and " + op2String; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/BinaryOperator.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.jetbrains.annotations.Contract; 5 | 6 | /** 7 | * A boolean operator with two sub-expressions. 8 | */ 9 | public abstract class BinaryOperator implements FilterExpression { 10 | enum Type { 11 | AND, 12 | OR 13 | } 14 | 15 | final FilterExpression op1; 16 | final FilterExpression op2; 17 | 18 | BinaryOperator(FilterExpression op1, FilterExpression op2) { 19 | this.op1 = op1; 20 | this.op2 = op2; 21 | } 22 | 23 | /** 24 | * Returns the first (left) operand of this binary expression. 25 | * 26 | * @return the left operand of a binary expression. 27 | */ 28 | public FilterExpression getLeftOperand() { 29 | return op1; 30 | } 31 | 32 | /** 33 | * Returns the right operand of this binary expression. 34 | * 35 | * @return the right operand of a binary expression. 36 | */ 37 | public FilterExpression getRightOperand() { 38 | return op2; 39 | } 40 | 41 | /** 42 | * Returns a new binary operator object fulfilling the given "operator" and two operands 43 | * (a "left" and a "right" sub-expressions). 44 | * 45 | * @param leftOperand The left operand. 46 | * @param operator The operator, such as "and" or "or". 47 | * @param rightOperand The right operand. 48 | * @return A new binary operator object fulfilling the given "operator" on two sub-expressions. 49 | */ 50 | @Contract(pure = true) 51 | public static BinaryOperator fromOperator( 52 | FilterExpression leftOperand, 53 | @Nonnull Type operator, 54 | FilterExpression rightOperand 55 | ) { 56 | switch (operator) { 57 | case AND: 58 | return new AndOperator(leftOperand, rightOperand); 59 | case OR: 60 | return new OrOperator(leftOperand, rightOperand); 61 | default: 62 | assert false : "invalid or null binary operator encountered"; 63 | throw new IllegalStateException("invalid or null binary operator encountered"); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ChangesetIdFilterEquals.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 5 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 6 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 7 | import org.jetbrains.annotations.Contract; 8 | 9 | /** 10 | * A filter which selects OSM contributions by a changeset id. 11 | */ 12 | public class ChangesetIdFilterEquals extends NegatableFilter { 13 | final long changesetId; 14 | 15 | ChangesetIdFilterEquals(long changesetId) { 16 | super(new FilterInternal() { 17 | @Override 18 | public boolean applyOSH(OSHEntity entity) { 19 | return applyToOSHEntityRecursively(entity, v -> v.getChangesetId() == changesetId); 20 | } 21 | 22 | @Override 23 | public boolean applyOSM(OSMEntity entity) { 24 | return true; 25 | } 26 | 27 | @Override 28 | public boolean applyOSMContribution(OSMContribution contribution) { 29 | return contribution.getChangesetId() == changesetId; 30 | } 31 | 32 | @Override 33 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot ignored) { 34 | throw new IllegalStateException("changeset filter is not applicable to entity snapshots"); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "changeset:" + changesetId; 40 | } 41 | }); 42 | this.changesetId = changesetId; 43 | } 44 | 45 | @Contract(pure = true) 46 | public long getChangesetId() { 47 | return this.changesetId; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ChangesetIdFilterEqualsAnyOf.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | import java.util.stream.Collectors; 7 | import javax.annotation.Nonnull; 8 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 9 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 10 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 11 | import org.jetbrains.annotations.Contract; 12 | 13 | /** 14 | * A filter which selects OSM contributions by matching to a list of changeset ids. 15 | */ 16 | public class ChangesetIdFilterEqualsAnyOf extends NegatableFilter { 17 | private final Collection changesetIdList; 18 | 19 | ChangesetIdFilterEqualsAnyOf(@Nonnull Collection changesetIdList) { 20 | super(new FilterInternal() { 21 | private final Set changesetIds = new HashSet<>(changesetIdList); 22 | 23 | @Override 24 | public boolean applyOSH(OSHEntity entity) { 25 | return applyToOSHEntityRecursively(entity, v -> changesetIds.contains(v.getChangesetId())); 26 | } 27 | 28 | @Override 29 | public boolean applyOSMContribution(OSMContribution contribution) { 30 | return changesetIds.contains(contribution.getChangesetId()); 31 | } 32 | 33 | @Override 34 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot ignored) { 35 | throw new IllegalStateException("changeset filter is not applicable to entity snapshots"); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "changeset:in(" + changesetIdList.stream().map(String::valueOf) 41 | .collect(Collectors.joining(",")) + ")"; 42 | } 43 | }); 44 | this.changesetIdList = changesetIdList; 45 | } 46 | 47 | @Contract(pure = true) 48 | public Collection getChangesetIdList() { 49 | return this.changesetIdList; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ChangesetIdFilterRange.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 5 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 6 | 7 | /** 8 | * A filter which selects OSM contributions by matching to a range of changeset ids. 9 | */ 10 | public class ChangesetIdFilterRange extends NegatableFilter { 11 | ChangesetIdFilterRange(IdRange changesetIdRange) { 12 | super(new FilterInternal() { 13 | @Override 14 | public boolean applyOSH(OSHEntity entity) { 15 | return applyToOSHEntityRecursively(entity, v -> changesetIdRange.test(v.getChangesetId())); 16 | } 17 | 18 | @Override 19 | public boolean applyOSMContribution(OSMContribution contribution) { 20 | return changesetIdRange.test(contribution.getChangesetId()); 21 | } 22 | 23 | @Override 24 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot ignored) { 25 | throw new IllegalStateException("changeset filter is not applicable to entity snapshots"); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "changeset:in-range" + changesetIdRange; 31 | } 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ConstantFilter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 5 | import org.jetbrains.annotations.Contract; 6 | 7 | /** 8 | * A filter which always evaluates to true or false. Used internally to represent empty filters. 9 | */ 10 | public class ConstantFilter implements Filter { 11 | private final boolean state; 12 | 13 | ConstantFilter(boolean state) { 14 | this.state = state; 15 | } 16 | 17 | /** Returns the true/false state of this filter. */ 18 | @Contract(pure = true) 19 | public boolean getState() { 20 | return this.state; 21 | } 22 | 23 | @Override 24 | public boolean applyOSM(OSMEntity entity) { 25 | return this.state; 26 | } 27 | 28 | @Override 29 | public boolean applyOSH(OSHEntity entity) { 30 | return this.state; 31 | } 32 | 33 | @Override 34 | public FilterExpression negate() { 35 | return new ConstantFilter(!this.state); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return Boolean.toString(this.state); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ContributorUserIdFilterEquals.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 5 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 6 | import org.jetbrains.annotations.Contract; 7 | 8 | /** 9 | * A filter which selects OSM contributions by a user id. 10 | */ 11 | public class ContributorUserIdFilterEquals extends NegatableFilter { 12 | final long userId; 13 | 14 | ContributorUserIdFilterEquals(long userId) { 15 | super(new FilterInternal() { 16 | @Override 17 | public boolean applyOSH(OSHEntity entity) { 18 | return applyToOSHEntityRecursively(entity, v -> v.getUserId() == userId); 19 | } 20 | 21 | @Override 22 | public boolean applyOSMContribution(OSMContribution contribution) { 23 | return contribution.getContributorUserId() == userId; 24 | } 25 | 26 | @Override 27 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot ignored) { 28 | throw new IllegalStateException("contributor filter is not applicable to entity snapshots"); 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return "contributor:" + userId; 34 | } 35 | }); 36 | this.userId = userId; 37 | } 38 | 39 | @Contract(pure = true) 40 | public long getUserId() { 41 | return this.userId; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ContributorUserIdFilterEqualsAnyOf.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | import java.util.stream.Collectors; 7 | import javax.annotation.Nonnull; 8 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 9 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 10 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 11 | import org.jetbrains.annotations.Contract; 12 | 13 | /** 14 | * A filter which selects OSM contributions by matching to a list of contributor user ids. 15 | */ 16 | public class ContributorUserIdFilterEqualsAnyOf extends NegatableFilter { 17 | private final Collection contributorUserIdList; 18 | 19 | ContributorUserIdFilterEqualsAnyOf(@Nonnull Collection contributorUserIdList) { 20 | super(new FilterInternal() { 21 | private final Set contributorUserIds = new HashSet<>(contributorUserIdList); 22 | 23 | @Override 24 | public boolean applyOSH(OSHEntity entity) { 25 | return applyToOSHEntityRecursively(entity, v -> contributorUserIds.contains(v.getUserId())); 26 | } 27 | 28 | @Override 29 | public boolean applyOSMContribution(OSMContribution contribution) { 30 | return contributorUserIds.contains(contribution.getContributorUserId()); 31 | } 32 | 33 | @Override 34 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot ignored) { 35 | throw new IllegalStateException("contributor filter is not applicable to entity snapshots"); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "contributor:in(" + contributorUserIdList.stream().map(String::valueOf) 41 | .collect(Collectors.joining(",")) + ")"; 42 | } 43 | }); 44 | this.contributorUserIdList = contributorUserIdList; 45 | } 46 | 47 | @Contract(pure = true) 48 | public Collection getContributorUserIdList() { 49 | return this.contributorUserIdList; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/ContributorUserIdFilterRange.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 5 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 6 | 7 | /** 8 | * A filter which selects OSM contributions by a range of contributor user ids. 9 | */ 10 | public class ContributorUserIdFilterRange extends NegatableFilter { 11 | ContributorUserIdFilterRange(IdRange contributorUserIdRange) { 12 | super(new FilterInternal() { 13 | @Override 14 | public boolean applyOSH(OSHEntity entity) { 15 | return applyToOSHEntityRecursively(entity, v -> contributorUserIdRange.test(v.getUserId())); 16 | } 17 | 18 | @Override 19 | public boolean applyOSMContribution(OSMContribution contribution) { 20 | return contributorUserIdRange.test(contribution.getContributorUserId()); 21 | } 22 | 23 | @Override 24 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot ignored) { 25 | throw new IllegalStateException("contributor filter is not applicable to entity snapshots"); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "contributor:in-range" + contributorUserIdRange; 31 | } 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterArea.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.heigit.ohsome.oshdb.util.geometry.Geo; 5 | 6 | /** 7 | * A filter which checks the area of OSM feature geometries. 8 | */ 9 | public class GeometryFilterArea extends GeometryFilter { 10 | GeometryFilterArea(@Nonnull ValueRange range) { 11 | super(range, GeometryMetricEvaluator.fromLambda(Geo::areaOf, "area")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterInnerRings.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.locationtech.jts.geom.Geometry; 5 | import org.locationtech.jts.geom.MultiPolygon; 6 | import org.locationtech.jts.geom.Polygon; 7 | 8 | /** 9 | * A filter which checks the number of inner rings of a multipolygon relation. 10 | */ 11 | public class GeometryFilterInnerRings extends GeometryFilter { 12 | /** 13 | * Creates a new inner rings filter object. 14 | * 15 | * @param range the allowed range (inclusive) of values to pass the filter 16 | */ 17 | public GeometryFilterInnerRings(@Nonnull ValueRange range) { 18 | super(range, GeometryMetricEvaluator.fromLambda(GeometryFilterInnerRings::countInnerRings, 19 | "geometry.inners")); 20 | } 21 | 22 | private static int countInnerRings(Geometry geometry) { 23 | if (geometry instanceof Polygon) { 24 | return ((Polygon) geometry).getNumInteriorRing(); 25 | } else if (geometry instanceof MultiPolygon) { 26 | var counter = 0; 27 | for (var i = 0; i < geometry.getNumGeometries(); i++) { 28 | counter += ((Polygon) geometry.getGeometryN(i)).getNumInteriorRing(); 29 | } 30 | return counter; 31 | } else { 32 | return -1; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterLength.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.heigit.ohsome.oshdb.util.geometry.Geo; 5 | 6 | /** 7 | * A filter which checks the length of OSM feature geometries. 8 | */ 9 | public class GeometryFilterLength extends GeometryFilter { 10 | public GeometryFilterLength(@Nonnull ValueRange range) { 11 | super(range, GeometryMetricEvaluator.fromLambda(Geo::lengthOf, "length")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterOuterRings.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.locationtech.jts.geom.Polygonal; 5 | 6 | /** 7 | * A filter which checks the number of outer rings of a multipolygon relation. 8 | */ 9 | public class GeometryFilterOuterRings extends GeometryFilter { 10 | /** 11 | * Creates a new outer rings filter object. 12 | * 13 | * @param range the allowed range (inclusive) of values to pass the filter 14 | */ 15 | public GeometryFilterOuterRings(@Nonnull ValueRange range) { 16 | super(range, GeometryMetricEvaluator.fromLambda(geometry -> 17 | geometry instanceof Polygonal ? geometry.getNumGeometries() : -1, 18 | "geometry.outers")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterPerimeter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.heigit.ohsome.oshdb.util.geometry.Geo; 5 | import org.locationtech.jts.geom.Polygonal; 6 | 7 | /** 8 | * A filter which checks the perimeter of polygonal OSM feature geometries. 9 | */ 10 | public class GeometryFilterPerimeter extends GeometryFilter { 11 | /** 12 | * Creates a new perimeter filter object. 13 | * 14 | * @param range the allowed range (inclusive) of values to pass the filter 15 | */ 16 | public GeometryFilterPerimeter(@Nonnull ValueRange range) { 17 | super(range, GeometryMetricEvaluator.fromLambda(geometry -> { 18 | if (!(geometry instanceof Polygonal)) { 19 | return 0; 20 | } 21 | var boundary = geometry.getBoundary(); 22 | return Geo.lengthOf(boundary); 23 | }, "perimeter")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterRoundness.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.heigit.ohsome.oshdb.util.geometry.Geo; 5 | 6 | /** 7 | * A filter which checks the roundness of polygonal OSM feature geometries. 8 | * 9 | *

Uses the Polsby-Popper test score, see 10 | * wikipedia for details.

11 | */ 12 | public class GeometryFilterRoundness extends GeometryFilter { 13 | /** 14 | * Creates a new "roundness" filter object. 15 | * 16 | * @param range the allowed range (inclusive) of values to pass the filter 17 | */ 18 | public GeometryFilterRoundness(@Nonnull ValueRange range) { 19 | super(range, GeometryMetricEvaluator.fromLambda(Geo::roundness, "geometry.roundness")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterSquareness.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.heigit.ohsome.oshdb.util.geometry.Geo; 5 | 6 | /** 7 | * A filter which checks the squareness of OSM feature geometries. 8 | * 9 | *

For the measure for the rectilinearity (or squareness) of a geometry, a methods adapted from the 10 | * paper "A Rectilinearity Measurement for Polygons" by Joviša Žunić and Paul L. Rosin 11 | * (DOI:10.1007/3-540-47967-8_50, https://link.springer.com/chapter/10.1007%2F3-540-47967-8_50, 12 | * https://www.researchgate.net/publication/221304067_A_Rectilinearity_Measurement_for_Polygons) is used.

13 | */ 14 | public class GeometryFilterSquareness extends GeometryFilter { 15 | /** 16 | * Creates a new squareness filter object. 17 | * 18 | * @param range the allowed range (inclusive) of values to pass the filter 19 | */ 20 | public GeometryFilterSquareness(@Nonnull ValueRange range) { 21 | super(range, GeometryMetricEvaluator.fromLambda(Geo::squareness, "squareness")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/GeometryFilterVertices.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.locationtech.jts.geom.Geometry; 5 | 6 | /** 7 | * A filter which checks the number of vertices of OSM feature geometries. 8 | */ 9 | public class GeometryFilterVertices extends GeometryFilter { 10 | public GeometryFilterVertices(@Nonnull ValueRange range) { 11 | super(range, GeometryMetricEvaluator.fromLambda(Geometry::getNumPoints, "geometry.vertices")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/IdFilterEquals.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 5 | import org.jetbrains.annotations.Contract; 6 | 7 | /** 8 | * A filter which selects OSM entities by their id. 9 | */ 10 | public class IdFilterEquals implements Filter { 11 | private final long id; 12 | 13 | IdFilterEquals(long id) { 14 | this.id = id; 15 | } 16 | 17 | @Contract(pure = true) 18 | public long getId() { 19 | return this.id; 20 | } 21 | 22 | @Override 23 | public boolean applyOSM(OSMEntity entity) { 24 | return entity.getId() == id; 25 | } 26 | 27 | @Override 28 | public boolean applyOSH(OSHEntity entity) { 29 | return entity.getId() == id; 30 | } 31 | 32 | @Override 33 | public FilterExpression negate() { 34 | return new IdFilterNotEquals(this.id); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "id:" + this.id; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/IdFilterEqualsAnyOf.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | import java.util.stream.Collectors; 7 | import javax.annotation.Nonnull; 8 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 9 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 10 | 11 | /** 12 | * A tag filter which executes a "id [not] in (id1, id2, …)" check. 13 | */ 14 | public class IdFilterEqualsAnyOf extends NegatableFilter { 15 | IdFilterEqualsAnyOf(@Nonnull Collection idList) { 16 | super(new FilterInternal() { 17 | private final Set ids = new HashSet<>(idList); 18 | 19 | @Override 20 | public boolean applyOSH(OSHEntity entity) { 21 | return this.ids.contains(entity.getId()); 22 | } 23 | 24 | @Override 25 | boolean applyOSHNegated(OSHEntity entity) { 26 | return !this.applyOSH(entity); 27 | } 28 | 29 | @Override 30 | public boolean applyOSM(OSMEntity entity) { 31 | return this.ids.contains(entity.getId()); 32 | } 33 | 34 | @Override 35 | boolean applyOSMNegated(OSMEntity entity) { 36 | return !this.applyOSM(entity); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "id:in" + this.ids.stream().map(String::valueOf).collect(Collectors.joining(",")); 42 | } 43 | }); 44 | 45 | if (idList.isEmpty()) { 46 | throw new IllegalStateException("list of ids must not be empty in a id in (list) filter"); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/IdFilterNotEquals.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 5 | import org.jetbrains.annotations.Contract; 6 | 7 | /** 8 | * A filter which selects OSM entities by their id. 9 | */ 10 | public class IdFilterNotEquals implements Filter { 11 | private final long id; 12 | 13 | IdFilterNotEquals(long id) { 14 | this.id = id; 15 | } 16 | 17 | @Contract(pure = true) 18 | public long getId() { 19 | return this.id; 20 | } 21 | 22 | @Override 23 | public boolean applyOSM(OSMEntity entity) { 24 | return entity.getId() != id; 25 | } 26 | 27 | @Override 28 | public boolean applyOSH(OSHEntity entity) { 29 | return entity.getId() != id; 30 | } 31 | 32 | @Override 33 | public FilterExpression negate() { 34 | return new IdFilterEquals(this.id); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "not-id:" + this.id; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/IdFilterRange.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import javax.annotation.Nonnull; 4 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 6 | 7 | /** 8 | * A filter which executes a "id [not] in range" check. 9 | */ 10 | public class IdFilterRange extends NegatableFilter { 11 | IdFilterRange(@Nonnull IdRange range) { 12 | super(new FilterInternal() { 13 | @Override 14 | public boolean applyOSH(OSHEntity entity) { 15 | return range.test(entity.getId()); 16 | } 17 | 18 | @Override 19 | boolean applyOSHNegated(OSHEntity entity) { 20 | return !this.applyOSH(entity); 21 | } 22 | 23 | @Override 24 | public boolean applyOSM(OSMEntity entity) { 25 | return range.test(entity.getId()); 26 | } 27 | 28 | @Override 29 | boolean applyOSMNegated(OSMEntity entity) { 30 | return !this.applyOSM(entity); 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "id:in-range" + range; 36 | } 37 | }); 38 | } 39 | } -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/IdRange.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Helper class to handle ranges of ids (incl. user ids, changeset ids, etc.). 7 | * 8 | *

The range's limits are tested inclusively: the range (10..12) would match the values 10, 9 | * 11 and 12, but not 9 or 13 for example.

10 | */ 11 | class IdRange implements Serializable { 12 | 13 | private final long fromId; 14 | private final long toId; 15 | 16 | /** 17 | * Creates a new id range. 18 | * 19 | * @param fromId lower limit of the range. 20 | * @param toId upper limit of the range. 21 | */ 22 | IdRange(long fromId, long toId) { 23 | this.fromId = Math.min(fromId, toId); 24 | this.toId = Math.max(fromId, toId); 25 | } 26 | 27 | /** Checks if the given id falls into the id range. */ 28 | public boolean test(long id) { 29 | return id >= fromId && id <= toId; 30 | } 31 | 32 | public String toString() { 33 | return (fromId == Long.MIN_VALUE ? "" : fromId) 34 | + ".." 35 | + (toId == Long.MAX_VALUE ? "" : toId); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/OrOperator.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.function.Supplier; 4 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 6 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 7 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 8 | import org.locationtech.jts.geom.Geometry; 9 | 10 | /** 11 | * A boolean "or" of two sub-expressions. 12 | */ 13 | public class OrOperator extends BinaryOperator { 14 | OrOperator(FilterExpression op1, FilterExpression op2) { 15 | super(op1, op2); 16 | } 17 | 18 | @Override 19 | public boolean applyOSM(OSMEntity entity) { 20 | return op1.applyOSM(entity) || op2.applyOSM(entity); 21 | } 22 | 23 | @Override 24 | public boolean applyOSH(OSHEntity entity) { 25 | return op1.applyOSH(entity) || op2.applyOSH(entity); 26 | } 27 | 28 | @Override 29 | public boolean applyOSMGeometry(OSMEntity entity, Supplier geometrySupplier) { 30 | return op1.applyOSMGeometry(entity, geometrySupplier) 31 | || op2.applyOSMGeometry(entity, geometrySupplier); 32 | } 33 | 34 | 35 | @Override 36 | public boolean applyOSMEntitySnapshot(OSMEntitySnapshot snapshot) { 37 | return op1.applyOSMEntitySnapshot(snapshot) || op2.applyOSMEntitySnapshot(snapshot); 38 | } 39 | 40 | @Override 41 | public boolean applyOSMContribution(OSMContribution contribution) { 42 | return op1.applyOSMContribution(contribution) || op2.applyOSMContribution(contribution); 43 | } 44 | 45 | @Override 46 | public FilterExpression negate() { 47 | return new AndOperator(op1.negate(), op2.negate()); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return op1.toString() + " or " + op2.toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterAnyOf.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.Optional; 6 | import java.util.Set; 7 | import javax.annotation.Nonnull; 8 | import org.heigit.ohsome.oshdb.OSHDBTag; 9 | 10 | /** 11 | * A tag filter which executes a "key [not] in (value1, value2, …)" check. 12 | */ 13 | abstract class TagFilterAnyOf implements Filter { 14 | final int keyId; 15 | final Set tags; 16 | 17 | TagFilterAnyOf(@Nonnull Collection tags) { 18 | Optional firstTag = tags.stream().findFirst(); 19 | if (!firstTag.isPresent()) { 20 | throw new IllegalStateException("list of tags must not be empty in a key in (values) filter"); 21 | } else { 22 | this.keyId = firstTag.get().getKey(); 23 | this.tags = new HashSet<>(tags); 24 | } 25 | if (!tags.stream().allMatch(tag -> tag.getKey() == this.keyId)) { 26 | throw new IllegalStateException( 27 | "list of tags must all share the same tag key in a key in (values) filter"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterEquals.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.OSHDBTag; 4 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 6 | 7 | /** 8 | * A tag filter which executes a "key=value" check. 9 | */ 10 | public class TagFilterEquals implements TagFilter { 11 | private final OSHDBTag tag; 12 | 13 | TagFilterEquals(OSHDBTag tag) { 14 | this.tag = tag; 15 | } 16 | 17 | @Override 18 | public OSHDBTag getTag() { 19 | return this.tag; 20 | } 21 | 22 | @Override 23 | public boolean applyOSM(OSMEntity entity) { 24 | return entity.getTags().hasTag(tag); 25 | } 26 | 27 | @Override 28 | public boolean applyOSH(OSHEntity entity) { 29 | return entity.hasTagKey(tag.getKey()); 30 | } 31 | 32 | @Override 33 | public FilterExpression negate() { 34 | return new TagFilterNotEquals(tag); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "tag:" + tag.getKey() + "=" + tag.getValue(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterEqualsAny.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 5 | import org.heigit.ohsome.oshdb.util.OSHDBTagKey; 6 | 7 | /** 8 | * A tag filter which executes a "key=*" check. 9 | */ 10 | public class TagFilterEqualsAny implements TagFilter { 11 | private final OSHDBTagKey tag; 12 | 13 | TagFilterEqualsAny(OSHDBTagKey tag) { 14 | this.tag = tag; 15 | } 16 | 17 | @Override 18 | public OSHDBTagKey getTag() { 19 | return this.tag; 20 | } 21 | 22 | @Override 23 | public boolean applyOSM(OSMEntity entity) { 24 | return entity.getTags().hasTagKey(tag.toInt()); 25 | } 26 | 27 | @Override 28 | public boolean applyOSH(OSHEntity entity) { 29 | return entity.hasTagKey(tag); 30 | } 31 | 32 | @Override 33 | public FilterExpression negate() { 34 | return new TagFilterNotEqualsAny(tag); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "tag:" + tag.toInt() + "=*"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterEqualsAnyOf.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.stream.Collectors; 5 | import javax.annotation.Nonnull; 6 | import org.heigit.ohsome.oshdb.OSHDBTag; 7 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 8 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 9 | 10 | /** 11 | * A tag filter which executes a "key in (value1, value2, …)" check. 12 | */ 13 | public class TagFilterEqualsAnyOf extends TagFilterAnyOf { 14 | TagFilterEqualsAnyOf(@Nonnull Collection tags) { 15 | super(tags); 16 | } 17 | 18 | @Override 19 | public boolean applyOSM(OSMEntity e) { 20 | for (OSHDBTag entityTag : e.getTags()) { 21 | int entityTagKey = entityTag.getKey(); 22 | if (entityTagKey == keyId) { 23 | return this.tags.contains(entityTag); 24 | } else if (entityTagKey > keyId) { 25 | return false; 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | @Override 32 | public boolean applyOSH(OSHEntity e) { 33 | return e.hasTagKey(this.keyId); 34 | } 35 | 36 | @Override 37 | public FilterExpression negate() { 38 | return new TagFilterNotEqualsAnyOf(tags); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "tag:" + keyId + "in" + tags.stream().map(OSHDBTag::getValue).map(String::valueOf) 44 | .collect(Collectors.joining(",")); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterNotEquals.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import com.google.common.collect.Streams; 4 | import org.heigit.ohsome.oshdb.OSHDBTag; 5 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 6 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 7 | 8 | /** 9 | * A tag filter which executes a "key!=value" check. 10 | */ 11 | public class TagFilterNotEquals implements TagFilter { 12 | private final OSHDBTag tag; 13 | 14 | TagFilterNotEquals(OSHDBTag tag) { 15 | this.tag = tag; 16 | } 17 | 18 | @Override 19 | public OSHDBTag getTag() { 20 | return this.tag; 21 | } 22 | 23 | @Override 24 | public boolean applyOSH(OSHEntity entity) { 25 | return Streams.stream(entity.getVersions()).anyMatch(this::applyOSM); 26 | } 27 | 28 | @Override 29 | public boolean applyOSM(OSMEntity entity) { 30 | return !entity.getTags().hasTag(tag); 31 | } 32 | 33 | @Override 34 | public FilterExpression negate() { 35 | return new TagFilterEquals(tag); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "tag:" + tag.getKey() + "!=" + tag.getValue(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterNotEqualsAny.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import com.google.common.collect.Streams; 4 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 6 | import org.heigit.ohsome.oshdb.util.OSHDBTagKey; 7 | 8 | /** 9 | * A tag filter which executes a "key!=*" check. 10 | */ 11 | public class TagFilterNotEqualsAny implements TagFilter { 12 | private final OSHDBTagKey tag; 13 | 14 | TagFilterNotEqualsAny(OSHDBTagKey tag) { 15 | this.tag = tag; 16 | } 17 | 18 | @Override 19 | public OSHDBTagKey getTag() { 20 | return this.tag; 21 | } 22 | 23 | @Override 24 | public boolean applyOSH(OSHEntity entity) { 25 | return Streams.stream(entity.getVersions()).anyMatch(this::applyOSM); 26 | } 27 | 28 | @Override 29 | public boolean applyOSM(OSMEntity entity) { 30 | return !entity.getTags().hasTagKey(tag.toInt()); 31 | } 32 | 33 | @Override 34 | public FilterExpression negate() { 35 | return new TagFilterEqualsAny(tag); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "tag:" + tag.toInt() + "!=*"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TagFilterNotEqualsAnyOf.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.stream.Collectors; 5 | import javax.annotation.Nonnull; 6 | import org.heigit.ohsome.oshdb.OSHDBTag; 7 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 8 | 9 | /** 10 | * A tag filter which executes a "key not in (value1, value2, …)" check. 11 | */ 12 | public class TagFilterNotEqualsAnyOf extends TagFilterAnyOf { 13 | TagFilterNotEqualsAnyOf(@Nonnull Collection tags) { 14 | super(tags); 15 | } 16 | 17 | @Override 18 | public boolean applyOSM(OSMEntity e) { 19 | for (OSHDBTag entityTag : e.getTags()) { 20 | int entityTagKey = entityTag.getKey(); 21 | if (entityTagKey == keyId) { 22 | return !this.tags.contains(entityTag); 23 | } else if (entityTagKey > keyId) { 24 | return true; 25 | } 26 | } 27 | return true; 28 | } 29 | 30 | @Override 31 | public FilterExpression negate() { 32 | return new TagFilterEqualsAnyOf(tags); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "tag:" + keyId + "not-in" + tags.stream().map(OSHDBTag::getValue).map(String::valueOf) 38 | .collect(Collectors.joining(",")); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /oshdb-filter/src/main/java/org/heigit/ohsome/oshdb/filter/TypeFilter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.EnumSet; 5 | import java.util.List; 6 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 7 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 8 | import org.heigit.ohsome.oshdb.osm.OSMType; 9 | import org.jetbrains.annotations.Contract; 10 | 11 | /** 12 | * A filter which selects OSM entities by their OSM type (i.e., node, way or relation). 13 | */ 14 | public class TypeFilter implements Filter { 15 | private final OSMType type; 16 | 17 | TypeFilter(OSMType type) { 18 | this.type = type; 19 | } 20 | 21 | @Contract(pure = true) 22 | public OSMType getType() { 23 | return this.type; 24 | } 25 | 26 | @Override 27 | public boolean applyOSM(OSMEntity entity) { 28 | return entity.getType() == type; 29 | } 30 | 31 | @Override 32 | public boolean applyOSH(OSHEntity entity) { 33 | return entity.getType() == type; 34 | } 35 | 36 | @Override 37 | public FilterExpression negate() { 38 | EnumSet otherTypes = EnumSet.of(OSMType.NODE, OSMType.WAY, OSMType.RELATION); 39 | otherTypes.remove(this.type); 40 | 41 | List otherTypesList = new ArrayList<>(otherTypes); 42 | assert otherTypesList.size() == 2 : "the negation of one osm type must equal exactly two types"; 43 | 44 | return new OrOperator( 45 | new TypeFilter(otherTypesList.get(0)), 46 | new TypeFilter(otherTypesList.get(1)) 47 | ); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return "type:" + type.toString().toLowerCase(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /oshdb-filter/src/test/java/org/heigit/ohsome/oshdb/filter/FilterByTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import java.io.IOException; 7 | import org.heigit.ohsome.oshdb.osh.OSHNode; 8 | import org.heigit.ohsome.oshdb.osm.OSMNode; 9 | import org.junit.jupiter.api.Test; 10 | import org.locationtech.jts.geom.GeometryFactory; 11 | 12 | /** 13 | * Tests helper methods for creating filters from lambda functions. 14 | */ 15 | class FilterByTest extends FilterTest { 16 | private final GeometryFactory gf = new GeometryFactory(); 17 | private final OSMNode testOSMEntity = createTestOSMEntityNode(); 18 | private final OSHNode testOSHEntity = createTestOSHEntityNode(testOSMEntity); 19 | 20 | FilterByTest() throws IOException { 21 | } 22 | 23 | @Test 24 | void testFilterByOSHEntity() { 25 | FilterExpression expression; 26 | expression = Filter.byOSHEntity(e -> e.getId() == 1); 27 | assertTrue(expression.applyOSH(testOSHEntity) && expression.applyOSM(testOSMEntity)); 28 | expression = expression.negate(); 29 | assertFalse(expression.applyOSH(testOSHEntity) && expression.applyOSM(testOSMEntity)); 30 | } 31 | 32 | @Test 33 | void testFilterByOSMEntity() { 34 | FilterExpression expression; 35 | expression = Filter.byOSMEntity(e -> e.getVersion() == 1); 36 | assertTrue(expression.applyOSH(testOSHEntity) && expression.applyOSM(testOSMEntity)); 37 | expression = expression.negate(); 38 | assertFalse(expression.applyOSH(testOSHEntity) && expression.applyOSM(testOSMEntity)); 39 | } 40 | 41 | @Test 42 | void testFilterByOSMEntityApplyGeometryFallback() { 43 | FilterExpression expression = Filter.byOSMEntity(e -> e.getVersion() == 1); 44 | assertTrue(expression.applyOSMGeometry(testOSMEntity, gf.createPoint())); 45 | assertFalse(expression.negate().applyOSMGeometry(testOSMEntity, gf.createPoint())); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /oshdb-filter/src/test/java/org/heigit/ohsome/oshdb/filter/NormalizeTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.filter; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.List; 6 | import org.heigit.ohsome.oshdb.osm.OSMType; 7 | import org.junit.jupiter.api.Test; 8 | 9 | /** 10 | * Tests for normalization of filters. 11 | */ 12 | class NormalizeTest { 13 | @Test 14 | void testAndOperator() { 15 | FilterExpression sub1 = new TypeFilter(OSMType.NODE); 16 | FilterExpression sub2 = new TypeFilter(OSMType.WAY); 17 | FilterExpression expression = BinaryOperator.fromOperator(sub1, BinaryOperator.Type.AND, sub2); 18 | List> norm = expression.normalize(); 19 | assertEquals(1, norm.size()); 20 | assertEquals(2, norm.get(0).size()); 21 | } 22 | 23 | @Test 24 | void testOrOperator() { 25 | FilterExpression sub1 = new TypeFilter(OSMType.NODE); 26 | FilterExpression sub2 = new TypeFilter(OSMType.WAY); 27 | FilterExpression expression = BinaryOperator.fromOperator(sub1, BinaryOperator.Type.OR, sub2); 28 | List> norm = expression.normalize(); 29 | assertEquals(2, norm.size()); 30 | assertEquals(1, norm.get(0).size()); 31 | assertEquals(1, norm.get(1).size()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /oshdb-filter/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=WARN, stderr 3 | 4 | # Redirect log messages to console 5 | log4j.appender.stderr=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stderr.Target=System.err 7 | log4j.appender.stderr.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stderr.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 9 | -------------------------------------------------------------------------------- /oshdb-helpers/oshdb-application-template/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.heigit.ohsome 7 | oshdb-helpers 8 | 1.3.0-SNAPSHOT 9 | 10 | 11 | oshdb-application-template 12 | OSHDB Application Template 13 | TODO 14 | 15 | 16 | 4.7.1 17 | 18 | 19 | 20 | 21 | ${project.groupId} 22 | oshdb-database-driver 23 | ${project.version} 24 | 25 | 26 | info.picocli 27 | picocli 28 | ${picocli.version} 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /oshdb-helpers/oshdb-application-template/src/main/java/org/heigit/ohsome/oshdb/helpers/applicationtemplate/PropsUtil.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.helpers.applicationtemplate; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.StandardOpenOption; 7 | import java.util.Optional; 8 | import java.util.Properties; 9 | 10 | class PropsUtil { 11 | 12 | private PropsUtil() { 13 | } 14 | 15 | static void load(Properties props, Path path) throws IOException { 16 | if (path != null && Files.exists(path)) { 17 | try (var in = Files.newInputStream(path, StandardOpenOption.READ)) { 18 | props.load(in); 19 | } 20 | } 21 | } 22 | 23 | static void set(Properties props, String key, String value) { 24 | if (value != null) { 25 | props.put(key, value); 26 | } 27 | } 28 | 29 | static void set(Properties props, String key, Boolean value) { 30 | if (value != null) { 31 | props.setProperty(key, Boolean.toString(value)); 32 | } 33 | } 34 | 35 | static Optional get(Properties props, String key) { 36 | return Optional.ofNullable(props.getProperty(key)); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /oshdb-helpers/oshdb-database-driver/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.heigit.ohsome 7 | oshdb-helpers 8 | 1.3.0-SNAPSHOT 9 | 10 | 11 | oshdb-database-driver 12 | OSHDB Database Driver 13 | TODO 14 | 15 | 16 | 5.0.1 17 | 18 | 19 | 20 | 21 | ${project.groupId} 22 | oshdb-api-ignite 23 | ${project.version} 24 | compile 25 | 26 | 27 | 28 | com.zaxxer 29 | HikariCP 30 | ${hikaricp.version} 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /oshdb-helpers/oshdb-database-driver/src/main/java/org/heigit/ohsome/oshdb/helpers/db/OSHDBConnection.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.helpers.db; 2 | 3 | import java.util.Properties; 4 | import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; 5 | import org.heigit.ohsome.oshdb.api.mapreducer.MapReducer; 6 | import org.heigit.ohsome.oshdb.api.mapreducer.OSMContributionView; 7 | import org.heigit.ohsome.oshdb.api.mapreducer.OSMEntitySnapshotView; 8 | import org.heigit.ohsome.oshdb.util.exceptions.OSHDBKeytablesNotFoundException; 9 | import org.heigit.ohsome.oshdb.util.mappable.OSMContribution; 10 | import org.heigit.ohsome.oshdb.util.mappable.OSMEntitySnapshot; 11 | import org.heigit.ohsome.oshdb.util.tagtranslator.TagTranslator; 12 | 13 | public class OSHDBConnection { 14 | 15 | private final Properties props; 16 | private final OSHDBDatabase oshdb; 17 | private final TagTranslator tagTranslator; 18 | 19 | public OSHDBConnection(Properties props, OSHDBDatabase oshdb) 20 | throws OSHDBKeytablesNotFoundException { 21 | this.props = props; 22 | this.oshdb = oshdb; 23 | this.tagTranslator = oshdb.getTagTranslator(); 24 | } 25 | 26 | public MapReducer getContributionView() { 27 | return OSMContributionView.on(oshdb); 28 | } 29 | 30 | public MapReducer getSnapshotView() { 31 | return OSMEntitySnapshotView.on(oshdb); 32 | } 33 | 34 | public Properties getProps() { 35 | return props; 36 | } 37 | 38 | public OSHDBDatabase getOSHDB() { 39 | return oshdb; 40 | } 41 | 42 | public TagTranslator getTagTranslator() { 43 | return tagTranslator; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /oshdb-helpers/oshdb-database-driver/src/main/java/org/heigit/ohsome/oshdb/helpers/db/Util.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.helpers.db; 2 | 3 | import java.util.Optional; 4 | import java.util.Properties; 5 | import java.util.regex.Pattern; 6 | 7 | class Util { 8 | 9 | private static final Pattern SUBSTITUTE = Pattern.compile("\\$\\{([^\\}]+)\\}"); 10 | 11 | private Util() {} 12 | 13 | static Optional getInterpolated(Properties props, String key) { 14 | return Optional.ofNullable(props.getProperty(key)).map(value -> interpolate(props, value)); 15 | } 16 | 17 | private static String interpolate(Properties props, String value) { 18 | var matcher = SUBSTITUTE.matcher(value); 19 | var sb = new StringBuffer(); 20 | while (matcher.find()) { 21 | var sub = matcher.group(1); 22 | matcher.appendReplacement(sb, getInterpolated(props, sub).orElse("\\${" + sub + "}")); 23 | } 24 | matcher.appendTail(sb); 25 | return sb.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /oshdb-helpers/oshdb-database-driver/src/test/java/org/heigit/ohsome/oshdb/helpers/db/OSHDBDriverH2Test.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.helpers.db; 2 | 3 | import static org.heigit.ohsome.oshdb.OSHDBBoundingBox.bboxWgs84Coordinates; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | import java.util.Properties; 8 | import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; 9 | import org.heigit.ohsome.oshdb.util.tagtranslator.TagTranslator; 10 | import org.junit.jupiter.api.DisplayName; 11 | import org.junit.jupiter.api.Test; 12 | 13 | class OSHDBDriverH2Test { 14 | 15 | private static final Properties props = new Properties(); 16 | 17 | public OSHDBDriverH2Test() { 18 | props.setProperty("oshdb", "h2:../../data/${test-file}"); 19 | // relevant for getter test 20 | props.setProperty("test-file", "test-data"); 21 | } 22 | 23 | @SuppressWarnings("ConstantConditions") 24 | private static int testGetters(OSHDBConnection oshdb) { 25 | assertTrue(oshdb.getProps() instanceof Properties); 26 | assertTrue(oshdb.getOSHDB() instanceof OSHDBDatabase); 27 | assertTrue(oshdb.getTagTranslator() instanceof TagTranslator); 28 | return 0; 29 | } 30 | 31 | @Test 32 | @DisplayName("OSHDBConnection getSnapshotView") 33 | void getSnapshotView() throws Exception { 34 | int queryResult = OSHDBDriver.connect(props, oshdb -> { 35 | var bbox = bboxWgs84Coordinates(8.651133, 49.387611, 8.6561, 49.390513); 36 | 37 | return oshdb.getSnapshotView() 38 | .areaOfInterest(bbox) 39 | .filter("type:node") 40 | .timestamps("2018-05-01") 41 | .count(); 42 | }); 43 | assertEquals(7, queryResult); 44 | } 45 | 46 | @Test 47 | @DisplayName("OSHDBConnection getContributionView") 48 | void getContributionView() throws Exception { 49 | int queryResult = OSHDBDriver.connect(props, oshdb -> { 50 | var bbox = bboxWgs84Coordinates(8.651133, 49.387611, 8.6561, 49.390513); 51 | 52 | return oshdb.getContributionView() 53 | .areaOfInterest(bbox) 54 | .filter("type:node") 55 | .timestamps("2007-11-01", "2019-01-01") 56 | .count(); 57 | }); 58 | assertEquals(16, queryResult); 59 | } 60 | 61 | @Test 62 | @DisplayName("OSHDBConnection Getter") 63 | void getter() throws Exception { 64 | OSHDBDriver.connect(props, OSHDBDriverH2Test::testGetters); 65 | } 66 | } -------------------------------------------------------------------------------- /oshdb-helpers/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.heigit.ohsome 7 | oshdb-parent 8 | 1.3.0-SNAPSHOT 9 | 10 | 11 | oshdb-helpers 12 | OSHDB Helpers 13 | A collection of helpers to ease the usage of OSHDB in your own code. 14 | pom 15 | 16 | 17 | 18 | 19 | 20 | oshdb-application-template 21 | oshdb-database-driver 22 | 23 | 24 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.heigit.ohsome 7 | oshdb-parent 8 | 1.3.0-SNAPSHOT 9 | 10 | 11 | oshdb-oshpbf-parser 12 | The PBF-Parser that transfers osh.pbf-files into database Objects. 13 | 14 | 15 | 1.5.0 16 | 2.1.9 17 | 18 | 19 | 20 | 21 | ${project.groupId} 22 | oshdb 23 | ${project.version} 24 | 25 | 26 | 27 | org.openstreetmap.pbf 28 | osmpbf 29 | ${osmpbf.version} 30 | 31 | 32 | 33 | io.reactivex.rxjava2 34 | rxjava 35 | ${rxjava2.version} 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/CommonEntityData.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | import java.util.Arrays; 4 | 5 | public class CommonEntityData { 6 | 7 | public final long id; 8 | public final int version; 9 | public final long timestamp; 10 | public final long changeset; 11 | public final boolean visible; 12 | public final int userId; 13 | public final String user; 14 | public final TagText[] tags; 15 | 16 | public CommonEntityData(long id, int version, long changeset, long timestamp, boolean visible, 17 | int userId, String user, TagText[] tags) { 18 | this.id = id; 19 | this.version = version; 20 | this.changeset = changeset; 21 | this.timestamp = timestamp; 22 | this.visible = visible; 23 | this.userId = userId; 24 | this.user = user; 25 | this.tags = tags; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return String.format("%d ver:%d,ch:%d,ts:%d,v:%s,uid:%d [%s]", id, version, changeset, 31 | timestamp, visible, userId, Arrays.toString(tags)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/Entity.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMType; 4 | 5 | public abstract class Entity { 6 | public final CommonEntityData entityData; 7 | 8 | public Entity(final CommonEntityData entityData) { 9 | this.entityData = entityData; 10 | } 11 | 12 | public long getId() { 13 | return entityData.id; 14 | } 15 | 16 | public int getVersion() { 17 | return entityData.version; 18 | } 19 | 20 | public long getTimestamp() { 21 | return entityData.timestamp; 22 | } 23 | 24 | public long getChangeset() { 25 | return entityData.changeset; 26 | } 27 | 28 | public int getUserId() { 29 | return entityData.userId; 30 | } 31 | 32 | public String getUser() { 33 | return entityData.user; 34 | } 35 | 36 | public boolean isVisible() { 37 | return entityData.visible; 38 | } 39 | 40 | public TagText[] getTags() { 41 | return entityData.tags; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return entityData.toString(); 47 | } 48 | 49 | public abstract OSMType getType(); 50 | } 51 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/Node.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMType; 4 | 5 | public class Node extends Entity { 6 | 7 | public final long longitude; 8 | public final long latitude; 9 | 10 | public Node(CommonEntityData entityData, long longitude, long latitude) { 11 | super(entityData); 12 | this.longitude = longitude; 13 | this.latitude = latitude; 14 | } 15 | 16 | @Override 17 | public OSMType getType() { 18 | return OSMType.NODE; 19 | } 20 | 21 | public long getLongitude() { 22 | return longitude; 23 | } 24 | 25 | public long getLatitude() { 26 | return latitude; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return String.format("%s (lon:%d,lat%d)", super.toString(), longitude, latitude); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/Relation.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMType; 4 | 5 | public class Relation extends Entity { 6 | 7 | public final RelationMember[] members; 8 | 9 | public Relation(CommonEntityData entityData, RelationMember[] members) { 10 | super(entityData); 11 | this.members = members; 12 | } 13 | 14 | @Override 15 | public OSMType getType() { 16 | return OSMType.RELATION; 17 | } 18 | 19 | public RelationMember[] getMembers() { 20 | return members; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "R " + super.toString() + " #members: " + members.length; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/RelationMember.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | public class RelationMember { 4 | 5 | public final long memId; 6 | public final String role; 7 | public final int type; 8 | 9 | public RelationMember(long memId, String role, int type) { 10 | this.memId = memId; 11 | this.role = role; 12 | this.type = type; 13 | } 14 | } -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/Tag.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | public interface Tag { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/TagText.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | public class TagText implements Tag { 4 | 5 | public final String key; 6 | public final String value; 7 | 8 | public TagText(String key, String value) { 9 | this.key = key; 10 | this.value = value; 11 | } 12 | 13 | @Override 14 | public boolean equals(Object obj) { 15 | if (obj == this) { 16 | return true; 17 | } 18 | if (!(obj instanceof TagText)) { 19 | return false; 20 | } 21 | TagText tag = (TagText) obj; 22 | 23 | return key.equals(tag.key) && value.equals(tag.value); 24 | } 25 | 26 | @Override 27 | public int hashCode() { 28 | int result = 37 * key.hashCode(); 29 | result = 37 * value.hashCode(); 30 | return result; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return key + "=" + value; 36 | } 37 | } -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/osm/v06/Way.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.osm.v06; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMType; 4 | 5 | public class Way extends Entity { 6 | 7 | public final long[] refs; 8 | 9 | public Way(CommonEntityData entityData, long[] refs) { 10 | super(entityData); 11 | this.refs = refs; 12 | } 13 | 14 | @Override 15 | public OSMType getType() { 16 | return OSMType.WAY; 17 | } 18 | 19 | public long[] getRefs() { 20 | return refs; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/pbf/PosContainer.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.pbf; 2 | 3 | public class PosContainer { 4 | public final long pos; 5 | public final T content; 6 | 7 | public PosContainer(long pos, T content) { 8 | this.pos = pos; 9 | this.content = content; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return String.format("Pos:%d - %s", pos, content.toString()); 15 | } 16 | 17 | public static PosContainer get(long pos, T content) { 18 | return new PosContainer<>(pos, content); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/rx/Osh.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.rx; 2 | 3 | import java.util.List; 4 | import org.heigit.ohsome.oshdb.osm.OSMType; 5 | import org.heigit.ohsome.oshpbf.parser.osm.v06.Entity; 6 | 7 | public class Osh { 8 | final boolean isComplete; 9 | final List versions; 10 | final long[] pos; 11 | 12 | public Osh(boolean isComplete, List versions, long pos) { 13 | this(isComplete, versions, new long[] {pos}); 14 | } 15 | 16 | public Osh(boolean isComplete, List versions, long pos1, long pos2) { 17 | this(isComplete, versions, new long[] {pos1, pos2}); 18 | } 19 | 20 | public Osh(boolean isComplete, List versions, long[] pos) { 21 | this.isComplete = isComplete; 22 | this.versions = versions; 23 | this.pos = pos; 24 | } 25 | 26 | public long getId() { 27 | return versions.get(0).getId(); 28 | } 29 | 30 | public OSMType getType() { 31 | return versions.get(0).getType(); 32 | } 33 | 34 | public List getVersions() { 35 | return versions; 36 | } 37 | 38 | /** 39 | * position in bytes of the blob containing this data in the pbf. 40 | * 41 | */ 42 | public long[] getPos() { 43 | return pos; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return String.format("%s[%d] complete:%s, #%d v:%d-%d", getType(), getId(), isComplete, 49 | versions.size(), versions.get(0).getVersion(), 50 | versions.get(versions.size() - 1).getVersion()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /oshdb-oshpbf-parser/src/main/java/org/heigit/ohsome/oshpbf/parser/util/ByteBufferBackedInputStream.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshpbf.parser.util; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.nio.ByteBuffer; 6 | 7 | public class ByteBufferBackedInputStream extends InputStream { 8 | protected final ByteBuffer buf; 9 | 10 | public ByteBufferBackedInputStream(ByteBuffer buf) { 11 | this.buf = buf; 12 | } 13 | 14 | @Override 15 | public int available() { 16 | return buf.remaining(); 17 | } 18 | 19 | @Override 20 | public int read() throws IOException { 21 | return buf.hasRemaining() ? buf.get() & 0xFF : -1; 22 | } 23 | 24 | @Override 25 | public int read(byte[] bytes, int off, int len) throws IOException { 26 | if (!buf.hasRemaining()) { 27 | return -1; 28 | } 29 | len = Math.min(len, buf.remaining()); 30 | buf.get(bytes, off, len); 31 | return len; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /oshdb-tool/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.heigit.ohsome 5 | oshdb-parent 6 | 1.3.0-SNAPSHOT 7 | 8 | 9 | oshdb-tool 10 | OSHDB CLI Toolkit 11 | Toolkit for the OSHDB 12 | 13 | 14 | 15 | 16 | 17 | 18 | ${project.groupId} 19 | oshdb-api-ignite 20 | ${project.version} 21 | 22 | 23 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/TableNames.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util; 2 | 3 | import java.util.Optional; 4 | import org.heigit.ohsome.oshdb.osm.OSMType; 5 | 6 | /** 7 | * Names for JDBC tables or Ignite caches. 8 | */ 9 | public enum TableNames { 10 | 11 | /** 12 | * Table holding keys in keytables. 13 | */ 14 | E_KEY("\"key\""), 15 | /** 16 | * Table holding keysvalues in keytables. 17 | */ 18 | E_KEYVALUE("keyvalue"), 19 | /** 20 | * Table holding roles in keytables. 21 | */ 22 | E_ROLE("role"), 23 | /** 24 | * Table holding users in keytables. 25 | */ 26 | E_USER("user"), 27 | /** 28 | * Table that holds Grid-OSH-Nodes in the oshdb. 29 | */ 30 | T_NODES("grid_node"), 31 | /** 32 | * Table that holds Grid-OSH-Ways in the oshdb. 33 | */ 34 | T_WAYS("grid_way"), 35 | /** 36 | * Table that holds Grid-OSH-Relations in the oshdb. 37 | */ 38 | T_RELATIONS("grid_relation"), 39 | /** 40 | * Table that holds metadata in the oshdb. 41 | */ 42 | T_METADATA("metadata"); 43 | 44 | private final String tablename; 45 | 46 | TableNames(String name) { 47 | this.tablename = name; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return tablename; 53 | } 54 | 55 | /** 56 | * Returns the table name with a given {@link String} prepended. 57 | * 58 | * @return table name with prefix 59 | */ 60 | public String toString(String prefix) { 61 | if (prefix != null && !prefix.trim().isEmpty()) { 62 | return prefix + "_" + this.toString(); 63 | } 64 | return this.toString(); 65 | } 66 | 67 | /** 68 | * Returns the {@link TableNames} object for a given {@link OSMType}. 69 | * 70 | * @return TableName for type 71 | */ 72 | public static Optional forOSMType(OSMType type) { 73 | switch (type) { 74 | case NODE: return Optional.of(T_NODES); 75 | case WAY: return Optional.of(T_WAYS); 76 | case RELATION: return Optional.of(T_RELATIONS); 77 | default: 78 | return Optional.empty(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/celliterator/ContributionType.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.celliterator; 2 | 3 | /** 4 | * Type of contribution to an OSM entity. 5 | */ 6 | public enum ContributionType { 7 | /** a new object has been created. */ 8 | CREATION, 9 | /** one object has been deleted. */ 10 | DELETION, 11 | /** at least one tag of this object has been modified. */ 12 | TAG_CHANGE, 13 | /** the geometry of the object has been altered. */ 14 | GEOMETRY_CHANGE 15 | } 16 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/celliterator/LazyEvaluatedContributionTypes.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.celliterator; 2 | 3 | import java.util.EnumSet; 4 | import java.util.function.Predicate; 5 | import java.util.function.Supplier; 6 | 7 | /** 8 | * An object offering access to lazily evaluated contribution type sets. 9 | * 10 | *

Which is based on a single predicate which if invoked will answer whether a given 11 | * contribution type is detected or not.

12 | * 13 | * @see LazyEvaluatedObject 14 | */ 15 | public class LazyEvaluatedContributionTypes implements Supplier> { 16 | private EnumSet values = EnumSet.noneOf(ContributionType.class); 17 | private EnumSet evaluated = EnumSet.noneOf(ContributionType.class); 18 | private Predicate evaluator; 19 | 20 | public LazyEvaluatedContributionTypes(Predicate evaluator) { 21 | this.evaluator = evaluator; 22 | } 23 | 24 | public LazyEvaluatedContributionTypes(EnumSet values) { 25 | this.values = values; 26 | this.evaluated = EnumSet.allOf(ContributionType.class); 27 | } 28 | 29 | /** 30 | * Check if the given {@link ContributionType} {@code t} is contained in the 31 | * {@link ContributionType} set. 32 | */ 33 | public boolean contains(ContributionType t) { 34 | if (!this.evaluated.contains(t)) { 35 | boolean value = this.evaluator.test(t); 36 | this.evaluated.add(t); 37 | if (value) { 38 | this.values.add(t); 39 | } 40 | return value; 41 | } 42 | return this.values.contains(t); 43 | } 44 | 45 | @Override 46 | public EnumSet get() { 47 | EnumSet unevaluated = EnumSet.allOf(ContributionType.class); 48 | unevaluated.removeAll(this.evaluated); 49 | for (ContributionType contributionType : unevaluated) { 50 | this.contains(contributionType); 51 | } 52 | return this.values; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/celliterator/LazyEvaluatedObject.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.celliterator; 2 | 3 | import java.util.function.Supplier; 4 | 5 | /** 6 | * A lazily evaluated object. 7 | * 8 | *

Useful as a wrapper to hold values which are potentially expensive to 9 | * calculate, but might sometimes not be requested.

10 | * 11 | * @param the (arbitrary) type of data to hold 12 | */ 13 | public class LazyEvaluatedObject implements Supplier { 14 | private T value = null; 15 | private boolean evaluated = false; 16 | private Supplier evaluator; 17 | 18 | /** 19 | * Constructs a {@link LazyEvaluatedObject} using a {@code evaluator} (supplier function) which 20 | * returns a value of generic type {@code T}, when requested from this object. 21 | * 22 | * @param evaluator a {@link Supplier} function which returns the value of interest when executed 23 | */ 24 | public LazyEvaluatedObject(Supplier evaluator) { 25 | this.evaluator = evaluator; 26 | } 27 | 28 | /** 29 | * Constructs a {@link LazyEvaluatedObject} using an already known {@code value} of generic 30 | * type {@code T}. 31 | * 32 | *

This simply wraps the value with a supplier method, but can be useful in situations where 33 | * sometimes an expensive to calculate value is already know, but one wants to use the lazy 34 | * evaluated interface for the remaining cases.

35 | * 36 | * @param value the value to store 37 | */ 38 | public LazyEvaluatedObject(T value) { 39 | this.value = value; 40 | this.evaluated = true; 41 | this.evaluator = null; 42 | } 43 | 44 | @Override 45 | public T get() { 46 | if (!this.evaluated) { 47 | this.value = this.evaluator.get(); 48 | this.evaluated = true; 49 | this.evaluator = null; 50 | } 51 | return this.value; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object o) { 56 | if (o instanceof LazyEvaluatedObject) { 57 | LazyEvaluatedObject lazyO = (LazyEvaluatedObject) o; 58 | return this.get().equals(lazyO.get()); 59 | } 60 | return false; 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | return this.get().hashCode(); 66 | } 67 | 68 | public boolean wasEvaluated() { 69 | return this.evaluated; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/celliterator/OSHEntitySource.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.celliterator; 2 | 3 | import com.google.common.collect.Streams; 4 | import java.util.stream.Stream; 5 | import org.heigit.ohsome.oshdb.OSHDBBoundingBox; 6 | import org.heigit.ohsome.oshdb.grid.GridOSHEntity; 7 | import org.heigit.ohsome.oshdb.index.XYGrid; 8 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 9 | import org.heigit.ohsome.oshdb.util.CellId; 10 | 11 | /** 12 | * A source of OSH entities. 13 | */ 14 | public interface OSHEntitySource { 15 | 16 | /** 17 | * Returns a stream of OSH entities. 18 | * 19 | * @return a stream of OSH entities 20 | */ 21 | Stream getData(); 22 | 23 | /** 24 | * Returns the bounding box of the entities returned by `getData()`. 25 | * 26 | *

By convention this bbox must contain the bboxes of all OSH entities returned by this source. 27 | * It should be the minimal bbox encompassing all of the entities.

28 | * 29 | * @return A bounding box enclosing all OSH entities of this source 30 | */ 31 | OSHDBBoundingBox getBoundingBox(); 32 | 33 | /** 34 | * A helper method which transforms a grid cell to an OSH entity source. 35 | * 36 | * @param cell A grid cell containing OSH entities 37 | * @return A source object which will return the entities of the given grid cell and its bbox 38 | */ 39 | static OSHEntitySource fromGridOSHEntity(GridOSHEntity cell) { 40 | return new OSHEntitySource() { 41 | @Override 42 | public Stream getData() { 43 | return Streams.stream(cell.getEntities()); 44 | } 45 | 46 | @Override 47 | public OSHDBBoundingBox getBoundingBox() { 48 | return XYGrid.getBoundingBox(new CellId(cell.getLevel(), cell.getId()), true); 49 | } 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/exceptions/OSHDBException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.exceptions; 2 | 3 | /** 4 | * General OSHDB exception. This exception is used to indicate any error condition while using 5 | * OSHDB. 6 | */ 7 | public class OSHDBException extends RuntimeException { 8 | 9 | /** 10 | * Create empty exception. 11 | */ 12 | public OSHDBException() { 13 | super(); 14 | } 15 | 16 | /** 17 | * Creates new exception with given error message. 18 | * 19 | * @param message Error message. 20 | */ 21 | public OSHDBException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Creates new grid exception with given throwable as a cause and source of error message. 27 | * 28 | * @param cause Non-null throwable cause. 29 | */ 30 | public OSHDBException(Throwable cause) { 31 | this(cause.getMessage(), cause); 32 | } 33 | 34 | /** 35 | * Creates new exception with given error message and optional nested exception. 36 | * 37 | * @param message Error message. 38 | * @param cause Optional nested exception (can be {@code null}). 39 | */ 40 | public OSHDBException(String message, Throwable cause) { 41 | super(message, cause); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/exceptions/OSHDBInvalidTimestampException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.exceptions; 2 | 3 | /** 4 | * An exception caused by invalid time string input. 5 | */ 6 | public class OSHDBInvalidTimestampException extends OSHDBException { 7 | public OSHDBInvalidTimestampException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/exceptions/OSHDBKeytablesNotFoundException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.exceptions; 2 | 3 | /** 4 | * Exception used if the OSHDB keytable cannot be found. 5 | */ 6 | public class OSHDBKeytablesNotFoundException extends OSHDBException { 7 | /** 8 | * Creates an exception with a message explaining that the OSHDB keytables db was not found. 9 | */ 10 | public OSHDBKeytablesNotFoundException() { 11 | super("Keytables database not found, or db doesn't contain the required \"keytables\" tables. " 12 | + "Make sure you have specified the right keytables database, for example by calling " 13 | + "`keytables()` when using the OSHDB-API."); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/exceptions/OSHDBNotImplementedException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.exceptions; 2 | 3 | /** 4 | * An exception which is thrown when a particular feature is not implemented in the OSHDB. 5 | * 6 | *

7 | * Mostly used internally for specific code paths for which fallback routines are implemented. 8 | *

9 | */ 10 | public class OSHDBNotImplementedException extends OSHDBException { 11 | public OSHDBNotImplementedException(String message) { 12 | super(message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/exceptions/OSHDBTableNotFoundException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.exceptions; 2 | 3 | /** 4 | * An exception caused by missing tables or caches. 5 | */ 6 | public class OSHDBTableNotFoundException extends OSHDBException { 7 | public OSHDBTableNotFoundException(String missingTable) { 8 | super("Database doesn't contain the required table(s)/cache(s): " + missingTable + "."); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/exceptions/OSHDBTimeoutException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.exceptions; 2 | 3 | /** 4 | * An exception caused by a timeout during a query. 5 | */ 6 | public class OSHDBTimeoutException extends OSHDBException { 7 | } 8 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/OSHEntityFilter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 4 | 5 | /** 6 | * A serializable {@link java.util.function.Predicate} on {@link OSHEntity} objects. 7 | */ 8 | public interface OSHEntityFilter extends SerializablePredicate {} 9 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/OSMEntityFilter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 4 | 5 | /** 6 | * A serializable {@link java.util.function.Predicate} on {@link OSMEntity} objects. 7 | */ 8 | public interface OSMEntityFilter extends SerializablePredicate {} 9 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableBiConsumer.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.BiConsumer; 5 | 6 | /** 7 | * A serializable {@link BiConsumer}. 8 | */ 9 | public interface SerializableBiConsumer extends BiConsumer, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableBiFunction.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.BiFunction; 5 | 6 | /** 7 | * A serializable {@link BiFunction}. 8 | */ 9 | public interface SerializableBiFunction extends BiFunction, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableBiPredicate.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.BiPredicate; 5 | 6 | /** 7 | * A serializable {@link BiPredicate}. 8 | */ 9 | public interface SerializableBiPredicate extends BiPredicate, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableBinaryOperator.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.BinaryOperator; 5 | 6 | /** 7 | * A serializable {@link BinaryOperator}. 8 | */ 9 | public interface SerializableBinaryOperator extends BinaryOperator, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableConsumer.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.Consumer; 5 | 6 | /** 7 | * A serializable {@link Consumer}. 8 | */ 9 | public interface SerializableConsumer extends Consumer, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableFunction.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.Function; 5 | 6 | /** 7 | * A serializable {@link Function}. 8 | */ 9 | public interface SerializableFunction extends Function, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializablePredicate.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.Predicate; 5 | 6 | /** 7 | * A serializable {@link Predicate}. 8 | */ 9 | public interface SerializablePredicate extends Predicate, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableSupplier.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.Supplier; 5 | 6 | /** 7 | * A serializable {@link Supplier}. 8 | */ 9 | public interface SerializableSupplier extends Supplier, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/SerializableToDoubleFunction.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.function; 2 | 3 | import java.io.Serializable; 4 | import java.util.function.ToDoubleFunction; 5 | 6 | /** 7 | * A serializable {@link ToDoubleFunction}. 8 | */ 9 | public interface SerializableToDoubleFunction extends ToDoubleFunction, Serializable {} 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/function/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Interfaces for functions declared in the API. 3 | * 4 | *

5 | * The purpose of these interfaces (copying the functionality of JAVA's generic lambda functions) 6 | * is to make them serializable. 7 | *

8 | */ 9 | package org.heigit.ohsome.oshdb.util.function; 10 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/geometry/fip/FastPointInPolygon.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.fip; 2 | 3 | import java.util.function.Predicate; 4 | import org.locationtech.jts.geom.Geometry; 5 | import org.locationtech.jts.geom.Point; 6 | import org.locationtech.jts.geom.Polygonal; 7 | 8 | /** 9 | * Fast point in (multi)polygon test inspired by 10 | * 11 | * https://blog.jochentopf.com/2017-02-06-expedicious-and-exact-extracts-with-osmium.html. 12 | */ 13 | public class FastPointInPolygon extends FastInPolygon implements Predicate { 14 | public

FastPointInPolygon(P geom) { 15 | super(geom); 16 | } 17 | 18 | /** 19 | * Tests if the given bounding box is fully inside of the polygon. 20 | */ 21 | @Override 22 | public boolean test(Point point) { 23 | return crossingNumber(point, true) % 2 == 1; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/mappable/OSHDBMapReducible.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.mappable; 2 | 3 | /** 4 | * Marks a class as possible data type of an OSHDB-MapReducer. 5 | */ 6 | public interface OSHDBMapReducible {} 7 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/mappable/OSMEntitySnapshot.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.mappable; 2 | 3 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 4 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 6 | import org.locationtech.jts.geom.Geometry; 7 | 8 | /** 9 | * Information about a single OSM object at a specific point in time ("snapshot"). 10 | */ 11 | public interface OSMEntitySnapshot extends OSHDBMapReducible, Comparable { 12 | /** 13 | * The timestamp for which the snapshot of this data entity has been obtained. 14 | * 15 | * @return snapshot timestamp as an OSHDBTimestamp object 16 | */ 17 | OSHDBTimestamp getTimestamp(); 18 | 19 | /** 20 | * The timestamp when the entity of the snapshot was last modified before the snapshot timestamp. 21 | * 22 | * @return last modification timestamp as an OSHDBTimestamp object 23 | */ 24 | OSHDBTimestamp getLastContributionTimestamp(); 25 | 26 | /** 27 | * The geometry of this entity at the snapshot's timestamp clipped to the requested area of 28 | * interest. 29 | * 30 | * @return the geometry as a JTS Geometry 31 | */ 32 | Geometry getGeometry(); 33 | 34 | /** 35 | * The geometry of this entity at the snapshot's timestamp. This is the full (unclipped) geometry 36 | * of the osm entity. 37 | * 38 | * @return the unclipped geometry of the osm entity snapshot as a JTS Geometry 39 | */ 40 | Geometry getGeometryUnclipped(); 41 | 42 | /** 43 | * The entity for which the snapshot has been obtained. 44 | * 45 | *

This is the (not deleted) version of a OSHEntity that was valid at the provided snapshot 46 | * timestamp.

47 | * 48 | * @return the OSMEntity object of this snapshot 49 | */ 50 | OSMEntity getEntity(); 51 | 52 | /** 53 | * The (parent) osh entity of the osm entity for which the snapshot has been obtained. 54 | * 55 | * @return the OSHEntity object corresponding to this snapshot 56 | */ 57 | OSHEntity getOSHEntity(); 58 | } 59 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/mappable/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Interfaces for "mappable" objects in the oshdb API. 3 | */ 4 | package org.heigit.ohsome.oshdb.util.mappable; 5 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/taginterpreter/InvertedHashSet.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.taginterpreter; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * Negated Set: contains(x) returns true only if x has not been add()ed to the inverted set 8 | * previously. Useful to supply where a method expects a whitelist "set", but one has a blacklist of 9 | * values instead. (or vv) 10 | */ 11 | public class InvertedHashSet extends HashSet implements Set { 12 | private static final long serialVersionUID = 1L; 13 | 14 | @Override 15 | public boolean isEmpty() { 16 | return false; 17 | } 18 | 19 | @Override 20 | public boolean contains(Object o) { 21 | return !super.contains(o); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/taginterpreter/TagInterpreter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.taginterpreter; 2 | 3 | import java.io.Serializable; 4 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 5 | import org.heigit.ohsome.oshdb.osm.OSMMember; 6 | import org.heigit.ohsome.oshdb.osm.OSMRelation; 7 | 8 | /** 9 | * Used to provided information needed to create actual geometries from OSM data. 10 | * 11 | *

12 | * Some information about OSM entities is only soft-coded into their tags, for example if a closed 13 | * way should represent a polygon (e.g. a building) or just a (linestring) loop (e.g. a roundabout). 14 | * Similarly, some information needed to build geometries from multipolygon relations is encoded 15 | * into the relation members' roles. 16 | *

17 | */ 18 | public interface TagInterpreter extends Serializable { 19 | 20 | boolean isArea(OSMEntity entity); 21 | 22 | boolean isLine(OSMEntity entity); 23 | 24 | boolean hasInterestingTagKey(OSMEntity osm); 25 | 26 | boolean isMultipolygonOuterMember(OSMMember osmMember); 27 | 28 | boolean isMultipolygonInnerMember(OSMMember osmMember); 29 | 30 | boolean isOldStyleMultipolygon(OSMRelation osmRelation); 31 | } 32 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/tagtranslator/ClosableSqlArray.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | import java.sql.Array; 4 | import java.sql.Connection; 5 | import java.sql.SQLException; 6 | import java.util.Collection; 7 | 8 | public class ClosableSqlArray implements AutoCloseable { 9 | 10 | public static ClosableSqlArray createArray(Connection conn, String typeName, Collection elements) throws SQLException { 11 | var array = conn.createArrayOf(typeName, elements.toArray()); 12 | return new ClosableSqlArray(array); 13 | } 14 | 15 | private Array array; 16 | 17 | public ClosableSqlArray(Array array) { 18 | this.array = array; 19 | } 20 | 21 | public Array get() { 22 | return array; 23 | } 24 | 25 | @Override 26 | public void close() throws Exception { 27 | array.free(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/tagtranslator/OSMRole.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | /** 4 | * Represents an OSM role (which can be an arbitrary string). 5 | */ 6 | public class OSMRole { 7 | private String role; 8 | 9 | public OSMRole(String role) { 10 | this.role = role; 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return this.role; 16 | } 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | return o instanceof OSMRole && ((OSMRole) o).role.equals(this.role); 21 | } 22 | 23 | @Override 24 | public int hashCode() { 25 | return this.role.hashCode(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/tagtranslator/OSMTag.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | /** 4 | * Represents an OSM tag (which consists of two arbitrary strings forming a key-value pair). 5 | */ 6 | public class OSMTag implements OSMTagInterface { 7 | private String key; 8 | private String value; 9 | 10 | public OSMTag(String key, String value) { 11 | this.key = key; 12 | this.value = value; 13 | } 14 | 15 | public String getKey() { 16 | return this.key; 17 | } 18 | 19 | public String getValue() { 20 | return this.value; 21 | } 22 | 23 | @Override 24 | public boolean equals(Object o) { 25 | return o instanceof OSMTag 26 | && ((OSMTag) o).key.equals(this.key) && ((OSMTag) o).value.equals(this.value); 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return this.key.hashCode() + this.value.hashCode(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return this.key + "=" + this.value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/tagtranslator/OSMTagInterface.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | /** 4 | * An OSM tag ({@link OSMTag}) or an OSM tag key ({@link OSMTagKey}). 5 | * 6 | *

This interface allows to write methods that accept both OSMTag and OSMTagKey 7 | * objects as parameters without overloading, and it allows to write methods that 8 | * return either an OSMTag or an OSMTagKey object.

9 | */ 10 | public interface OSMTagInterface {} 11 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/tagtranslator/OSMTagKey.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | /** 4 | * Represents an OSM tag key (which can be an arbitrary string). 5 | */ 6 | public class OSMTagKey implements OSMTagInterface { 7 | private String key; 8 | 9 | public OSMTagKey(String key) { 10 | this.key = key; 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return this.key; 16 | } 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | return o instanceof OSMTagKey && ((OSMTagKey) o).key.equals(this.key); 21 | } 22 | 23 | @Override 24 | public int hashCode() { 25 | return this.key.hashCode(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/time/OSHDBTimestampException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.time; 2 | 3 | /** 4 | * An exception representing a problem of handling timestamps in the OSHDB. 5 | */ 6 | public class OSHDBTimestampException extends RuntimeException { 7 | 8 | public OSHDBTimestampException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/time/OSHDBTimestampIllegalArgumentException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.time; 2 | 3 | /** 4 | * An exception marking a problem with (for the OSHDB) illegal timestamps. 5 | */ 6 | public class OSHDBTimestampIllegalArgumentException extends OSHDBTimestampException { 7 | 8 | public OSHDBTimestampIllegalArgumentException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/time/OSHDBTimestampInterval.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.time; 2 | 3 | import java.io.Serializable; 4 | import java.util.Objects; 5 | import java.util.SortedSet; 6 | import javax.annotation.Nonnull; 7 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 8 | 9 | /** 10 | * A from-to time interval. 11 | */ 12 | public class OSHDBTimestampInterval implements Serializable, Comparable { 13 | private final OSHDBTimestamp fromTimestamp; 14 | private final OSHDBTimestamp toTimestamp; 15 | 16 | public OSHDBTimestampInterval() { 17 | this(new OSHDBTimestamp(Long.MIN_VALUE), new OSHDBTimestamp(Long.MAX_VALUE)); 18 | } 19 | 20 | public OSHDBTimestampInterval(OSHDBTimestamp fromTimestamp, OSHDBTimestamp toTimestamp) { 21 | this.fromTimestamp = fromTimestamp; 22 | this.toTimestamp = toTimestamp; 23 | } 24 | 25 | public OSHDBTimestampInterval(SortedSet oshdbTimestamps) { 26 | this(oshdbTimestamps.first(), oshdbTimestamps.last()); 27 | } 28 | 29 | public boolean intersects(OSHDBTimestampInterval other) { 30 | return other.toTimestamp.getEpochSecond() >= this.fromTimestamp.getEpochSecond() 31 | && other.fromTimestamp.getEpochSecond() <= this.toTimestamp.getEpochSecond(); 32 | } 33 | 34 | public boolean includes(OSHDBTimestamp timestamp) { 35 | return timestamp.getEpochSecond() >= this.fromTimestamp.getEpochSecond() 36 | && timestamp.getEpochSecond() < this.toTimestamp.getEpochSecond(); 37 | } 38 | 39 | @SuppressWarnings("MissingJavadocMethod") 40 | public int compareAgainstTimestamp(@Nonnull OSHDBTimestamp timestamp) { 41 | if (this.includes(timestamp)) { 42 | return 0; 43 | } 44 | return timestamp.getEpochSecond() < this.fromTimestamp.getEpochSecond() ? -1 : 1; 45 | } 46 | 47 | @Override 48 | public int compareTo(@Nonnull OSHDBTimestampInterval o) { 49 | int c = this.fromTimestamp.compareTo(o.fromTimestamp); 50 | if (c == 0) { 51 | c = this.toTimestamp.compareTo(o.toTimestamp); 52 | } 53 | return c; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object o) { 58 | return o instanceof OSHDBTimestampInterval 59 | && this.fromTimestamp.equals(((OSHDBTimestampInterval) o).fromTimestamp) 60 | && this.toTimestamp.equals(((OSHDBTimestampInterval) o).toTimestamp); 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | return Objects.hash(fromTimestamp, toTimestamp); 66 | } 67 | } -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/time/OSHDBTimestampList.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.time; 2 | 3 | import java.io.Serializable; 4 | import java.util.SortedSet; 5 | import java.util.TreeSet; 6 | import java.util.stream.Collectors; 7 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 8 | 9 | /** 10 | * Provider of a sorted list of (unix) timestamps. 11 | */ 12 | public interface OSHDBTimestampList extends Serializable { 13 | /** 14 | * Provides a sorted set of OSHDBTimestamps. 15 | * 16 | * @return a sorted set of oshdb timestamps 17 | */ 18 | SortedSet get(); 19 | 20 | /** 21 | * Convenience method that converts the timestamp list into raw unix timestamps (long values). 22 | * 23 | * @return this list of timestamps as raw unix timestamps (measured in seconds) 24 | */ 25 | default SortedSet getRawUnixTimestamps() { 26 | return this.get().stream() 27 | .map(OSHDBTimestamp::getEpochSecond) 28 | .collect(Collectors.toCollection(TreeSet::new)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /oshdb-util/src/main/java/org/heigit/ohsome/oshdb/util/time/OSHDBTimestampParseException.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.time; 2 | 3 | /** 4 | * An exception marking a parsing problem. 5 | */ 6 | public class OSHDBTimestampParseException extends OSHDBTimestampException { 7 | 8 | public OSHDBTimestampParseException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /oshdb-util/src/main/resources/json/uninterestingTags.json: -------------------------------------------------------------------------------- 1 | [ 2 | "source", 3 | "source_ref", 4 | "source:ref", 5 | "history", 6 | "attribution", 7 | "created_by", 8 | "tiger:county", 9 | "tiger:tlid", 10 | "tiger:upload_uuid" 11 | ] -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/OSHDBGeometryTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry; 2 | 3 | import static org.heigit.ohsome.oshdb.util.geometry.helpers.TimestampParser.toOSHDBTimestamp; 4 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 5 | 6 | import com.google.common.collect.ListMultimap; 7 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 8 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 9 | import org.heigit.ohsome.oshdb.osm.OSMNode; 10 | import org.heigit.ohsome.oshdb.osm.OSMRelation; 11 | import org.heigit.ohsome.oshdb.osm.OSMWay; 12 | import org.heigit.ohsome.oshdb.util.geometry.helpers.OSMXmlReaderTagInterpreter; 13 | import org.heigit.ohsome.oshdb.util.taginterpreter.TagInterpreter; 14 | import org.heigit.ohsome.oshdb.util.xmlreader.OSMXmlReader; 15 | import org.locationtech.jts.geom.Geometry; 16 | 17 | public abstract class OSHDBGeometryTest { 18 | protected final OSMXmlReader testData = new OSMXmlReader(); 19 | protected final ListMultimap nodes; 20 | protected final ListMultimap ways; 21 | protected final ListMultimap relations; 22 | protected final TagInterpreter areaDecider; 23 | 24 | protected OSHDBGeometryTest(String... testdata) { 25 | for (var data : testdata) { 26 | testData.add(data); 27 | } 28 | nodes = testData.nodes(); 29 | ways = testData.ways(); 30 | relations = testData.relations(); 31 | areaDecider = new OSMXmlReaderTagInterpreter(testData); 32 | } 33 | 34 | protected OSMNode nodes(long id, int index) { 35 | return nodes.get(id).get(index); 36 | } 37 | 38 | protected OSMWay ways(long id, int index) { 39 | return ways.get(id).get(index); 40 | } 41 | 42 | protected OSMRelation relations(long id, int index) { 43 | return relations.get(id).get(index); 44 | } 45 | 46 | protected Geometry buildGeometry(OSMEntity entity) { 47 | OSHDBTimestamp timestamp = new OSHDBTimestamp(entity); 48 | return buildGeometry(entity, timestamp); 49 | } 50 | 51 | protected Geometry buildGeometry(OSMEntity entity, String timestamp) { 52 | return buildGeometry(entity, toOSHDBTimestamp(timestamp)); 53 | } 54 | 55 | protected Geometry buildGeometry(OSMEntity entity, OSHDBTimestamp timestamp) { 56 | return assertDoesNotThrow(() -> 57 | OSHDBGeometryBuilder.getGeometry(entity, timestamp, areaDecider)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/helpers/FakeTagInterpreter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.helpers; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMMember; 5 | import org.heigit.ohsome.oshdb.osm.OSMRelation; 6 | import org.heigit.ohsome.oshdb.util.taginterpreter.TagInterpreter; 7 | 8 | /** 9 | * A dummy implementation of the {@link TagInterpreter} interface. 10 | */ 11 | public abstract class FakeTagInterpreter implements TagInterpreter { 12 | @Override 13 | public boolean isArea(OSMEntity entity) { 14 | return false; 15 | } 16 | 17 | @Override 18 | public boolean isLine(OSMEntity entity) { 19 | return !isArea(entity); 20 | } 21 | 22 | @Override 23 | public boolean hasInterestingTagKey(OSMEntity osm) { 24 | return false; 25 | } 26 | 27 | @Override 28 | public boolean isMultipolygonOuterMember(OSMMember osmMember) { 29 | return false; 30 | } 31 | 32 | @Override 33 | public boolean isMultipolygonInnerMember(OSMMember osmMember) { 34 | return false; 35 | } 36 | 37 | @Override 38 | public boolean isOldStyleMultipolygon(OSMRelation osmRelation) { 39 | return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/helpers/FakeTagInterpreterAreaAlways.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.helpers; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMMember; 5 | import org.heigit.ohsome.oshdb.osm.OSMWay; 6 | import org.heigit.ohsome.oshdb.util.taginterpreter.TagInterpreter; 7 | 8 | /** 9 | * A dummy implementation of the {@link TagInterpreter} interface which interprets all closed ways 10 | * as polygons. 11 | */ 12 | public class FakeTagInterpreterAreaAlways extends FakeTagInterpreter { 13 | @Override 14 | public boolean isArea(OSMEntity e) { 15 | if (e instanceof OSMWay) { 16 | OSMMember[] nds = ((OSMWay) e).getMembers(); 17 | return (nds.length >= 4 && nds[0].getId() == nds[nds.length - 1].getId()); 18 | } 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/helpers/FakeTagInterpreterAreaMultipolygonAllOuters.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.helpers; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMMember; 4 | import org.heigit.ohsome.oshdb.util.taginterpreter.TagInterpreter; 5 | 6 | /** 7 | * A dummy implementation of the {@link TagInterpreter} interface which interprets all 8 | * multipolygon members as outer ways. 9 | */ 10 | public class FakeTagInterpreterAreaMultipolygonAllOuters extends FakeTagInterpreterAreaAlways { 11 | @Override 12 | public boolean isMultipolygonOuterMember(OSMMember osmMember) { 13 | return true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/helpers/FakeTagInterpreterAreaNever.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.helpers; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 4 | import org.heigit.ohsome.oshdb.util.taginterpreter.TagInterpreter; 5 | 6 | /** 7 | * A dummy implementation of the {@link TagInterpreter} interface which interprets all OSM ways 8 | * as lines. 9 | */ 10 | public class FakeTagInterpreterAreaNever extends FakeTagInterpreter { 11 | @Override 12 | public boolean isArea(OSMEntity e) { 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/helpers/OSMXmlReaderTagInterpreter.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.helpers; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 4 | import org.heigit.ohsome.oshdb.osm.OSMMember; 5 | import org.heigit.ohsome.oshdb.osm.OSMRelation; 6 | import org.heigit.ohsome.oshdb.osm.OSMType; 7 | import org.heigit.ohsome.oshdb.osm.OSMWay; 8 | import org.heigit.ohsome.oshdb.util.xmlreader.OSMXmlReader; 9 | 10 | /** 11 | * An implementation of the tag interpreter for use with {@link OSMXmlReader}. 12 | */ 13 | public class OSMXmlReaderTagInterpreter extends FakeTagInterpreter { 14 | private final int area; 15 | private final int areaYes; 16 | private final int type; 17 | private final int typeMultipolygon; 18 | private final int emptyRole; 19 | private final int outer; 20 | private final int inner; 21 | 22 | /** 23 | * Constructor reading all required values from a given {@link OSMXmlReader}. 24 | */ 25 | public OSMXmlReaderTagInterpreter(OSMXmlReader osmXmlReader) { 26 | area = osmXmlReader.keys().getOrDefault("area", -1); 27 | areaYes = area == -1 ? -1 : osmXmlReader.keyValues().get(area).getOrDefault("yes", -1); 28 | type = osmXmlReader.keys().getOrDefault("type", -1); 29 | typeMultipolygon = type == -1 ? -1 : osmXmlReader.keyValues().get(type) 30 | .getOrDefault("multipolygon", -1); 31 | emptyRole = osmXmlReader.roles().getOrDefault("", -1); 32 | outer = osmXmlReader.roles().getOrDefault("outer", -1); 33 | inner = osmXmlReader.roles().getOrDefault("inner", -1); 34 | } 35 | 36 | @Override 37 | public boolean isArea(OSMEntity e) { 38 | if (e instanceof OSMWay) { 39 | OSMMember[] nds = ((OSMWay) e).getMembers(); 40 | return nds.length >= 4 && nds[0].getId() == nds[nds.length - 1].getId() 41 | && e.getTags().hasTag(area, areaYes); 42 | } 43 | if (e instanceof OSMRelation) { 44 | return e.getTags().hasTag(type, typeMultipolygon); 45 | } 46 | return true; 47 | } 48 | 49 | @Override 50 | public boolean isMultipolygonOuterMember(OSMMember osmMember) { 51 | return osmMember.getType() == OSMType.WAY 52 | && (osmMember.getRole().getId() == outer || osmMember.getRole().getId() == emptyRole); 53 | } 54 | 55 | @Override 56 | public boolean isMultipolygonInnerMember(OSMMember osmMember) { 57 | return osmMember.getType() == OSMType.WAY && osmMember.getRole().getId() == inner; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/helpers/TimestampParser.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.helpers; 2 | 3 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 4 | import org.heigit.ohsome.oshdb.util.time.IsoDateTimeParser; 5 | 6 | /** 7 | * Helper methods in addition to the {@link IsoDateTimeParser} class. 8 | */ 9 | public class TimestampParser { 10 | /** 11 | * Returns an {@link OSHDBTimestamp} converted with 12 | * {@link IsoDateTimeParser#parseIsoDateTime(String)} using a given {@link String timeString}. 13 | */ 14 | public static OSHDBTimestamp toOSHDBTimestamp(String timeString) { 15 | return new OSHDBTimestamp(IsoDateTimeParser.parseIsoDateTime(timeString).toEpochSecond()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/incomplete/OSHDBGeometryBuilderTestWayIncompleteDataTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.incomplete; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 7 | import org.heigit.ohsome.oshdb.util.geometry.OSHDBGeometryBuilder; 8 | import org.heigit.ohsome.oshdb.util.geometry.OSHDBGeometryTest; 9 | import org.heigit.ohsome.oshdb.util.geometry.helpers.TimestampParser; 10 | import org.junit.jupiter.api.Test; 11 | import org.locationtech.jts.geom.Geometry; 12 | import org.locationtech.jts.geom.LineString; 13 | 14 | /** 15 | * Tests the {@link OSHDBGeometryBuilder} class on incomplete ways. 16 | */ 17 | class OSHDBGeometryBuilderTestWayIncompleteDataTest extends OSHDBGeometryTest { 18 | private final OSHDBTimestamp timestamp = 19 | TimestampParser.toOSHDBTimestamp("2014-01-01T00:00:00Z"); 20 | 21 | OSHDBGeometryBuilderTestWayIncompleteDataTest() { 22 | super("./src/test/resources/incomplete-osm/way.osm"); 23 | } 24 | 25 | @Test 26 | void testOneOfNodesNotExistent() { 27 | // Way with four node references, one node missing 28 | Geometry result = buildGeometry(ways(100L, 0), timestamp); 29 | assertTrue(result instanceof LineString); 30 | assertTrue(result.isValid()); 31 | assertTrue(result.getCoordinates().length >= 3); 32 | } 33 | 34 | @Test 35 | void testWayAreaYes() { 36 | // Way with four nodes, area = yes 37 | Geometry result = buildGeometry(ways(101L, 0), timestamp); 38 | assertTrue(result instanceof LineString); 39 | assertTrue(result.isValid()); 40 | assertTrue(result.getCoordinates().length >= 3); 41 | } 42 | 43 | @Test 44 | void testAllNodesNotExistent() { 45 | // Way with two nodes, both missing 46 | Geometry result = buildGeometry(ways(102L, 0), timestamp); 47 | assertEquals(0, result.getCoordinates().length); 48 | assertTrue(result.isValid()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/relations/OSHDBGeometryBuilderMultipolygonInvalidInnersTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.relations; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 6 | import org.heigit.ohsome.oshdb.util.geometry.OSHDBGeometryBuilder; 7 | import org.heigit.ohsome.oshdb.util.geometry.OSHDBGeometryTest; 8 | import org.heigit.ohsome.oshdb.util.geometry.helpers.TimestampParser; 9 | import org.junit.jupiter.api.Test; 10 | import org.locationtech.jts.geom.Geometry; 11 | import org.locationtech.jts.geom.Polygon; 12 | 13 | /** 14 | * Tests the {@link OSHDBGeometryBuilder} class for the special case of multipolygons with 15 | * invalid inner rings. 16 | */ 17 | class OSHDBGeometryBuilderMultipolygonInvalidInnersTest extends OSHDBGeometryTest { 18 | private final OSHDBTimestamp timestamp = 19 | TimestampParser.toOSHDBTimestamp("2014-01-01T00:00:00Z"); 20 | 21 | OSHDBGeometryBuilderMultipolygonInvalidInnersTest() { 22 | super("./src/test/resources/relations/invalid-inner-rings.osm"); 23 | } 24 | 25 | @Test 26 | void testDuplicateInnerRings() { 27 | // data has invalid (duplicate) inner rings 28 | Geometry result = buildGeometry(relations(1L, 0), timestamp); 29 | assertTrue(result instanceof Polygon); 30 | } 31 | 32 | @Test 33 | void testTouchingIncompleteInnerRings() { 34 | // data has invalid (duplicate) inner rings 35 | Geometry result = buildGeometry(relations(2L, 0), timestamp); 36 | assertTrue(result instanceof Polygon); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/geometry/relations/OSHDBGeometryBuilderMultipolygonInvalidOutersTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.geometry.relations; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 6 | import org.heigit.ohsome.oshdb.util.geometry.OSHDBGeometryBuilder; 7 | import org.heigit.ohsome.oshdb.util.geometry.OSHDBGeometryTest; 8 | import org.heigit.ohsome.oshdb.util.geometry.helpers.TimestampParser; 9 | import org.junit.jupiter.api.Test; 10 | import org.locationtech.jts.geom.Geometry; 11 | import org.locationtech.jts.geom.MultiPolygon; 12 | 13 | /** 14 | * Tests the {@link OSHDBGeometryBuilder} class for the special case of multipolygons with 15 | * invalid outer rings. 16 | */ 17 | class OSHDBGeometryBuilderMultipolygonInvalidOutersTest extends OSHDBGeometryTest { 18 | private final OSHDBTimestamp timestamp = 19 | TimestampParser.toOSHDBTimestamp("2014-01-01T00:00:00Z"); 20 | 21 | OSHDBGeometryBuilderMultipolygonInvalidOutersTest() { 22 | super("./src/test/resources/relations/invalid-outer-ring.osm"); 23 | } 24 | 25 | @Test 26 | void test() { 27 | // data has invalid (self-intersecting) outer ring 28 | Geometry result = buildGeometry(relations(1L, 0), timestamp); 29 | assertTrue(result instanceof MultiPolygon); 30 | } 31 | } -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/tagtranslator/CachedTagTranslatorTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | /** 4 | * Tests the {@link CachedTagTranslator} class. 5 | */ 6 | class CachedTagTranslatorTest extends AbstractTagTranslatorTest { 7 | 8 | @Override 9 | TagTranslator getTranslator() { 10 | return new CachedTagTranslator(new JdbcTagTranslator(source), 1000, 1000); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/tagtranslator/JdbcTagTranslatorTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.tagtranslator; 2 | 3 | /** 4 | * Tests the {@link JdbcTagTranslator} class. 5 | */ 6 | class JdbcTagTranslatorTest extends AbstractTagTranslatorTest { 7 | 8 | @Override 9 | TagTranslator getTranslator() { 10 | return new JdbcTagTranslator(source); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/time/OSHDBTimestampIntervalTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.time; 2 | 3 | import static java.lang.Integer.signum; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 7 | import org.junit.jupiter.api.Test; 8 | 9 | /** 10 | * Test Suite for {@code OSHDBTimestampInterval}. 11 | */ 12 | class OSHDBTimestampIntervalTest { 13 | 14 | /** 15 | * Test for the contract of {@code Comparable.compareTo}. 16 | */ 17 | @Test 18 | void testCompareTo() { 19 | var x = new OSHDBTimestampInterval(new OSHDBTimestamp(0), new OSHDBTimestamp(1)); 20 | var y = new OSHDBTimestampInterval(new OSHDBTimestamp(0), new OSHDBTimestamp(2)); 21 | 22 | assertEquals(-1, signum(x.compareTo(y))); 23 | assertEquals(1, signum(y.compareTo(x))); 24 | 25 | // The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. 26 | // This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) 27 | // throws an exception. 28 | assertEquals(true, signum(x.compareTo(y)) == signum(y.compareTo(x)) * -1); 29 | 30 | // The implementor must also ensure that the relation is transitive: 31 | // (x.compareTo(y) > 0 && y.compareTo(z) > 0) implies x.compareTo(z) > 0. 32 | var z = new OSHDBTimestampInterval(new OSHDBTimestamp(1), new OSHDBTimestamp(2)); 33 | assertEquals(-1, signum(y.compareTo(z))); 34 | assertEquals(-1, signum(x.compareTo(z))); 35 | 36 | // Finally, the implementor must ensure that x.compareTo(y)==0 implies that 37 | // sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z. 38 | y = new OSHDBTimestampInterval(new OSHDBTimestamp(0), new OSHDBTimestamp(1)); 39 | assertEquals(0, x.compareTo(y)); 40 | assertEquals(true, signum(x.compareTo(z)) == signum(y.compareTo(z))); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/xmlreader/MutableOSMEntity.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.xmlreader; 2 | 3 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 4 | 5 | /** 6 | * A mutable OSM entity, specifically for use in {@link OSMXmlReader}. 7 | */ 8 | public class MutableOSMEntity { 9 | 10 | private long id; 11 | 12 | private int version; 13 | private boolean visible; 14 | private long timestamp; 15 | private long changeset; 16 | private int userId; 17 | private int[] tags; 18 | 19 | public long getId() { 20 | return id; 21 | } 22 | 23 | public void setId(long id) { 24 | this.id = id; 25 | } 26 | 27 | public int getVersion() { 28 | return version; 29 | } 30 | 31 | public boolean isVisible() { 32 | return visible; 33 | } 34 | 35 | public void isVisible(boolean visible) { 36 | this.visible = visible; 37 | } 38 | 39 | 40 | public void setVersion(int version) { 41 | this.version = version; 42 | } 43 | 44 | public long getEpochSecond() { 45 | return timestamp; 46 | } 47 | 48 | 49 | public void setTimestamp(OSHDBTimestamp timestamp) { 50 | this.timestamp = timestamp.getEpochSecond(); 51 | } 52 | 53 | public void setTimestamp(long timestamp) { 54 | this.timestamp = timestamp; 55 | } 56 | 57 | public long getChangeset() { 58 | return changeset; 59 | } 60 | 61 | public void setChangeset(long changeset) { 62 | this.changeset = changeset; 63 | } 64 | 65 | public int getUserId() { 66 | return userId; 67 | } 68 | 69 | public void setUserId(int userId) { 70 | this.userId = userId; 71 | } 72 | 73 | public int[] getTags() { 74 | return tags; 75 | } 76 | 77 | public void setTags(int[] tags) { 78 | this.tags = tags; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/xmlreader/MutableOSMNode.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.xmlreader; 2 | 3 | /** 4 | * A mutable OSM node, specifically for use in {@link OSMXmlReader}. 5 | */ 6 | public class MutableOSMNode extends MutableOSMEntity { 7 | private int longitude; 8 | private int latitude; 9 | 10 | public int getLon() { 11 | return longitude; 12 | } 13 | 14 | public void setLon(int longitude) { 15 | this.longitude = longitude; 16 | } 17 | 18 | public int getLat() { 19 | return latitude; 20 | } 21 | 22 | public void setLat(int latitude) { 23 | this.latitude = latitude; 24 | } 25 | 26 | public void setExtension(int longitude, int latitude) { 27 | this.longitude = longitude; 28 | this.latitude = latitude; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/xmlreader/MutableOSMRelation.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.xmlreader; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMMember; 4 | 5 | /** 6 | * A mutable OSM relation, specifically for use in {@link OSMXmlReader}. 7 | */ 8 | public class MutableOSMRelation extends MutableOSMEntity { 9 | private OSMMember[] members; 10 | 11 | public OSMMember[] getMembers() { 12 | return members; 13 | } 14 | 15 | public void setExtension(OSMMember[] members) { 16 | this.members = members; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /oshdb-util/src/test/java/org/heigit/ohsome/oshdb/util/xmlreader/MutableOSMWay.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.xmlreader; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMMember; 4 | 5 | /** 6 | * A mutable OSM way, specifically for use in {@link OSMXmlReader}. 7 | */ 8 | public class MutableOSMWay extends MutableOSMEntity { 9 | private OSMMember[] members; 10 | 11 | public OSMMember[] getMembers() { 12 | return members; 13 | } 14 | 15 | public void setExtension(OSMMember[] members) { 16 | this.members = members; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /oshdb-util/src/test/resources/different-timestamps/not-osm-type-specific.osm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /oshdb-util/src/test/resources/geometryBuilder.osh: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /oshdb-util/src/test/resources/incomplete-osm/way.osm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /oshdb-util/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=WARN, stderr 3 | 4 | # Redirect log messages to console 5 | log4j.appender.stderr=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stderr.Target=System.err 7 | log4j.appender.stderr.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stderr.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 9 | -------------------------------------------------------------------------------- /oshdb-util/src/test/resources/osm-testdata/readme.md.txt: -------------------------------------------------------------------------------- 1 | Test data from [osmcode/osm-testdata](https://github.com/osmcode/osm-testdata). Downloaded on 2018-03-20. -------------------------------------------------------------------------------- /oshdb-util/src/test/resources/relations/invalid-inner-rings.osm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /oshdb/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.heigit.ohsome 7 | oshdb-parent 8 | 1.3.0-SNAPSHOT 9 | 10 | 11 | oshdb 12 | OSHDB core 13 | The central data model of the OpenStreetMap History Database. 14 | 15 | 16 | 3.3.0 17 | 18 | 19 | 20 | 21 | org.slf4j 22 | slf4j-api 23 | 24 | 25 | 26 | com.google.guava 27 | guava 28 | ${guava.version} 29 | 30 | 31 | 32 | org.slf4j 33 | slf4j-log4j12 34 | test 35 | 36 | 37 | 38 | com.h2database 39 | h2 40 | ${h2.version} 41 | test 42 | 43 | 44 | 45 | 46 | 47 | withDep 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-assembly-plugin 53 | ${mavenassembly.version} 54 | 55 | 56 | jar-with-dependencies 57 | 58 | 59 | 60 | 61 | make-assembly 62 | package 63 | 64 | single 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDB.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | public class OSHDB { 4 | private OSHDB() {} 5 | 6 | public static final int MAXZOOM = 14; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDBRole.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | import java.io.Serializable; 4 | import java.util.Objects; 5 | import java.util.stream.IntStream; 6 | 7 | /** 8 | * Class for representing the role of a relation member. 9 | * 10 | */ 11 | public class OSHDBRole implements Serializable { 12 | /** 13 | * The empty OSHDBRole. 14 | */ 15 | public static final OSHDBRole EMPTY = new OSHDBRole(-1); 16 | 17 | private static final int CACHE_SIZE = 256; 18 | private static final OSHDBRole[] cache = IntStream.range(0, CACHE_SIZE) 19 | .mapToObj(OSHDBRole::new) 20 | .toArray(OSHDBRole[]::new); 21 | 22 | /** 23 | * Returns an {@code OSHDBRole} instance representing the specified 24 | * {@code role id} value. 25 | * 26 | * @param id integer id of the OSHDBRole. 27 | * @return OSHDBRole instance. 28 | */ 29 | public static OSHDBRole of(int id) { 30 | if (id == -1) { 31 | return EMPTY; 32 | } 33 | if (id >= 0 && id < CACHE_SIZE) { 34 | return cache[id]; 35 | } 36 | return new OSHDBRole(id); 37 | } 38 | 39 | private static final long serialVersionUID = 1L; 40 | private int role; 41 | 42 | private OSHDBRole(int role) { 43 | this.role = role; 44 | } 45 | 46 | /** 47 | * Return integer id representation for this OSHDBRole object. 48 | * 49 | * @return integer id 50 | */ 51 | public int getId() { 52 | return this.role; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | return Objects.hash(role); 58 | } 59 | 60 | @Override 61 | public boolean equals(Object obj) { 62 | if (this == obj) { 63 | return true; 64 | } 65 | if (!(obj instanceof OSHDBRole)) { 66 | return false; 67 | } 68 | OSHDBRole other = (OSHDBRole) obj; 69 | return role == other.role; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return Integer.toString(this.role); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDBTag.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | import java.io.Serializable; 4 | import java.util.Comparator; 5 | import java.util.Objects; 6 | 7 | /** 8 | * Key/Value id base OSM Tag class. 9 | * 10 | */ 11 | public class OSHDBTag implements Comparable, Serializable { 12 | /** 13 | * Order by keyId/valueId, default Comparator for OSHDBTag. 14 | */ 15 | public static final Comparator ORDER_BY_ID = Comparator 16 | .comparingInt(OSHDBTag::getKey) 17 | .thenComparingInt(OSHDBTag::getValue); 18 | 19 | private static final long serialVersionUID = 1L; 20 | private final int key; 21 | private final int value; 22 | 23 | public OSHDBTag(int key, int value) { 24 | this.key = key; 25 | this.value = value; 26 | } 27 | 28 | public int getKey() { 29 | return this.key; 30 | } 31 | 32 | public int getValue() { 33 | return this.value; 34 | } 35 | 36 | @Override 37 | public int compareTo(OSHDBTag o) { 38 | return ORDER_BY_ID.compare(this, o); 39 | } 40 | 41 | @Override 42 | public boolean equals(Object o) { 43 | return o instanceof OSHDBTag 44 | && ((OSHDBTag) o).key == this.key && ((OSHDBTag) o).value == this.value; 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | return Objects.hash(this.key, this.value); 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return key + "=" + value; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDBTemporal.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | import java.time.Instant; 4 | import java.time.ZoneOffset; 5 | import java.time.ZonedDateTime; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Interface for objects which are associated to a single timestamp. 10 | */ 11 | public interface OSHDBTemporal { 12 | 13 | long getEpochSecond(); 14 | 15 | default boolean isBefore(OSHDBTemporal other) { 16 | return getEpochSecond() < other.getEpochSecond(); 17 | } 18 | 19 | default boolean isAfter(OSHDBTemporal other) { 20 | return getEpochSecond() > other.getEpochSecond(); 21 | } 22 | 23 | static int compare(OSHDBTemporal a, OSHDBTemporal b) { 24 | return Long.compare(a.getEpochSecond(), b.getEpochSecond()); 25 | } 26 | 27 | /** 28 | * Converts the given {@code OSHDBTemporal} to an iso-date-time string. 29 | * 30 | * @param temporal The {@code OSHDBTemporal} which should converted. 31 | * @return the iso-date-time string for the {@code OSHDBTemporal} 32 | */ 33 | static String toIsoDateTime(OSHDBTemporal temporal) { 34 | ZonedDateTime zdt = 35 | ZonedDateTime.ofInstant(Instant.ofEpochSecond(temporal.getEpochSecond()), ZoneOffset.UTC); 36 | return zdt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDBTimestamp.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class OSHDBTimestamp implements OSHDBTemporal, Comparable, Serializable { 7 | private static final long serialVersionUID = 1L; 8 | private final long epochSecond; 9 | 10 | public OSHDBTimestamp(OSHDBTemporal temporal) { 11 | this(temporal.getEpochSecond()); 12 | } 13 | 14 | public OSHDBTimestamp(long tstamp) { 15 | this.epochSecond = tstamp; 16 | } 17 | 18 | public OSHDBTimestamp(Date tstamp) { 19 | this(tstamp.getTime() / 1000); 20 | } 21 | 22 | @Override 23 | public int compareTo(OSHDBTimestamp other) { 24 | return Long.compare(this.epochSecond, other.epochSecond); 25 | } 26 | 27 | @Override 28 | public boolean equals(Object other) { 29 | if (other instanceof OSHDBTimestamp) { 30 | return this.epochSecond == ((OSHDBTimestamp) other).epochSecond; 31 | } else { 32 | return super.equals(other); 33 | } 34 | } 35 | 36 | @Override 37 | public int hashCode() { 38 | return Long.hashCode(this.epochSecond); 39 | } 40 | 41 | public Date toDate() { 42 | return new Date(this.epochSecond * 1000); 43 | } 44 | 45 | @Override 46 | public long getEpochSecond() { 47 | return this.epochSecond; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return OSHDBTemporal.toIsoDateTime(this); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/grid/GridOSHEntity.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.grid; 2 | 3 | import java.io.Serializable; 4 | import java.util.Locale; 5 | import org.heigit.ohsome.oshdb.OSHDBBoundingBox; 6 | import org.heigit.ohsome.oshdb.index.XYGrid; 7 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 8 | import org.heigit.ohsome.oshdb.util.CellId; 9 | 10 | public abstract class GridOSHEntity 11 | implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | protected final long id; 15 | protected final int level; 16 | 17 | protected final long baseTimestamp; 18 | 19 | protected final long baseLongitude; 20 | protected final long baseLatitude; 21 | 22 | protected final long baseId; 23 | 24 | protected final int[] index; 25 | protected final byte[] data; 26 | 27 | /** 28 | * Base constructor {@code GridOSHEntity}. 29 | */ 30 | protected GridOSHEntity(final long id, final int level, final long baseId, 31 | final long baseTimestamp, final int baseLongitude, final int baseLatitude, final int[] index, 32 | final byte[] data) { 33 | 34 | this.id = id; 35 | this.level = level; 36 | this.baseTimestamp = baseTimestamp; 37 | this.baseLongitude = baseLongitude; 38 | this.baseLatitude = baseLatitude; 39 | this.baseId = baseId; 40 | 41 | this.index = index; 42 | this.data = data; 43 | } 44 | 45 | public long getId() { 46 | return id; 47 | } 48 | 49 | public int getLevel() { 50 | return level; 51 | } 52 | 53 | public abstract Iterable getEntities(); 54 | 55 | @Override 56 | public String toString() { 57 | if (id >= 0) { 58 | OSHDBBoundingBox bbox = XYGrid.getBoundingBox(new CellId(level, id)); 59 | return String.format(Locale.ENGLISH, "ID:%d Level:%d %s", id, level, bbox); 60 | } else { 61 | return String.format(Locale.ENGLISH, "ID:%d Level:%d", id, level); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/grid/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package holds the top-level abstraction of the OSM-Data, grouping it in cells. 3 | */ 4 | package org.heigit.ohsome.oshdb.grid; 5 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/index/Grid.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.index; 2 | 3 | public interface Grid { 4 | long getId(double longitude, double latitude); 5 | } 6 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/index/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definitions for Grid-Cells. 3 | */ 4 | package org.heigit.ohsome.oshdb.index; 5 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osh/OSHEntity.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osh; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import org.heigit.ohsome.oshdb.OSHDBBoundable; 6 | import org.heigit.ohsome.oshdb.osm.OSMEntity; 7 | import org.heigit.ohsome.oshdb.osm.OSMType; 8 | import org.heigit.ohsome.oshdb.util.OSHDBTagKey; 9 | 10 | public interface OSHEntity { 11 | 12 | long getId(); 13 | 14 | OSMType getType(); 15 | 16 | OSHDBBoundable getBoundable(); 17 | 18 | Iterable getTagKeys(); 19 | 20 | boolean hasTagKey(OSHDBTagKey tag); 21 | 22 | boolean hasTagKey(int key); 23 | 24 | Iterable getVersions(); 25 | 26 | default List getNodes() { 27 | return Collections.emptyList(); 28 | } 29 | 30 | default List getWays() { 31 | return Collections.emptyList(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osh/OSHNode.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osh; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMNode; 4 | import org.heigit.ohsome.oshdb.osm.OSMType; 5 | 6 | public interface OSHNode extends OSHEntity { 7 | 8 | @Override 9 | default OSMType getType() { 10 | return OSMType.NODE; 11 | } 12 | 13 | @Override 14 | Iterable getVersions(); 15 | } 16 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osh/OSHRelation.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osh; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMRelation; 4 | import org.heigit.ohsome.oshdb.osm.OSMType; 5 | 6 | public interface OSHRelation extends OSHEntity { 7 | 8 | @Override 9 | default OSMType getType() { 10 | return OSMType.RELATION; 11 | } 12 | 13 | @Override 14 | Iterable getVersions(); 15 | } 16 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osh/OSHWay.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osh; 2 | 3 | import org.heigit.ohsome.oshdb.osm.OSMType; 4 | import org.heigit.ohsome.oshdb.osm.OSMWay; 5 | 6 | public interface OSHWay extends OSHEntity { 7 | 8 | @Override 9 | default OSMType getType() { 10 | return OSMType.WAY; 11 | } 12 | 13 | @Override 14 | Iterable getVersions(); 15 | } 16 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osh/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * OSHDB-Representation of OSM-Objects over time. 3 | */ 4 | package org.heigit.ohsome.oshdb.osh; 5 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMCoordinates.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | /** 4 | * Helper class for converting double precision floating point lon/lat to 5 | * osm-coordinate fix presision 7 decimal integer system. 6 | */ 7 | public class OSMCoordinates { 8 | 9 | // osm only stores 7 decimals for each coordinate 10 | public static final double GEOM_PRECISION_TO_LONG = 1E7; 11 | public static final double GEOM_PRECISION = 1.0 / GEOM_PRECISION_TO_LONG; 12 | 13 | public static int toOSM(double value) { 14 | return (int) (value * GEOM_PRECISION_TO_LONG); 15 | } 16 | 17 | public static double toWgs84(int value) { 18 | return value * GEOM_PRECISION; 19 | } 20 | 21 | public static boolean validLon(int lon) { 22 | return Math.abs(lon) < 180_0000000; 23 | } 24 | 25 | public static boolean validLat(int lat) { 26 | return Math.abs(lat) < 90_0000000; 27 | } 28 | 29 | private OSMCoordinates() {} 30 | } 31 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMEntity.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | import java.io.Serializable; 4 | import org.heigit.ohsome.oshdb.OSHDBTags; 5 | import org.heigit.ohsome.oshdb.OSHDBTemporal; 6 | 7 | /** 8 | * Base interface for single version osm-elements. 9 | * 10 | */ 11 | public interface OSMEntity extends OSHDBTemporal, Serializable { 12 | 13 | 14 | OSMType getType(); 15 | 16 | long getId(); 17 | 18 | int getVersion(); 19 | 20 | long getChangesetId(); 21 | 22 | int getUserId(); 23 | 24 | boolean isVisible(); 25 | 26 | /** 27 | * Returns a "view" of the current osm tags. 28 | */ 29 | OSHDBTags getTags(); 30 | } 31 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMMember.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | import java.io.Serializable; 4 | import java.util.Objects; 5 | import org.heigit.ohsome.oshdb.OSHDBRole; 6 | import org.heigit.ohsome.oshdb.osh.OSHEntity; 7 | 8 | /** 9 | * Holds an OSH-Object that belongs to the Way or Relation this Member is contained in. 10 | */ 11 | public class OSMMember implements Serializable { 12 | private final long id; 13 | private final OSMType type; 14 | private final OSHDBRole role; 15 | private final transient OSHEntity entity; 16 | 17 | public OSMMember(final long id, final OSMType type, final int roleId) { 18 | this(id, type, roleId, null); 19 | } 20 | 21 | /** 22 | * Create a new {@code OSMMember} instance. 23 | */ 24 | public OSMMember(final long id, final OSMType type, final int roleId, 25 | OSHEntity entity) { 26 | this.id = id; 27 | this.type = type; 28 | this.role = OSHDBRole.of(roleId); 29 | this.entity = entity; 30 | } 31 | 32 | public long getId() { 33 | return id; 34 | } 35 | 36 | public OSMType getType() { 37 | return type; 38 | } 39 | 40 | public OSHDBRole getRole() { 41 | return role; 42 | } 43 | 44 | public OSHEntity getEntity() { 45 | return entity; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return String.format("T:%s ID:%d R:%d", type, id, role.getId()); 51 | } 52 | 53 | @Override 54 | public int hashCode() { 55 | return Objects.hash(type, id, role.getId()); 56 | } 57 | 58 | @Override 59 | public boolean equals(Object obj) { 60 | if (this == obj) { 61 | return true; 62 | } 63 | if (!(obj instanceof OSMMember)) { 64 | return false; 65 | } 66 | OSMMember other = (OSMMember) obj; 67 | return type == other.type && id == other.id && role.equals(other.role); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMNode.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | /** 4 | * Interface for single version osm-element node. 5 | * 6 | */ 7 | public interface OSMNode extends OSMEntity { 8 | 9 | @Override 10 | default OSMType getType() { 11 | return OSMType.NODE; 12 | } 13 | 14 | public double getLongitude(); 15 | 16 | public double getLatitude(); 17 | 18 | public int getLon(); 19 | 20 | public int getLat(); 21 | } 22 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMRelation.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | import java.util.function.Predicate; 4 | import java.util.stream.Stream; 5 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 6 | 7 | /** 8 | * Interface for single version osm-element relation. 9 | */ 10 | public interface OSMRelation extends OSMEntity { 11 | 12 | @Override 13 | default OSMType getType() { 14 | return OSMType.RELATION; 15 | } 16 | 17 | /** 18 | * Returns the members for this current version. 19 | * 20 | * @return OSMMember for this version 21 | */ 22 | OSMMember[] getMembers(); 23 | 24 | /** 25 | * Returns a stream of all member entities (OSM) for the given timestamp. 26 | * 27 | * @param timestamp the timestamp for the osm member entity 28 | * @param memberFilter apply filter to Stream of members 29 | * @return stream of member entities (OSM) 30 | */ 31 | Stream getMemberEntities(OSHDBTimestamp timestamp, Predicate memberFilter); 32 | 33 | /** 34 | * Returns a stream of all member entities (OSM) for the given timestamp. 35 | * 36 | * @param timestamp the timestamp for the osm member entity 37 | * @return stream of member entities (OSM) 38 | */ 39 | Stream getMemberEntities(OSHDBTimestamp timestamp); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMType.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | public enum OSMType { 4 | NODE(0), 5 | WAY(1), 6 | RELATION(2); 7 | 8 | private final int value; 9 | 10 | OSMType(final int value) { 11 | this.value = value; 12 | } 13 | 14 | /** 15 | * Returns an {@code OSMType} instance represented by the given integer value (0-2), or throws an 16 | * exception otherwise. 17 | */ 18 | public static OSMType fromInt(final int value) { 19 | switch (value) { 20 | case 0: 21 | return NODE; 22 | case 1: 23 | return WAY; 24 | case 2: 25 | return RELATION; 26 | default: { 27 | final String msg = 28 | String.format("Unknown OSMType! Should be between 0 and 2, got [%d]", value); 29 | throw new IllegalArgumentException(msg); 30 | } 31 | } 32 | } 33 | 34 | public final int intValue() { 35 | return this.value; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return name().toLowerCase(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/OSMWay.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osm; 2 | 3 | import java.util.stream.Stream; 4 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 5 | 6 | /** 7 | * Interface for single version osm-element way. 8 | */ 9 | public interface OSMWay extends OSMEntity { 10 | 11 | @Override 12 | default OSMType getType() { 13 | return OSMType.WAY; 14 | } 15 | 16 | /** 17 | * Returns the members for this current version. 18 | * 19 | * @return OSMMember for this version 20 | */ 21 | OSMMember[] getMembers(); 22 | 23 | /** 24 | * Returns a stream of all member entities (OSM) for the given timestamp. 25 | * 26 | * @param timestamp the timestamp for the osm member entity 27 | * @return stream of member entities (OSM) 28 | */ 29 | Stream getMemberEntities(OSHDBTimestamp timestamp); 30 | } 31 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/osm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * OSHDB-Representation of OSM-Data. 3 | */ 4 | package org.heigit.ohsome.oshdb.osm; 5 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Core of the OSHDB-Project. It contains the three level of data-abstraction. 3 | */ 4 | package org.heigit.ohsome.oshdb; 5 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/util/OSHDBTagKey.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util; 2 | 3 | import java.io.Serializable; 4 | 5 | public class OSHDBTagKey implements Serializable { 6 | private static final long serialVersionUID = 1L; 7 | private int key; 8 | 9 | public OSHDBTagKey(int key) { 10 | this.key = key; 11 | } 12 | 13 | public int toInt() { 14 | return this.key; 15 | } 16 | 17 | public boolean isPresentInKeytables() { 18 | return this.key >= 0; 19 | } 20 | 21 | @Override 22 | public boolean equals(Object o) { 23 | return o instanceof OSHDBTagKey && ((OSHDBTagKey) o).key == this.key; 24 | } 25 | 26 | @Override 27 | public int hashCode() { 28 | return this.key; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return Integer.toString(this.key); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/util/bytearray/OSHDBByteArrayOutputStream.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util.bytearray; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | 5 | public class OSHDBByteArrayOutputStream extends ByteArrayOutputStream { 6 | 7 | public OSHDBByteArrayOutputStream(int size) { 8 | super(size); 9 | } 10 | 11 | public byte[] array() { 12 | return buf; 13 | } 14 | 15 | public int length() { 16 | return count; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /oshdb/src/main/java/org/heigit/ohsome/oshdb/util/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Utilities and helpers for a comfortable, fast and easy (raw) data access. 3 | */ 4 | package org.heigit.ohsome.oshdb.util; 5 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/OSHDBRoleTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 5 | 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.params.ParameterizedTest; 8 | import org.junit.jupiter.params.provider.ValueSource; 9 | 10 | class OSHDBRoleTest { 11 | 12 | @Test 13 | void testEmptyRole() { 14 | var empty = OSHDBRole.of(-1); 15 | assertEquals(-1, empty.getId()); 16 | assertEquals(OSHDBRole.EMPTY, empty); 17 | } 18 | 19 | @ParameterizedTest 20 | @ValueSource(ints = {-2, -1, 0, 1, 3, 5, 15, 256, 525, Integer.MAX_VALUE}) 21 | void testHashCodeAndEquals(int id) { 22 | var expected = OSHDBRole.of(id); 23 | var role = OSHDBRole.of(id); 24 | assertEquals(role, role); 25 | assertEquals(expected, role); 26 | assertEquals(expected.hashCode(), role.hashCode()); 27 | 28 | var unexpect = OSHDBRole.of(2); 29 | assertNotEquals(unexpect, role); 30 | } 31 | 32 | @Test 33 | void testNotEqualsOtherType() { 34 | var unexpect = OSHDBRole.of(2); 35 | assertNotEquals(unexpect, unexpect.toString()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/OSHDBTagTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | import org.junit.jupiter.api.Test; 8 | 9 | class OSHDBTagTest { 10 | 11 | @Test 12 | void test() { 13 | var tag = new OSHDBTag(10, 20); 14 | assertEquals(10, tag.getKey()); 15 | assertEquals(20, tag.getValue()); 16 | } 17 | 18 | @Test 19 | void testComparable() { 20 | var tag = new OSHDBTag(10, 10); 21 | 22 | assertEquals(0, tag.compareTo(new OSHDBTag(10, 10))); 23 | assertTrue(tag.compareTo(new OSHDBTag(5, 10)) > 0); 24 | assertTrue(tag.compareTo(new OSHDBTag(10, 5)) > 0); 25 | assertTrue(tag.compareTo(new OSHDBTag(20, 10)) < 0); 26 | assertTrue(tag.compareTo(new OSHDBTag(10, 15)) < 0); 27 | } 28 | 29 | @Test 30 | void testHashEqual() { 31 | var tag = new OSHDBTag(10, 10); 32 | 33 | assertEquals(tag, tag); 34 | assertEquals(tag, new OSHDBTag(10, 10)); 35 | assertEquals(tag.hashCode(), new OSHDBTag(10, 10).hashCode()); 36 | 37 | assertNotEquals(tag, new OSHDBTag(10, 20)); 38 | assertNotEquals(tag, new OSHDBTag(20, 10)); 39 | 40 | assertNotEquals(tag, tag.toString());; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/grid/GridOSHNodesTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.grid; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import com.google.common.collect.Iterables; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import org.heigit.ohsome.oshdb.impl.osh.OSHNodeImpl; 10 | import org.heigit.ohsome.oshdb.osh.OSHNode; 11 | import org.heigit.ohsome.oshdb.osm.OSM; 12 | import org.heigit.ohsome.oshdb.osm.OSMNode; 13 | import org.junit.jupiter.api.Test; 14 | 15 | class GridOSHNodesTest { 16 | 17 | @Test 18 | void testRebaseEntities() throws IOException { 19 | List hosmNodes = new ArrayList<>(); 20 | for (int i = 0; i < 3; i++) { 21 | List versions = new ArrayList<>(); 22 | versions.add(OSM.node(123L + 10 * i, 1, 123001L + 10 * i, 0L, 123, new int[] {}, 23 | 86809727 - 1000000 * i, 494094984 - 1000000 * i)); 24 | versions.add(OSM.node(123L + 10 * i, 2, 123002L + 10 * i, 0L, 123, new int[] {}, 25 | 86809727 - 1000000 * i, 494094984 - 1000000 * i)); 26 | hosmNodes.add(OSHNodeImpl.build(versions)); 27 | } 28 | 29 | GridOSHNodes instance = GridOSHNodes.rebase(2, 2, 100, 100000L, 86000000, 490000000, hosmNodes); 30 | var entities = instance.getEntities(); 31 | assertEquals(hosmNodes.size(), Iterables.size(entities)); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/grid/GridOSHWaysTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.grid; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import com.google.common.collect.Iterables; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import org.heigit.ohsome.oshdb.impl.osh.OSHNodeImpl; 11 | import org.heigit.ohsome.oshdb.impl.osh.OSHWayImpl; 12 | import org.heigit.ohsome.oshdb.osh.OSHNode; 13 | import org.heigit.ohsome.oshdb.osh.OSHWay; 14 | import org.heigit.ohsome.oshdb.osm.OSM; 15 | import org.heigit.ohsome.oshdb.osm.OSMMember; 16 | import org.heigit.ohsome.oshdb.osm.OSMNode; 17 | import org.heigit.ohsome.oshdb.osm.OSMType; 18 | import org.heigit.ohsome.oshdb.osm.OSMWay; 19 | import org.junit.jupiter.api.Test; 20 | 21 | class GridOSHWaysTest { 22 | 23 | static OSHNode buildOSHNode(List versions) { 24 | return OSHNodeImpl.build(versions); 25 | } 26 | 27 | OSHNode node100 = buildOSHNode( 28 | Arrays.asList(OSM.node(100L, 1, 1L, 0L, 123, new int[] {1, 2}, 494094984, 86809727))); 29 | OSHNode node102 = buildOSHNode( 30 | Arrays.asList(OSM.node(102L, 1, 1L, 0L, 123, new int[] {2, 1}, 494094984, 86809727))); 31 | OSHNode node104 = buildOSHNode( 32 | Arrays.asList(OSM.node(104L, 1, 1L, 0L, 123, new int[] {2, 4}, 494094984, 86809727))); 33 | 34 | @Test 35 | void testGrid() throws IOException { 36 | List hosmWays = new ArrayList<>(); 37 | for (int i = 0; i < 3; i++) { 38 | List versions = new ArrayList<>(); 39 | versions.add(OSM.way(123, 1, 3333L, 4444L, 23, new int[] {1, 1, 2, 1}, new OSMMember[] { 40 | new OSMMember(102, OSMType.NODE, 0), new OSMMember(104, OSMType.NODE, 0)})); 41 | versions.add(OSM.way(123, 3, 3333L, 4444L, 23, new int[] {1, 1, 2, 2}, new OSMMember[] { 42 | new OSMMember(100, OSMType.NODE, 0), new OSMMember(104, OSMType.NODE, 0)})); 43 | hosmWays.add(OSHWayImpl.build(versions, Arrays.asList(node100, node102, node104))); 44 | } 45 | 46 | GridOSHWays instance = GridOSHWays.compact(2, 2, 100, 100000L, 86000000, 490000000, hosmWays); 47 | var entities = instance.getEntities(); 48 | assertEquals(hosmWays.size(), Iterables.size(entities)); 49 | } 50 | } -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/osh/OSHEntityTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.osh; 2 | 3 | import static org.heigit.ohsome.oshdb.osh.OSHNodeTest.buildOSHNode; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 6 | 7 | import com.google.common.collect.Lists; 8 | import java.io.IOException; 9 | import java.util.Collections; 10 | import org.heigit.ohsome.oshdb.impl.osh.OSHRelationImpl; 11 | import org.heigit.ohsome.oshdb.osm.OSM; 12 | import org.heigit.ohsome.oshdb.osm.OSMMember; 13 | import org.junit.jupiter.api.Test; 14 | 15 | class OSHEntityTest { 16 | 17 | @Test 18 | void testHashCodeEquals() throws IOException { 19 | var expected = buildOSHNode( 20 | OSM.node(123L, 1, 1L, 0L, 1, new int[0], 0, 0) 21 | ); 22 | 23 | var a = buildOSHNode( 24 | OSM.node(123L, 1, 1L, 0L, 1, new int[0], 0, 0) 25 | ); 26 | 27 | var b = OSHRelationImpl.build(Lists.newArrayList( 28 | OSM.relation(123L, 1, 3333L, 4444L, 23, new int[0], 29 | new OSMMember[0])), Collections.emptyList(), Collections.emptyList()); 30 | 31 | assertEquals(expected.hashCode(), a.hashCode()); 32 | assertNotEquals(expected.hashCode(), b.hashCode()); 33 | 34 | assertEquals(expected, a); 35 | assertNotEquals(expected, b); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/util/CellIdTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | class CellIdTest { 8 | 9 | @Test 10 | void testGetid() { 11 | CellId instance = new CellId(1, 1L); 12 | long expResult = 1L; 13 | long result = instance.getId(); 14 | assertEquals(expResult, result); 15 | } 16 | 17 | @Test 18 | void testGetzoomlevel() { 19 | CellId instance = new CellId(1, 1L); 20 | int expResult = 1; 21 | int result = instance.getZoomLevel(); 22 | assertEquals(expResult, result); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/util/OSHDBBoundableTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertFalse; 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | import org.heigit.ohsome.oshdb.OSHDBBoundable; 8 | import org.heigit.ohsome.oshdb.OSHDBBoundingBox; 9 | import org.junit.jupiter.api.Test; 10 | 11 | class OSHDBBoundableTest { 12 | private OSHDBBoundable point = OSHDBBoundingBox.bboxOSMCoordinates(0, 0, 0, 0); 13 | private OSHDBBoundable box = OSHDBBoundingBox.bboxOSMCoordinates(-1, -1, 1, 1); 14 | 15 | @Test 16 | void testPoint() { 17 | assertTrue(point.isPoint()); 18 | assertFalse(box.isPoint()); 19 | } 20 | 21 | @Test 22 | void testValid() { 23 | assertTrue(point.isValid()); 24 | assertTrue(box.isValid()); 25 | OSHDBBoundable invalid = OSHDBBoundingBox.bboxOSMCoordinates(1, 1, -1, -1); 26 | assertFalse(invalid.isValid()); 27 | } 28 | 29 | @Test 30 | void testCovered() { 31 | assertTrue(point.coveredBy(box)); 32 | assertFalse(point.coveredBy(null)); 33 | } 34 | 35 | @Test 36 | void testIntersects() { 37 | assertTrue(point.intersects(box)); 38 | assertFalse(point.intersects(null)); 39 | } 40 | 41 | @Test 42 | void testIntersection() { 43 | OSHDBBoundable box2 = OSHDBBoundingBox.bboxOSMCoordinates(0, 0, 2, 2); 44 | OSHDBBoundable intersection = box2.intersection(box); 45 | assertEquals(0, intersection.getMinLongitude()); 46 | assertEquals(0, intersection.getMinLatitude()); 47 | assertEquals(1, intersection.getMaxLongitude()); 48 | assertEquals(1, intersection.getMaxLatitude()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /oshdb/src/test/java/org/heigit/ohsome/oshdb/util/OSHDBTemporalTest.java: -------------------------------------------------------------------------------- 1 | package org.heigit.ohsome.oshdb.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.heigit.ohsome.oshdb.OSHDBTemporal; 7 | import org.heigit.ohsome.oshdb.OSHDBTimestamp; 8 | import org.junit.jupiter.api.Test; 9 | 10 | class OSHDBTemporalTest { 11 | @Test 12 | void testBeforeAfter() { 13 | OSHDBTemporal t1 = new OSHDBTimestamp(0); 14 | OSHDBTemporal t2 = new OSHDBTimestamp(1); 15 | assertTrue(t1.isBefore(t2)); 16 | assertTrue(t2.isAfter(t1)); 17 | assertEquals(0, OSHDBTemporal.compare(t1, t1)); 18 | assertTrue(OSHDBTemporal.compare(t1, t2) < 0); 19 | assertTrue(OSHDBTemporal.compare(t2, t1) > 0); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oshdb/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=WARN, stderr 3 | 4 | # Redirect log messages to console 5 | log4j.appender.stderr=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stderr.Target=System.err 7 | log4j.appender.stderr.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stderr.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 9 | -------------------------------------------------------------------------------- /pipeline_config.groovy: -------------------------------------------------------------------------------- 1 | libraries{ 2 | maven 3 | misc 4 | rocketchat 5 | } --------------------------------------------------------------------------------