Skip to content

Commit e5c72f9

Browse files
authored
Feature changes (#392)
1 parent fc163a3 commit e5c72f9

File tree

8 files changed

+355
-21
lines changed

8 files changed

+355
-21
lines changed

xtraplatform-features-sql/src/main/java/de/ii/xtraplatform/features/sql/app/FeatureEncoderSql.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,9 @@ public Class<? extends ModifiableContext<SqlQuerySchema, SqlQueryMapping>> getCo
321321

322322
@Override
323323
public ModifiableContext<SqlQuerySchema, SqlQueryMapping> createContext() {
324-
return ModifiableFeatureEncoderSqlContext.create();
324+
return ModifiableFeatureEncoderSqlContext.create()
325+
.setType(mapping.getMainSchema().getName())
326+
.setMappings(Map.of(mapping.getMainSchema().getName(), mapping));
325327
}
326328

327329
private boolean checkJson(Tuple<SqlQuerySchema, SqlQueryColumn> column) {

xtraplatform-features-sql/src/main/java/de/ii/xtraplatform/features/sql/domain/FeatureProviderSql.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,10 +1299,11 @@ private MutationResult writeFeatures(
12991299

13001300
ImmutableMutationResult.Builder builder =
13011301
ImmutableMutationResult.builder().type(type).hasFeatures(false);
1302+
FeatureTokenStatsCollector statsCollector = new FeatureTokenStatsCollector(builder, crs);
13021303

13031304
Source<FeatureDataSql> featureSqlSource =
13041305
featureTokenSource
1305-
// TODO: Simple .via(statsCollector)
1306+
.via(statsCollector)
13061307
.via(
13071308
new FeatureEncoderSql(
13081309
queryMapping.get().get(0),
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright 2022 interactive instruments GmbH
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
package de.ii.xtraplatform.features.sql.domain;
9+
10+
import de.ii.xtraplatform.crs.domain.BoundingBox;
11+
import de.ii.xtraplatform.crs.domain.EpsgCrs;
12+
import de.ii.xtraplatform.features.domain.ImmutableMutationResult.Builder;
13+
import de.ii.xtraplatform.features.domain.SchemaBase.Role;
14+
import de.ii.xtraplatform.features.domain.Tuple;
15+
import de.ii.xtraplatform.geometries.domain.Geometry;
16+
import de.ii.xtraplatform.geometries.domain.transform.MinMaxDeriver;
17+
import java.time.LocalDate;
18+
import java.time.ZoneOffset;
19+
import java.time.ZonedDateTime;
20+
import java.util.Objects;
21+
import org.slf4j.Logger;
22+
import org.slf4j.LoggerFactory;
23+
24+
public class FeatureTokenStatsCollector extends FeatureTokenTransformerSql {
25+
26+
private static final Logger LOGGER = LoggerFactory.getLogger(FeatureTokenStatsCollector.class);
27+
28+
private final Builder builder;
29+
private final EpsgCrs crs;
30+
private int axis = 0;
31+
private int dim = 2;
32+
private Double xmin = null;
33+
private Double ymin = null;
34+
private Double xmax = null;
35+
private Double ymax = null;
36+
private String start = "";
37+
private String end = "";
38+
39+
public FeatureTokenStatsCollector(Builder builder, EpsgCrs crs) {
40+
this.builder = builder;
41+
this.crs = crs;
42+
}
43+
44+
@Override
45+
public void onStart(ModifiableContext<SqlQuerySchema, SqlQueryMapping> context) {
46+
// TODO: get crs
47+
this.dim = context.geometryDimension().orElse(2);
48+
49+
super.onStart(context);
50+
}
51+
52+
@Override
53+
public void onEnd(ModifiableContext<SqlQuerySchema, SqlQueryMapping> context) {
54+
if (xmin != null && ymin != null && xmax != null && ymax != null) {
55+
builder.spatialExtent(BoundingBox.of(xmin, ymin, xmax, ymax, crs));
56+
}
57+
58+
if (!start.isEmpty() || !end.isEmpty()) {
59+
builder.temporalExtent(Tuple.of(parseTemporal(start), parseTemporal(end)));
60+
}
61+
62+
super.onEnd(context);
63+
}
64+
65+
private Long parseTemporal(String temporal) {
66+
if (temporal.isEmpty()) {
67+
return null;
68+
}
69+
try {
70+
if (temporal.length() > 10) {
71+
return ZonedDateTime.parse(temporal).toInstant().toEpochMilli();
72+
}
73+
return LocalDate.parse(temporal).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli();
74+
} catch (Throwable e) {
75+
return null;
76+
}
77+
}
78+
79+
@Override
80+
public void onValue(ModifiableContext<SqlQuerySchema, SqlQueryMapping> context) {
81+
if (Objects.nonNull(context.value())) {
82+
String value = context.value();
83+
84+
if (hasRole(context, Role.PRIMARY_INSTANT)) {
85+
if (start.isEmpty() || value.compareTo(start) < 0) {
86+
this.start = value;
87+
}
88+
if (end.isEmpty() || value.compareTo(end) > 0) {
89+
this.end = value;
90+
}
91+
} else if (hasRole(context, Role.PRIMARY_INTERVAL_START)) {
92+
if (start.isEmpty() || value.compareTo(start) < 0) {
93+
this.start = value;
94+
}
95+
} else if (hasRole(context, Role.PRIMARY_INTERVAL_END)) {
96+
if (end.isEmpty() || value.compareTo(end) > 0) {
97+
this.end = value;
98+
}
99+
}
100+
}
101+
102+
super.onValue(context);
103+
}
104+
105+
@Override
106+
public void onGeometry(ModifiableContext<SqlQuerySchema, SqlQueryMapping> context) {
107+
if (Objects.nonNull(context.geometry())) {
108+
Geometry<?> value = context.geometry();
109+
110+
double[][] minMax = value.accept(new MinMaxDeriver());
111+
if (minMax.length > 1 && minMax[0].length >= dim && minMax[1].length >= dim) {
112+
this.xmin = minMax[0][0];
113+
this.xmax = minMax[1][0];
114+
this.ymin = minMax[0][1];
115+
this.ymax = minMax[1][1];
116+
}
117+
}
118+
}
119+
120+
private boolean hasRole(ModifiableContext<SqlQuerySchema, SqlQueryMapping> context, Role role) {
121+
return context
122+
.mapping()
123+
.getSchemaForRole(role)
124+
.filter(schema -> Objects.equals(schema.getFullPathAsString(), context.pathAsString()))
125+
.isPresent();
126+
}
127+
}

xtraplatform-features-sql/src/main/java/de/ii/xtraplatform/features/sql/domain/FeatureTokenTransformerSql.java

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,36 @@
77
*/
88
package de.ii.xtraplatform.features.sql.domain;
99

10-
import de.ii.xtraplatform.features.domain.FeatureEventHandler.ModifiableContext;
11-
import de.ii.xtraplatform.features.domain.FeatureTokenContext;
12-
import de.ii.xtraplatform.features.domain.FeatureTokenTransformerBase;
13-
import de.ii.xtraplatform.features.sql.app.ModifiableSqlMutationContext;
14-
import de.ii.xtraplatform.features.sql.app.SqlMutationContext;
10+
import de.ii.xtraplatform.features.domain.pipeline.FeatureEventHandlerSimple.ModifiableContext;
11+
import de.ii.xtraplatform.features.domain.pipeline.FeatureTokenContextSimple;
12+
import de.ii.xtraplatform.features.domain.pipeline.FeatureTokenTransformerBaseSimple;
1513
import java.util.Objects;
1614

1715
public abstract class FeatureTokenTransformerSql
18-
extends FeatureTokenTransformerBase<
19-
SchemaSql, SchemaMappingSql, ModifiableContext<SchemaSql, SchemaMappingSql>> {
16+
extends FeatureTokenTransformerBaseSimple<
17+
SqlQuerySchema, SqlQueryMapping, ModifiableContext<SqlQuerySchema, SqlQueryMapping>> {
2018

21-
private ModifiableContext<SchemaSql, SchemaMappingSql> context;
19+
private ModifiableContext<SqlQuerySchema, SqlQueryMapping> context;
2220

2321
@Override
24-
public Class<? extends ModifiableContext<SchemaSql, SchemaMappingSql>> getContextInterface() {
25-
if (getDownstream() instanceof FeatureTokenContext<?>) {
26-
return ((FeatureTokenContext<ModifiableContext<SchemaSql, SchemaMappingSql>>) getDownstream())
22+
public Class<? extends ModifiableContext<SqlQuerySchema, SqlQueryMapping>> getContextInterface() {
23+
if (getDownstream() instanceof FeatureTokenContextSimple<?>) {
24+
return ((FeatureTokenContextSimple<ModifiableContext<SqlQuerySchema, SqlQueryMapping>>)
25+
getDownstream())
2726
.getContextInterface();
2827
}
2928

30-
return SqlMutationContext.class;
29+
return null;
3130
}
3231

3332
@Override
34-
public final ModifiableContext<SchemaSql, SchemaMappingSql> createContext() {
35-
ModifiableContext<SchemaSql, SchemaMappingSql> context =
36-
getDownstream() instanceof FeatureTokenContext<?>
37-
? ((FeatureTokenContext<ModifiableContext<SchemaSql, SchemaMappingSql>>)
33+
public final ModifiableContext<SqlQuerySchema, SqlQueryMapping> createContext() {
34+
ModifiableContext<SqlQuerySchema, SqlQueryMapping> context =
35+
getDownstream() instanceof FeatureTokenContextSimple<?>
36+
? ((FeatureTokenContextSimple<ModifiableContext<SqlQuerySchema, SqlQueryMapping>>)
3837
getDownstream())
3938
.createContext()
40-
: ModifiableSqlMutationContext.create();
39+
: null;
4140

4241
if (Objects.isNull(this.context)) {
4342
this.context = context;
@@ -46,7 +45,7 @@ public final ModifiableContext<SchemaSql, SchemaMappingSql> createContext() {
4645
return context;
4746
}
4847

49-
protected final ModifiableContext<SchemaSql, SchemaMappingSql> getContext() {
48+
protected final ModifiableContext<SqlQuerySchema, SqlQueryMapping> getContext() {
5049
if (Objects.isNull(context)) {
5150
return createContext();
5251
}

xtraplatform-features-sql/src/main/java/de/ii/xtraplatform/features/sql/domain/SqlQueryMapping.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ default Optional<FeatureSchema> getSchemaForRole(Role role) {
142142
if (role == Role.PRIMARY_GEOMETRY) {
143143
return getMainSchema().getPrimaryGeometry();
144144
}
145+
if (role == Role.PRIMARY_INSTANT) {
146+
return getMainSchema().getPrimaryInstant();
147+
}
148+
if (role == Role.PRIMARY_INTERVAL_START) {
149+
return getMainSchema()
150+
.getPrimaryInterval()
151+
.map(de.ii.xtraplatform.features.domain.Tuple::first);
152+
}
153+
if (role == Role.PRIMARY_INTERVAL_END) {
154+
return getMainSchema()
155+
.getPrimaryInterval()
156+
.map(de.ii.xtraplatform.features.domain.Tuple::second);
157+
}
145158

146159
return Optional.empty();
147160
}

xtraplatform-features/src/main/java/de/ii/xtraplatform/features/app/FeatureChangeHandlerImpl.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ public void handle(DatasetChange change) {
8383

8484
@Override
8585
public void handle(FeatureChange change) {
86-
executor.submit(() -> featureListeners.forEach(listener -> listener.onFeatureChange(change)));
86+
executor.submit(
87+
() -> {
88+
if (LOGGER.isTraceEnabled()) {
89+
LOGGER.trace("Handling feature change: {}", change);
90+
}
91+
92+
featureListeners.forEach(
93+
listener -> {
94+
if (LOGGER.isTraceEnabled()) {
95+
LOGGER.trace(
96+
"Notifying feature change listener: {}", listener.getClass().getSimpleName());
97+
}
98+
listener.onFeatureChange(change);
99+
});
100+
});
87101
}
88102
}

0 commit comments

Comments
 (0)