Skip to content

Commit

Permalink
implementing /users/count/groupBy/key
Browse files Browse the repository at this point in the history
  • Loading branch information
kowatsch committed Jun 11, 2018
1 parent 6b64ea8 commit e71b990
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,49 @@ public GroupByResponse getCountGroupByTag(
groupByValues);
}

/**
* GET request giving the count of OSM users grouped by the key.
* <p>
* The parameters are described in the
* {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.controller.dataAggregation.CountController#getCount(String, String, String, String[], String[], String[], String[], String[], String)
* getCount} method.
*
* @return {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.output.dataAggregationResponse.groupByResponse.GroupByResponse
* GroupByResponseContent}
*/
@ApiOperation(value = "Count of OSM users grouped by the tag")
@ApiImplicitParams({
@ApiImplicitParam(name = "groupByKeys", value = ParameterDescriptions.KEYS_DESCR,
defaultValue = DefaultSwaggerParameters.BUILDING_KEY, paramType = "query",
dataType = "string", required = true)})
@RequestMapping(value = "count/groupBy/key", method = RequestMethod.GET,
produces = "application/json")
public GroupByResponse getCountGroupByKey(
@ApiParam(hidden = true) @RequestParam(value = "bboxes", defaultValue = "",
required = false) String bboxes,
@ApiParam(hidden = true) @RequestParam(value = "bcircles", defaultValue = "",
required = false) String bcircles,
@ApiParam(hidden = true) @RequestParam(value = "bpolys", defaultValue = "",
required = false) String bpolys,
@ApiParam(hidden = true) @RequestParam(value = "types", defaultValue = "",
required = false) String[] types,
@ApiParam(hidden = true) @RequestParam(value = "keys", defaultValue = "",
required = false) String[] keys,
@ApiParam(hidden = true) @RequestParam(value = "values", defaultValue = "",
required = false) String[] values,
@ApiParam(hidden = true) @RequestParam(value = "userids", defaultValue = "",
required = false) String[] userids,
@ApiParam(hidden = true) @RequestParam(value = "time", defaultValue = "",
required = false) String[] time,
@ApiParam(hidden = true) @RequestParam(value = "showMetadata",
defaultValue = "false") String showMetadata,
@RequestParam(value = "groupByKeys", defaultValue = "", required = false) String[] groupByKey)
throws UnsupportedOperationException, Exception {

return UsersRequestExecutor.executeCountGroupByKey(new RequestParameters(false, false, false,
bboxes, bcircles, bpolys, types, keys, values, userids, time, showMetadata), groupByKey);
}

