Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package pl.niziol.gwt.lib;
- import java.util.ArrayList;
- import java.util.List;
- import com.google.gwt.core.client.JsArray;
- import com.google.gwt.dom.client.NativeEvent;
- import com.google.gwt.event.dom.client.ClickEvent;
- import com.google.gwt.event.dom.client.ClickHandler;
- import com.google.gwt.event.dom.client.MouseUpEvent;
- import com.google.gwt.event.dom.client.MouseUpHandler;
- import com.google.gwt.event.shared.HandlerRegistration;
- import com.google.gwt.maps.client.MapWidget;
- import com.google.gwt.maps.client.base.LatLng;
- import com.google.gwt.maps.client.base.Point;
- import com.google.gwt.maps.client.overlays.MapCanvasProjection;
- import com.google.gwt.maps.client.overlays.OverlayView;
- import com.google.gwt.maps.client.overlays.overlayhandlers.OverlayViewMethods;
- import com.google.gwt.maps.client.overlays.overlayhandlers.OverlayViewOnAddHandler;
- import com.google.gwt.maps.client.overlays.overlayhandlers.OverlayViewOnDrawHandler;
- import com.google.gwt.maps.client.overlays.overlayhandlers.OverlayViewOnRemoveHandler;
- import com.google.gwt.maps.client.services.DirectionsLeg;
- import com.google.gwt.maps.client.services.DirectionsRenderer;
- import com.google.gwt.maps.client.services.DirectionsRequest;
- import com.google.gwt.maps.client.services.DirectionsResult;
- import com.google.gwt.maps.client.services.DirectionsResultHandler;
- import com.google.gwt.maps.client.services.DirectionsRoute;
- import com.google.gwt.maps.client.services.DirectionsService;
- import com.google.gwt.maps.client.services.DirectionsStatus;
- import com.google.gwt.maps.client.services.DirectionsWaypoint;
- import com.google.gwt.user.client.Event;
- import com.google.gwt.user.client.Window;
- import com.google.gwt.user.client.ui.Button;
- import com.google.gwt.user.client.ui.PopupPanel;
- import com.google.gwt.user.client.ui.Widget;
- /**
- * Allows removing waypoints plotted by user on DirectionsRenderer.
- * To remove a waypoint: right-click on it and select "Delete this waypoint" from a pop-up menu.
- * After using call dispose() method.
- * @author Bartlomiej Wrega, [email protected]
- *
- */
- public class WaipointRemover {
- static public final double WAYPOINT_ICON_RADIUS = 5.5d;//size of waypoint icon on the map
- private final DirectionsRenderer directionsRenderer;
- private DirectionsRequest originalRequest;
- private MapCanvasProjection projection;
- private MapWidget mapWidget;
- /**
- *
- * @param mapWidget
- * @param directionsRenderer
- * @param originalRequest used to get request options for next queries
- */
- public WaipointRemover(MapWidget mapWidget,
- DirectionsRenderer directionsRenderer,
- DirectionsRequest originalRequest) {
- this.directionsRenderer = directionsRenderer;
- this.mapWidget = mapWidget;
- setOriginalRequest(originalRequest);
- initProjection();
- initClicking();
- }
- /**
- * Cleans up.
- */
- public void dispose(){
- if (mouseUpHandler!=null){
- mouseUpHandler.removeHandler();
- mouseUpHandler = null;
- }
- }
- private HandlerRegistration mouseUpHandler = null;
- private void initClicking() {
- Widget widgetToGetClicked = mapWidget;// directionsRenderer.getMap() doesn't work for some reason
- //mouse click event doesn't work for right mouse button (tested on IE9),
- //so I used MouseUpEvent instead
- mouseUpHandler = widgetToGetClicked.addHandler(new MouseUpHandler() {
- public void onMouseUp(MouseUpEvent event) {
- if (event.getNativeButton() != NativeEvent.BUTTON_RIGHT) {
- return;
- }
- int x = event.getX();
- int y = event.getY();
- int clickedWaypoint = getClickedWaypointIndex(x, y);
- if (clickedWaypoint >= 0) {
- PopupPanel popupPanel = new PopupPanel(true);
- popupPanel.setWidget(new RemoveWaypointButton(
- clickedWaypoint,popupPanel));
- popupPanel.setAnimationEnabled(true);
- popupPanel.setPopupPosition(event.getClientX(),
- event.getClientY());
- popupPanel.show();
- }
- }
- }, MouseUpEvent.getType());
- widgetToGetClicked.sinkEvents(Event.ONMOUSEUP);
- }
- /**
- * Uses only non-stopover waypoints (mark as circles on the path).
- *
- * @param x,y coordinates relative to left-top corner of map area
- * @return -1 if no waypoint was clicked
- */
- private int getClickedWaypointIndex(double x, double y) {
- List<LatLng> waypoints = getAllViaWaypoints();
- double minimalDistanceSquare = WAYPOINT_ICON_RADIUS
- * WAYPOINT_ICON_RADIUS;// square to avoid sqrt
- int minimalIndex = -1;// index of the closest waypoint
- for (int i = 0; i < waypoints.size(); i++) {
- LatLng next = waypoints.get(i);
- Point waypointPoint = projection.fromLatLngToContainerPixel(next);
- double distanceSquare = Math.pow(x - waypointPoint.getX(), 2.0d)
- + Math.pow(y - waypointPoint.getY(), 2.0d);
- if (distanceSquare <= minimalDistanceSquare) {
- minimalDistanceSquare = distanceSquare;
- minimalIndex = i;
- }
- }
- return minimalIndex;
- }
- /**
- * @return all the not-stopover waypoints from current result
- */
- private List<LatLng> getAllViaWaypoints() {
- List<LatLng> ret = new ArrayList<LatLng>();
- DirectionsResult currentResult = directionsRenderer.getDirections();
- DirectionsRoute route = currentResult.getRoutes().get(
- directionsRenderer.getRouteIndex());
- for (int l = 0; l < route.getLegs().length(); l++) {
- DirectionsLeg leg = route.getLegs().get(l);
- for (int w = 0; w < leg.getVia_Waypoints().length(); w++) {
- LatLng viaWaypoint = leg.getVia_Waypoints().get(w);
- ret.add(viaWaypoint);
- }
- }
- return ret;
- }
- private void deleteNthWaypoint(int waypointIndex) {
- DirectionsResult currentResult = directionsRenderer.getDirections();
- DirectionsRequest newRequest = cloneOriginalRequest();
- DirectionsRoute route = currentResult.getRoutes().get(
- directionsRenderer.getRouteIndex());
- newRequest.setOrigin(route.getLegs().get(0).getStart_Location());
- newRequest.setDestination(route.getLegs()
- .get(route.getLegs().length() - 1 // last leg
- ).getEnd_Location());
- JsArray<DirectionsWaypoint> waypoints = JsArray.createArray().cast();
- int waypointCounter = 0; // counts not-stopover waypoints
- //copies all waypoints to newRequest, except for the one that needs to be deleted
- for (int l = 0; l < route.getLegs().length(); l++) {
- DirectionsLeg leg = route.getLegs().get(l);
- if (l != 0) {// for all but first leg add start location as stopover
- // waypoint
- DirectionsWaypoint waypoint = DirectionsWaypoint.newInstance();
- waypoint.setLocation(leg.getStart_Location());
- waypoint.setStopOver(true);
- waypoints.push(waypoint);
- }
- for (int w = 0; w < leg.getVia_Waypoints().length(); w++) {
- if (waypointIndex != (waypointCounter++)) {
- LatLng viaWaypoint = leg.getVia_Waypoints().get(w);
- DirectionsWaypoint waypoint = DirectionsWaypoint
- .newInstance();
- waypoint.setLocation(viaWaypoint);
- waypoint.setStopOver(false);
- waypoints.push(waypoint);
- }
- }
- }
- newRequest.setWaypoints(waypoints);
- directionsService.route(newRequest, new DirectionsResultHandler() {
- public void onCallback(DirectionsResult result,
- DirectionsStatus status) {
- if (status != DirectionsStatus.OK) {
- Window.alert("Error routing track: " + status);
- return;
- }
- // status is OK
- directionsRenderer.setDirections(result);
- }
- });
- }
- private DirectionsService directionsService = DirectionsService
- .newInstance();
- private DirectionsRequest cloneOriginalRequest() {
- DirectionsRequest ret = cloneRequest(originalRequest);
- ret.setOptimizeWaypoints(false);// we always want to keep the order
- return ret;
- }
- private native DirectionsRequest cloneRequest(DirectionsRequest originalRequest)/*-{
- return JSON.parse(JSON.stringify(originalRequest));
- }-*/;
- private void initProjection() {
- //a MapCanvasProjection is needed in this case
- //and this is a (quite sophisticated) way to retrieve it
- //not tested if this instance will function properly after i.e. resizing the map
- @SuppressWarnings("unused")
- OverlayView oView = OverlayView.newInstance(
- directionsRenderer.getMap(), new OverlayViewOnDrawHandler() {
- public void onDraw(OverlayViewMethods methods) {
- projection = methods.getProjection();
- }
- }, new OverlayViewOnAddHandler() {
- public void onAdd(OverlayViewMethods methods) {
- }
- }, new OverlayViewOnRemoveHandler() {
- public void onRemove(OverlayViewMethods methods) {
- }
- });
- }
- public DirectionsRequest getOriginalRequest() {
- return originalRequest;
- }
- public void setOriginalRequest(DirectionsRequest originalRequest) {
- this.originalRequest = cloneRequest(originalRequest);
- }
- private class RemoveWaypointButton extends Button {
- public RemoveWaypointButton(final int waypointIndex, final PopupPanel popupToHide) {
- super("Delete this waypoint", new ClickHandler() {
- public void onClick(ClickEvent event) {
- popupToHide.hide();
- deleteNthWaypoint(waypointIndex);
- }
- });
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement