How to implement a geo route fence - mongodb

Say I keep getting a set of Geo coordinates from a moving vehicle.
There is a predefined route that the vehicle needs to follow from Point A to Point B.
The route will be defined by giving the user the option to select points A and B and also selecting the WayPoints in between and letting the Google API select the best route.
As the vehicle moves I need to check whether the vehicle has deviated more than 50 m from the predefined route.
My solution (not fully tested)
When the user has selected the start and the end points and the waypoints in between, I can make a call to the Google Directions API which would give me all the points on the road in between
(The polyline property inside the steps gives you the exact points on the road which the UI uses to draw the lines. You can call the following URL to see the polyline response
https://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&destination=Concord,MA&waypoints=Charlestown,MA|Lexington,MA
)
and store these points in some database (Mongo) with a route id.
When I get the geo cordinates from the vehicle I can make a query to Mongo asking for all those points with the route id and whose distance is less than 50m from the vehicle coordinates. And if there are non then the vehicle has deviated from the route.
Is there a better way of doing this?

Related

How to compute bounding boxes of specific roads from Overpass api

I have a high volume dataset with keys like this:
lat:6.897585,
long:52.785805,
speed:12,
bearing:144
Basically it is a dataset of records of various trips on cars. The data was stored every few seconds during each trip. The main goal of this project is to be able to visualize only u-turns (turn arounds) on a map. But for now, I am trying to at least show the data on specifc roads. For that, I am using Overpass API
With the help of Overpass Turbo, I can get a dataset with all the roads I need.
However, in the dataset, the road's geometry is represented with LineString type.
My question is, How can I get a bounding box(es) of the roads from Overpass API, so later on, I can display events that happened only on the given roads? Or maybe you have a better solution on how to achieve this?
A bounding box wouldn't be very helpful here, as using it to filter your points would show everything that falls within the box (which could include other nearby roads)
It sounds like getting a buffer around a linestring might get you closer, but could still include points that are within the buffer but not on the road you are inspecting.
The smarter way to do this would be to assign each event to a road segment using some logic based on their attributes/properties, so you don't have to depend on a spatial filter.

Finding the next intersection on the current street by using OpenStreetMap

I'm new to OSM and would like to know if my approach for finding the next intersection ahead is possible when doing it offline.
The goal is to get the coordinates (latitude/longitude) of the next intersection on the street I'm currently driving on. For that I have my actual position (lat/lon coordinates) and heading (w.r.t. the north-pole) at disposition.
My current approach right now is to first use my coordinates for getting the name of the street/way/trace in which I am driving; then use that name for knowing which are the next intersections on that street (to both sides); and then use the heading for knowing which direction is the one I should pay attention to.
Once I have the intersection, I would get its coordinates and continue with the program.
My questions are then, is it possible to do all of that offline, i.e. with a .osm file (or similar)?
And, do you know a better approach for getting the coordinates of the next intersection ahead?
Thanks a lot in advance!
PS. I was able to get the name of the street by using nominatim and to get all the intersections of a street by using Overpass turbo, but this solutions would need internet; or is there a way of using them offline?

Creating a Dynamic Google Earth Web Link

I've been tasked with creating a Google Earth Web link programmatically when given coordinates. I have the street address as well, where I'd ideally like to drop a pin.
For example, I can get a link to the white house using its lat/lon at a distance of 150 meters like this:
https://earth.google.com/web/#38.8976633,-77.0365739,150d
If I search using the google earth web app I can generate a link with a pin, where a few of the parameters in the link change slightly:
https://earth.google.com/web/#38.8976763,-77.0365298,18.0497095a,800.41606338d,35y,0h,45t,0r/data=ChIaEAoIL20vMDgxc3EYAiABKAIoAg
Am I able to dynamically generate the data element, or whichever element creates the pin, at my desired location? I've also had trouble finding the correct distance d and elevation a parameters in my links.
As you found, you can generate links to specific views in the Google Earth web client by adding the correct parameters to the URL, including the latitude, longitude and altitude (a) of the view target, and the distance (d) of the camera from that target. Note that altitude and distance are both in meters, and altitude is above sea level, not above ground elevation. If you look at the a and d parameters that Earth puts in the URL as you fly around, often altitude will be the terrain (or builing-top) elevation at the target lat/lon, and the distance will be how far the camera is from that altitude. The other available parameters include heading (h) and roll (r).
So long as your tilt (t) remains zero, then altitude and distance should be interchangeable, or if both are >0, then they will be summed together for the final camera height above sea level. But if you add a tilt (zero degrees is looking straight down), then the altitude determines the elevation of the view target (above the lat & lon location), and the distance determines how far the camera is from that point. If you make d=0, then altitude will define both the view target and camera height above sea level. If you make a=0, then the distance will be from the lat,lon at sea level (even if that's underground).
Unfortunately there's no way to manually construct the data parameter, as it can contain many different things. To do that right would require an API, which Earth for Web currently does not provide. Hopefully that kind of functionality will come after Earth finishes its work to become cross-browser compatible via Web Assembly. Until then, there's not a way to add a point the map via just a URL.

Framework for plotting latitude longitude in a map based on country, state and district depending on the zoom level

I need a framework which takes a set of latitude longitude points and plots on a world map, grouped by country having the count of points as a marker on each country. Grouping here is the count of latitude longitude points in a country.
And as I drill down into a country, the clustering should change to state based one. And the next level, to districts.
Leaflet marker cluster is something very similar to what I have asked for, but the grouping is based on proximity and it doesn't consider country or state boundaries. That is, they are not region aware.
Regionbound.com has tweaked in some code in the leaflet code for making it region aware,
Sample marker definition:
var marker1 = new L.marker([-37.8, 145], {regions: ["Asia-Pac", "Australia", "VIC", "Melbourne"]} );
But the sample code says, every latitude longitude must be defined along with some extra parameter containing place information.
I could get the place information using reverse geocoding, but reverse geocoding every latitude longitude is time consuming right.
Highmaps provided by Highcharts is one another solution, but there, every country has code which should be assigned a value[count of point coordinates belonging to that country].
But all I have is latitude longitude points, no country or state information.
Thus, I need something which takes only a set of latitude longitude and does clustering based on country, state, district depending on the zoom level.
You have 2 separate needs in your questions:
Map your lat/lng coordinates to appropriate administrative areas. E.g. through the reverse geocoding that you mention.
Display "clusters" on those administrative areas depending on zoom level.
As for point 1, you know that lat/lng points do not say by themselves which administrative area(s) they belong to. So "reverse geocoding every latitude longitude" is a mandatory step. Whether time consuming or not depends on the solution you choose to perform this operation.
If I understand correctly, you would like a "framework" that could do that automatically for you. But frameworks are usually data agnostic, and if they do not have data about boundaries of those administrative areas, they cannot help you.
You may rather look for "services" (like the Mapbox Geocoding API that you mention) or software that would already have such data. It is not time consuming if you can program the lookup (or perform "bulk" operations) and if you are not limited by the requests rate and your amount of points to map (which may be the case with Mapbox).
You could very well set up your own application to perform this mapping:
As for the dataset for administrative areas boundaries, you would probably be interested in links in this post: Are there any free administrative boundaries available as shapefiles? If your points are limited to a few countries, it will be easier for you to find the appropriate data source(s).
Once you have that data, many GIS software should be capable of mapping your lat/lng points to the areas they belong to. This would be mainly for a "one-shot" operation, if your set of points do not change much.
A "web-compatible" alternative would be for example to use Leaflet with point in polygon for Leaflet plugin. You would need your boundaries data converted to GeoJSON format first. Again, GIS software should be capable of doing so, or many online services as well (search for "convert geojson" for example).
A server-side solution would avoid having to manage the entire boundaries data through network and in client browser (if you need to perform the mapping dynamically). I am sure many GIS servers are capable of performing this operation, once they are fed with the boundaries data.
For point 2, once you have completed the above step, I think you would have many options available, including those you mention (RegionBound, Highmaps).
Even with standard mapping libraries (Leaflet, OpenLayers 3), you would just need to build your "clusters" (markers on administrative areas with a number saying how many points are in there), like you have to do with Highmaps anyway for example.
Computing the number of "clustered" point is as easy as filtering your points per area name / code. Then switch the clusters to the desired administrative level when the map zoom changes.
So the key is really to determine first to which areas your points belong to (point 1).
Then a small question would rise about where to place the "cluster" marker:
On centroid of the administrative area? You need the coordinates of that centroid from your data source, or a good algorithm to compute it from the boundaries (good luck on that…).
On "center" of the bounding box of the area? Leaflet can easily compute that: from your area vector shape, you would do myShape.getBounds().getCenter().
On barycentre / centroid of the clustered points? This is what Leaflet.markercluster and RegionBound do (do not know for Highmaps).
Good luck!

Google maps snap to road for walking - Swift

I have an iOS app that is using the Google Maps SDK. I track a user as they walk or run then use those coordinates to plot their course along the road using snap to roads.
I have found however the snap to roads uses the direction of the road to plot the course so when it comes to roundabouts the course follows this around even if the user was on the inside of the block.
Is there a way to use snap to roads (or directions) that allows for walking tracks and follows the shortest distance?
Thanks
Looking at the documentation, snap to road is not for walking...
The snapToRoads method takes up to 100 GPS points collected along a route, and returns a similar set of data, with the points snapped to the most likely roads the vehicle was traveling along.
but well.. what you can do it to compare the points, and if the returned points are "some" distance faraway then the original point, you know that this points should be inside the block.