diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f8d7b820..74b52be7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,7 +12,7 @@ A clear and concise description of what the bug is. ### General Information Please include the following general information about the issue and list any additional steps needed to reproduce the bug. - - Version of the ohsome API [e.g. `1.5.0`] + - Version of the ohsome API [e.g. `1.8.0`] - Which API instance was requested [e.g. remote instance at `https://api.ohsome.org/v1`, local instance with an h2 file or connected to the cluster, etc.] - Affected endpoint(s) [e.g. /contributions/count] - URL of your request (and request body if applicable) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c38c175..f8608bb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ Changelog ========= +## 1.9.0-SNAPSHOT (current master) + + +## 1.8.1 + +### Bug Fixes +* Fix crash and incorrect output of `…/groupBy/tag` and `…/groupBy/key` endpoints when non-existing tag keys or values are used in a query ([#291]) + +### Documentation +* Complete documentation of ohsome filters ([#290]) + +[#290]: https://github.com/GIScience/ohsome-api/pull/290 +[#291]: https://github.com/GIScience/ohsome-api/pull/291 + + ## 1.8.0 ### Breaking Changes diff --git a/README.md b/README.md index 2fa37ef6..5e2b0f87 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The ohsome API is a generic web API for in-depth analysis of OpenStreetMap (OSM) data with a focus on its history. It allows to get aggregated statistics about the evolution of OSM data itself and about the contributors behind the data. Furthermore, data extraction methods are provided to access the historic development of individual OSM features. -The functionalities of the ohsome API can be accessed via HTTP requests. As a basis underneath serves the [OSHDB API](https://github.com/GIScience/oshdb). The current stable version is [v1.8.0](https://github.com/GIScience/ohsome-api/releases/tag/1.8.0). Developed and maintained by [HeiGIT](https://heigit.org/). +The functionalities of the ohsome API can be accessed via HTTP requests. As a basis underneath serves the [OSHDB API](https://github.com/GIScience/oshdb). The current stable version is [v1.8.1](https://github.com/GIScience/ohsome-api/releases/tag/1.8.1). Developed and maintained by [HeiGIT](https://heigit.org/). ## Using the ohsome API @@ -39,7 +39,7 @@ Here you see an example response giving the length of residential roads for a bo "url": "https://ohsome.org/copyrights", "text": "© OpenStreetMap contributors" }, - "apiVersion": "1.8.0", + "apiVersion": "1.8.1", "metadata": { "executionTime": 858, "description": "Total length of items in meters.", @@ -122,8 +122,8 @@ These instructions will get you a copy of the project up and running on your loc 2. move to your Maven project directory in a shell (e.g. Windows PowerShell) 3. enter the command `mvn -DskipTests=true package` to build the project (if you want to build it running the integrated tests too, look at the section [Testing](#testing)) 4. to run the jar file enter the following (if no additional keytables file is given, you can assume that it is included): - * keytables included: `java -jar target/ohsome-api-1.8.0.jar --database.db=C:/path-to-your-data/ba-wue.oshdb` - * keytables not included: `java -jar target/ohsome-api-1.8.0.jar --database.db=C:/path-to-your-data/ba-wue.oshdb --database.keytables=C:/path-to-your-keytablesFile/keytables` + * keytables included: `java -jar target/ohsome-api-1.8.1.jar --database.db=C:/path-to-your-data/ba-wue.oshdb` + * keytables not included: `java -jar target/ohsome-api-1.8.1.jar --database.db=C:/path-to-your-data/ba-wue.oshdb --database.keytables=C:/path-to-your-keytablesFile/keytables` Now you should have a running local API, which is ready for receiving requests under *http://localhost:8080/*.
To check if it is running properly, you should be able to visit the swagger documentation under *http://localhost:8080/swagger-ui.html*. diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 00000000..748088cb --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,4 @@ +html.writer-html5 .rst-content table.docutils td > p, html.writer-html5 .rst-content table.docutils th > p { + /* this setting is changed in the theme for tables, but shouldn't change for us. */ + line-height: 24px; +} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 4eb3a818..3ef5610f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -97,6 +97,8 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +html_css_files = ['custom.css'] + # Custom sidebar templates, must be a dictionary that maps document names # to template names. # diff --git a/docs/endpoints.rst b/docs/endpoints.rst index ff49cccc..a512780c 100644 --- a/docs/endpoints.rst +++ b/docs/endpoints.rst @@ -65,7 +65,7 @@ How big is the area of farmland in the region Rhein-Neckar? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2014-01-01T00:00:00Z", "value" : 1.020940258E7 @@ -79,7 +79,7 @@ How big is the area of farmland in the region Rhein-Neckar? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2014-01-01T00:00:00Z", "value" : 1.020940258E7 @@ -93,7 +93,7 @@ How big is the area of farmland in the region Rhein-Neckar? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2014-01-01T00:00:00Z", "value" : 10209402.58 @@ -107,7 +107,7 @@ How big is the area of farmland in the region Rhein-Neckar? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2014-01-01T00:00:00Z", "value" : 1.020940258E7 @@ -160,7 +160,7 @@ What is the density of restaurants with wheelchair access in Heidelberg? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2019-05-07T00:00:00Z", "value" : 0.79 @@ -174,7 +174,7 @@ What is the density of restaurants with wheelchair access in Heidelberg? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2019-05-07T00:00:00Z", "value" : 0.79 @@ -188,7 +188,7 @@ What is the density of restaurants with wheelchair access in Heidelberg? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2019-05-07T00:00:00Z", "value" : 0.79 @@ -202,7 +202,7 @@ What is the density of restaurants with wheelchair access in Heidelberg? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "timestamp" : "2019-05-07T00:00:00Z", "value" : 0.79 @@ -262,7 +262,7 @@ How many oneway streets exist within living_street streets in Heidelberg over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "ratioResult" : [ { "timestamp" : "2016-01-01T00:00:00Z", "value" : 28660.519999999997, @@ -288,7 +288,7 @@ How many oneway streets exist within living_street streets in Heidelberg over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "ratioResult" : [ { "timestamp" : "2016-01-01T00:00:00Z", "value" : 28660.519999999997, @@ -314,7 +314,7 @@ How many oneway streets exist within living_street streets in Heidelberg over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "ratioResult" : [ { "timestamp" : "2016-01-01T00:00:00Z", "value" : 28660.519999999997, @@ -340,7 +340,7 @@ How many oneway streets exist within living_street streets in Heidelberg over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "ratioResult" : [ { "timestamp" : "2016-01-01T00:00:00Z", "value" : 28660.519999999997, @@ -412,7 +412,7 @@ How often information about the roof of buildings is present? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -441,7 +441,7 @@ How often information about the roof of buildings is present? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -470,7 +470,7 @@ How often information about the roof of buildings is present? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -499,7 +499,7 @@ How often information about the roof of buildings is present? "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -582,7 +582,7 @@ Compare length of different types of streets for two or more regions. "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -641,7 +641,7 @@ Compare length of different types of streets for two or more regions. "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -700,7 +700,7 @@ Compare length of different types of streets for two or more regions. "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -759,7 +759,7 @@ Compare length of different types of streets for two or more regions. "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "result" : [ { "timestamp" : "2018-01-01T00:00:00Z", @@ -884,7 +884,7 @@ Show number of users editing buildings before, during and after Nepal earthquake "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2015-03-01T00:00:00Z", "toTimestamp" : "2015-04-01T00:00:00Z", @@ -915,7 +915,7 @@ Show number of users editing buildings before, during and after Nepal earthquake "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2015-03-01T00:00:00Z", "toTimestamp" : "2015-04-01T00:00:00Z", @@ -946,7 +946,7 @@ Show number of users editing buildings before, during and after Nepal earthquake "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2015-03-01T00:00:00Z", "toTimestamp" : "2015-04-01T00:00:00Z", @@ -977,7 +977,7 @@ Show number of users editing buildings before, during and after Nepal earthquake "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2015-03-01T00:00:00Z", "toTimestamp" : "2015-04-01T00:00:00Z", @@ -1063,7 +1063,7 @@ Number of contributions to the building 'Stadthalle Heidelberg' between 2010 and "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2010-01-01T00:00:00Z", @@ -1080,7 +1080,7 @@ Number of contributions to the building 'Stadthalle Heidelberg' between 2010 and "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2010-01-01T00:00:00Z", @@ -1097,7 +1097,7 @@ Number of contributions to the building 'Stadthalle Heidelberg' between 2010 and "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2010-01-01T00:00:00Z", @@ -1114,7 +1114,7 @@ Number of contributions to the building 'Stadthalle Heidelberg' between 2010 and "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2010-01-01T00:00:00Z", @@ -1167,7 +1167,7 @@ Density of contributions to shops within the oldtown area of Heidelberg between "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1184,7 +1184,7 @@ Density of contributions to shops within the oldtown area of Heidelberg between "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1201,7 +1201,7 @@ Density of contributions to shops within the oldtown area of Heidelberg between "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1218,7 +1218,7 @@ Density of contributions to shops within the oldtown area of Heidelberg between "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1244,7 +1244,7 @@ Number of the latest contributions to residential buildings with a geometry chan .. code-tab:: bash curl (POST) - curl -X POST 'https://api.ohsome.org/v1/contributions/latest/count' --data-urlencode 'bboxes=8.69282,49.40766,8.71673,49.4133' --data-urlenconde 'contributionType=geometryChange' --data-urlencode 'filter=building=residential' --data-urlencode 'time=2014-01-01,2015-01-01' + curl -X POST 'https://api.ohsome.org/v1/contributions/latest/count' --data-urlencode 'bboxes=8.69282,49.40766,8.71673,49.4133' --data-urlencode 'contributionType=geometryChange' --data-urlencode 'filter=building=residential' --data-urlencode 'time=2014-01-01,2015-01-01' .. code-tab:: python Python @@ -1271,7 +1271,7 @@ Number of the latest contributions to residential buildings with a geometry chan "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2014-01-01T00:00:00Z", @@ -1288,7 +1288,7 @@ Number of the latest contributions to residential buildings with a geometry chan "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2014-01-01T00:00:00Z", @@ -1305,7 +1305,7 @@ Number of the latest contributions to residential buildings with a geometry chan "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2014-01-01T00:00:00Z", @@ -1322,7 +1322,7 @@ Number of the latest contributions to residential buildings with a geometry chan "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2014-01-01T00:00:00Z", @@ -1375,7 +1375,7 @@ Density of the latest contributions with a geometry change to shops within the o "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1392,7 +1392,7 @@ Density of the latest contributions with a geometry change to shops within the o "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1409,7 +1409,7 @@ Density of the latest contributions with a geometry change to shops within the o "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1426,7 +1426,7 @@ Density of the latest contributions with a geometry change to shops within the o "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "result" : [ { "fromTimestamp" : "2012-01-01T00:00:00Z", @@ -1479,7 +1479,7 @@ Number of contributions to shops in different suburbs of Heidelberg (Altstadt an "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1504,7 +1504,7 @@ Number of contributions to shops in different suburbs of Heidelberg (Altstadt an "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1529,7 +1529,7 @@ Number of contributions to shops in different suburbs of Heidelberg (Altstadt an "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1554,7 +1554,7 @@ Number of contributions to shops in different suburbs of Heidelberg (Altstadt an "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1615,7 +1615,7 @@ Density of contributions to shops within different suburbs of Heidelberg (Altsta "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1640,7 +1640,7 @@ Density of contributions to shops within different suburbs of Heidelberg (Altsta "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1665,7 +1665,7 @@ Density of contributions to shops within different suburbs of Heidelberg (Altsta "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1690,7 +1690,7 @@ Density of contributions to shops within different suburbs of Heidelberg (Altsta "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "groupByResult" : [ { "groupByObject" : "Heidelberg-Altstadt", "result" : [ { @@ -1825,7 +1825,7 @@ Extract the modifications of the blown up tower of the heidelberg castle over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "type" : "FeatureCollection", "features" : [{ "type" : "Feature", @@ -1863,7 +1863,7 @@ Extract the modifications of the blown up tower of the heidelberg castle over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "type" : "FeatureCollection", "features" : [{ "type" : "Feature", @@ -1901,7 +1901,7 @@ Extract the modifications of the blown up tower of the heidelberg castle over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "type" : "FeatureCollection", "features" : [{ "type" : "Feature", @@ -1939,7 +1939,7 @@ Extract the modifications of the blown up tower of the heidelberg castle over ti "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "type" : "FeatureCollection", "features" : [{ "type" : "Feature", @@ -2024,7 +2024,7 @@ Get the changes of pharmacies with opening hours in a certain area of Heidelberg "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6720,49.3988,8.7026,49.4274&filter=amenity=pharmacy%20and%20opening_hours=*%20and%20type:node&time=2020-02-01,2020-06-29&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2101,7 +2101,7 @@ Get the changes of pharmacies with opening hours in a certain area of Heidelberg "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6720,49.3988,8.7026,49.4274&filter=amenity=pharmacy%20and%20opening_hours=*%20and%20type:node&time=2020-02-01,2020-06-29&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2178,7 +2178,7 @@ Get the changes of pharmacies with opening hours in a certain area of Heidelberg "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6720,49.3988,8.7026,49.4274&filter=amenity=pharmacy%20and%20opening_hours=*%20and%20type:node&time=2020-02-01,2020-06-29&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2255,7 +2255,7 @@ Get the changes of pharmacies with opening hours in a certain area of Heidelberg "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6720,49.3988,8.7026,49.4274&filter=amenity=pharmacy%20and%20opening_hours=*%20and%20type:node&time=2020-02-01,2020-06-29&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2376,7 +2376,7 @@ Get the latest change of constructions in a certain area of the Bahnstadt in Hei "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6644159,49.401099,8.6663353,49.4027195&filter=landuse=construction%20and%20type:way&time=2020-06-29,2014-07-01&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2425,7 +2425,7 @@ Get the latest change of constructions in a certain area of the Bahnstadt in Hei "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6644159,49.401099,8.6663353,49.4027195&filter=landuse=construction%20and%20type:way&time=2020-06-29,2014-07-01&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2474,7 +2474,7 @@ Get the latest change of constructions in a certain area of the Bahnstadt in Hei "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6644159,49.401099,8.6663353,49.4027195&filter=landuse=construction%20and%20type:way&time=2020-06-29,2014-07-01&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2523,7 +2523,7 @@ Get the latest change of constructions in a certain area of the Bahnstadt in Hei "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "metadata" : { "description" : "Latest contributions as GeoJSON features.", "requestUrl" : "https://api.ohsome.org/v1/contributions/latest/geometry?bboxes=8.6644159,49.401099,8.6663353,49.4027195&filter=landuse=construction%20and%20type:way&time=2020-06-29,2014-07-01&showMetadata=yes&properties=metadata,tags&clipGeometry=false" @@ -2606,7 +2606,7 @@ Get metadata of the underlying OSHDB data "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "timeout": 600.0, "extractRegion" : { "spatialExtent" : { @@ -2628,7 +2628,7 @@ Get metadata of the underlying OSHDB data "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "extractRegion" : { "spatialExtent" : { "type" : "Polygon", @@ -2649,7 +2649,7 @@ Get metadata of the underlying OSHDB data "url" : "https://ohsome.org/copyrights", "text" : "© OpenStreetMap contributors" }, - "apiVersion" : "1.8.0", + "apiVersion" : "1.8.1", "extractRegion" : { "spatialExtent" : { "type" : "Polygon", diff --git a/docs/filter.rst b/docs/filter.rst index d08f4afb..25be1f6c 100644 --- a/docs/filter.rst +++ b/docs/filter.rst @@ -16,72 +16,100 @@ Selectors .. table:: :widths: 24 50 24 - +-------------------------+------------------------------------+------------------------+ - | | **description** | **example** | - +=========================+====================================+========================+ - | ``key=value`` | | matches all entities which | ``natural=tree`` | - | | | have this exact tag | | - +-------------------------+------------------------------------+------------------------+ - | ``key=*`` | | matches all entities which have | ``addr:housenumber=*`` | - | | | any tag with the given key | | - +-------------------------+------------------------------------+------------------------+ - | ``key!=value`` | | matches all entities | ``oneway!=yes`` | - | | | which do not have | | - | | | this exact tag | | - +-------------------------+------------------------------------+------------------------+ - | ``key!=*`` | | matches all entities which do not| ``name!=*`` | - | | | have any tag with the given key | | - | | | | | - +-------------------------+------------------------------------+------------------------+ - | ``key in (value list)`` | | matches all entities which do | ``highway in | - | | | have any tag with the given key | (residential, | - | | | and one of the given values | living_street)`` | - +-------------------------+------------------------------------+------------------------+ - | ``type:osm-type`` | | matches all entities of the | ``type:node`` | - | | | given osm type | | - +-------------------------+------------------------------------+------------------------+ - | ``id:osm-id`` | | matches all entities with the | ``id:1234`` | - | | | given osm id [1]_ | | - +-------------------------+------------------------------------+------------------------+ - | ``id:osm-type/osm-id`` | | matches the entity with the given| ``id:node/1234`` | - | | | osm type and id | | - +-------------------------+------------------------------------+------------------------+ - | ``id:(id list)`` | | matches all entities with the | ``id:(1, 42, 1234)`` | - | | | given osm ids [1]_ | | - +-------------------------+------------------------------------+------------------------+ - | ``id:(id list)`` | | matches all entities with the | ``id:(node/1, way/3)`` | - | | | given osm types and ids | | - +-------------------------+------------------------------------+------------------------+ - | ``id:(id range)`` | | matches all entities with an id | ``id:(1 .. 9999)`` | - | | | matching the given id range [2]_ | | - +-------------------------+------------------------------------+------------------------+ - | ``geometry:geom-type`` | | matches anything which has a | ``geometry:polygon`` | - | | | geometry of the given type | | - | | | (point, line, polygon, or other) | | - +-------------------------+------------------------------------+------------------------+ - | ``area:(from..to)`` | | matches features with a geometry | ``area:(1.0 .. 1E6)`` | - | | | having an area (measured in m²) | | - | | | in the given range [2]_ | | - +-------------------------+------------------------------------+------------------------+ - | ``length:(from..to)`` | | matches features with a geometry | ``length:( .. 100)`` | - | | | having a length (measured in m) | | - | | | in the given range [2]_ | | - +-------------------------+------------------------------------+------------------------+ - | ``changeset:id`` | | matches contributions [3]_ | ``changeset:42`` | - | | | performed in the specified | | - | | | changeset | | - +-------------------------+------------------------------------+------------------------+ - | ``changeset:(id list)`` | | matches contributions [3]_ | ``changeset:(10, 42)`` | - | | | performed in one of the | | - | | | specified changesets | | - +-------------------------+------------------------------------+------------------------+ - | ``changeset:(from..to)``| | matches contributions [3]_ | ``changeset:(10..42)`` | - | | | performed in a range of | | - | | | changesets | | - +-------------------------+------------------------------------+------------------------+ + +------------------------------------+------------------------------------+-----------------------------------+ + | | **description** | **example** | + +====================================+====================================+===================================+ + | ``key=value`` | matches all entities which | ``natural=tree`` | + | | have this exact tag | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``key=*`` | matches all entities which have | ``addr:housenumber=*`` | + | | any tag with the given key | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``key!=value`` | matches all entities | ``oneway!=yes`` | + | | which do not have | | + | | this exact tag | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``key!=*`` | matches all entities which do not | ``name!=*`` | + | | have any tag with the given key | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``key in (value list)`` | matches all entities which do | ``highway in`` | + | | have any tag with the given key | ``(residential, | + | | and one of the given values | living_street)`` | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``type:osm-type`` | matches all entities of the | ``type:node`` | + | | given osm type | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``id:osm-id`` | matches all entities with the | ``id:1234`` | + | | given osm id [1]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``id:osm-type/osm-id`` | matches the entity with the given | ``id:node/1234`` | + | | osm type and id | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``id:(id list)`` | matches all entities with the | ``id:(1, 42, 1234)`` | + | | given osm ids [1]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``id:(id list)`` | matches all entities with the | ``id:(node/1, way/3)`` | + | | given osm types and ids | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``id:(id range)`` | matches all entities with an id | ``id:(1 .. 9999)`` | + | | matching the given id range [2]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``geometry:geom-type`` | matches anything which has a | ``geometry:polygon`` | + | | geometry of the given type | | + | | (point, line, polygon, or other) | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``area:(from..to)`` | matches features with a geometry | ``area:(1.0 .. 1E6)`` | + | | having an area (measured in m²) | | + | | in the given range [2]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``length:(from..to)`` | matches features with a geometry | ``length:( .. 100)`` | + | | having a length (measured in m) | | + | | in the given range [2]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``perimeter:(from..to)`` | matches features with a | ``perimeter:( .. 100)`` | + | | perimeter (measured in m) in the | | + | | given range [2]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``geometry.vertices:(from..to)`` | matches features by the number | ``geometry.vertices:(1 .. 10)`` | + | | of points they consists of | | + | | in the given range [2]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``geometry.outers:number`` | matches features by the number | ``geometry.outers:1`` | + | or | of outer rings they consists of | or | + | ``geometry.outers:(from..to)`` | in the given range [2]_ | ``geometry.outers:(2 .. )`` | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``geometry.inners:number`` | matches features by the number | ``geometry.inners:0`` | + | or | of holes (inner rings) they | or | + | ``geometry.inners:(from..to)`` | consists of in the given range | ``geometry.inners:(1 .. )`` | + | | [2]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``geometry.roundness:(from..to)`` | matches features which have a | ``geometry.roundness:(0.8 .. )`` | + | | *roundness* (or *compactness*) | | + | | in the given range [2]_ [4]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``geometry.squareness:(from..to)`` | matches features which have a | ``geometry.squareness:(0.8 .. )`` | + | | *squareness* | | + | | in the given range [2]_ [5]_ | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``changeset:id`` | matches contributions [3]_ | ``changeset:42`` | + | | performed in the specified | | + | | changeset | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``changeset:(id list)`` | matches contributions [3]_ | ``changeset:(10, 42)`` | + | | performed in one of the | | + | | specified changesets | | + +------------------------------------+------------------------------------+-----------------------------------+ + | ``changeset:(from..to)`` | matches contributions [3]_ | ``changeset:(10..42)`` | + | | performed in a range of | | + | | changesets | | + +------------------------------------+------------------------------------+-----------------------------------+ .. [1] Keep in mind that osm ids are not unique between osm types. In order to include only a specific object the id needs to be used together with an osm type filter. Alternatively, one can also use the combined type+id filter (e.g. `id:node/1234`). .. [2] The lower or upper bound of a range may be omitted to indicate that the values are only to be limited to be "up to" or "starting from" the given value, respectively. For example: `id:(10..)` will accept all entities with an id of 10 or higher. .. [3] The `changeset` filters can only be used in `contribution` based API endpoints. +.. [4] This is using the `"Polsby–Popper test" score`_ where all values fall in the interval 0 to 1 and 1 represents a perfect circle. +.. [5] This is using the `rectilinearity measurement by Žunić and Rosin`_ where all values fall in the interval 0 to 1 and 1 represents a perfectly rectilinear geometry. +.. _"Polsby–Popper test" score: https://en.wikipedia.org/wiki/Polsby%E2%80%93Popper_test +.. _rectilinearity measurement by Žunić and Rosin: https://www.researchgate.net/publication/221304067_A_Rectilinearity_Measurement_for_Polygons) | @@ -94,18 +122,18 @@ Operators +------------------------+------------------------------------+------------------------+ | | **description** | **example** | +========================+====================================+========================+ - | ``(…)`` | | can be used to change | ``highway=primary and | - | | | precedence of operators | (name=* or ref=*)`` | + | ``(…)`` | can be used to change | ``highway=primary and | + | | precedence of operators | (name=* or ref=*)`` | +------------------------+------------------------------------+------------------------+ - | ``not X`` | | negates the following filter | ``not type:node`` | - | | | expression | | + | ``not X`` | negates the following filter | ``not type:node`` | + | | expression | | +------------------------+------------------------------------+------------------------+ - | ``X and Y`` | | returns entities which match | ``highway=service and | - | | | both filter expressions X and Y | service=driveway`` | + | ``X and Y`` | returns entities which match | ``highway=service and | + | | both filter expressions X and Y | service=driveway`` | +------------------------+------------------------------------+------------------------+ - | ``X or Y`` | | returns entities which match at | ``natural=wood or | - | | | least one of the filter | landuse=forest`` | - | | | expressions X or Y | | + | ``X or Y`` | returns entities which match at | ``natural=wood or | + | | least one of the filter | landuse=forest`` | + | | expressions X or Y | | +------------------------+------------------------------------+------------------------+ Operators follow the following order of precedence: parentheses before ``not``, before ``and``, before ``or``. @@ -134,61 +162,61 @@ Examples Here's some useful examples for querying some OSM features: .. table:: - :widths: 24 50 24 + :widths: 24 34 34 +------------------+--------------------------------------------------------+------------------------------+ | **OSM Feature** | **filter** | **comment** | +==================+========================================================+==============================+ - | | forests/woods | | ``(landuse=forest or natural=wood) and`` | | Using | - | | | ``geometry:polygon`` | | ``geometry:polygon`` will | - | | | | select closed ways as | - | | | | well as multipolygons | - | | | | (e.g. a forest with | - | | | | clearings). | + | forests/woods | | ``(landuse=forest or natural=wood) and`` | Using | + | | | ``geometry:polygon`` | ``geometry:polygon`` will | + | | | select closed ways as | + | | | well as multipolygons | + | | | (e.g. a forest with | + | | | clearings). | +------------------+--------------------------------------------------------+------------------------------+ - | | parks and | | ``leisure=park and geometry:polygon or`` | | A filter can also fetch | - | | park benches | | ``amenity=bench and (geometry:point or`` | | features of different | - | | | ``geometry:line)`` | | geometry types: this | - | | | | returns parks | - | | | | (polygons) as well as | - | | | | park benches (points or | - | | | | lines). | + | parks and | | ``leisure=park and geometry:polygon or`` | A filter can also fetch | + | park benches | | ``amenity=bench and (geometry:point or`` | features of different | + | | | ``geometry:line)`` | geometry types: this | + | | | returns parks | + | | | (polygons) as well as | + | | | park benches (points or | + | | | lines). | +------------------+--------------------------------------------------------+------------------------------+ - | | buildings | | ``building=* and building!=no and`` | | This filter also | - | | | ``geometry:polygon`` | | excludes the (rare) | - | | | | objects marked with | - | | | | ``building=no``, which is | - | | | | a tag used to indicate | - | | | | that a feature might be | - | | | | expected to be a | - | | | | building (e.g. from an | - | | | | outdated aerial imagery | - | | | | source), but is in reality | - | | | | not one. | + | buildings | | ``building=* and building!=no and`` | This filter also | + | | | ``geometry:polygon`` | excludes the (rare) | + | | | objects marked with | + | | | ``building=no``, which is | + | | | a tag used to indicate | + | | | that a feature might be | + | | | expected to be a | + | | | building (e.g. from an | + | | | outdated aerial imagery | + | | | source), but is in reality | + | | | not one. | +------------------+--------------------------------------------------------+------------------------------+ - | | highways | | ``type:way and (highway in (motorway,`` | | The list of used tags | - | | | ``motorway_link, trunk, trunk_link, primary,`` | | depends on the exact | - | | | ``primary_link, secondary, secondary_link,`` | | definition of a | - | | | ``tertiary, tertiary_link, unclassified,`` | | "highway". In a | - | | | ``residential, living_street, pedestrian) or`` | | different context, it may | - | | | ``(highway=service and service=alley))`` | | also include less or even | - | | | | more tags | - | | | | (``footway``, ``cycleway``,| - | | | | ``track``, ``path``, all | - | | | | ``highway=service``, etc.) | + | highways | | ``type:way and (highway in (motorway,`` | The list of used tags | + | | | ``motorway_link, trunk, trunk_link,`` | depends on the exact | + | | | ``primary, primary_link, secondary,`` | definition of a | + | | | ``secondary_link, tertiary,`` | "highway". In a | + | | | ``tertiary_link, unclassified,`` | different context, it may | + | | | ``residential, living_street, pedestrian)`` | also include less or even | + | | | ``or (highway=service and service=alley))`` | more tags | + | | | (``footway``, ``cycleway``, | + | | | ``track``, ``path``, all | + | | | ``highway=service``, etc.) | +------------------+--------------------------------------------------------+------------------------------+ - | | residential | | ``type:way and highway=residential and`` | | Note that some roads | - | | roads missing | | ``name!=* and noname!=yes`` | | might be actually | - | | a name (for | | | unnamed in reality. | - | | quality | | | Such features can be | - | | assurance) | | | marked as unnamed | - | | | | with the ``noname`` tag | - | | | | in OSM. | + | residential | | ``type:way and highway=residential and`` | Note that some roads | + | roads missing | | ``name!=* and noname!=yes`` | might be actually | + | a name (for | | unnamed in reality. | + | quality | | Such features can be | + | assurance) | | marked as unnamed | + | | | with the ``noname`` tag | + | | | in OSM. | +------------------+--------------------------------------------------------+------------------------------+ - | | implausibly | | ``geometry:polygon and building=* and building!=no`` | | The currently largest | - | | large | | ``and area:(1E6..)`` | | building by footprint area | - | | buildings | | | is a car factory building | - | | | | measuring about 887,800 m².| + | implausibly | | ``geometry:polygon and building=* and`` | The currently largest | + | large | | ``building!=no and area:(1E6..)`` | building by footprint area | + | buildings | | is a car factory building | + | | | measuring about 887,800 m². | +------------------+--------------------------------------------------------+------------------------------+ | diff --git a/pom.xml b/pom.xml index 98f340e9..671dbeb4 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ https://api.ohsome.org A public Web-RESTful-API for "ohsome" OpenStreetMap history data. jar - 1.8.0 + 1.8.1 scm:git:git@github.com:GIScience/ohsome-api.git diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/ElementsRequestExecutor.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/ElementsRequestExecutor.java index 95df128d..289f0c75 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/ElementsRequestExecutor.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/ElementsRequestExecutor.java @@ -181,11 +181,12 @@ public static

