use of au.gov.asd.tac.constellation.views.mapview.utilities.GraphElement in project constellation by constellation-app.
the class AbstractPathsLayer method update.
@Override
public PImage update() {
if (graph == null) {
return null;
}
final Set<Marker> onScreenMarkers;
final List<Tuple<GraphElement, GraphElement>> paths = new ArrayList<>();
try (final ReadableGraph readableGraph = graph.getReadableGraph()) {
// update on screen markers, collecting the ids of the vertices involved in valid paths along the way
final ScreenPosition topLeft = map.getScreenPosition(map.getTopLeftBorder());
final ScreenPosition bottomRight = map.getScreenPosition(map.getBottomRightBorder());
onScreenMarkers = renderer.getMarkerCache().keys().stream().filter(marker -> {
final ScreenPosition markerPosition = map.getScreenPosition(marker.getLocation());
final boolean onScreen = markerPosition != null && markerPosition.x > topLeft.x && markerPosition.y > topLeft.y && markerPosition.x < bottomRight.x && markerPosition.y < bottomRight.y;
if (drawPathsToOffscreenMarkers() || onScreen) {
final Set<GraphElement> elementsAtMarker = renderer.getMarkerCache().get(marker);
if (elementsAtMarker != null) {
elementsAtMarker.forEach(element -> paths.addAll(getPathsForElement(readableGraph, element)));
}
}
return onScreen;
}).collect(Collectors.toSet());
onScreenMarkerCount = onScreenMarkers.size();
}
if (onScreenMarkers.isEmpty()) {
return null;
}
final Map<GraphElement, Marker> elementToMarkerCache = new HashMap<>();
renderer.getMarkerCache().keys().forEach(marker -> renderer.getMarkerCache().get(marker).forEach(element -> elementToMarkerCache.put(element, marker)));
// set up a color palette
final int[] palette = Arrays.asList(ConstellationColor.createLinearPalette(N_COLORS, SRC_COLOR, DST_COLOR)).stream().mapToInt(c -> MarkerUtilities.color(c)).toArray();
final int width = renderer.width - 5;
final int height = renderer.height - 5;
final PGraphics pathsImage = renderer.createGraphics(width, height, PConstants.JAVA2D);
pathsImage.beginDraw();
// deduplicate paths, storing duplicate counts
int maxWeight = 1;
final Map<Tuple<GraphElement, GraphElement>, Integer> dedupedPaths = new HashMap<>();
for (final Tuple<GraphElement, GraphElement> path : paths) {
if (dedupedPaths.containsKey(path)) {
final int weight = dedupedPaths.get(path) + 1;
if (weight > maxWeight) {
maxWeight = weight;
}
dedupedPaths.put(path, weight);
} else {
dedupedPaths.put(path, 1);
}
}
// draw weighted paths
final int maxWeightFinal = maxWeight;
dedupedPaths.forEach((path, weight) -> {
final Marker sourceMarker = elementToMarkerCache.get(path.getFirst());
final Marker destinationMarker = elementToMarkerCache.get(path.getSecond());
final boolean validPath = (drawPathsToOffscreenMarkers() && (onScreenMarkers.contains(sourceMarker) || onScreenMarkers.contains(destinationMarker))) || (onScreenMarkers.contains(sourceMarker) && onScreenMarkers.contains(destinationMarker));
if (validPath) {
final Location sourceLocation = sourceMarker != null ? sourceMarker.getLocation() : null;
final Location destinationLocation = destinationMarker != null ? destinationMarker.getLocation() : null;
if (sourceLocation != null && destinationLocation != null) {
final ScreenPosition sourcePosition = map.getScreenPosition(sourceLocation);
final ScreenPosition destinationPosition = map.getScreenPosition(destinationLocation);
final float lineWidth = Math.max(maxWeightFinal > MAX_LINE_WIDTH ? (MAX_LINE_WIDTH * (weight / (float) maxWeightFinal)) + 1 : weight + 1, 2);
pathsImage.strokeWeight(lineWidth);
pathsImage.pushMatrix();
pathsImage.translate(sourcePosition.x, sourcePosition.y);
pathsImage.rotate(PApplet.atan2((destinationPosition.y - sourcePosition.y), (destinationPosition.x - sourcePosition.x)));
final float translatedDestiniationPosition = (float) Math.hypot(destinationPosition.x - sourcePosition.x, destinationPosition.y - sourcePosition.y);
drawColoredLine(pathsImage, translatedDestiniationPosition, lineWidth, palette);
pathsImage.popMatrix();
}
}
});
pathsImage.endDraw();
return pathsImage;
}
use of au.gov.asd.tac.constellation.views.mapview.utilities.GraphElement in project constellation by constellation-app.
the class EntityPathsLayer method getPathsForElement.
@Override
public List<Tuple<GraphElement, GraphElement>> getPathsForElement(final ReadableGraph graph, final GraphElement element) {
final List<Tuple<GraphElement, GraphElement>> paths = new ArrayList<>();
if (element.getType() == GraphElementType.VERTEX) {
final int vertexTypeAttributeId = AnalyticConcept.VertexAttribute.TYPE.get(graph);
final int transactionDateTimeAttributeId = TemporalConcept.TransactionAttribute.DATETIME.get(graph);
final SchemaVertexType vertexType = graph.getObjectValue(vertexTypeAttributeId, element.getId());
if (vertexType != null && vertexType.isSubTypeOf(AnalyticConcept.VertexType.LOCATION)) {
final int neighbourCount = graph.getVertexNeighbourCount(element.getId());
for (int neighbourPosition = 0; neighbourPosition < neighbourCount; neighbourPosition++) {
final int neighbourId = graph.getVertexNeighbour(element.getId(), neighbourPosition);
final SchemaVertexType neighbourType = graph.getObjectValue(vertexTypeAttributeId, neighbourId);
if (neighbourType != null && !neighbourType.isSubTypeOf(AnalyticConcept.VertexType.LOCATION)) {
final Set<Long> locationDateTimes = new HashSet<>();
final int neighbourLinkId = graph.getLink(element.getId(), neighbourId);
final int neighbourLinkTransactionCount = graph.getLinkTransactionCount(neighbourLinkId);
for (int neighbourLinkTransactionPosition = 0; neighbourLinkTransactionPosition < neighbourLinkTransactionCount; neighbourLinkTransactionPosition++) {
final int neighbourLinkTransactionId = graph.getLinkTransaction(neighbourLinkId, neighbourLinkTransactionPosition);
final long neighbourLinkTransactionDateTime = graph.getLongValue(transactionDateTimeAttributeId, neighbourLinkTransactionId);
locationDateTimes.add(neighbourLinkTransactionDateTime);
}
final List<Integer> validNeighbourNeighbours = new ArrayList<>();
final int neighbourNeighbourCount = graph.getVertexNeighbourCount(neighbourId);
for (int neighbourNeighbourPosition = 0; neighbourNeighbourPosition < neighbourNeighbourCount; neighbourNeighbourPosition++) {
final int neighbourNeighbourId = graph.getVertexNeighbour(neighbourId, neighbourNeighbourPosition);
final SchemaVertexType neighbourNeighbourType = graph.getObjectValue(vertexTypeAttributeId, neighbourNeighbourId);
if (neighbourNeighbourType != null && neighbourNeighbourType.isSubTypeOf(AnalyticConcept.VertexType.LOCATION)) {
validNeighbourNeighbours.add(neighbourNeighbourId);
}
}
locationDateTimes.forEach(locationDateTime -> {
int pathNeighbourNeighbour = GraphConstants.NOT_FOUND;
long closestTimeDifference = Long.MAX_VALUE;
for (final int neighbourNeighbourId : validNeighbourNeighbours) {
final int neighbourNeighbourLinkId = graph.getLink(neighbourId, neighbourNeighbourId);
final int neighbourNeighbourLinkTransactionCount = graph.getLinkTransactionCount(neighbourNeighbourLinkId);
for (int neighbourNeighbourLinkTransactionPosition = 0; neighbourNeighbourLinkTransactionPosition < neighbourNeighbourLinkTransactionCount; neighbourNeighbourLinkTransactionPosition++) {
final int neighbourNeighbourLinkTransactionId = graph.getLinkTransaction(neighbourNeighbourLinkId, neighbourNeighbourLinkTransactionPosition);
final long neighbourNeighbourLinkTransactionDateTime = graph.getLongValue(transactionDateTimeAttributeId, neighbourNeighbourLinkTransactionId);
final long timeDifference = neighbourNeighbourLinkTransactionDateTime - locationDateTime;
if (timeDifference > 0 && timeDifference < closestTimeDifference) {
closestTimeDifference = timeDifference;
pathNeighbourNeighbour = neighbourNeighbourId;
}
}
}
if (pathNeighbourNeighbour != GraphConstants.NOT_FOUND) {
paths.add(Tuple.create(element, new GraphElement(pathNeighbourNeighbour, GraphElementType.VERTEX)));
}
});
}
}
}
}
return paths;
}
use of au.gov.asd.tac.constellation.views.mapview.utilities.GraphElement in project constellation by constellation-app.
the class LocationPathsLayer method getPathsForElement.
@Override
public List<Tuple<GraphElement, GraphElement>> getPathsForElement(final ReadableGraph graph, final GraphElement element) {
final List<Tuple<GraphElement, GraphElement>> paths = new ArrayList<>();
if (element.getType() == GraphElementType.VERTEX) {
final int vertexTypeAttributeId = AnalyticConcept.VertexAttribute.TYPE.get(graph);
final SchemaVertexType vertexType = graph.getObjectValue(vertexTypeAttributeId, element.getId());
if (vertexType != null && vertexType.isSubTypeOf(AnalyticConcept.VertexType.LOCATION)) {
final int neighbourCount = graph.getVertexNeighbourCount(element.getId());
for (int neighbourPosition = 0; neighbourPosition < neighbourCount; neighbourPosition++) {
final int neighbourId = graph.getVertexNeighbour(element.getId(), neighbourPosition);
final SchemaVertexType neighbourType = graph.getObjectValue(vertexTypeAttributeId, neighbourId);
if (neighbourType != null && neighbourType.isSubTypeOf(AnalyticConcept.VertexType.LOCATION)) {
final int neighbourLinkId = graph.getLink(element.getId(), neighbourId);
final int outgoingDirection = element.getId() < neighbourId ? GraphConstants.UPHILL : GraphConstants.DOWNHILL;
final int linkOutgoingTransactionCount = graph.getLinkTransactionCount(neighbourLinkId, outgoingDirection);
for (int i = 0; i < linkOutgoingTransactionCount; i++) {
paths.add(Tuple.create(element, new GraphElement(neighbourId, GraphElementType.VERTEX)));
}
}
}
}
}
return paths;
}
use of au.gov.asd.tac.constellation.views.mapview.utilities.GraphElement in project constellation by constellation-app.
the class PointMarkerErrorLayer method update.
@Override
public PImage update() {
if (map.getMarkers().isEmpty()) {
return null;
}
markerCount = map.getMarkers().size();
final int width = renderer.width - 5;
final int height = renderer.height - 5;
// get on screen markers
final ScreenPosition topLeft = map.getScreenPosition(map.getTopLeftBorder());
final ScreenPosition bottomRight = map.getScreenPosition(map.getBottomRightBorder());
final List<ConstellationAbstractMarker> markers = renderer.getMarkerCache().getAllMarkers().stream().filter(marker -> {
final ScreenPosition markerPosition = map.getScreenPosition(marker.getLocation());
return markerPosition != null && markerPosition.x > topLeft.x && markerPosition.y > topLeft.y && markerPosition.x < bottomRight.x && markerPosition.y < bottomRight.y;
}).collect(Collectors.toList());
// create error region data from markers
final PGraphics errorRegionImage = renderer.createGraphics(width, height, PConstants.JAVA2D);
errorRegionImage.beginDraw();
errorRegionImage.stroke(STROKE_COLOR);
errorRegionImage.fill(ERROR_REGION_COLOR);
if (graph != null) {
final ReadableGraph readableGraph = graph.getReadableGraph();
try {
final int vertexPrecisionAttributeId = SpatialConcept.VertexAttribute.PRECISION.get(readableGraph);
final int transactionPrecisionAttributeId = SpatialConcept.TransactionAttribute.PRECISION.get(readableGraph);
for (final ConstellationAbstractMarker marker : markers) {
if (!(marker instanceof ConstellationPointMarker)) {
continue;
}
float minimumPrecision = DEFAULT_PRECISION;
final Set<GraphElement> elements = renderer.getMarkerCache().get(marker);
for (final GraphElement element : elements) {
final float elementPrecision;
switch(element.getType()) {
case VERTEX:
if (vertexPrecisionAttributeId != Graph.NOT_FOUND) {
elementPrecision = readableGraph.getFloatValue(vertexPrecisionAttributeId, element.getId());
minimumPrecision = Math.max(elementPrecision, minimumPrecision);
} else {
elementPrecision = DEFAULT_PRECISION;
minimumPrecision = DEFAULT_PRECISION;
}
break;
case TRANSACTION:
elementPrecision = transactionPrecisionAttributeId != Graph.NOT_FOUND ? readableGraph.getFloatValue(transactionPrecisionAttributeId, element.getId()) : DEFAULT_PRECISION;
break;
default:
elementPrecision = DEFAULT_PRECISION;
break;
}
minimumPrecision = Math.max(elementPrecision, minimumPrecision);
}
// don't bother drawing if there isn't a precision
if (minimumPrecision == 0) {
continue;
}
final Location errorRegionRadiusLocation = new Location(marker.getLocation().getLat() - Haversine.kilometersToDecimalDegrees(minimumPrecision), marker.getLocation().getLon() - Haversine.kilometersToDecimalDegrees(minimumPrecision));
final List<Location> errorRegionLocations = MarkerUtilities.generateCircle(marker.getLocation(), errorRegionRadiusLocation);
final List<MapPosition> errorRegionPositions = errorRegionLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
errorRegionImage.beginShape();
errorRegionPositions.forEach(position -> errorRegionImage.vertex(position.x, position.y));
errorRegionImage.endShape(PConstants.CLOSE);
}
} finally {
readableGraph.release();
}
}
errorRegionImage.endDraw();
return errorRegionImage;
}
use of au.gov.asd.tac.constellation.views.mapview.utilities.GraphElement in project constellation by constellation-app.
the class PopularityHeatmapLayer method getWeight.
@Override
public float getWeight(final ConstellationAbstractMarker marker) {
int popularityCount = 0;
if (graph != null) {
final ReadableGraph readableGraph = graph.getReadableGraph();
try {
final Set<Integer> seenLinks = new HashSet<>();
for (final GraphElement element : renderer.getMarkerCache().get(marker)) {
switch(element.getType()) {
case VERTEX:
popularityCount += readableGraph.getVertexNeighbourCount(element.getId());
break;
case TRANSACTION:
final int linkId = readableGraph.getTransactionLink(element.getId());
if (!seenLinks.contains(linkId)) {
seenLinks.add(linkId);
popularityCount += 1;
}
break;
default:
break;
}
}
} finally {
readableGraph.release();
}
}
return popularityCount;
}
Aggregations