Smoothing noise for geo locations - javascript

My mobile web app utilizes navigator.geolocation.watchPosition to track polylines and waypoints for historical walking tours. (A customer requirement no-native app)
My first testing was done in a vehicle due to bad weather and seemed to produce reasonable results when plotting the polyline on an embedded Google Map in real-time. However, when walking it produced a more zig zag line.
Some research has revealed that I need to filter the retrieved location instead of just calculating the distance of two points.
The suggested filter, Kalman filter, seems to be something over my head, and I'm wondering whether there is an open source implementation for JavaScript available, which can be of help for my use case.
An open source C/C++ implementation of the Kalman filter that could be compiled to JavaScript using emscripten might be of help too.

I posted a simple Kalman filter that can be used for geolocation data in an answer to this question: Smooth GPS data . It was designed for Android, where the GPS location readings are accompanied by a single error-bar number called accuracy which is measured in metres. That means that for each GPS location reading, with 67% probability the true location is within the circle centered on the specified location, and the radius of the circle is given by the accuracy number. If your situation is different then a bit of work will be required, and if so I would suggest that you edit the question to spec out in more detail what inputs you have for the Kalman filter.

Related

Generating a continuous interpolated surface from point data with Mapbox GL JS

I'm relatively new to Mapbox and its GL JS Library, but so far have been really impressed at its capabilities.
I'm currently working with a dataset of approximately 100,000 points and am trying to devise a way of quickly generating/visualising a continuous interpolated surface within the convex hull of the dataset I have (essentially trying to generate something that's as fast/responsive as the heatmap function, but looking to interpolate from the point data values rather than spatial density).
The documentation for the heatmap functionality discusses this exact scenario:
Among maps you'll find on the web, there are two common categories of
heatmaps: those that encourage the user to explore dense point data,
and those that interpolate discrete values over a continuous surface,
creating a smooth gradient between those points. The latter is less
common and most often used in scientific publications or when a
phenomenon is distributed over an area in a predictable way. For
example, your town may only have a few weather stations, but your
favorite weather app displays a smooth gradient of temperatures across
the entire area of your town. For your local weather service, it is
reasonable to assume that, if two adjacent stations report different
temperatures, the temperature between them will transition gradually
from one to the next.
But then proceeds to explain this is less common and there's no documentation/example provided for this type of application.
At this stage I've tried converting the points to voronoi cell polygons and colour coding by data value (a nearest neighbour approach to visualising), but the render seems to struggle with 100,000 points at lower zoom levels (0 through 8). Does anyone know if it's possible to create a fast-rendering surface interpolation from point values? Any examples would be fantastic.
The Mapbox Delaunator library is a very fast JavaScript library for Delaunay triangulation of 2D points. d3-delaunay and d3-geo-voronoi are both based off of this library. You could use these libraries and then display the results on your map via a custom style layer.
Looks like what you are trying to do is some sort of Spatial Interpolation.
Here is a summary of popular methods typically used for this purpose.
https://michaelminn.net/tutorials/r-spatial-interpolation/

interpolation method for google maps

