Skip to content

Commit

Permalink
implementing osm-data extraction
Browse files Browse the repository at this point in the history
via the resource /elements
  • Loading branch information
FabiKo117 committed Sep 26, 2018
1 parent 018fc43 commit 57f3540
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.heigit.bigspatialdata.ohsome.ohsomeapi.controller.rawData;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.executor.ElementsRequestExecutor;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.executor.RequestParameters;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
* REST controller containing the method, which is mapped to "/elements" and used to return OSM
* data.
*/
@Api(tags = "dataExtraction")
@RestController
@RequestMapping("/elements")
public class ElementsController {

/**
* Gives raw OSM objects as GeoJSON features.
*
* <p>
* The parameters are described in the
* {@link org.heigit.bigspatialdata.ohsome.ohsomeapi.controller.dataaggregation.CountController#count(String, String, String, String[], String[], String[], String[], String[], String, HttpServletRequest)
* count} method.
*
* @return {@link org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.Response
* Response}
*/
@ApiOperation(value = "Raw OSM Data", nickname = "rawData")
@RequestMapping(value = "", method = {RequestMethod.GET, RequestMethod.POST})
public void retrieveRawData(
@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,
@ApiParam(hidden = true) HttpServletRequest request,
@ApiParam(hidden = true) HttpServletResponse response)
throws UnsupportedOperationException, Exception {
ElementsRequestExecutor.executeRetrieveRawData(new RequestParameters(request.getMethod(), true,
false, bboxes, bcircles, bpolys, types, keys, values, userids, time, showMetadata),
response);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
import java.util.Map.Entry;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.geojson.GeoJsonObject;
Expand All @@ -34,6 +37,7 @@
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.elements.ElementsResult;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.groupByResponse.GroupByResponse;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.groupByResponse.GroupByResult;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.rawDataResponse.DataResponse;
import org.heigit.bigspatialdata.oshdb.api.generic.OSHDBCombinedIndex;
import org.heigit.bigspatialdata.oshdb.api.generic.function.SerializableFunction;
import org.heigit.bigspatialdata.oshdb.api.mapreducer.MapAggregator;
Expand All @@ -44,8 +48,15 @@
import org.heigit.bigspatialdata.oshdb.util.OSHDBTag;
import org.heigit.bigspatialdata.oshdb.util.OSHDBTimestamp;
import org.heigit.bigspatialdata.oshdb.util.geometry.Geo;
import org.heigit.bigspatialdata.oshdb.util.tagtranslator.OSMTag;
import org.heigit.bigspatialdata.oshdb.util.tagtranslator.TagTranslator;
import org.heigit.bigspatialdata.oshdb.util.time.TimestampFormatter;
import org.wololo.geojson.Feature;
import org.wololo.jts2geojson.GeoJSONWriter;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygonal;

Expand All @@ -55,6 +66,94 @@ public class ElementsRequestExecutor {
private static final String url = ExtractMetadata.attributionUrl;
private static final String text = ExtractMetadata.attributionShort;

/**
* Performs an OSM data extraction.
*
* <p>
*
* @param requestParams <code>RequestParameters</code> object, which holds those parameters that
* are used in every request.
* @param response <code>HttpServletResponse</code> object, which is used to send the response as
* a stream.
*/
public static void executeRetrieveRawData(RequestParameters requestParams,
HttpServletResponse response) throws UnsupportedOperationException, Exception {
long startTime = System.currentTimeMillis();
MapReducer<OSMEntitySnapshot> mapRed = null;
InputProcessor inputProcessor = new InputProcessor();
String requestUrl = null;
if (!requestParams.getRequestMethod().equalsIgnoreCase("post")) {
requestUrl = RequestInterceptor.requestUrl;
}
mapRed = inputProcessor.processParameters(mapRed, requestParams);
TagTranslator tt = DbConnData.tagTranslator;
String[] keys = requestParams.getKeys();
String[] values = requestParams.getValues();
int[] keysInt = new int[keys.length];
int[] valuesInt = new int[values.length];
if (keys.length != 0) {
for (int i = 0; i < keys.length; i++) {
keysInt[i] = tt.getOSHDBTagKeyOf(keys[0]).toInt();
if (values.length != 0 && i < values.length) {
// works as the relation between keys:values must be n:(m<=n)
valuesInt[i] = tt.getOSHDBTagOf(keys[i], values[i]).getValue();
}
}
}
List<Feature> result = null;
GeoJSONWriter gjw = new GeoJSONWriter();
result = mapRed.map(snapshot -> {
Map<String, Object> properties = new TreeMap<>();
properties.put("timestamp", snapshot.getTimestamp().toString());
properties.put("osm-id", snapshot.getEntity().getType().toString().toLowerCase() + "/"
+ snapshot.getEntity().getId());
if (keys.equals(null) || keys.length == 0) {
for (OSHDBTag OSHDBTag : snapshot.getEntity().getTags()) {
OSMTag tag = tt.getOSMTagOf(OSHDBTag.getKey(), OSHDBTag.getValue());
properties.put(tag.getKey(), tag.getValue());
}
} else {
int[] tags = snapshot.getEntity().getRawTags();
for (int i = 0; i < tags.length; i += 2) {
int tagKeyId = tags[i];
int tagValueId = tags[i + 1];
for (int key : keysInt) {
if (tagKeyId == key) {
if (valuesInt.length == 0) {
OSMTag tag = tt.getOSMTagOf(tagKeyId, tagValueId);
properties.put(tag.getKey(), tag.getValue());
} else {
for (int value : valuesInt) {
if (tagValueId == value) {
OSMTag tag = tt.getOSMTagOf(tagKeyId, tagValueId);
properties.put(tag.getKey(), tag.getValue());
}
}
}
}
}
}
}
return new Feature(gjw.write(snapshot.getGeometry()), properties);
}).collect();
Metadata metadata = null;
if (ProcessingData.showMetadata) {
long duration = System.currentTimeMillis() - startTime;
metadata = new Metadata(duration, "Raw OSM data.", requestUrl);
}
DataResponse OSMData = new DataResponse(new Attribution(url, text), Application.apiVersion,
metadata, "FeatureCollection", result);

JsonFactory jsonFactory = new JsonFactory();
ServletOutputStream stream = response.getOutputStream();
response.addHeader("Content-disposition", "attachment;filename=ohsomeApiResponse.json");
response.setContentType("application/json");
JsonGenerator jsonGen = jsonFactory.createGenerator(stream, JsonEncoding.UTF8);
jsonGen.setCodec(new ObjectMapper());
jsonGen.writeObject(OSMData);
response.flushBuffer();
}

/**
* Performs a count|length|perimeter|area calculation.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* ShareGroupByBoundaryResponse}</li>
* <li>{@link org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.RatioResponse
* RatioResponse}</li>
* <li>{@link org.heigit.bigspatialdata.ohsome.ohsomeapi.output.rawDataResponse.DataResponse
* DataResponse}</li>
* </ul>
*/
public interface Response {
Expand All @@ -24,5 +26,4 @@ public interface Response {
public String getApiVersion();

public Metadata getMetadata();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.heigit.bigspatialdata.ohsome.ohsomeapi.output.rawDataResponse;

import java.util.List;
import org.wololo.geojson.Feature;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.Attribution;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.Metadata;
import org.heigit.bigspatialdata.ohsome.ohsomeapi.output.dataAggregationResponse.Response;
import io.swagger.annotations.ApiModelProperty;

/**
* Represents the whole GeoJSON response object for the /elements resource.
*/
public class DataResponse implements Response {

@ApiModelProperty(notes = "License and copyright info", required = true)
private Attribution attribution;
@ApiModelProperty(notes = "Version of this api", required = true)
private String apiVersion;
@ApiModelProperty(notes = "Metadata describing the output")
private Metadata metadata;
@ApiModelProperty(notes = "Type of the GeoJSON", required = true)
private String type;
@ApiModelProperty(notes = "List of GeoJSON features containing the OSM data")
private List<Feature> features;

public DataResponse(Attribution attribution, String apiVersion, Metadata metadata, String type,
List<Feature> features) {
this.attribution = attribution;
this.apiVersion = apiVersion;
this.metadata = metadata;
this.type = type;
this.features = features;
}

@Override
public Attribution getAttribution() {
return attribution;
}

@Override
public String getApiVersion() {
return apiVersion;
}

@Override
public Metadata getMetadata() {
return metadata;
}

public String getType() {
return type;
}

public List<Feature> getFeatures() {
return features;
}
}

0 comments on commit 57f3540

Please sign in to comment.