AnyLogic: compensating for double overflow in GISRegion.area() - java

I'm trying to sort a collection of AnyLogic GISRegions by their geographical area. Said area is calculated using GISRegion.area(units), which is straightforward enough. The areas I'm using, however, are city-scale and the method returns a double. This appears to cause overflow problems:
I don't think I'm doing anything wrong with my code, so presumably this is an AnyLogic problem. For brevity, I've included a line that prints each region's area rather than the sorting steps:
// For each region of the Australian Capital Territory, print its area in km^2:
areas.forEach(next -> traceln(""+next.name+": " + next.gisRegion.area(SQ_KILOMETER)));
Has anyone encountered this issue? How did you get around it?
For non-AnyLogic users, I have all the lat-long points in each geoshape. How might I calculate the area using those points?

[Not really a full answer, but the ideas are too long for a comment.]
I assume you've raised an AnyLogic support request since it seems 100% a bug. Since this is just a basic 'calculate area' function, I can't see any way round it other than, as you suggest, calculating it in an alternative manner from the vertex lat/longs that you have, and can get via getPoints() on the GISRegion.
Since this is just an N-sided polygon, surely there must be standard Java libraries that could calculate that, though that's not allowing for the GIS projection (not sure what level of error that might introduce); you'd expect open GIS libraries to cope with the latter. Since a GISRegion has a createOMGraphicObject() method to create an OpenMap standard(?) format graphic, that could be useful if that's a standard format other libraries can work with.
There's code on glennon's answer to this GIS StackOverflow question that claims to perform the calculation (or you make be able to hook in to PostGIS as in fmark's answer).

Related

How can I correctly convert geographical coordinates to pixels on screen?

I'm trying to make a Java project that pinpoints the place on a image of a map, when given coordinates (taken from Google Maps).
I've tried using the top-left corner of the image (place that has highest latitude, and the lowest longitude), as an some kind of an reference point, which would be (0,0) point on the map image, and than I've tried to calculate every place on the map based on that reference point. However, this method proved inaccurate, probably because of the curvature of the Earth (mind that the map I'm working with (Serbia) covers area of 4° latitude, and 4° longitude).
I've seen couple of answers talking about converting into Mercator projection, but they are not very clear to me, because they are not covering a case similar to mine, and are not written in Java.
What can I do to pinpoint those points more accurately (±3km would be accurate enough)?
As comments have pointed oit correctly, in order to precisely convert between geographic coordinates and map position, you have to know the method of projection used for the map, and a sufficient number of parameters so that tuning the remaining parameters using a suitable set of reference points becomes feasible.
So if you assume a conic projection, then read the document David pointed out, and this referenced follow-up as well. As you can see, within the family of conic projections, there are a few alternatives to choose from. Each of them is described by a few parameters (i.e. standard parallels, cone constant, aspect ratio, …). You'd make guesses for these and then use some numerical optimization to obtain a best fit. Then you take the best parameter fit for each kind of projection and see which of them has the best overall fit. Quite a bit of work. If you don't want to implement the code for all these projections you can use proj.4 either on the command line or as a native library. To do the numeric optimization, you could possibly try to adapt one of the COIN-OR projects to your application.
In any case, the first step would be creating a suitable set of reference points which you can use to evaluate the fit. So pick a few prominent points on your map and find Google Earth coordinates for these. I'd say you should have at least a dozen points, to account for the fact that you know so little about your map. Otherwise there is a great risk that you will tune the large number of parameters to exactly fit your points while the rest of the map is still completely off. Even with this number of reference points, since the area of Serbia is not that big (compared to maps spanning whole continents), the errors of a wrong guess or a bad fit might be very small. So it might be hard to actually decide which projection has been used.
With all that I said above, and even with external libraries taking care of the projection and the numerical optimization, it might easily take you half a year just to set up the tools to work out the projection. So decide whether that's worth the effort. If not, there are several alternatives. One would be to take a different map, one where you know the projection. Or contact the author of your map and obtain the projection. Or ask someone working in geodesics in Serbia, because they might have enough experience to recognize the projection at a glance, I don't know.
One other option is by combining the fact that you need reference points with the fact that you might not be able to work out the exact projection in any case. Simply combine these in the following way: choose a suitably dense set of reference points, evenly distributed over the map. Then interpolate between them, picewise linearily or with higher degree or using some weighted interpolation scheme or whatever. You know there is a projection behind all this, but you give up on working out the projection, and simply mitigate the symptom: by having enough reference points, each data item is close enough to a reference point to keep the error smaller than your threshold.
I found an answer I was looking for in this thread: Java, convert lat/lon to UTM
I find out that the actual projection of my map was UTM. From there, it was simply finding a class that would convert my lat/lon coordinates into UTM eastings and northings (very useful code in this answer), and then I would do simple math to find out where the point is compared to the boundaries of the map, and it's actually working.

Does the getFocusDistances() camera API function actually work for Nexus 5? or any other device?

I would like to determine the distance of an object from my Nexus 5 camera, preferably without using an object like a coin for scale. I figured the Camera.Parameters getFocusDistances function would work for this.
I attempted to do this via something like the following in my takePicture() jpeg callback:
Parameters params = camera.getParameters();
Float focusDistances[] = new float [3];
params.getFocusDistances( focusDistances );
I tried running this a few times with objects of different distances from the camera, though each time, focusDistances[FOCUS_DISTANCE_NEAR_INDEX], focusDistances[FOCUS_DISTANCE_OPTIMAL_INDEX], and focusDistances[FOCUS_DISTANCE_FAR_INDEX] all contained the value positive infinity.
It's possible I'm doing something wrong, in which case please let me know if there is a specific way I'm which this will work on the Nexus 5. However the android API specifically states you can call getParameters() (and then getFocusDistances()) at any time to get the latest focus distances and therefore I think this should work. One thing I haven't tried yet is doing the above in an on auto focus handler, however I don't see why this should matter.
I did some research to try and see what was going on, and I found several questions regarding this sort of behavior from getFocusDistances() and typically the answer, if there was one, was that the function is not supported by the android API and/or the hardware manufacturer. Now a lot of these discussions I found online were from several years ago, and dispite the questionable feelings it gives me about getFocusDistances, I've still seen this function suggested to be used for getting the focus distance so I figure it must work on SOME device for SOME android API version.
Does anybody know if getFocusDistances() works for any particular version of android on the Nexus 5? If not, does anybody know ANY device it does work on?
EDIT:
Since posting, I have tried obtaining the focus distances in the onAutoFocus handler, as well as trying a bit more extensively for objects atvarious distances. The results have been consistent - positive infinity is always returned for all 3 focus distances (NEAR, OPTIMAL, and FAR). I even tried this with a Nexus 7 and getFocusDistances always returns the constant values (0.95, 1.9, and infinity), so apparently getFocusDistances isn't implemented on that device either.
Therefore, I really have two questions:
Is there any way to get somewhat accurate focus distances using the android Camera API with the Nexus 5? I'm even wondering if there is custom android version where getFocusDistances is actually implemented, since otherwise I may attempt to do so myself depending on what I find when examining the API code.
Are there any android capable devices that are known to implement getFocusDistances in a somewhat accurate manner?
First of all, It's very difficult to measure the object distance from one single shot/view. You would find many research papers which tried to employ vision based techniques to judge the object distance. I can refer you one such paper. They tried to implement a positioning system that would solely work on mobile camera+sensors. You would probably realize how non-trivial it is to measure the object distance from one single camera view. They finally used a method called "structure from motion" vision technique to calculate the distance (From multiple photos taken from multiple angle).
Even traditional apps like SmartDistance and SmartMeasure needs to use geometric tricks to measure the distance. None of them could only rely on camera parameters. Sorry for the elongated introduction. I have done a project of this sort before and I am telling you all these based on my experience.
To answer your query, I haven't found any Android device yet which returns realistic values of focus distances. They are either returned as some constant values or sometimes 0 and infinity. I found someone reporting that it worked for Galaxy Nexus but only within 30cm object distance, it doesn't work for distances more than that. The bottom line is that you cannot rely on this function from camera API which is heavily dependent on the device drivers. And, phone camera's are not well-known for their lens/sensor qualities. It would be very very difficult for you to work on any optics based formula for mobile-phone cameras. I would suggest you to rather go for some sensor based geometric tricks.

Programmatically finding periodicity of a given function

I am working on a project in Android for my Signal Processing course. My aim is to find signal properties, such as periodicity, even/odd, causality etc, given a user-input function. Right now, I am stuck at trying to figure out how to programmatically calculate the periodicity of a given function. I know the basics behind periodicity: f(t+T) = f(t)
The only idea I have right now is to extensively calculate values for the function, and then check for repetition of values. I know the method is quite stupid, given the fact I don't know how many such values I need to calculate to determine if it is periodic or not.
I know this can be done easily in Matlab, but again very difficult to port Matlab to Java. Is there something I am missing? I have been searching a lot, but haven't found anything useful.
Thanks for any help, in advance!
If the function f is given as a symbolic expression, then the equation you stated can in some cases be solved symbolically. The amount of work required for this will depend on how your functions are described, what kinds of functions you allow, what libraries you use and so on.
If your only interaction with the function is evaluating it, i.e. if you treat the function description as a black box or obtain its values from some sensor, then your best bet would be a Fourier transformation of the data, to convert it from the time domain into frequency domain. In particularly, you probably want to choose your number of of samples to analyze as a power of two, and then use FFT to quickly obtain intensities for various frequencies.

Feature/blob correlation and histogram analysis

I'm working on a sketch search engine that correlates whatever someone's sketching with a picture in the database (the db is just about 40 pictures now). I'm doing this mostly for fun so I'm not that well-versed in computer imaging techniques.
First of all, are there any rules of thumb on how one should create histograms (bin sizes, ranges, etc)? I'm using some histogram code found at http://www.scribd.com/doc/6194304/Histograms (but ported to JavaCV). Sometimes I get good results, sometimes I get bad results, most of the time I get "meh" results. I've been experimenting a TON with bin sizes and ranges and I'm wondering if comparing higher dimensional histograms may be the answer here.
Second of all, it seems that black makes a very strong presence in my current histogram setup (even a black dot shifts the entire result set). Should this be expected? Or did I screw something up? Example:
And after the dot:
Note how I'm already getting pictures of "earthrise" as "close" matches.
I'm also wondering what methods I should use for blob or feature analysis. I think that stuff like SURF may be overkill because I only want to broadly compare blobs, not accurately map templates. Is there any way I can compare the edges after being passed through a Canny filter? (Low complexity if possible):
For example, here, I want the two smiley faces to be at the top because the needle smiley "blob" is more closely related to the smily face shape than to a bunch of passion fruit or a galaxy.
Phew long question. If you want to try out the engine for yourself, go to http://skrch.dvt.name/ (shameless plug, I know, I know -- only works in FF/Chrome/Safari). Maybe more experienced computer vision people can make suggestions based on results. Oh, I'm using the CV_COMP_BHATTACHARYYA distance when comparing histograms (it seemed that it gave the best results although chi-square isn't bad either).
Is there a background ?
IS it significant ?
Maybe you need to look at whether there is a user-supplied background or not.
then you "just" need to have 2 histogram per db entry, one with bg, one without.
That'll stop earthrise looking like an apple with a dot.
for basic bg separation, try a canny, then taking "outside" and removing it from a copy of the original.

Convert a list java.awt.geom.Point2D to a java.awt.geom.Area

I have a set of points that i want to turn into a closed polygon in Java. I'm currently trying to use java.awt.geom.Point2D and java.awt.geom.Area but can't figure out how to turn a group of the points into an Area.
I think I can define a set of Line2Ds based on the points and then add those to the Areas, but that's a lot of work and I'm lazy. So is there an easier way to go.
The problem is I have a list of lat/lon coordinates and want to build up an area that I can use for hit testing.
Non-core Java libraries are a possibility as well.
Update, I looked at using java.awt.Polygon but it only supports ints and I'm operating with doubles for the coordinates.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4077518
Hear that, "customer"? You should be using GeneralPath, even though the absence of Polygon2D since the late 1990s is an obvious monster-truck-sized hole in the API.
If you are actually working with Geodetic lat/lon values, you can actually use OpenMap to do some of this work. I just spent some time using the Geo class in that API to bounce an object around an area defined by a polygon of lat/lon points. There are intersection calls and everything and all of the math is done spherically so that the points are more correct as far as projections go.
The simplest (and laziest) thing to do is to create a bounding box for the points from the maximum and minimum of the X, Y ordinate values.
If you need a closer fit then rather than devise your own algorithm, this might be a good place to start:

Categories