Skip to content
This repository has been archived by the owner on Mar 7, 2024. It is now read-only.

Feat/custom popups #31

Merged
merged 10 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions backend/examples/example-application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ spring:

ldes:
streams:
-
gipod:
member-type: "https://data.vlaanderen.be/ns/mobiliteit#Mobiliteitshinder"
timestamp-path: "http://www.w3.org/ns/prov#generatedAtTime"
property-predicates:
startTime: "http://data.europa.eu/m8g/startTime"
endTime: "http://data.europa.eu/m8g/endTime"
verkeersmeting:
member-type: "https://data.vlaanderen.be/ns/verkeersmetingen#Verkeersmeting"
timestamp-path: "http://www.w3.org/ns/prov#generatedAtTime"
property-predicates:
fullName: "http://custom/meetpunt#VolledigeNaam"
countObservationResult: "http://def.isotc211.org/iso19156/2011/CountObservation#OM_CountObservation.result"
graphdb:
url: "http://localhost:8080/rdf4j-server/repositories/"
repositoryId: "test"
server:
port: 8080
port: 8084
5 changes: 5 additions & 0 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@
<artifactId>hibernate-spatial</artifactId>
<version>6.1.7.Final</version>
</dependency>
<dependency>
<groupId>io.hypersistence</groupId>
<artifactId>hypersistence-utils-hibernate-60</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.wololo</groupId>
<artifactId>jts2geojson</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@