Response aggregateGroupByBoundary TagTranslator tt = DbConnData.tagTranslator; Integer[] valuesInt = new Integer[groupByValues.length]; ArrayList> zeroFill = new ArrayList<>(); - int keysInt = tt.getOSHDBTagKeyOf(groupByKey[0]).map(OSHDBTagKey::toInt).orElse(-1); + int keyInt = tt.getOSHDBTagKeyOf(groupByKey[0]).map(OSHDBTagKey::toInt).orElse(-2); if (groupByValues.length != 0) { for (int j = 0; j < groupByValues.length; j++) { - valuesInt[j] = tt.getOSHDBTagOf(groupByKey[0], groupByValues[j]).map(OSHDBTag::getValue).orElse(-j); - zeroFill.add(new ImmutablePair<>(keysInt, valuesInt[j])); + valuesInt[j] = tt.getOSHDBTagOf(groupByKey[0], groupByValues[j]) + .map(OSHDBTag::getValue).orElse(-j - 1); + zeroFill.add(new ImmutablePair<>(keyInt, valuesInt[j])); } } var arrGeoms = new ArrayList<>(processingData.getBoundaryList()); @@ -201,7 +202,7 @@ public static

Response aggregateGroupByBoundary mapAgg = mapAgg.filter(filter.get()); } var result = ExecutionUtils.computeNestedResult(requestResource, - mapAgg.map(f -> ExecutionUtils.mapSnapshotToTags(keysInt, valuesInt, f)) + mapAgg.map(f -> ExecutionUtils.mapSnapshotToTags(keyInt, valuesInt, f)) .aggregateBy(Pair::getKey, zeroFill).map(Pair::getValue) .aggregateByTimestamp(OSMEntitySnapshot::getTimestamp)); var groupByResult = OSHDBCombinedIndex.nest(result); @@ -217,10 +218,12 @@ public static