/**
* GET request giving the density of OSM users (number of users per square-kilometers).
* <p>
Expand Down Expand Up @@ -270,7 +313,7 @@ public GroupByResponse getCountDensityGroupByTag(
bboxes, bcircles, bpolys, types, keys, values, userids, time, showMetadata), groupByKey,
groupByValues);
}

/**
* POST request giving the count of OSM users. POST requests should only be used if the request
* URL would be too long for a GET request.
Expand Down Expand Up @@ -421,6 +464,56 @@ public GroupByResponse postCountGroupByTag(String bboxes, String bcircles, Strin
groupByValues);
}

/**
* POST request giving the count of OSM users grouped by the key. POST requests should only be
* used if the request URL would be too long for a GET request.
* <p>
* The other parameters are described in the
* {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.controller.dataAggregation.CountController#getCount(String, String, String, String[], String[], String[], String[], String[], String)
* getCount} method.
*
* @param groupByKeys <code>String</code> array containing the keys used for the grouping.
* @return {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.output.dataAggregationResponse.groupByResponse.GroupByResponse
* GroupByResponse Content}
*/
@ApiOperation(value = "Count of OSM users grouped by the key")
@ApiImplicitParams({
@ApiImplicitParam(name = "bboxes", paramType = "form", dataType = "string",
defaultValue = DefaultSwaggerParameters.BBOX, required = false,
value = ParameterDescriptions.BBOXES_DESCR),
@ApiImplicitParam(name = "bcircles", paramType = "form", dataType = "string",
required = false, value = ParameterDescriptions.BCIRCLES_DESCR),
@ApiImplicitParam(name = "bpolys", paramType = "form", dataType = "string", required = false,
value = ParameterDescriptions.BPOLYS_DESCR),
@ApiImplicitParam(name = "types", paramType = "form", dataType = "string",
defaultValue = DefaultSwaggerParameters.TYPE, required = false,
value = ParameterDescriptions.TYPES_DESCR),
@ApiImplicitParam(name = "keys", paramType = "form", dataType = "string",
defaultValue = DefaultSwaggerParameters.BUILDING_KEY, required = false,
value = ParameterDescriptions.KEYS_DESCR),
@ApiImplicitParam(name = "values", paramType = "form", dataType = "string", defaultValue = "",
required = false, value = ParameterDescriptions.VALUES_DESCR),
@ApiImplicitParam(name = "userids", paramType = "form", dataType = "string", required = false,
value = ParameterDescriptions.USERIDS_DESCR),
@ApiImplicitParam(name = "time", paramType = "form", dataType = "string",
defaultValue = DefaultSwaggerParameters.TIME, required = false,
value = ParameterDescriptions.TIME_DESCR),
@ApiImplicitParam(name = "showMetadata", paramType = "form", dataType = "string",
defaultValue = DefaultSwaggerParameters.SHOW_METADATA, required = false,
value = ParameterDescriptions.SHOW_METADATA_DESCR),
@ApiImplicitParam(name = "groupByKeys", paramType = "form", dataType = "string",
defaultValue = "height", required = true, value = ParameterDescriptions.KEYS_DESCR)})
@RequestMapping(value = "/count/groupBy/key", method = RequestMethod.POST,
produces = "application/json", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public GroupByResponse postCountGroupByKey(String bboxes, String bcircles, String bpolys,
String[] types, String[] keys, String[] values, String[] userids, String[] time,
String showMetadata, String[] groupByKeys)
throws UnsupportedOperationException, Exception, BadRequestException {

return UsersRequestExecutor.executeCountGroupByKey(new RequestParameters(true, false, false,
bboxes, bcircles, bpolys, types, keys, values, userids, time, showMetadata), groupByKeys);
}

/**
* POST request giving the density of OSM users (number of users per square-kilometers). POST
* requests should only be used if the request URL would be too long for a GET request.
Expand Down Expand Up @@ -515,8 +608,8 @@ public GroupByResponse postCountDensityGroupByType(String bboxes, String bcircle
}

/**
* POST request giving the density of OSM users grouped by the tag. POST requests should only
* be used if the request URL would be too long for a GET request.
* POST request giving the density of OSM users grouped by the tag. POST requests should only be
* used if the request URL would be too long for a GET request.
* <p>
* The parameters are described in the
* {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.controller.dataAggregation.CountController#getCount(String, String, String, String[], String[], String[], String[], String[], String)
Expand Down Expand Up @@ -550,15 +643,16 @@ public GroupByResponse postCountDensityGroupByType(String bboxes, String bcircle
@ApiImplicitParam(name = "showMetadata", paramType = "form", dataType = "string",
defaultValue = DefaultSwaggerParameters.SHOW_METADATA, required = false,
value = ParameterDescriptions.SHOW_METADATA_DESCR),
@ApiImplicitParam(name = "groupByKey", paramType = "form", dataType = "string",
@ApiImplicitParam(name = "groupByKey", paramType = "form", dataType = "string",
defaultValue = "height", required = true, value = ParameterDescriptions.KEYS_DESCR),
@ApiImplicitParam(name = "groupByValues", paramType = "form", dataType = "string",
defaultValue = "", required = false, value = ParameterDescriptions.VALUES_DESCR)})
@RequestMapping(value = "/count/density/groupBy/tag", method = RequestMethod.POST,
produces = "application/json", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public GroupByResponse postCountDensityGroupByTag(String bboxes, String bcircles, String bpolys,
String[] types, String[] keys, String[] values, String[] userids, String[] time,
String showMetadata, String[] groupByKey, String[] groupByValues) throws UnsupportedOperationException, Exception {
String showMetadata, String[] groupByKey, String[] groupByValues)
throws UnsupportedOperationException, Exception {

return UsersRequestExecutor.executeCountGroupByTag(new RequestParameters(true, false, true,
bboxes, bcircles, bpolys, types, keys, values, userids, time, showMetadata), groupByKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
Expand Down Expand Up @@ -264,6 +265,105 @@ public static GroupByResponse executeCountGroupByTag(RequestParameters rPs, Stri
return response;
}

/**
* Performs a count calculation grouped by the key.
* <p>
* The other parameters are described in the
* {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.controller.dataAggregation.CountController#getCountGroupByTag(String, String, String, String[], String[], String[], String[], String[], String, String[], String[])
* getCountGroupByKey} method.
*
* @param rPs <code>RequestParameters</code> object, which holds those parameters that are used in
* every request.
* @return {@link org.heigit.bigspatialdata.ohsome.ohsomeApi.output.dataAggregationResponse.groupByResponse.GroupByResponse
* GroupByResponseContent}
*/
public static GroupByResponse executeCountGroupByKey(RequestParameters rPs, String[] groupByKeys)
throws UnsupportedOperationException, Exception {

long startTime = System.currentTimeMillis();
if (groupByKeys == null || groupByKeys.length == 0)
throw new BadRequestException(
"You need to give at least one groupByKey parameter, if you want to use groupBy/key");
ExecutionUtils exeUtils = new ExecutionUtils();
SortedMap<OSHDBTimestampAndIndex<Integer>, Integer> result = null;
SortedMap<Integer, SortedMap<OSHDBTimestamp, Integer>> groupByResult;
MapReducer<OSMContribution> mapRed = null;
InputProcessor iP = new InputProcessor();
String description = null;
String requestURL = null;
DecimalFormat df = exeUtils.defineDecimalFormat("#.##");
if (!rPs.isPost())
requestURL = RequestInterceptor.requestUrl;
TagTranslator tt = DbConnData.tagTranslator;
mapRed = iP.processParameters(mapRed, rPs);
Integer[] keysInt = new Integer[groupByKeys.length];
for (int i = 0; i < groupByKeys.length; i++) {
keysInt[i] = tt.getOSHDBTagKeyOf(groupByKeys[i]).toInt();
}
result = mapRed.flatMap(f -> {
List<Pair<Integer, OSMContribution>> res = new LinkedList<>();
int[] tags;
// next 10 lines should be put into distinct method
if (f.getContributionTypes().contains(ContributionType.DELETION)) {
tags = f.getEntityBefore().getRawTags();
} else if (f.getContributionTypes().contains(ContributionType.CREATION)) {
tags = f.getEntityAfter().getRawTags();
} else {
int[] tagsBefore = f.getEntityBefore().getRawTags();
int[] tagsAfter = f.getEntityAfter().getRawTags();
tags = new int[tagsBefore.length + tagsAfter.length];
System.arraycopy(tagsBefore, 0, tags, 0, tagsBefore.length);
System.arraycopy(tagsAfter, 0, tags, tagsBefore.length, tagsAfter.length);
}
for (int i = 0; i < tags.length; i += 2) {
int tagKeyId = tags[i];
for (int key : keysInt) {
if (tagKeyId == key) {
res.add(new ImmutablePair<>(tagKeyId, f));
}
}
}
if (res.isEmpty())
res.add(new ImmutablePair<>(-1, f));
return res;
}).aggregateByTimestamp().aggregateBy(Pair::getKey).zerofillIndices(Arrays.asList(keysInt))
.map(Pair::getValue).map(contrib -> {
return contrib.getContributorUserId();
}).countUniq();
groupByResult = MapAggregatorByTimestampAndIndex.nest_IndexThenTime(result);
GroupByResult[] resultSet = new GroupByResult[groupByResult.size()];
String groupByName = "";
String[] toTimestamps = iP.getUtils().getToTimestamps();
int count = 0;
for (Entry<Integer, SortedMap<OSHDBTimestamp, Integer>> entry : groupByResult
.entrySet()) {
UsersResult[] results =
exeUtils.fillUsersResult(entry.getValue(), rPs.isDensity(), toTimestamps, df, null);
// check for non-remainder objects (which do have the defined key)
if (entry.getKey() != -1) {
groupByName = tt.getOSMTagKeyOf(entry.getKey().intValue()).toString();
} else {
groupByName = "remainder";
}
resultSet[count] = new GroupByResult(groupByName, results);
count++;
}
if (rPs.isDensity()) {
description =
"Density of distinct users per time interval (number of users per square-kilometer) aggregated on the key.";
} else {
description = "Number of distinct users per time interval aggregated on the key.";
}
Metadata metadata = null;
if (iP.getShowMetadata()) {
long duration = System.currentTimeMillis() - startTime;
metadata = new Metadata(duration, description, requestURL);
}
GroupByResponse response = new GroupByResponse(new Attribution(url, text),
Application.apiVersion, metadata, resultSet);
return response;
}

/**
* NOT IN USE YET Performs a count calculation grouped by the boundary.
* <p>
Expand Down

0 comments on commit e71b990

Please sign in to comment.