Skip to content

Commit

Permalink
fix some issues with full history output
Browse files Browse the repository at this point in the history
also slightly leaner implementation with less special cases
  • Loading branch information
tyrasd committed Nov 27, 2018
1 parent c9ab41b commit 4d3bf2e
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,64 +259,64 @@ public static void executeElementsFullHistory(RequestParameters contributionRequ
String endTimestamp = endTimestampWithZ.substring(0, endTimestampWithZ.length() - 1);

contributionPreResult = mapRedContribution.groupByEntity().flatMap(contributions -> {
Map<String, Object> properties = new TreeMap<>();
List<Feature> output = new LinkedList<>();
int startIndex = 1;

Map<String, Object> properties;
Geometry currentGeom = null;
OSMEntity currentEntity = null;
String validFrom = null;
String validTo;
boolean skipNext = false;

// first contribution:
// if not "creation": take "before" as starting "row" (geom, tags), validFrom = t_start
if (!contributions.get(0).getContributionTypes().contains(ContributionType.CREATION)) {
properties.put("validFrom", startTimestamp);
if (contributions.get(0).is(ContributionType.CREATION)) {
// if creation: skip next output
skipNext = true;
} else {
// if creation
properties.put("validFrom", contributions.get(0).getTimestamp().toString());
if (contributions.size() == 1) {
// use latest timestamp from input parameter for validTo
properties.put("validTo", endTimestamp);
output.add(exeUtils.createOSMDataFeature(keys, values, mapTagTranslator.get(), keysInt,
valuesInt, contributions.get(0), false, properties, gjw, includeTags,
includeOSMMetadata, elemGeom));
properties = new TreeMap<>();
return output;
} else {
// use timestamp of contribution 2 for validTo
properties.put("validTo", contributions.get(1).getTimestamp().toString());
output.add(exeUtils.createOSMDataFeature(keys, values, mapTagTranslator.get(), keysInt,
valuesInt, contributions.get(0), false, properties, gjw, includeTags,
includeOSMMetadata, elemGeom));
// if not "creation": take "before" as starting "row" (geom, tags), valid_from = t_start
currentEntity = contributions.get(0).getEntityBefore();
currentGeom = contributions.get(0).getGeometryBefore();
validFrom = startTimestamp;
}

// then for each contribution:
for (OSMContribution contribution : contributions) {
// set valid_to of previous row, add to output list (output.add(…))
validTo = contribution.getTimestamp().toString();
if (!skipNext) {
properties = new TreeMap<>();
properties.put("validFrom", validFrom);
properties.put("validTo", validTo);
output.add(exeUtils.createOSMFeature(
currentEntity, currentGeom, properties,
keysInt, includeTags, includeOSMMetadata, elemGeom, mapTagTranslator.get(), gjw
));
}
if (!contributions.get(1).getContributionTypes().contains(ContributionType.DELETION)) {
properties.put("validFrom", contributions.get(1).getTimestamp().toString());
}
// to skip the 2nd contribution in the following loop
startIndex = 2;
}
for (int i = startIndex; i < contributions.size(); i++) {
// for each contribution:
// set valid_to of previous row, add to output list (output.add(…))
properties.put("validTo", contributions.get(i).getTimestamp().toString());
output.add(exeUtils.createOSMDataFeature(keys, values, mapTagTranslator.get(), keysInt,
valuesInt, contributions.get(i), false, properties, gjw, includeTags,
includeOSMMetadata, elemGeom));
properties = new TreeMap<>();
// if deletion: skip output of next row
if (contributions.get(i).getContributionTypes().contains(ContributionType.DELETION)) {
i++;
skipNext = false;
if (contribution.is(ContributionType.DELETION)) {
// if deletion: skip output of next row
skipNext = true;
} else {
// else: take "after" as next row
properties.put("validFrom", contributions.get(i).getTimestamp().toString());
// else: take "after" as next row
currentEntity = contribution.getEntityAfter();
currentGeom = contribution.getGeometryAfter();
validFrom = contribution.getTimestamp().toString();
}
}

// after loop:
// if last contribution was not "deletion": set valid_to = t_end, add row to output list
if (!contributions.get(contributions.size() - 1).getContributionTypes()
.contains(ContributionType.DELETION)) {
properties.put("validTo", endTimestamp);
output.add(exeUtils.createOSMDataFeature(keys, values, mapTagTranslator.get(), keysInt,
valuesInt, contributions.get(contributions.size() - 1), false, properties, gjw,
includeTags, includeOSMMetadata, elemGeom));
if (!contributions.get(contributions.size()-1).is(ContributionType.DELETION)) {
// if last contribution was not "deletion": set valid_to = t_end, add row to output list
validTo = endTimestamp;
properties = new TreeMap<>();
properties.put("validFrom", validFrom);
properties.put("validTo", validTo);
output.add(exeUtils.createOSMFeature(
currentEntity, currentGeom, properties,
keysInt, includeTags, includeOSMMetadata, elemGeom, mapTagTranslator.get(), gjw
));
}

return output;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,49 @@ public org.wololo.geojson.Feature createOSMDataFeature(String[] keys, String[] v
}
}

/** Creates the <code>Feature</code> objects in the OSM data response. */
public org.wololo.geojson.Feature createOSMFeature(OSMEntity entity,
Geometry geometry, Map<String, Object> properties, int[] keysInt,
boolean includeTags, boolean includeOSMMetadata, ElementsGeometry elemGeom,
TagTranslator tt, GeoJSONWriter gjw) {
properties.put("osmId", entity.getType().toString().toLowerCase() + "/" + entity.getId());
if (includeOSMMetadata) {
properties.put("version", entity.getVersion());
properties.put("osmType", entity.getType());
properties.put("changesetId", entity.getChangeset());
}
if (includeTags) {
for (OSHDBTag oshdbTag : entity.getTags()) {
OSMTag tag = tt.getOSMTagOf(oshdbTag);
properties.put(tag.getKey(), tag.getValue());
}
} else if (keysInt != null && keysInt.length != 0) {
int[] tags = entity.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) {
OSMTag tag = tt.getOSMTagOf(tagKeyId, tagValueId);
properties.put(tag.getKey(), tag.getValue());
}
}
}
}
switch (elemGeom) {
case BBOX:
Envelope envelope = geometry.getEnvelopeInternal();
OSHDBBoundingBox bbox = OSHDBGeometryBuilder.boundingBoxOf(envelope);
return new org.wololo.geojson.Feature(gjw.write(OSHDBGeometryBuilder.getGeometry(bbox)),
properties);
case CENTROID:
return new org.wololo.geojson.Feature(gjw.write(geometry.getCentroid()), properties);
case RAW:
default:
return new org.wololo.geojson.Feature(gjw.write(geometry), properties);
}
}

/** Computes the result for the /count|length|perimeter|area/groupBy/boundary resources. */
@SuppressWarnings({"unchecked"}) // intentionally as check for P on Polygonal is already performed
public <P extends Geometry & Polygonal> SortedMap<OSHDBCombinedIndex<OSHDBTimestamp, Integer>, ? extends Number> computeCountLengthPerimeterAreaGbB(
Expand Down

0 comments on commit 4d3bf2e

Please sign in to comment.