Response aggregateGroupByBoundary int tagValue = entry.getKey().getSecondIndex().getValue(); String tagIdentifier; // check for non-remainder objects (which do have the defined key and value) - if (entry.getKey().getSecondIndex().getKey() != -1 && tagValue != -1) { - tagIdentifier = tt.lookupTag(keysInt, tagValue).toString(); - } else { + if (entry.getKey().getSecondIndex().getKey() == -1) { tagIdentifier = "remainder"; + } else if (tagValue < 0) { + tagIdentifier = groupByKey[0] + '=' + groupByValues[-tagValue - 1]; + } else { + tagIdentifier = tt.lookupTag(keyInt, tagValue).toString(); } resultSet[count] = new GroupByResult(new Object[] {boundaryIds[boundaryIdentifier], tagIdentifier}, results); @@ -288,14 +291,15 @@ public static Response aggregateGroupByTag(RequestResource requestResource, TagTranslator tt = DbConnData.tagTranslator; Integer[] valuesInt = new Integer[groupByValues.length]; ArrayList> zeroFill = new ArrayList<>(); - int keysInt = tt.getOSHDBTagKeyOf(groupByKey[0]).map(OSHDBTagKey::toInt).orElse(-1); + int keyInt = tt.getOSHDBTagKeyOf(groupByKey[0]).map(OSHDBTagKey::toInt).orElse(-2); if (groupByValues.length != 0) { for (int j = 0; j < groupByValues.length; j++) { - valuesInt[j] = tt.getOSHDBTagOf(groupByKey[0], groupByValues[j]).map(OSHDBTag::getValue).orElse(-j); - zeroFill.add(new ImmutablePair<>(keysInt, valuesInt[j])); + valuesInt[j] = tt.getOSHDBTagOf(groupByKey[0], groupByValues[j]) + .map(OSHDBTag::getValue).orElse(-j - 1); + zeroFill.add(new ImmutablePair<>(keyInt, valuesInt[j])); } } - var preResult = mapRed.map(f -> ExecutionUtils.mapSnapshotToTags(keysInt, valuesInt, f)) + var preResult = mapRed.map(f -> ExecutionUtils.mapSnapshotToTags(keyInt, valuesInt, f)) .aggregateByTimestamp().aggregateBy(Pair::getKey, zeroFill).map(Pair::getValue); var result = ExecutionUtils.computeResult(requestResource, preResult); var groupByResult = ExecutionUtils.nest(result); @@ -307,10 +311,12 @@ public static Response aggregateGroupByTag(RequestResource requestResource, ElementsResult[] results = ExecutionUtils.fillElementsResult( entry.getValue(), requestParameters.isDensity(), df, geom); // check for non-remainder objects (which do have the defined key and value) - if (entry.getKey().getKey() != -1 && entry.getKey().getValue() != -1) { - groupByName = tt.lookupTag(keysInt, entry.getKey().getValue()).toString(); - } else { + if (entry.getKey().getKey() == -1) { groupByName = "remainder"; + } else if (entry.getKey().getValue() < 0) { + groupByName = groupByKey[0] + '=' + groupByValues[-entry.getKey().getValue() - 1]; + } else { + groupByName = tt.lookupTag(keyInt, entry.getKey().getValue()).toString(); } resultSet[count] = new GroupByResult(groupByName, results); count++; @@ -431,7 +437,7 @@ public static Response aggregateGroupByKey(RequestResource requestResource, TagTranslator tt = DbConnData.tagTranslator; Integer[] keysInt = new Integer[groupByKeys.length]; for (int i = 0; i < groupByKeys.length; i++) { - keysInt[i] = tt.getOSHDBTagKeyOf(groupByKeys[i]).map(OSHDBTagKey::toInt).orElse(-i); + keysInt[i] = tt.getOSHDBTagKeyOf(groupByKeys[i]).map(OSHDBTagKey::toInt).orElse(-i - 2); } MapAggregator, OSMEntitySnapshot> preResult = mapRed.flatMap(f -> { @@ -460,10 +466,12 @@ public static Response aggregateGroupByKey(RequestResource requestResource, ElementsResult[] results = ExecutionUtils.fillElementsResult( entry.getValue(), requestParameters.isDensity(), df, null); // check for non-remainder objects (which do have the defined key) - if (entry.getKey() != -1) { - groupByName = tt.lookupTag(entry.getKey(), 0).getKey(); - } else { + if (entry.getKey() == -1) { groupByName = "remainder"; + } else if (entry.getKey() < -1) { + groupByName = groupByKeys[-entry.getKey() - 2]; + } else { + groupByName = tt.lookupTag(entry.getKey(), 0).getKey(); } resultSet[count] = new GroupByResult(groupByName, results); count++; @@ -531,18 +539,19 @@ public static Response aggregateBasicFiltersRatio(RequestResource requestResourc Integer[] keysInt2 = new Integer[keys2.length]; Integer[] valuesInt2 = new Integer[values2.length]; for (int i = 0; i < requestParameters.getKeys().length; i++) { - keysInt1[i] = tt.getOSHDBTagKeyOf(requestParameters.getKeys()[i]).map(OSHDBTagKey::toInt) - .orElse(-i); + keysInt1[i] = tt.getOSHDBTagKeyOf(requestParameters.getKeys()[i]) + .map(OSHDBTagKey::toInt).orElse(-i - 1); if (requestParameters.getValues() != null && i < requestParameters.getValues().length) { valuesInt1[i] = tt.getOSHDBTagOf(requestParameters.getKeys()[i], requestParameters.getValues()[i]) - .map(OSHDBTag::getValue).orElse(-i); + .map(OSHDBTag::getValue).orElse(-i - 1); } } for (int i = 0; i < keys2.length; i++) { - keysInt2[i] = tt.getOSHDBTagKeyOf(keys2[i]).map(OSHDBTagKey::toInt).orElse(-i); + keysInt2[i] = tt.getOSHDBTagKeyOf(keys2[i]).map(OSHDBTagKey::toInt).orElse(-i - 1); if (i < values2.length) { - valuesInt2[i] = tt.getOSHDBTagOf(keys2[i], values2[i]).map(OSHDBTag::getValue).orElse(-i); + valuesInt2[i] = tt.getOSHDBTagOf(keys2[i], values2[i]) + .map(OSHDBTag::getValue).orElse(-i - 1); } } EnumSet osmTypes1 = @@ -782,18 +791,19 @@ public static

