Closed bchen0867 closed 4 years ago
isInside(float, float, List<? extends PVector>)
is protected and should be used internally. Only isInside(UnfoldingMap, float, float)
and the isInsideByLocation
methods are public.
You could implement the isInside(float, float, List<? extends PVector>)
in your RouteMarker.
Lastly, alas, Unfolding does not provide a function to calculate distance from a point to a line.
Thank you for your help! I got it working as I wanted.
Here is how I fixed my code in case someone else wants to implement the same feature.
Firstly, I've implemented the isInside(float, float, List<? extends PVector>)
to be the result of a boolean function checkForClick(int mouseX, int mouseY, List<PVector> vectors)
in my RouteMarker class.
public class RouteMarker extends SimpleLinesMarker
{
// constructor and other functions not shown here
public boolean checkForClick(int mouseX, int mouseY, List<PVector> vectors) {
return this.isInside(mouseX, mouseY, vectors);
}
}
Then, I fixed the get vector data section using getLocations()
function before getScreenPosition()
. In my old code, I used getScreenPosition()
directly on the RouteMarker
(which extends SimpleLinesMarker, and can't resolve to one location to return its screen position, thus returning to 0 ).
/** select the first route marker is clicked by the mouse*/
private void checkRouteForClick(List<Marker> markers)
{
for (Marker m: markers)
{
RouteMarker marker = (RouteMarker) m;
float w = marker.getStrokeWeight()*20; // increase the weight for test
List<ScreenPosition> posList = marker.getLocations().stream().map(b -> map.getScreenPosition(b)).collect(Collectors.toList());
float x1 = min(posList.get(0).x, posList.get(1).x);
float y1 = min(posList.get(0).y, posList.get(1).y);
float x2 = max(posList.get(0).x, posList.get(1).x);
float y2 = max(posList.get(0).y, posList.get(1).y);
List<PVector> vectors = new ArrayList<>();
vectors.add(new PVector (x1 - w, y1 - w));
vectors.add(new PVector (x1 - w, y1 + w));
vectors.add(new PVector (x2 + w, y2 + w));
vectors.add(new PVector (x2 + w, y2 - w));
System.out.println(vectors);
pushStyle();
stroke(255);
if (marker.checkForClick(mouseX, mouseY, vectors)) { // need to change the isInside method to the vector version
lastClicked = marker;
marker.setClicked(true);
System.out.println("Route Marker clicked");
System.out.println(marker.getProperties()); // test for clicking the route
return;
}
}
}
@Override
public void mouseClicked()
{
// reset lastClicked to make sure only one is set Clicked per time
if (lastClicked != null) {
lastClicked.setClicked(false);
lastClicked = null;
}
checkRouteForClick(showRoutes());
}
Good to hear and thanks for sharing your code!
(NB for others: This seems to check for a bounding box around the line, resulting in an angle dependent click area.)
I am trying to implement a feature to allow a user to click a SimpleLinesMarker to select and highlight it. I used the isInside method of the SimpleLinesMarker Class.
Below is the related information in the JavaDoc of UnfoldingMaps:
And here is how I tried to implement it in my code: (RouteMarker class is a subclass of SimpleLinesMarker.)
This code gives this error: "The method isInside(float, float, List<? extends PVector>) from the type AbstractShapeMarker is not visible."
I am not sure if I'm on the right path to use this method to add the wanted feature (let the user click any part of the line to select the SimpleLinesMarker), and I'm also not sure how to implement it correctly. Any help would be very much appreciated! Vielen Dank!
I've also tried to use getFirstHitMarker method of Map, but it only catches AbstractMarker.
Other Info: Java SE 14.0.1 Eclipse IDE for Java Developers, Version: 2020-06 (4.16.0)