import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class EventStreamConfig {
private String name;
private String memberType;
private String timestampPath;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

private Map<String, String> propertyPredicates;
public String getMemberType() {
return memberType;
}
Expand All @@ -31,4 +25,15 @@ public String getTimestampPath() {
public void setTimestampPath(String timestampPath) {
this.timestampPath = timestampPath;
}

public Map<String, String> getPropertyPredicates() {
if(propertyPredicates == null) {
propertyPredicates = new HashMap<>();
}
return propertyPredicates;
}

public void setPropertyPredicates(Map<String, String> propertyPredicates) {
this.propertyPredicates = propertyPredicates;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Map;
import java.util.Optional;

@Configuration
@ConfigurationProperties(prefix = "ldes")
public class StreamsConfig {
private List<EventStreamConfig> streams;
private Map<String, EventStreamConfig> streams;

public List<EventStreamConfig> getStreams() {
public Map<String, EventStreamConfig> getStreams() {
return streams;
}

public Optional<EventStreamConfig> getStream(String collection) {
return Optional.ofNullable(streams.get(collection));
}

public List<String> getMemberTypes() {
return streams.stream().map(EventStreamConfig::getMemberType).toList();
return streams.values().stream().map(EventStreamConfig::getMemberType).toList();
}

public void setStreams(List<EventStreamConfig> streams) {
public void setStreams(Map<String, EventStreamConfig> streams) {
this.streams = streams;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import be.informatievlaanderen.vsds.demonstrator.member.application.config.EventStreamConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.config.StreamsConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.InvalidGeometryProvidedException;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.MissingCollectionException;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.ResourceNotFoundException;
import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.IngestedMemberDto;
import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.MemberDto;
Expand Down Expand Up @@ -43,9 +44,12 @@ public MemberServiceImpl(MemberRepository repository, StreamsConfig streams, Mes
@Override
public void ingestMember(IngestedMemberDto ingestedMemberDto) {
try {
Member member = ingestedMemberDto.getMember(streams.getStreams());
EventStreamConfig eventStreamConfig = streams.getStream(ingestedMemberDto.getCollection())
.orElseThrow(() -> new MissingCollectionException(ingestedMemberDto.getCollection()));
Member member = ingestedMemberDto.getMember(eventStreamConfig);
repository.saveMember(member);
messageController.send(new MemberDto(member.getMemberId(), geoJSONWriter.write(member.getGeometry()), member.getTimestamp()), ingestedMemberDto.getCollection());
MemberDto memberDto = new MemberDto(member.getMemberId(), geoJSONWriter.write(member.getGeometry()), member.getTimestamp(), member.getProperties());
messageController.send(memberDto, ingestedMemberDto.getCollection());

log.info("new member ingested");
} catch (FactoryException | TransformException e) {
Expand All @@ -58,14 +62,14 @@ public List<MemberDto> getMembersInRectangle(Geometry rectangleGeometry, String
var duration = Duration.parse(timePeriod).dividedBy(2);
return repository.getMembersByGeometry(rectangleGeometry, collectionName, timestamp.minus(duration), timestamp.plus(duration))
.stream()
.map(memberGeometry -> new MemberDto(memberGeometry.getMemberId(), geoJSONWriter.write(memberGeometry.getGeometry()), memberGeometry.getTimestamp()))
.map(memberGeometry -> new MemberDto(memberGeometry.getMemberId(), geoJSONWriter.write(memberGeometry.getGeometry()), memberGeometry.getTimestamp(), memberGeometry.getProperties()))
.toList();
}

@Override
public MemberDto getMemberById(String memberId) {
return repository.findByMemberId(memberId)
.map(memberGeometry -> new MemberDto(memberGeometry.getMemberId(), geoJSONWriter.write(memberGeometry.getGeometry()), memberGeometry.getTimestamp()))
.map(memberGeometry -> new MemberDto(memberGeometry.getMemberId(), geoJSONWriter.write(memberGeometry.getGeometry()), memberGeometry.getTimestamp(), memberGeometry.getProperties()))
.orElseThrow(() -> new ResourceNotFoundException("Member", memberId));
}

Expand All @@ -86,8 +90,8 @@ public LineChartDto getLineChartDtos() {

streams
.getStreams()
.keySet()
.stream()
.map(EventStreamConfig::getName)
.map(collection -> {
long numberOfMembers = getNumberOfMembersByCollection(collection);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
import org.apache.jena.rdf.model.Model;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Optional;

@Service
public class MemberValidatorImpl implements MemberValidator {

Expand All @@ -21,13 +18,11 @@ public MemberValidatorImpl(StreamsConfig streams) {

@Override
public void validate(Model member, String collectionName) {
Optional<EventStreamConfig> streamConfig = streams.getStreams().stream().filter(streams -> Objects.equals(streams.getName(), collectionName)).findFirst();
if(streamConfig.isEmpty()) {
throw new MissingCollectionException(collectionName);
} else if (!testMembertype(member, streamConfig.get().getMemberType())) {
throw new MembertypeException("todo", streamConfig.get().getMemberType());
EventStreamConfig streamConfig = streams.getStream(collectionName)
.orElseThrow(() -> new MissingCollectionException(collectionName));
if (!testMembertype(member, streamConfig.getMemberType())) {
throw new MembertypeException("todo", streamConfig.getMemberType());
}

}

private boolean testMembertype(Model member, String memberType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import be.informatievlaanderen.vsds.demonstrator.member.application.config.EventStreamConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.NoGeometryProvidedException;
import be.informatievlaanderen.vsds.demonstrator.member.domain.member.entities.Member;
import org.apache.jena.ext.com.google.common.collect.Iterables;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.geosparql.implementation.vocabulary.SRS_URI;
import org.apache.jena.rdf.model.*;
Expand All @@ -14,13 +13,16 @@

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
import static org.apache.jena.rdf.model.ResourceFactory.createResource;

public class IngestedMemberDto {
private static final Property RDF_SYNTAX_TYPE = createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
private final String collection;
private final Model model;

Expand All @@ -29,24 +31,29 @@ public IngestedMemberDto(String collection, Model model) {
this.model = model;
}

public String getCollection() {
return collection;
}

public Model getModel() {
return model;
}

public Member getMember(List<EventStreamConfig> streams) throws FactoryException, TransformException {
Geometry geometry = getMember();
String memberId = getMemberId(streams);
String timestampString = (String) getTimestampPath(streams);
public Member getMember(EventStreamConfig eventStreamConfig) throws FactoryException, TransformException {
Geometry geometry = getGeometry();
String memberId = getMemberId(eventStreamConfig);
String timestampString = getTimestampPath(eventStreamConfig, memberId);
Map<String, String> properties = getProperties(eventStreamConfig);
LocalDateTime timestamp;
if (timestampString.contains("Z") || timestampString.contains("+")) {
timestamp = ZonedDateTime.parse(timestampString).toLocalDateTime();
} else {
timestamp = LocalDateTime.parse(timestampString);
}
return new Member(memberId, collection, geometry, timestamp);
return new Member(memberId, collection, geometry, timestamp, properties);
}

private Geometry getMember() throws FactoryException, TransformException {
private Geometry getGeometry() throws FactoryException, TransformException {
List<RDFNode> wktNodes = model.listObjectsOfProperty(model.createProperty("http://www.opengis.net/ont/geosparql#asWKT")).toList();
if (wktNodes.isEmpty()) {
throw new NoGeometryProvidedException();
Expand All @@ -57,29 +64,29 @@ private Geometry getMember() throws FactoryException, TransformException {
}
}

private Statement getMemberProperty(List<EventStreamConfig> streams, Function<EventStreamConfig, Selector> createSelector) {
return Iterables.getOnlyElement(streams
.stream()
.filter(stream -> stream.getName().equals(collection))
.map(stream -> model.listStatements(createSelector.apply(stream)))
.map(StmtIterator::nextStatement)
.toList());
private Statement getMemberProperty(EventStreamConfig config, Function<EventStreamConfig, Selector> createSelector) {
return model.listStatements(createSelector.apply(config)).nextStatement();
}

private String getMemberId(List<EventStreamConfig> streams) {
return getMemberProperty(streams, stream -> new SelectorImpl(null, null, createResource(stream.getMemberType())))
private String getMemberId(EventStreamConfig streamConfig) {
return getMemberProperty(streamConfig, stream -> new SelectorImpl(null, RDF_SYNTAX_TYPE, createResource(stream.getMemberType())))
.getSubject()
.getURI();
}

private Object getTimestampPath(List<EventStreamConfig> streams) {
return getMemberProperty(streams, stream -> new SelectorImpl(null, createProperty(stream.getTimestampPath()), (Resource) null))
private String getTimestampPath(EventStreamConfig streamConfig, String memberId) {
return getMemberProperty(streamConfig, stream -> new SelectorImpl(createResource(memberId), createProperty(stream.getTimestampPath()), (Resource) null))
.getObject()
.asLiteral().getString();

}

public String getCollection() {
return collection;
private Map<String, String> getProperties(EventStreamConfig streamConfig) {
final Map<String, String> properties = new HashMap<>();
for (Map.Entry<String, String> propertyPredicateEntry : streamConfig.getPropertyPredicates().entrySet()) {
model.listStatements(null, createProperty(propertyPredicateEntry.getValue()), (Resource) null)
.nextOptional()
.ifPresent(statement -> properties.put(propertyPredicateEntry.getKey(), statement.getLiteral().getString()));
}
return properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import org.wololo.geojson.Geometry;

import java.time.LocalDateTime;
import java.util.Map;

public class MemberDto {
private final String memberId;
private final Geometry geojsonGeometry;
private final LocalDateTime timestamp;
private final Map<String, String> properties;

public MemberDto(String memberId, Geometry geojsonGeometry, LocalDateTime timestamp) {
public MemberDto(String memberId, Geometry geojsonGeometry, LocalDateTime timestamp, Map<String, String> properties) {
this.memberId = memberId;
this.geojsonGeometry = geojsonGeometry;
this.timestamp = timestamp;
this.properties = properties;
}

public String getMemberId() {
Expand All @@ -26,4 +29,8 @@ public Geometry getGeojsonGeometry() {
public LocalDateTime getTimestamp() {
return timestamp;
}

public Map<String, String> getProperties() {
return properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
@Component
public class MeetPuntRepository {

private final Map<String, Statement> meetpuntLocaties;
private final Map<String, List<Statement>> meetpuntLocaties;

public MeetPuntRepository() {
this.meetpuntLocaties = new HashMap<>();
Expand All @@ -42,13 +42,18 @@ private void initializeMeetpunten() {
for (Element e : doc.select("meetpunt")) {
String meetpuntId = e.attr("unieke_id");
String wkt = "POINT (" + e.select("lengtegraad_EPSG_4326").get(0).text().replace(",", ".") + " " + e.select("breedtegraad_EPSG_4326").get(0).text().replace(",", ".") + ")";
String fullName = e.select("volledige_naam").get(0).text();
var statements = List.of(
createStatement(createResource("http://custom/meetpunt"), createProperty("http://www.opengis.net/ont/geosparql#asWKT"), createTypedLiteral(wkt, TypeMapper.getInstance().getTypeByName("http://www.opengis.net/ont/geosparql#wktLiteral"))),
createStatement(createResource("http://custom/meetpunt"), createProperty("http://custom/meetpunt#VolledigeNaam"), createStringLiteral(fullName))
);

meetpuntLocaties.put(meetpuntId, createStatement(createResource("http://custom"), createProperty("http://www.opengis.net/ont/geosparql#asWKT"), createTypedLiteral(wkt, TypeMapper.getInstance().getTypeByName("http://www.opengis.net/ont/geosparql#wktLiteral"))));
meetpuntLocaties.put(meetpuntId, statements);
}
}


public List<Statement> get(String s) {
return List.of(meetpuntLocaties.get(s));
return meetpuntLocaties.get(s);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
import org.locationtech.jts.geom.Geometry;

import java.time.LocalDateTime;
import java.util.Map;

public class Member {
private final String memberId;
private final String collection;
private final Geometry geometry;
private final LocalDateTime timestamp;
private final Map<String, String> properties;

public Member(String memberId, String collection, Geometry geometry, LocalDateTime timestamp) {
public Member(String memberId, String collection, Geometry geometry, LocalDateTime timestamp, Map<String, String> properties) {
this.memberId = memberId;
this.collection = collection;
this.geometry = geometry;
this.timestamp = timestamp;
this.properties = properties;
}

public String getMemberId() {
Expand All @@ -34,6 +37,10 @@ public String getCollection() {
return collection;
}

public Map<String, String> getProperties() {
return properties;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Loading
Loading