-
Notifications
You must be signed in to change notification settings - Fork 91
Setting a custom API URL doesn't work #40
Comments
@vreixo do you think this is a quick fix you could implement and we could get out in a v2.0.1 release in the next day or two? If not, we can wait. |
Custom server API issue always happens. I enter the Trimet URL, then I get the Toast |
Here's my LogCat output, althought I don't see any obvious issues:
|
I've having the issue on a Samsung Galaxy S3 with Android 4.1.2. |
I have discovered that this is not a problem of how a custom server is selected, is a problem of how is made the calculation to check if a marker is inside the bounds. This is a fairly complex calculation that calculates the distance in the map between coordinates several times, which produces some inexactness which added one to the other overpass the acceptable error (not by far). I have changed the function to check if a point is inside of the bounding box to a much simpler one that just checks if the latitude and longitude are bigger and smaller than the server limits (within an acceptable error of 0.005 degrees) and it just works OK. As I don't have an important background in GeoLocation please tell me if you think this approach is correct. Also I have detected a related error: the app crashes if the marker is dragged directly outside the boundaries (if it was dragged before it does not crash). For solve this I have changed the way to restore the previous location after an invalid drag. |
I have found another erratic behavior for setting a custom server but is not very related to this so I have created Issue #43 |
@vreixo on changing the bounding box calculations - the more complex calculations are probably to handle the situation where the bounding box crosses the International Date Line. This is more complex since you can't assume that the minimum longitude is the left side of the bounding box (e.g., if the box crosses the IDL, then the minLong is actually the right side of the box, and the maxLong is the left side - hence why OTP includes the "lowerleft" and "upperright" coordinates, since there is no abiguity over whether or not the box crosses the IDL). I'd like to keep this calculation if possible - or, correct it if its producing wrong results. In my tests, it didn't seem to be an error in accuracy, since I was trying to plan a trip in downtown Portland (which I believe is well within the box) and it was giving me this error. Also, are we using the same bounds calculation for server auto-detection? If so, that seems to work ok. Let me know what you think. @mentaer - thoughts? |
I will make some tests to see if my theory of the problems with the accuracy of the function is right. I understand that for the situation that you said are necessary this "complex" calculations, so I wont change them, I will just check if they're correct or augment the acceptable error if that is the problem. |
@vreixo Ok, thanks! fyi, here's a sample map I put together a while back explaining why lowerLeft/upperRight coordinates are preferred to minLat/minLong. |
@barbeau thanks for the link! Now I fully understand why are needed UpperRight and LowerLeft and why in OTP min and max have been deprecated (it was a question that I have asked myself some time ago). Regarding the issue I'm now more convinced that is an accuracy problem. For check this I have used the test google doc https://docs.google.com/spreadsheet/ccc?key=0AsoU647elPShdDlCUVNKS0JQUXprX3pQd0ZENW5JMGc&single=true&gid=0#gid=0 and I have set the same bounds for the Portland server that are in the metadata http://rtp.trimet.org/opentripplanner-api-webapp/ws/metadata and make the custom server fail. With these bounds the error is the same when you try to put a marker that is with the custom URL. I have also made the test with Tampa putting huge bounds and also an error is obtained placing the marker. One important point is that the calculations don't fail in all the area of the server, as it possible to set a marker close to the borders, as you can see in the image (this is also possible when setting a custom server. If the bounds where the same used for the previous server this won't be possible at all (I have also checked that they are actually not the same in the code of the app). To be sure I have made some more tests with incremental size for the bounds and checked the errors. The error is proportional to how far is the point from the center and how big are the bounds, values of max errors in meters (horizontal or vertical), in the center from smaller to bigger bounds: Also for Tampa I have checked: With this context, I think that is safe to set a bigger acceptable error to solve the problem or use a better function that the provided by the API to calculate the distance in the map. With an error of 5 km we will cover approximately a region with the size of the state of Florida, so maybe is OK as a quick solution. The message is because I have tried to put after a marker in the middle. |
I have remembered now that @mentaer said that there is a class in OTP to calculate this, org.opentripplanner.common.geometry.SphericalDistanceLibrary, maybe is more accurate. Although, this won't be a quick fix. |
Oh - so the error is in our measurement of distance between two points? Can you share a link to this section of the code? If this is the case, there is a built in Android class (Location.distanceTo())to measure distance between two points. We should use this, as it uses Vincenty's formula, which is accurate to within millimeters even accounting for error when measuring distance between two points on WGS84. There are also some utilities related to bounds measurements in OBA Android - we can use code from that project too, since its also licensed under Apache 2.0. Also, please beware of your GSoC 2013 deadline - I don't recall exactly when it is, but this can all wait until after the deadline if you still need to create documentation, etc. |
@vreixo I should note that the OBA Android isLocationWithinRegion() method doesn't handle the IDL issue properly, so just beware of that. And thanks for all your work on this! |
I have just made a quick test converting the latitudes and longitudes to Locations and using Location.distanceTo and the errors are the same. We are now already using an Android function, Location.distanceBetween(). Here is the code https://github.com/CUTR-at-USF/OpenTripPlanner-for-Android/blob/master/src/edu/usf/cutr/opentripplanner/android/util/LocationUtil.java You're right about the deadline, so I will organize the fixes that I have already made to the most important bugs and after I will continue with documentation work. |
@mentaer I have tried with spherical distance from OTP https://github.com/openplans/OpenTripPlanner/blob/c9f4184263c740f886384afded3399f58aa91288/otp-core/src/main/java/org/opentripplanner/common/geometry/SphericalDistanceLibrary.java and for large bounds as Portland metadata bounds still does not work. For smaller ones is OK. |
@vreixo could you list the set of lat/long points and the erroneous distance that Location.distanceBetween() returned for each? This method has always worked correctly for me in other projects, so I'd like to try and dig deeper to figure out why its returning an incorrect distance. |
LocationUtil.checkPointInBoundingBox() method to help troubleshoot the issue in #40. Note that currently the test fails because the method isn't working correctly.
@vreixo I created a unit test (and test project for OTP Android) to help troubleshoot the Main test code is in the BoundsTest class. Important code looks like this:
Please add additional points and servers here, and submit them via a pull request to this branch (I'll merge the test project into the main repo once we're done, since we should really have one anyway). To use this, you'll need to import the new OpenTripPlannerAndroidTests project (off the root folder) into Eclipse using "File->Import->Existing Android code". Then, right-click on project and click "Run As->Android JUnit Test". Note that you'll need an emulator or device connected to execute the test. After it runs, the JUnit windows should pop up in Ecilpse and the two assertion tests should currently fail (since the method isn't working correctly). After the method is fixed, these tests (and any you add) should pass. Hopefully this should be a lot faster than editing the code manually with different test cases. More on unit testing on Android here. |
I have expanded the test class to check all the "official" servers and I have added also Portland with the bounds from metadata that are bigger. I have check the calculations and repeated them step-by-step with the help of this tool http://www.daftlogic.com/projects-google-maps-distance-calculator.htm and the results are slightly different but there are also with very big errors. Checking these things I have thought why the algorithm does not measure the total size horizontal and vertical at the latitude or longitude of the point, if it would be more accurate. Now, for measure horizontal distance it uses the upper right latitude of the server bounds instead of the point latitude and for vertical distance it uses the lower right longitude instead of the one of the point. I have made some tests in the online tool and use part of the original point seems to work better. I have looked around for another source of this bounds algorithm used and I didn't found anything, so, I have changed the algorithm myself following previous point and now it works perfect! All tests pass with an accepted error of 10 meters. Here is the change (locationLat and locationLong refer to the chosen point): New:
Previous:
If you agree with me and you think that this is the correct solution I will made a pull request with the solution (and I will also make another request to update the tests with all the servers to your branch). |
@vreixo Great! Glad you were able to come up with a fix. Before submitting a pull request, I'd ask that you add a few test cases with bounds that cross the International Date Line (IDL), since that is the reason for the more complicated method. So, I'd test points within the bounds to the west of the IDL, points within the bounds to the east of the IDL, and points to outside the box with both negative and positive longitudes. These tests will also make it clear to future developers why we're using more complex methods (if you could add more comments in the code itself as well, that would be great too). If these all pass, then please submit the pull request. |
Fix #40 - Bounding box calculations are more accurate now.
If you perform these steps:
You get the message
Location outside of network boundaries. Marker not set
.I got this after the app auto-detected Tampa, and it seems to be retaining the bounding box info from the Tampa server and enforcing it on the custom API URL trip requests.
The text was updated successfully, but these errors were encountered: