Plotting lineArcs with turf.js that don't match up with their surrounding geodesic strings - google-maps

Background
We are supplied with some AIXM data (an XML based superset of GML) which describes polygon areas on a map as a mix of GeodesicStrings (a list of coordinates) and ArcByCentrePoints (a centre point coordinate with a radius, start bearing and end bearing). We are taking this data and converting it into a simple list of coordinates that we then display using a Google maps polyline.
Problem
When we plot a shape with an arc, the start and end points of the arc usually don't match up with the end point of the preceding line and the start point of the subsequent line. It looks as if the radial distance is out by an amount which doesn't appear to be proportional to the radius. See screenshot: interestingly the smaller arc at the top seems fine but the larger arc is inset.
We're pretty sure the data is correct because it looks fine when we use a third party tool to visualise it, so we're doing something wrong.
Implementation
We are using the turf.js library to convert the arc description into a set of points using their lineArc function. Internally this utilises their destination function which "uses the Haversine formula to account for global curvature". We combine these generated points, in the correct sequence, with the points taken directly from the preceding and subsequent GeodesicString elements to give us our final polygon.
Data
Input: Fragment of AIXM (GML) describing polygon
Output: Resulting list of points
Help!
I'm aware this question is light on code but I hope I've described the problem adequately and that some kind person with more GIS knowledge than me (>0) might be able to point me in the right direction. Thanks :)

I've given a couple of presentations on debugging and one of the things I say is that you should keep an open mind and shouldn't get too fixated on a possible cause of a bug because you can waste a lot of time tracking down a false lead.
Sadly in this case I didn't take my own advice. I was so obsessed with the idea that the problem arose from a complex cause, such as issues with the implementation of the Haversine formula, that I overlooked the far simpler answer. My code was taking a string representation of the radius, including the units (e.g. nautical miles or meters) and converting it into kilometres. Sadly I was using parseInt rather than parseFloat as part of this and so instantly losing precision. It was a simple as that - a schoolboy error.
Big thanks to Stefano Borghi, a maintainer of Turf JS, for all his help with this and for helping me see the wood for the trees.

Related

Polygonal Search

I have read several of the posts concerning Polygonal Search, but they are all about fixing or updating the programs. I am just wondering how it works. If there is a way I can get something like pseudo code of it or an explanation of how a shape captures the data points.
To further specify my goal, I am trying to make a constant square that will be held over a map (such as google maps), but the map can move around behind the square, however, the square will continue to report whatever cities lie within its bounds. [I will eventually proceed to building it, I just need some guidance]
Thank you.
There is an open-source library which has a function to check if two shapes overlap. You can check source code:
http://turfjs.org/static/docs/module-turf_inside.html
If you look for theory behind it check Hyperplane separation theorem

central coordinates of regular map tiles

I am trying to retrieve a set of static map tiles from Google Maps using the simple web services API.
For zoom level 0, where there is only one tile, I simply specify the center as (0,0), which is trivial. (And yes, I am aware, that the south-north range is [-85.05113°,85.05113°] only, i. e. I have read about Mercator projection (not only the Wikipedia article).
So for zoom level 1 with 2×2 tiles I know that it'd be naive to think the central coordinates of the tiles would be (±90,±45). I applied one of the functions listed in above article's "Derivation of the Mercator projection" section. In PHP this looks like
function mercor($aLat) {
return rad2deg(asinh(tan(deg2rad($aLat))));
}
which always returns 50.498987 when passing in 45. I tried several of the alternative expressions :-) all with the same result, indeed, and even checked that value with a dedicated calculator.
Anyway, the value is obviously not correct, as you can see here (which was supposed to show the north west quadrant of the Earth's map, but here the equator is shifted to the north) (image source):
By trial and error I found the correct value to be close to 66.65, but I have no idea how to calculate that. I tried several manipulations of the R factor shown in the expressions in that mentioned "Derivation of the Mercator projection" section, and also fiddled with the "Scale factor" described in the same document, but whatever I do, I do not come close to 66.65.
Here you can see that 66.65 is the (close to) correct value, the equator at the bottom edge (image source):
And taking an illustration like, for example (image source):
and a tool like kruler, it also becomes obvious that it should be 66.65.
So, any idea would be greatly appreciated. Thanks in advance...
(Currently I'm trying it from withing HTML documents, because it's relatively simple, but later I'd like to do it from an environment in which I have no way to call JavaScript. so the JavaScript API is not an option.)
I have prepared a website describing the popular tiling system used behind Google Maps, OSM and similar slippy maps. Have a look at:
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
With a click on the interactive map you receive bounds calculated in both the Mercator coordinates (in meters) as well as WGS84 lat/lon (in geodetic degrees).
Down on the page you find an open-source python code (which has been in the meanwhile ported to other programming languages by other people). This contains documented description of all the math you may need.
In fact, I have created this resource after working for Google SoC on the GDAL2Tiles/MapTiler project - which has been reimplemented into C/C++ and significantly improved and is now available via http://www.maptiler.com/.
UPDATE:
If you want to use the Google Maps Static API requests you may find useful another online tool which I prepared: http://www.maptiler.org/photoshop-google-maps-overlay-tiles/.
Feel free to review the JavaScript source code.

Equally distribute objects across a bezier curve

Can somebody walk me through how this madness works:
http://www.youtube.com/watch?v=KL8QLLmUvbg
Specifically I'm interested in equally distributing a given number of squares along a path. I'm also wondering if this would work with multiple line segments-- this is one curved segment and I need a solution to distribute objects across one big line with multiple curves in it.
Basically I'm trying to make a tail that realistically follows a character.
Thanks
First a Bezier spline is a curve parametrized by t. However t is not arc-length along the curve. So the procedure is this.
Calculate the length of the bezier curve.
Find the t values that divide the curve into N equal length segments.
However these two steps are tricky.
The first has a closed form solution only for quadratic Beziers. (You can find the solution here )
Otherwise you use a subdivide and approximate approach, or a numerical integration approach (and in some sense these are equivalent - I'd go the numerical integration approach as this has better provable behavior at the cost of slightly trickier implementation, but you may or may not care about that.)
The second is basically a guess a t value, and improve approach (using the same style of calculation at each step as step 1). I'd implement this using a secant style search, as I suspect the derivatives required to use a Newton's method search would be too expensive to calculate.
Once you've got the positions of the objects, you need to use the curve tangent and cotangent to create a local reference frame for the object. This allows the objects to sit nicely in the path of the curve, rather than all having the same orientation. Note that this only works nicely in 2D - in 3D you can still get some weird behavior with object orientation.
You can start by looking into how a bezier curve is calculated. Wikipedia has some nice animations with the explanation and this link has some as3 code.
but if you're trying to create a tail, there are simpler ways of doing that, like using following behaviour or a physics library
I ended up creating a following behavior system like Daniel recommended for simplicities sake. But to elaborate on Michael's awesome answer I stumbled onto this tutorial which details the the spline technique.
http://gamedev.tutsplus.com/tutorials/implementation/create-a-glowing-flowing-lava-river-using-bezier-curves-and-shaders/

Calculate 3D coordinates from 2D Image plane accounting for perspective without direct access to view/projection matrix

First time asking a question on the stack exchange, hopefully this is the right place.
I can't seem to develop a close enough approximation algorithm for my situation as I'm not exactly the best in terms of 3D math.
I have a 3d environment in which I can access the position and rotation of any object, including my camera, as well as run trace lines from any two points to get distances between a point and a point of collision. I also have my camera's field of view. I do not have any form of access to the world/view/projection matrices however.
I also have a collection of 2d images that are basically a set of screenshots of the 3d environment from the camera, each collection is from the same point and angle and the average set is taken at about an average of a 60 degree angle down from the horizon.
I have been able to get to the point of using "registration point entities" that can be placed in the 3d world that represent the corners of the 2d image, and then when a point is picked on the 2d image it is read as a coordinate with range 0-1, which is then interpolated between the 3d positions of the registration points. This seems to work well, but only if the image is a perfect top down angle. When the camera is tilted and another dimension of perspective is introduced, the results become more grossly inaccurate as there no compensation for this perspective.
I don't need to be able to calculate the height of a point, say a window on a sky scraper, but at least the coordinate at the base of the image plane, or which if I extend a line out from my image from a specified image space point I need at least the point that the line will intersect with the ground if there was nothing in the way.
All of the material I found about this says to just deproject the point using the world/view/projection matrices, which I find straightforward in itself except I don't have access to these matrices, just data I can collect at screenshot time and other algorithms use complex maths I simply don't grasp yet.
One end goal of this would be able to place markers in the 3d environment where a user clicks in the image, while not being able to run a simple deprojection from the user's view.
Any help would be appreciated, thanks.
Edit: Herp derp, while my implementation for doing so is a bit odd due to the limitations of my situation, the solution essentially boiled down to ananthonline's answer about simply recalculating the view/projection matrices.
Between position, rotation and FOV of the camera, could you not calculate the View/Projection matrices of the camera (songho.ca/opengl/gl_projectionmatrix.html) - thus allowing you to unproject known 3D points?

How to simplify (reduce number of points) in KML?

I have a similar problem to this post. I need to display up to 1000 polygons on an embedded Google map. The polygons are in a SQL database, and I can render each one as a single KML file on the fly using a custom HttpHandler (in ASP.NET), like this http://alpha.foresttransparency.org/concession.1.kml .
Even on my (very fast) development machine, it takes a while to load up even a couple dozen shapes. So two questions, really:
What would be a good strategy for rendering these as markers instead of overlays once I'm beyond a certain zoom level?
Is there a publicly available algorithm for simplifying a polygon (reducing the number of points) so that I'm not showing more points than make sense at a certain zoom level?
For your second question: you need the Douglas-Peucker Generalization Algorithm
For your first question, could you calculate the area of a particular polygon, and relate each zoom level to a particular minimum area, so as you zoom in or out polygon's disappear and markers appear depending on the zoom level.
For the second question, I'd use Mark Bessey's suggestion.
I don't know much aobut KML, but I think the usual solution to question #2 involves iterating over the points, and deleting any line segments under a certain size. This will cause some "unfortunate" effects in some cases, but it's relatively fast and easy to do.
I would recommend 2 things:
- Calculate and combine polygons that are touching. This involves a LOT of processing and hard math, but I've done it so I know it's possible.
- Create your own overlay instead of using KML in PNG format, while you combine them in the previous suggestion. You'll have to create a LOT of PNGs but it is blazing fast on the client.
Good luck :)
I needed a solution to your #2 question a little bit ago and after looking at a few of the available line-simplification algorithms, I created my own.
The process is simple and it seems to work well, though it can be a bit slow if you don't implement it correctly:
P[0..n] is your array of points
Let T[n] be defined as the triangle formed by points P[n-1], P[n], P[n+1]
Max is the number of points you are trying to reduce this line to.
Calculate the area of every possible triangle T[1..n-1] in the set.
Choose the triangle T[i] with the smallest area
Remove the point P[i] to essentially flatten the triangle
Recalculate the area of the affected triangles T[n-1], T[n+1]
Go To Step #2 if the number of points > Max