use of de.fhpotsdam.unfolding.geo.Location in project constellation by constellation-app.
the class MapViewTileRenderer method handleMouseZoom.
/**
* Update the zoom level of the map based on the given set of markers.
*
* @param event the mouse event which caused the zoom
* @param markers the markers to zoom to
*/
private void handleMouseZoom(final Set<ConstellationAbstractMarker> markers) {
assert !SwingUtilities.isEventDispatchThread();
if (markers == null) {
return;
}
// the zoomAndPanToFit method is known to break for any of the following locations
final List<Location> breakingLocations = new ArrayList<>();
breakingLocations.add(new Location(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
breakingLocations.add(new Location(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY));
breakingLocations.add(new Location(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY));
breakingLocations.add(new Location(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
final List<Location> locations = markers.stream().map(marker -> marker.getLocation()).filter(location -> !breakingLocations.contains(location)).collect(Collectors.toList());
if (!locations.isEmpty()) {
map.zoomAndPanToFit(locations);
}
}
use of de.fhpotsdam.unfolding.geo.Location in project constellation by constellation-app.
the class MapViewTileRenderer method mousePressed.
@Override
public void mousePressed(final MouseEvent event) {
assert !SwingUtilities.isEventDispatchThread();
if (event.getButton() == PConstants.CENTER || event.getButton() == PConstants.LEFT) {
// zoom to box
boxOriginX = event.getX();
boxOriginY = event.getY();
} else if (event.getButton() == PConstants.RIGHT && event.getCount() == 2) {
dispatcher.register(map, ZoomMapEvent.TYPE_ZOOM, map.getId());
// Pan + Zoom (order is important)
final PanMapEvent panMapEvent = new PanMapEvent(this, map.getId());
final Location location = map.getLocation(mouseX, mouseY);
panMapEvent.setToLocation(location);
dispatcher.fireMapEvent(panMapEvent);
final ZoomMapEvent zoomMapEvent = new ZoomMapEvent(this, map.getId(), ZoomMapEvent.ZOOM_BY_LEVEL, 1);
zoomMapEvent.setTransformationCenterLocation(location);
dispatcher.fireMapEvent(zoomMapEvent);
dispatcher.unregister(map, ZoomMapEvent.TYPE_ZOOM, map.getId());
} else {
// Do nothing
}
overlays.forEach(overlay -> overlay.mousePressed(event));
}
use of de.fhpotsdam.unfolding.geo.Location in project constellation by constellation-app.
the class MapViewTopComponent method zoomLocationBasedOnGeoType.
private void zoomLocationBasedOnGeoType(final String geoType, final String location) throws AssertionError {
final ConstellationAbstractMarker marker;
switch(geoType) {
case GEO_TYPE_COORDINATE:
final String[] coordinate = location.split("[,\\s]+");
if (coordinate.length != 2 && coordinate.length != 3) {
NotifyDisplayer.display("Invalid coordinate syntax provided, should be comma or space separated", NotifyDescriptor.ERROR_MESSAGE);
return;
}
final float latitude;
final float longitude;
final float radius;
try {
latitude = Float.parseFloat(coordinate[0]);
longitude = Float.parseFloat(coordinate[1]);
if (coordinate.length == 3) {
radius = Float.parseFloat(coordinate[2]);
} else {
radius = 0;
}
} catch (final NumberFormatException ex) {
NotifyDisplayer.display("Invalid coordinate data provided, latitude and longitude should be numbers", NotifyDescriptor.ERROR_MESSAGE);
return;
}
if (latitude <= -90F || latitude >= 90F) {
NotifyDisplayer.display("Invalid coordinate data provided, latitude should be in the range [-90. 90]", NotifyDescriptor.ERROR_MESSAGE);
return;
}
if (longitude <= -180F || longitude >= 180F) {
NotifyDisplayer.display("Invalid coordinate data provided, longitude should be in the range [-180, 180]", NotifyDescriptor.ERROR_MESSAGE);
return;
}
if (radius < 0F) {
NotifyDisplayer.display("Invalid coordinate data provided, radius should be greater than or equal to 0", NotifyDescriptor.ERROR_MESSAGE);
return;
}
final Location coordinateLocation = new Location(latitude, longitude);
if (radius > 0) {
final float radiusDD = (float) Distance.Haversine.kilometersToDecimalDegrees(radius);
final Location coordinateDelta = new Location(coordinateLocation.x + radiusDD, coordinateLocation.y + radiusDD);
final List<Location> circleVertices = MarkerUtilities.generateCircle(coordinateLocation, coordinateDelta);
final ConstellationShapeFeature coordinateFeature = new ConstellationShapeFeature(ConstellationFeatureType.POLYGON);
circleVertices.forEach(vertex -> coordinateFeature.addLocation(vertex));
marker = renderer.addCustomMarker(coordinateFeature);
} else {
final ConstellationPointFeature coordinateFeature = new ConstellationPointFeature(coordinateLocation);
marker = renderer.addCustomMarker(coordinateFeature);
}
break;
case GEO_TYPE_GEOHASH:
final double[] geohashCoordinates = Geohash.decode(location, Geohash.Base.B16);
final ConstellationShapeFeature geohashFeature = new ConstellationShapeFeature(ConstellationFeatureType.POLYGON);
geohashFeature.addLocation(new Location(geohashCoordinates[0] - geohashCoordinates[2], geohashCoordinates[1] - geohashCoordinates[3]));
geohashFeature.addLocation(new Location(geohashCoordinates[0] + geohashCoordinates[2], geohashCoordinates[1] - geohashCoordinates[3]));
geohashFeature.addLocation(new Location(geohashCoordinates[0] + geohashCoordinates[2], geohashCoordinates[1] + geohashCoordinates[3]));
geohashFeature.addLocation(new Location(geohashCoordinates[0] - geohashCoordinates[2], geohashCoordinates[1] + geohashCoordinates[3]));
geohashFeature.addLocation(new Location(geohashCoordinates[0] - geohashCoordinates[2], geohashCoordinates[1] - geohashCoordinates[3]));
marker = renderer.addCustomMarker(geohashFeature);
break;
case GEO_TYPE_MGRS:
final double[] mgrsCoordinates = Mgrs.decode(location);
final Location mgrsLocation = new Location(mgrsCoordinates[0], mgrsCoordinates[1]);
final ConstellationPointFeature mgrsFeature = new ConstellationPointFeature(mgrsLocation);
marker = renderer.addCustomMarker(mgrsFeature);
break;
default:
marker = null;
break;
}
renderer.zoomToLocation(marker == null ? null : marker.getLocation());
}
use of de.fhpotsdam.unfolding.geo.Location 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 de.fhpotsdam.unfolding.geo.Location in project constellation by constellation-app.
the class DayNightLayer method update.
@Override
public PImage update() {
final int width = renderer.width - 5;
final int height = renderer.height - 5;
final PGraphics dayNightImage = renderer.createGraphics(width, height, PConstants.JAVA2D);
dayNightImage.beginDraw();
final long currentTime = System.currentTimeMillis();
final Location sunLocation = getSunPosition(currentTime);
final ScreenPosition sunPosition = map.getScreenPosition(sunLocation);
final Location leftShadowLocation = getShadowPosition(sunLocation, ShadowOrientation.LEFT);
final Location rightShadowLocation = getShadowPosition(sunLocation, ShadowOrientation.RIGHT);
// draw the sun
dayNightImage.stroke(STROKE_COLOR);
dayNightImage.fill(SUN_COLOR);
dayNightImage.ellipse(sunPosition.x, sunPosition.y, 10, 10);
// calculate shadow radius
final float twighlightCivilRadiusMeters = getShadowRadiusFromAngle(0.566666);
final float twighlightNauticalRadiusMeters = getShadowRadiusFromAngle(6.0);
final float twighlightAstronomicalRadiusMeters = getShadowRadiusFromAngle(12.0);
final float nightRadiusMeters = getShadowRadiusFromAngle(18.0);
// left twilight civil
final Location leftTwighlightCivilRadiusLocation = new Location(leftShadowLocation.getLat() - Distance.Haversine.kilometersToDecimalDegrees(twighlightCivilRadiusMeters / 1000), leftShadowLocation.getLon() - Distance.Haversine.kilometersToDecimalDegrees(twighlightCivilRadiusMeters / 1000));
final List<Location> leftTwighlightCivilLocations = MarkerUtilities.generateCircle(leftShadowLocation, leftTwighlightCivilRadiusLocation);
final List<MapPosition> leftTwighlightCivilPositions = leftTwighlightCivilLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(TWIGHLIGHT_CIVIL_COLOR);
dayNightImage.beginShape();
leftTwighlightCivilPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// left twilight nautical
final Location leftTwighlightNauticalRadiusLocation = new Location(leftShadowLocation.getLat() - Distance.Haversine.kilometersToDecimalDegrees(twighlightNauticalRadiusMeters / 1000), leftShadowLocation.getLon() - Distance.Haversine.kilometersToDecimalDegrees(twighlightNauticalRadiusMeters / 1000));
final List<Location> leftTwighlightNauticalLocations = MarkerUtilities.generateCircle(leftShadowLocation, leftTwighlightNauticalRadiusLocation);
final List<MapPosition> leftTwighlightNauticalPositions = leftTwighlightNauticalLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(TWIGHLIGHT_NAUTICAL_COLOR);
dayNightImage.beginShape();
leftTwighlightNauticalPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// left twilight astronomical
final Location leftTwighlightAstronomicalRadiusLocation = new Location(leftShadowLocation.getLat() + Distance.Haversine.kilometersToDecimalDegrees(twighlightAstronomicalRadiusMeters / 1000), leftShadowLocation.getLon() + Distance.Haversine.kilometersToDecimalDegrees(twighlightAstronomicalRadiusMeters / 1000));
final List<Location> leftTwighlightAstronomicalLocations = MarkerUtilities.generateCircle(leftShadowLocation, leftTwighlightAstronomicalRadiusLocation);
final List<MapPosition> leftTwighlightAstronomicalPositions = leftTwighlightAstronomicalLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(TWIGHLIGHT_ASTRONOMICAL_COLOR);
dayNightImage.beginShape();
leftTwighlightAstronomicalPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// left night
final Location leftNightRadiusLocation = new Location(leftShadowLocation.getLat() + Distance.Haversine.kilometersToDecimalDegrees(nightRadiusMeters / 1000), leftShadowLocation.getLon() + Distance.Haversine.kilometersToDecimalDegrees(nightRadiusMeters / 1000));
final List<Location> leftNightLocations = MarkerUtilities.generateCircle(leftShadowLocation, leftNightRadiusLocation);
final List<MapPosition> leftNightPositions = leftNightLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(NIGHT_COLOR);
dayNightImage.beginShape();
leftNightPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// right twilight civil
final Location rightTwighlightCivilRadiusLocation = new Location(rightShadowLocation.getLat() - Distance.Haversine.kilometersToDecimalDegrees(twighlightCivilRadiusMeters / 1000), rightShadowLocation.getLon() - Distance.Haversine.kilometersToDecimalDegrees(twighlightCivilRadiusMeters / 1000));
final List<Location> rightTwighlightCivilLocations = MarkerUtilities.generateCircle(rightShadowLocation, rightTwighlightCivilRadiusLocation);
final List<MapPosition> rightTwighlightCivilPositions = rightTwighlightCivilLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(TWIGHLIGHT_CIVIL_COLOR);
dayNightImage.beginShape();
rightTwighlightCivilPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// right twilight nautical
final Location rightTwighlightNauticalRadiusLocation = new Location(rightShadowLocation.getLat() - Distance.Haversine.kilometersToDecimalDegrees(twighlightNauticalRadiusMeters / 1000), rightShadowLocation.getLon() - Distance.Haversine.kilometersToDecimalDegrees(twighlightNauticalRadiusMeters / 1000));
final List<Location> rightTwighlightNauticalLocations = MarkerUtilities.generateCircle(rightShadowLocation, rightTwighlightNauticalRadiusLocation);
final List<MapPosition> rightTwighlightNauticalPositions = rightTwighlightNauticalLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(TWIGHLIGHT_NAUTICAL_COLOR);
dayNightImage.beginShape();
rightTwighlightNauticalPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// right twilight astronomical
final Location rightTwighlightAstronomicalRadiusLocation = new Location(rightShadowLocation.getLat() + Distance.Haversine.kilometersToDecimalDegrees(twighlightAstronomicalRadiusMeters / 1000), rightShadowLocation.getLon() + Distance.Haversine.kilometersToDecimalDegrees(twighlightAstronomicalRadiusMeters / 1000));
final List<Location> rightTwighlightAstronomicalLocations = MarkerUtilities.generateCircle(rightShadowLocation, rightTwighlightAstronomicalRadiusLocation);
final List<MapPosition> rightTwighlightAstronomicalPositions = rightTwighlightAstronomicalLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(TWIGHLIGHT_ASTRONOMICAL_COLOR);
dayNightImage.beginShape();
rightTwighlightAstronomicalPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
// right night
final Location rightNightRadiusLocation = new Location(rightShadowLocation.getLat() + Distance.Haversine.kilometersToDecimalDegrees(nightRadiusMeters / 1000), rightShadowLocation.getLon() + Distance.Haversine.kilometersToDecimalDegrees(nightRadiusMeters / 1000));
final List<Location> rightNightLocations = MarkerUtilities.generateCircle(rightShadowLocation, rightNightRadiusLocation);
final List<MapPosition> rightNightPositions = rightNightLocations.stream().map(location -> new MapPosition(map.mapDisplay.getObjectFromLocation(location))).collect(Collectors.toList());
dayNightImage.noStroke();
dayNightImage.fill(NIGHT_COLOR);
dayNightImage.beginShape();
rightNightPositions.forEach(position -> dayNightImage.vertex(position.x, position.y));
dayNightImage.endShape(PConstants.CLOSE);
dayNightImage.endDraw();
return dayNightImage;
}
Aggregations