Response aggregateBasicFiltersRat Integer[] valuesInt2 = new Integer[values2.length]; TagTranslator tt = DbConnData.tagTranslator; for (int i = 0; i < requestParameters.getKeys().length; i++) { - keysInt1[i] = tt.getOSHDBTagKeyOf(requestParameters.getKeys()[i]).map(OSHDBTagKey::toInt) - .orElse(-i); + keysInt1[i] = tt.getOSHDBTagKeyOf(requestParameters.getKeys()[i]) + .map(OSHDBTagKey::toInt).orElse(-i - 1); if (requestParameters.getValues() != null && i < requestParameters.getValues().length) { valuesInt1[i] = tt.getOSHDBTagOf(requestParameters.getKeys()[i], requestParameters.getValues()[i]) - .map(OSHDBTag::getValue).orElse(-i); + .map(OSHDBTag::getValue).orElse(-i - 1); } } for (int i = 0; i < keys2.length; i++) { - keysInt2[i] = tt.getOSHDBTagKeyOf(keys2[i]).map(OSHDBTagKey::toInt).orElse(-i); + keysInt2[i] = tt.getOSHDBTagKeyOf(keys2[i]).map(OSHDBTagKey::toInt).orElse(-i - 1); if (i < values2.length) { - valuesInt2[i] = tt.getOSHDBTagOf(keys2[i], values2[i]).map(OSHDBTag::getValue).orElse(-i); + valuesInt2[i] = tt.getOSHDBTagOf(keys2[i], values2[i]) + .map(OSHDBTag::getValue).orElse(-i - 1); } } EnumSet osmTypes1 = (EnumSet) processingData.getOsmTypes(); diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/UsersRequestExecutor.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/UsersRequestExecutor.java index 6e995c8c..50d1bab2 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/UsersRequestExecutor.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/executor/UsersRequestExecutor.java @@ -120,12 +120,12 @@ public static Response countGroupByTag(HttpServletRequest servletRequest, TagTranslator tt = DbConnData.tagTranslator; Integer[] valuesInt = new Integer[groupByValues.length]; ArrayList> zeroFill = new ArrayList<>(); - int keysInt = tt.getOSHDBTagKeyOf(groupByKey[0]).map(OSHDBTagKey::toInt).orElse(-1); + int keyInt = tt.getOSHDBTagKeyOf(groupByKey[0]).map(OSHDBTagKey::toInt).orElse(-3); if (groupByValues.length != 0) { for (int j = 0; j < groupByValues.length; j++) { - valuesInt[j] = tt.getOSHDBTagOf(groupByKey[0], groupByValues[j]).map(OSHDBTag::getValue) - .orElse(-j); - zeroFill.add(new ImmutablePair<>(keysInt, valuesInt[j])); + valuesInt[j] = tt.getOSHDBTagOf(groupByKey[0], groupByValues[j]) + .map(OSHDBTag::getValue).orElse(-j - 1); + zeroFill.add(new ImmutablePair<>(keyInt, valuesInt[j])); } } SortedMap>, Integer> result = null; @@ -138,7 +138,7 @@ public static Response countGroupByTag(HttpServletRequest servletRequest, for (OSHDBTag tag : tags) { int tagKeyId = tag.getKey(); int tagValueId = tag.getValue(); - if (tagKeyId == keysInt) { + if (tagKeyId == keyInt) { if (valuesInt.length == 0) { res.add(new ImmutablePair<>(new ImmutablePair<>(tagKeyId, tagValueId), f)); } @@ -169,12 +169,14 @@ public static Response countGroupByTag(HttpServletRequest servletRequest, groupByResult.entrySet()) { ContributionsResult[] results = ExecutionUtils.fillContributionsResult(entry.getValue(), requestParameters.isDensity(), inputProcessor, df, geom); - if (entry.getKey().getKey() == -2 && entry.getKey().getValue() == -2) { + if (entry.getKey().getKey() == -2) { groupByName = "total"; - } else if (entry.getKey().getKey() == -1 && entry.getKey().getValue() == -1) { + } else if (entry.getKey().getKey() == -1) { groupByName = "remainder"; + } else if (entry.getKey().getValue() < 0) { + groupByName = groupByKey[0] + '=' + groupByValues[-entry.getKey().getValue() - 1]; } else { - groupByName = tt.lookupTag(keysInt, entry.getKey().getValue()).toString(); + groupByName = tt.lookupTag(keyInt, entry.getKey().getValue()).toString(); } resultSet[count] = new GroupByResult(groupByName, results); count++; @@ -216,7 +218,7 @@ public static Response countGroupByKey(HttpServletRequest servletRequest, TagTranslator tt = DbConnData.tagTranslator; Integer[] keysInt = new Integer[groupByKeys.length]; for (int i = 0; i < groupByKeys.length; i++) { - keysInt[i] = tt.getOSHDBTagKeyOf(groupByKeys[i]).map(OSHDBTagKey::toInt).orElse(-i); + keysInt[i] = tt.getOSHDBTagKeyOf(groupByKeys[i]).map(OSHDBTagKey::toInt).orElse(-i - 3); } SortedMap, Integer> result = null; result = mapRed @@ -257,6 +259,8 @@ public static Response countGroupByKey(HttpServletRequest servletRequest, groupByName = "total"; } else if (entry.getKey() == -1) { groupByName = "remainder"; + } else if (entry.getKey() < -2) { + groupByName = groupByKeys[-entry.getKey() - 3]; } else { groupByName = tt.lookupTag(entry.getKey(), 0).getKey(); } diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/inputprocessing/StringSimilarity.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/inputprocessing/StringSimilarity.java index 5bb91f13..9c523c0a 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/inputprocessing/StringSimilarity.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/inputprocessing/StringSimilarity.java @@ -2,7 +2,6 @@ import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Locale; import org.apache.commons.text.similarity.FuzzyScore; diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/oshdb/DbConnData.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/oshdb/DbConnData.java index fe80b983..c6f16055 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/oshdb/DbConnData.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/oshdb/DbConnData.java @@ -2,7 +2,6 @@ import javax.sql.DataSource; import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; -import org.heigit.ohsome.oshdb.api.db.OSHDBJdbc; import org.heigit.ohsome.oshdb.util.tagtranslator.TagTranslator; /** Holds the database connection objects. */ diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/ConfigureApplication.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/ConfigureApplication.java index 62cd0015..4ad991ae 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/ConfigureApplication.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/ConfigureApplication.java @@ -99,7 +99,8 @@ private ConfigureApplication(ApplicationArguments args) { } /** - * Method run by the Application class to parse incoming command line arguments + * Method run by the Application class to parse incoming command line arguments. + * * @param args ApplicationArguments from spring to be parsed. */ public static void parseArguments(ApplicationArguments args) diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/FilterUtil.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/FilterUtil.java index 767722a9..573e0b72 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/FilterUtil.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/FilterUtil.java @@ -4,12 +4,21 @@ import java.util.stream.Collectors; import org.heigit.ohsome.oshdb.osm.OSMType; +/** + * Utility functions for OSHDB filters. + */ public class FilterUtil { private FilterUtil() {} + /** + * Creates an OSHDB filter which selects OSM objects by their type. + * + * @param types the set of allowed OSM types + * @return a string representing an OSHDB filter matching the given set of OSM types + */ public static String filter(Set types) { return types.stream() .map(type -> "type:" + type.toString().toLowerCase()) - .collect(Collectors.joining(" or ", "( "," )")); + .collect(Collectors.joining(" or ", "( ", " )")); } } diff --git a/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/RequestUtils.java b/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/RequestUtils.java index 005a2a0a..229ef033 100644 --- a/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/RequestUtils.java +++ b/src/main/lombok/org/heigit/ohsome/ohsomeapi/utils/RequestUtils.java @@ -4,13 +4,11 @@ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import org.heigit.ohsome.ohsomeapi.exception.DatabaseAccessException; -import org.heigit.ohsome.ohsomeapi.exception.ExceptionMessages; import org.heigit.ohsome.ohsomeapi.inputprocessing.GeometryBuilder; import org.heigit.ohsome.ohsomeapi.inputprocessing.ProcessingData; import org.heigit.ohsome.ohsomeapi.oshdb.DbConnData; import org.heigit.ohsome.ohsomeapi.oshdb.ExtractMetadata; import org.heigit.ohsome.oshdb.api.db.OSHDBDatabase; -import org.heigit.ohsome.oshdb.api.db.OSHDBJdbc; /** Utils class containing request-specific static utility methods. */ public class RequestUtils { diff --git a/src/test/java/org/heigit/ohsome/ohsomeapi/controller/DataExtractionTest.java b/src/test/java/org/heigit/ohsome/ohsomeapi/controller/DataExtractionTest.java index 84bfa912..15a05369 100644 --- a/src/test/java/org/heigit/ohsome/ohsomeapi/controller/DataExtractionTest.java +++ b/src/test/java/org/heigit/ohsome/ohsomeapi/controller/DataExtractionTest.java @@ -92,7 +92,7 @@ public void elementsGeomSimpleFeaturesOtherLineTest() { assertTrue("GeometryCollection" .equals(response.getBody().get("features").get(0).get("geometry").get("type").asText())); } - + @Test public void elementsGeomUsingNoTagsTest() { TestRestTemplate restTemplate = new TestRestTemplate(); diff --git a/src/test/java/org/heigit/ohsome/ohsomeapi/controller/GetControllerTest.java b/src/test/java/org/heigit/ohsome/ohsomeapi/controller/GetControllerTest.java index d7623e99..9510f3a8 100644 --- a/src/test/java/org/heigit/ohsome/ohsomeapi/controller/GetControllerTest.java +++ b/src/test/java/org/heigit/ohsome/ohsomeapi/controller/GetControllerTest.java @@ -11,8 +11,10 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; +import java.util.stream.Collectors; import java.util.stream.StreamSupport; import org.apache.commons.csv.CSVRecord; import org.heigit.ohsome.ohsomeapi.Application; @@ -177,6 +179,42 @@ public void getElementsCountGroupByBoundaryGroupByTagTest() { .findFirst().get().get("result").get(0).get("value").asInt()); } + @Test + public void getElementsCountGroupByBoundaryGroupByTagUnknownValuesTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = restTemplate.getForEntity(server + port + + "/elements/count/groupBy/boundary/groupBy/tag?bboxes=8.68086,49.39948,8.69401,49.40609&" + + "time=2016-11-09&groupByKey=building&groupByValues=xxx,yyy,zzz&" + + "filter=type:way and building=*", + JsonNode.class); + assertEquals( + Set.of("building=xxx", "building=yyy", "building=zzz", "remainder"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .filter(jsonNode -> + "boundary1".equalsIgnoreCase(jsonNode.get("groupByObject").get(0).asText())) + .map(jsonNode -> jsonNode.get("groupByObject").get(1).asText()) + .collect(Collectors.toSet())); + } + + @Test + public void getElementsCountGroupByBoundaryGroupByTagUnknownKeyTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = restTemplate.getForEntity(server + port + + "/elements/count/groupBy/boundary/groupBy/tag?bboxes=8.68086,49.39948,8.69401,49.40609&" + + "time=2016-11-09&groupByKey=DoesNotExist&groupByValues=xxx&" + + "filter=type:way and building=*", + JsonNode.class); + assertEquals( + Set.of("DoesNotExist=xxx", "remainder"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .filter(jsonNode -> + "boundary1".equalsIgnoreCase(jsonNode.get("groupByObject").get(0).asText())) + .map(jsonNode -> jsonNode.get("groupByObject").get(1).asText()) + .collect(Collectors.toSet())); + } + @Test public void getElementsCountGroupByTypeTest() { TestRestTemplate restTemplate = new TestRestTemplate(); @@ -206,6 +244,38 @@ public void getElementsCountGroupByTagTest() { .findFirst().get().get("result").get(0).get("value").asInt()); } + @Test + public void getElementsCountGroupByTagUnknownValuesTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = restTemplate.getForEntity( + server + port + "/elements/count/groupBy/tag?bboxes=8.67859,49.41189,8.67964,49.41263&" + + "time=2017-01-01&groupByKey=building&groupByValues=xxx,yyy,zzz&" + + "filter=building=* and type:way", + JsonNode.class); + assertEquals( + Set.of("building=xxx", "building=yyy", "building=zzz", "remainder"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .map(jsonNode -> jsonNode.get("groupByObject").asText()) + .collect(Collectors.toSet())); + } + + @Test + public void getElementsCountGroupByTagUnknownKeyTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = restTemplate.getForEntity( + server + port + "/elements/count/groupBy/tag?bboxes=8.67859,49.41189,8.67964,49.41263&" + + "time=2017-01-01&groupByKey=DoesNotExist&groupByValues=xxx&" + + "filter=building=* and type:way", + JsonNode.class); + assertEquals( + Set.of("DoesNotExist=xxx", "remainder"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .map(jsonNode -> jsonNode.get("groupByObject").asText()) + .collect(Collectors.toSet())); + } + @Test public void getElementsCountGroupByKeyTest() { TestRestTemplate restTemplate = new TestRestTemplate(); @@ -222,6 +292,23 @@ public void getElementsCountGroupByKeyTest() { .findFirst().get().get("result").get(0).get("value").asInt()); } + @Test + public void getElementsCountGroupByKeyUnknownKeysTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = + restTemplate.getForEntity( + server + port + "/elements/count/groupBy/key?bboxes=8.67859,49.41189,8.67964,49.41263&" + + "time=2012-01-01&groupByKeys=DoesNotExist1,DoesNotExist2,DoesNotExist3&" + + "filter=type:way and building=*", + JsonNode.class); + assertEquals( + Set.of("DoesNotExist1", "DoesNotExist2", "DoesNotExist3", "remainder"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .map(jsonNode -> jsonNode.get("groupByObject").asText()) + .collect(Collectors.toSet())); + } + @Test public void getElementsCountRatioTest() { final double expectedValue = 0.153933; @@ -585,6 +672,24 @@ public void getUsersCountGroupByKeyTest() { .findFirst().get().get("result").get(0).get("value").asInt()); } + @Test + public void getUsersCountGroupByKeyUnknownKeysTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = + restTemplate.getForEntity( + server + port + "/users/count/groupBy/key?bboxes=8.67859,49.41189,8.67964,49.41263&" + + "time=2014-01-01,2015-01-01&" + + "groupByKeys=DoesNotExist1,DoesNotExist2,DoesNotExist3&" + + "filter=type:way and building=*", + JsonNode.class); + assertEquals( + Set.of("DoesNotExist1", "DoesNotExist2", "DoesNotExist3", "remainder", "total"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .map(jsonNode -> jsonNode.get("groupByObject").asText()) + .collect(Collectors.toSet())); + } + @Test public void getUsersCountGroupByTagTest() { TestRestTemplate restTemplate = new TestRestTemplate(); @@ -599,6 +704,41 @@ public void getUsersCountGroupByTagTest() { .findFirst().get().get("result").get(0).get("value").asInt()); } + @Test + public void getUsersCountGroupByTagUnknownValuesTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = + restTemplate.getForEntity( + server + port + "/users/count/groupBy/tag?bboxes=8.67859,49.41189,8.67964,49.41263&" + + "time=2014-01-01,2015-01-01&groupByKey=building&" + + "groupByValues=DoesNotExist1,DoesNotExist2&" + + "filter=type:way and building=*", + JsonNode.class); + assertEquals( + Set.of("building=DoesNotExist1", "building=DoesNotExist2", "remainder", "total"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .map(jsonNode -> jsonNode.get("groupByObject").asText()) + .collect(Collectors.toSet())); + } + + @Test + public void getUsersCountGroupByTagUnknownKeyTest() { + TestRestTemplate restTemplate = new TestRestTemplate(); + ResponseEntity response = + restTemplate.getForEntity( + server + port + "/users/count/groupBy/tag?bboxes=8.67859,49.41189,8.67964,49.41263&" + + "time=2014-01-01,2015-01-01&groupByKey=DoesNotExist&groupByValues=xxx&" + + "filter=type:way and building=*", + JsonNode.class); + assertEquals( + Set.of("DoesNotExist=xxx", "remainder", "total"), + StreamSupport.stream(Spliterators.spliteratorUnknownSize( + response.getBody().get("groupByResult").iterator(), Spliterator.ORDERED), false) + .map(jsonNode -> jsonNode.get("groupByObject").asText()) + .collect(Collectors.toSet())); + } + @Test public void getUsersCountDensityTest() { final double expectedValue = 14.33; diff --git a/src/test/java/org/heigit/ohsome/ohsomeapi/executor/ContributionsExecutorTest.java b/src/test/java/org/heigit/ohsome/ohsomeapi/executor/ContributionsExecutorTest.java index 7cbf4d59..a3441d95 100644 --- a/src/test/java/org/heigit/ohsome/ohsomeapi/executor/ContributionsExecutorTest.java +++ b/src/test/java/org/heigit/ohsome/ohsomeapi/executor/ContributionsExecutorTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.EnumSet; import java.util.Set; import java.util.function.Predicate; @@ -45,7 +46,8 @@ public void contributionsFilter() { @Test public void contributionsFilterInvalid() { - assertThrows(BadRequestException.class, () -> ExecutionUtils.contributionsFilter("doesnotexist")); + assertThrows(BadRequestException.class, () -> + ExecutionUtils.contributionsFilter("doesnotexist")); } diff --git a/src/test/java/org/heigit/ohsome/ohsomeapi/inputprocessing/GeometryBuilderTest.java b/src/test/java/org/heigit/ohsome/ohsomeapi/inputprocessing/GeometryBuilderTest.java index 602dd21e..2f12ea59 100644 --- a/src/test/java/org/heigit/ohsome/ohsomeapi/inputprocessing/GeometryBuilderTest.java +++ b/src/test/java/org/heigit/ohsome/ohsomeapi/inputprocessing/GeometryBuilderTest.java @@ -124,7 +124,8 @@ public void createPolygonFromGeoJsonWithWrongGeomType() { + "{\"id\":\"Neuenheim\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[[[8.68465," + "49.41769]]]}}]}"; InputProcessor inputProcessor = new InputProcessor(processingData); - assertThrows(BadRequestException.class, () -> geomBuilder.createGeometryFromGeoJson(geoJson, inputProcessor)); + assertThrows(BadRequestException.class, () -> + geomBuilder.createGeometryFromGeoJson(geoJson, inputProcessor)); } @Test @@ -136,14 +137,16 @@ public void createPolygonFromGeoJsonWithWrongFormat() { + "[8.2933214,49.4329125],[8.2936734,49.4330121],[8.2940745,49.4331354]," + "[8.2950478,49.4317345],[8.2944706,49.4313443]]]]}]}"; InputProcessor inputProcessor = new InputProcessor(processingData); - assertThrows(BadRequestException.class, () -> geomBuilder.createGeometryFromGeoJson(geoJson, inputProcessor)); + assertThrows(BadRequestException.class, () -> + geomBuilder.createGeometryFromGeoJson(geoJson, inputProcessor)); } @Test public void createGeometryFromInvalidInputGeoJson() { String geoJson = "{\"type\": \"FeatureCollection\"}"; InputProcessor inputProcessor = new InputProcessor(processingData); - assertThrows(BadRequestException.class, () -> geomBuilder.createGeometryFromGeoJson(geoJson, inputProcessor)); + assertThrows(BadRequestException.class, () -> + geomBuilder.createGeometryFromGeoJson(geoJson, inputProcessor)); } @Test @@ -194,6 +197,7 @@ public void createGeometryFromMetadataGeoJson() { @Test public void createGeometryFromWrongMetadataGeoJson() { String geoJson = "{\"type\":\"Polygon\",\"coordinates\":[Invalid-Input]}"; - assertThrows(RuntimeException.class, () ->geomBuilder.createGeometryFromMetadataGeoJson(geoJson)); + assertThrows(RuntimeException.class, () -> + geomBuilder.createGeometryFromMetadataGeoJson(geoJson)); } }