I wanted to ask you about the way to make spatial interpolation in google maps API. This means- I have values for some points inside an area and want to recalculate values for every point in this area (and create an raster overlay).
In "offline" GIS softwares, there are more methods to do this. For example Kriging (http://en.wikipedia.org/wiki/Kriging).
Thanks for answer
There is no real practical way to do such a thing. Spatial Interpolation is something you really need a full-blown GIS to accomplish. It requires storing, analyzing, and presenting data in way that ArcGis or QGis is best suited for. There is some new feature in ArcGis Online that works with Google Maps API but I don't know much about it and am unsure if it would be any help for you but a link is here.
I know, its not something geostatiscically correct, but I have made this:
- I have created a net of rectangle polygons.
- I have connected all my points to polygon they lie and have made mean value for polygons with at least one point
- I have checked every polygon without points and at least 2 neighbourly polygons with points, and have made mean from this neighbourly values
- I have checked again all my polygons with values and at least 2 neighbourly polygons with values and smoothed origin values according to the neighbours´ values.

How to determine the vertexes for a polygon whose outer edge is a given distance from a line or area in javascript on Google maps?

I have an exercise in problem solving for those who like that kind of thing. I'm working on a mapping application that uses Google Maps. A user first enters a series of coordinates and a "radius". The user then requests either a line or an area be plotted. The plots are taking place on Google Maps using polygons. In other words, given the blue line (or area) defined by the blue points and a distance, calculate the red points and draw the red polygon where the edges are of the given distance away from the user-provided edges:
I have managed to get this to work in "most" situations by calculate forward and reverse bearings, then finding the points with a bearing 90 degrees off these in the appropriate direction. For the arcs I just calculated the location points along that arc at 5 degree intervals. In the case of the inside of an acute angle, I determine where the two lines intersect and use that point, but this fails miserably sometimes when the cross-track distance at that point is greater than the radius that was provided.
I'm hoping someone knows of an easier way? Maybe one that works all the time regardless of the ratio of the cross-track to radius distances? Or maybe a library already exists to do this?
I hope what I'm trying to do makes sense... It's hard to put in words. Maybe if I had the words a search would have been helpful even.
Well, the answer turned out to be simpler than I thought. It took me back to a lesson I was taught during CompSci 101 almost 15 years ago:
"Use existing libraries whenever possible."
Once I found out (via googling), that what I'm looking for isn't called an "offset" or a "scale" but is actually called a "buffer" in GIS computing, it was simple. There are some great libraries like Clipper by Angus Johnson that can do it, but I wanted something JavaScript specific.
That brought me to arcGIS's GeometryService. They even have a Google Maps version but it's only API v2. Luckily, there's an official, unsupported version I found via the arcGIS forums that works with GMaps API v3.
So, my solution was to use that, called arcgislink, and it's buffer function works perfectly with Google Maps LatLng points, Google Maps Polygons/Polylines, and any of the standard arcGIS types. Anyone else needing to do this with Google Maps, I highly recommend looking at their libraries.
In the general setting, this problem is quite difficult because it is a global one (you cannot just solve locally, at each polygon vertex but just handling the two incoming edges). And also uneasy because it involves circular arcs.
There is a solution which is quite unefficient but safe: assume you have a general polygon union algorithm (like http://gvu.gatech.edu/~jarek/graphics/papers/04PolygonBooleansMargalit.pdf); you will add inflated versions of every edge one by one (every time a rectangle and two half-disks approximated by polygons), together with the original polygon for closed shapes.
For the sake of efficiency, you can design a "sweepline" algorithm that works by slicing the plane with horizontal lines at every "event point", i.e. segment/arc endpoints and arc apexes, so that the configuration in every slice is simpler. Do you see what I mean ?
BTW, what do you call the "cross-track distance" ?

How to draw a rectangular area on a large google map and query database to find locations/points that exist inside the rectangle?

I've got an application where I would like to present the end user with a google map and allow them to select an area of the map with a simple rectangular drawing tool and then have all of the locations stored in the client's database that fall in that rectangular selection area show up as points on the map...
I have a simple understanding of google maps and can get google maps to plot all the locations on the database w/o a problem... my problem comes in allowing the end user to draw the rectangle. Not sure how to implement this.
Can someone explain or link me to an example of how it's done?
Looks like this question was asked (and answered) a few months before Google posted about the new drawing tools in v3 API ...
I have to say that using the API's drawing tools gives a better user experience than #rcravens solution. Here's a very specific implementation that lets you "select" an area on the map by drawing a rectangle or polygon, and then checking to see if a marker is inside the shape: http://jsfiddle.net/JsAJA/306/.
Interesting question. I love the google maps api. Here is a jsFiddle with your solution:
http://jsfiddle.net/JsAJA/2/
You will have to query your database for points between the minimum/maximum lat and lngs. Hope this helps.
Bob
P.S. Note that this breaks the natural user experience of google maps. The map is no longer dragged when you mouse down. It needs a better user experience.
You might be interested in learning about Csquares, which encodes lat,lon into a text string which can be inserted into an indexed column.
I have ported the public domain Csquare encoding logic to Java and Javascript.
Let me know if you want it.
http://www.cmar.csiro.au/csquares/csq-faq.htm#10
EXCERPT
What is c-squares, and what purpose does it serve?
C-squares stands for "Concise Spatial Query and Representation System" and is a method of indexing the geographic location of objects or observational data on the surface of the earth, in a simple alphanumeric format suitable for subsequent querying by any text-based system or search engine.
. . .
In addition, c-squares can be defined at a flexible range of scales, from 10 x 10 degrees (approx. 1000 km) through 5 x 5 degrees (500 km), 1 x 1 degrees (100 km), 0.5 x 0.5 degrees (50 km), 0.1 x 0.1 degrees (10 km) and so on, as fine as the user requires.
Who can benefit from using c-squares?
Anyone interested in the storage, exchange, and retrieval of data or information with a geographic component, who does not wish to go to the level of sophistication of a fully fledged geographic information system (GIS) merely to be able to search their data holdings by geographic location...
Why not simply store, and quote, latitude and longitude values with a particular data item?
Individual values of latitude and longitude can be, and in most cases would continue to be, stored with particular data items (georeferenced objects). C-squares provides an additional level of functionality over and above these "native" values, in several respects:
(i) the system reduces latitude and longitude (2 dimensional variable) to a single dimensional variable, for easy indexing and subsequent searching
(ii) the system reduces redundancy for multi-point data which occur within a single square (a single code indicating "data present" replaces multiple individual values, for metadata-level information)...

Hybrid static/dynamic Google Map

Ever noticed that when you go to maps.google.com and do a search (say, car wash), it renders a lot of results (represented by small circles) and a few prominent ones (seen as regular-size pins)?
Notice how quickly it does this?
From what I can tell from analyzing this in Firebug, much of this is generated on the server and sent to the client as a static image.
However, it's still dynamic. You can still zoom in and out, or click on a result and see a dynamic InfoWindow rendered.
Google have made the map quick and smooth using static images, while still making it flexible.
Is there a way to do this kind of 'pre-loading' with my own Google Map (implemented with the Google Maps API)?
The technology that maps.google.com uses is similar to that used in a GLayer. The server dynamically builds tiles and "hotspot" info. The GLayer tiles are also constructed dynamically (and possibly cached) even though the underlying data is fairly static. From the client side, the searched dots technology is identical to the Wikipedia or Panoramio GLayer. The only new trick is that the dot information is generated dynamically on Google's big fast servers.
The API does not (yet) provide any tools for creating custom GLayers. If you want to do the same sort of thing yourself, using your own database of locations, there are three steps that you need to code:
Create your own custom tileserver
which searches your database for
items in the tile area and uses a
graphics library like gd or
imagemagic to place dots on the
tile. Use those tiles to create a
GTileLayerOverlay on the client.
When the user clicks on the map,
send the location of that click to a
second server. That server should
check your database and return the
infowindow text for the dot at that
location, if any. Returning all the infowindow contents from all the dots imaged by the tileserver would be unacceptably slow, so you have to fetch them one by one, as needed.
Changing the cursor when the mouse
is over a dot is more tricky. What Google
do is return a list of hotspot
coordinates for all the dots on each
tile. Whenever the mouse moves, the
API determines which tile the
pointer is over and uses a quadtree
algorithm to see if the pointer is
over a hotspot, and change the
cursor if necessary. If you only
have a modest number of hotspots per
tile, then a linear search would
probably be acceptably fast. If you might have thousands of dots per tile, then you'll probably need to write your own quadtree algorithm. The Google quadtree code is not exposed, so you can't use it.
Here's a page where somebody has done all that. In this case the hotspots are calculated as circles, by comparing the distance from the centre point, even though the dots are square. On maps.google.com the hotspots are calculated as rectangles, by using GBounds.containsPoint(), even though the dots are round.
I'm doing something similar - but instead using a tile layer, I just send server-clustered markers to the browser whenever the view changes. If your data is static, you can pre-cluster your markers and it would be incredibly fast with tens of thousands of markers.
Our site can't use pre-clustering because the markers can be searched and filtered, but it's still pretty fast up to about 20,000 markers. Still working on it...

Categories