From b27c48cf0e4c3e3c8d6b6958932d3269b0cb3026 Mon Sep 17 00:00:00 2001 From: vperez Date: Tue, 9 Oct 2018 22:31:11 -0300 Subject: [PATCH 1/3] Add touch screen support. Experimental --- .../webapp/synoptic/javascript/synoptic.js | 173 +++++++++++++++++- 1 file changed, 172 insertions(+), 1 deletion(-) diff --git a/transitclockWebapp/src/main/webapp/synoptic/javascript/synoptic.js b/transitclockWebapp/src/main/webapp/synoptic/javascript/synoptic.js index 49b9543b7..43053d07f 100644 --- a/transitclockWebapp/src/main/webapp/synoptic/javascript/synoptic.js +++ b/transitclockWebapp/src/main/webapp/synoptic/javascript/synoptic.js @@ -135,6 +135,7 @@ class Sinoptico this.buses=null; this.stops=null; this.resized=false; + this.distFinger=null; this.onVehiClick=params.onVehiClick; if(params.predictionFunction!=undefined) this.predictionFunction=params.predictionFunction; @@ -143,6 +144,11 @@ class Sinoptico this.textSeparation=6; this.maxBusLabelWidth=0; this.__mouseWheelHandler = this.__mouseWheelHandler.bind(this); + this.__touchendHandler = this.__touchendHandler.bind(this); + this.__touchstartHandler = this.__touchstartHandler.bind(this); + this.__touchmoveHandler=this.__touchmoveHandler.bind(this); + this.__onlongtouch=this.__onlongtouch.bind(this); + this.initTouchEvent=null; } init() { @@ -152,6 +158,11 @@ class Sinoptico this.canvas.addEventListener('contextmenu', this.__handleMouseEvent); this.canvas.addEventListener('mousemove',this.__handleMouseEvent); this.canvas.addEventListener('wheel',this.__mouseWheelHandler); + this.canvas.addEventListener('touchend',this.__touchendHandler); + this.canvas.addEventListener('touchmove',this.__touchmoveHandler); + this.canvas.addEventListener('touchstart',this.__touchstartHandler); + this.canvas.addEventListener('gestureend',this.__gestureendHandler); + //this.canvas.addEventListener('touchstart', function(e){ alert(e); e.preventDefault();}); this.stopImg.onload = this.resize; //It has to be here for the first time it loads the image. this.stopImg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEwAACxMBAJqcGAAAAPVJREFUOI2Vkl1qwlAQhT/z1GQpNYRQ29XUJYkiqOiDS7GldBENFUSx\ne2jjy/XhnluHGPJzYEgyOTNz5gfu8QRsgD1wkX0DayCv4f8jAbaAa7ENENcFf4rwC0yk5EE2AqbA\nnzgf1SSh8gl4bFCZAmdx17bnULkp2CYpFZOjnpxkd8VMMSvw03ZSYlEdnsWzfAX4NTn8sLomSOQr\nox6yaxEBR70Pe8QF7iEC3vTxWiENKmYx1nMHfhUOfyRph+oZtzVmwRlWeW5JkgE/4i7tjxh/nkHJ\nDL+qRPYCzE3ld+63RmyUNNmyLtgix19YoYol8AUsbM8BV0fAV591YB1RAAAAAElFTkSuQmCC\n'; @@ -194,7 +205,7 @@ class Sinoptico } for(var m=0;m=x && this.stops[m].posY+5>=y ) + if(this.stops[m].posX<=x && this.stops[m].posY<=y && this.stops[m].posX+10>=x && this.stops[m].posY+10>=y ) elements.push(this.stops[m]); } return elements; @@ -380,6 +391,7 @@ class Sinoptico this.__showContexMenu([event.target.element],{ top, left}); } + __showContexMenu(elements,{ top, left }) { @@ -484,6 +496,165 @@ class Sinoptico this.resize(); this.__hideContexMenu(); } + __gestureendHandler(event) + { + alert("zoom "+event.scale); + } + __onlongtouch() + { + + + var rect = this.canvas.getBoundingClientRect(); + var touchobj = this.initTouchEvent.changedTouches[0];//first touch event + var x= touchobj.clientX-rect.left; + var y= touchobj.clientY-rect.top; + var elements=this.getElements(x,y); + + + + this.__hideTooltip(); + if(elements!=undefined && elements.length>0) + { + + const origin = { + left: x, + top: y + }; + this.menuIsShown=true; + this.__showContexMenu(elements,origin); + + return; + + } + } + __touchstartHandler(event) + { + //alert("a"); + this.__hideContexMenu(); + this.menuIsShown=false; + this.initTouchEvent=null; + this.initTouchEventMove=event; + this.timer = setTimeout(__onlongtouch, 500); + + + + if(event.changedTouches.length>1) + { + alert("a"); + + } + else + { + + } + event.preventDefault(); + } + __touchendHandler(event) + { + if (this.timer!=undefined) + clearTimeout(timer); + event.preventDefault(); + + if(this.menuIsShown!=undefined && this.menuIsShown) + return; + var rect = this.canvas.getBoundingClientRect(); + var touchobj = event.changedTouches[0];//first touch event + var x= touchobj.clientX-rect.left; + var y= touchobj.clientY-rect.top; + var elements=this.getElements(x,y); + + //alert(x,y) + + + if(elements!=undefined && elements.length>0) + { + const origin = { + left: elements[0].posX, + top: elements[0].posY + }; + //console.log(origin); + this.__showTooltip(elements,origin); + } + else + this.__hideTooltip(); + this.initTouchEvent=null; + + } + + __touchmoveHandler(event) + { + + // alert(( event.changedTouches.length>1 && this.initTouchEvent!=null)) + + if( event.changedTouches.length>1 && this.initTouchEvent==null) + { + //alert("Move init"); + this.initTouchEvent=event; + this.distFinger= Math.hypot( + event.changedTouches[0].pageX - event.changedTouches[1].pageX, + event.changedTouches[0].pageY - event.changedTouches[1].pageY); + //alert(this.distFinger); + + } + else if( event.changedTouches.length>1 && this.initTouchEvent!=null) + { + var deltaxd1=event.changedTouches[0].clientX-this.initTouchEvent.changedTouches[0].clientX;//Dedo 1 + var deltaxd2=event.changedTouches[1].clientX-this.initTouchEvent.changedTouches[1].clientX; + var deltayd1=event.changedTouches[0].clientY-this.initTouchEvent.changedTouches[0].clientY;//Dedo 1 + var deltayd2=event.changedTouches[1].clientY-this.initTouchEvent.changedTouches[1].clientY; + // alert((deltayd1)+ " delta dedo1 "+deltayd2) + + var dist = Math.hypot( + event.changedTouches[0].pageX - event.changedTouches[1].pageX, + event.changedTouches[0].pageY - event.changedTouches[1].pageY); + if(this.distFinger-dist<0 ) + this.__zoomIn(); + else + this.__zoomOut(); + this.distFinger=dist; + //this.initTouchEvent=null; + event.preventDefault(); + return; + + } + + //alert(event.changedTouches.length); + var rect = this.canvas.getBoundingClientRect(); + var touchobj = event.changedTouches[0];//first touch event + var x= touchobj.clientX-rect.left; + var y= touchobj.clientY-rect.top; + //alert(x,y) + var elements=this.getElements(x,y); + + if(elements!=undefined && elements.length>0) + { + const origin = { + left: elements[0].posX, + top: elements[0].posY + }; + //console.log(origin); + this.__showTooltip(elements,origin); + } + else + { + //leftScroll=this.container.scrollLeft; + if(this.container.scrollLeft!=undefined && this.initTouchEventMove!=undefined && this.initTouchEventMove!=null) + { + this.container.scrollLeft+=(this.initTouchEventMove.changedTouches[0].clientX-touchobj.clientX); + + } + // document.body.scrollTop=500; + // alert(document.documentElement.scrollTop); + // alert(document.body.scrollTop); + if(document.documentElement.scrollTop !=undefined && this.initTouchEventMove!=undefined && this.initTouchEventMove!=null) + document.documentElement.scrollTop+=(this.initTouchEventMove.changedTouches[0].clientY-touchobj.clientY); + this.__hideTooltip(); + } + this.initTouchEventMove=event; + //this.initTouchEvent=null; + event.preventDefault(); + + } __handleMouseEvent(event) { var rect = this.canvas.getBoundingClientRect(); From dbedd8b0194f1048f476c157421503b39e29a4c7 Mon Sep 17 00:00:00 2001 From: vperez Date: Tue, 29 Jan 2019 23:32:17 -0300 Subject: [PATCH 2/3] Fix issue 122 Add param assigned boolean, defalt false i order to return assigned vehicles only. It needs to be tested. --- .../transitclock/ipc/data/IpcVehicleComplete.java | 12 ++++++------ .../org/transitclock/api/data/ApiVehicleDetails.java | 2 +- .../transitclock/api/data/ApiVehiclesDetails.java | 5 +++-- .../api/rootResources/TransitimeApi.java | 11 ++++++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java index cbd7bcdc9..cda340c30 100644 --- a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java +++ b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java @@ -48,9 +48,9 @@ public class IpcVehicleComplete extends IpcVehicleGtfsRealtime { private final String originStopId; private final String destinationId; - private final double distanceToNextStop; - private final double distanceOfNextStopFromTripStart; - private final double distanceAlongTrip; + private final Double distanceToNextStop; + private final Double distanceOfNextStopFromTripStart; + private final Double distanceAlongTrip; private double headway; private static final long serialVersionUID = 8154105842499551461L; @@ -99,9 +99,9 @@ public IpcVehicleComplete(VehicleState vs) { // Vehicle not assigned to trip so null out parameters this.originStopId = null; this.destinationId = null; - this.distanceToNextStop = Double.NaN; - this.distanceOfNextStopFromTripStart = Double.NaN; - this.distanceAlongTrip = Double.NaN; + this.distanceToNextStop =null; //Double.NaN; + this.distanceOfNextStopFromTripStart =null;// Double.NaN; + this.distanceAlongTrip =null; // Double.NaN; } } diff --git a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java index 2999fa73e..7ca1ed6be 100644 --- a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java +++ b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java @@ -164,7 +164,7 @@ public ApiVehicleDetails(IpcVehicle vehicle, Time timeForAgency, UiMode... uiTyp licensePlate=vehicle.getLicensePlate(); isCanceled=false; headway=-1; - if(vehicle instanceof IpcVehicleComplete ) + if(vehicle instanceof IpcVehicleComplete && tripId!=null ) { distanceAlongTrip=((IpcVehicleComplete)vehicle).getDistanceAlongTrip(); isCanceled=((IpcVehicleComplete)vehicle).isCanceled(); diff --git a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehiclesDetails.java b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehiclesDetails.java index 190ece441..d8dbc2217 100644 --- a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehiclesDetails.java +++ b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehiclesDetails.java @@ -63,11 +63,12 @@ protected ApiVehiclesDetails() { * @param uiTypesForVehicles * Specifies how vehicles should be drawn in UI. Can be NORMAL, * SECONDARY, or MINOR + * @param assigned * @throws InvocationTargetException * @throws IllegalAccessException */ public ApiVehiclesDetails(Collection vehicles, - String agencyId, Map uiTypesForVehicles) throws IllegalAccessException, InvocationTargetException { + String agencyId, Map uiTypesForVehicles, boolean assigned) throws IllegalAccessException, InvocationTargetException { // Get Time object based on timezone for agency WebAgency webAgency = WebAgency.getCachedWebAgency(agencyId); Agency agency = webAgency.getAgency(); @@ -79,7 +80,7 @@ public ApiVehiclesDetails(Collection vehicles, for (IpcVehicle vehicle : vehicles) { // Determine UI type for vehicle UiMode uiType = uiTypesForVehicles.get(vehicle.getId()); - + if((assigned && vehicle.getTripId()!=null ) || !assigned) vehiclesData.add(new ApiVehicleDetails(vehicle, timeForAgency, uiType)); } diff --git a/transitclockApi/src/main/java/org/transitclock/api/rootResources/TransitimeApi.java b/transitclockApi/src/main/java/org/transitclock/api/rootResources/TransitimeApi.java index 3ecdef5a2..b89e418ec 100644 --- a/transitclockApi/src/main/java/org/transitclock/api/rootResources/TransitimeApi.java +++ b/transitclockApi/src/main/java/org/transitclock/api/rootResources/TransitimeApi.java @@ -295,7 +295,7 @@ public Response getVehicleLocation(@BeanParam StandardParameters stdParameters, + " adherence and driver IDs.",tags= {"vehicle"}) @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getVehiclesDetails(@BeanParam StandardParameters stdParameters, - @Parameter(description="Specifies which vehicles to get data for",required=true) + @Parameter(description="Specifies which vehicles to get data for",required=false) @QueryParam(value = "v") List vehicleIds, @Parameter(description="Specifies which routes to get data for",required=false) @QueryParam(value = "r") List routesIdOrShortNames, @@ -306,7 +306,12 @@ public Response getVehiclesDetails(@BeanParam StandardParameters stdParameters, @QueryParam(value = "s") String stopId, @Parameter(description=" For when determining which vehicles are generating the" + "predictions so can label minor vehicles",required=false)@QueryParam(value = "numPreds") - @DefaultValue("3") int numberPredictions) throws WebApplicationException { + @DefaultValue("3") int numberPredictions + , + @Parameter(description=" Return only assigned vehicles",required=false)@QueryParam(value = "assgined") + @DefaultValue("false") boolean assigned + + ) throws WebApplicationException { // Make sure request is valid stdParameters.validate(); @@ -337,7 +342,7 @@ public Response getVehiclesDetails(@BeanParam StandardParameters stdParameters, // Convert IpcVehiclesDetails to ApiVehiclesDetails ApiVehiclesDetails apiVehiclesDetails = new ApiVehiclesDetails(vehicles, stdParameters.getAgencyId(), - uiTypesForVehicles); + uiTypesForVehicles,assigned); // return ApiVehiclesDetails response Response result = null; From 7203b6aefd8c064d73500961125933352b197aca Mon Sep 17 00:00:00 2001 From: vperez Date: Wed, 30 Jan 2019 13:04:03 -0300 Subject: [PATCH 3/3] Change serialization to be able to handle Doube insted of double for distanceToNextStop,distanceOfNextStopFromTripStart and distanceAlongTrip --- .../ipc/data/IpcVehicleComplete.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java index cda340c30..0f02e23ee 100644 --- a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java +++ b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleComplete.java @@ -148,9 +148,9 @@ private IpcVehicleComplete(String blockId, String nextStopId, String nextStopName, String vehicleType, long tripStartEpochTime, boolean atStop, String atOrNextStopId, Integer atOrNextGtfsStopSeq, String originStopId, - String destinationId, double distanceToNextStop, + String destinationId, Double distanceToNextStop, - double distanceOfNextStopFromTripStart, double distanceAlongTrip, long freqStartTime, IpcHoldingTime holdingTime, double predictedLatitude, double predictedLongitude,boolean isCanceled, + Double distanceOfNextStopFromTripStart, Double distanceAlongTrip, long freqStartTime, IpcHoldingTime holdingTime, double predictedLatitude, double predictedLongitude,boolean isCanceled, double headway) { super(blockId, blockAssignmentMethod, avl, pathHeading, routeId, @@ -178,9 +178,9 @@ protected static class CompleteVehicleSerializationProxy // Exact copy of fields of IpcCompleteVehicle enclosing class object private String originStopId; private String destinationId; - private double distanceToNextStop; - private double distanceOfNextStopFromTripStart; - private double distanceAlongTrip; + private Double distanceToNextStop; + private Double distanceOfNextStopFromTripStart; + private Double distanceAlongTrip; private double headway; private static final short currentSerializationVersion = 0; @@ -212,9 +212,9 @@ protected void writeObject(java.io.ObjectOutputStream stream) stream.writeObject(originStopId); stream.writeObject(destinationId); - stream.writeDouble(distanceToNextStop); - stream.writeDouble(distanceOfNextStopFromTripStart); - stream.writeDouble(distanceAlongTrip); + stream.writeObject(distanceToNextStop); + stream.writeObject(distanceOfNextStopFromTripStart); + stream.writeObject(distanceAlongTrip); stream.writeDouble(headway); } @@ -240,9 +240,9 @@ protected void readObject(java.io.ObjectInputStream stream) // Read in data for this class originStopId = (String) stream.readObject(); destinationId = (String) stream.readObject(); - distanceToNextStop = stream.readDouble(); - distanceOfNextStopFromTripStart = stream.readDouble(); - distanceAlongTrip = stream.readDouble(); + distanceToNextStop = (Double)stream.readObject(); + distanceOfNextStopFromTripStart = (Double)stream.readObject(); + distanceAlongTrip =(Double) stream.readObject(); isCanceled=stream.readBoolean(); headway=stream.readDouble(); }