I am currently working on a University project and I am going to create a hitch hiking mobile app. I am looking to use phonegap and Javascript on the front end and laravel as my RESTFUL API. I have looked at he Google maps API documentation but I have still not seen a plugin for Laravel which allows GPS route details to be stored on the backend in laravel.
I presume the mapping of routes between drivers and hitch hikers will need to be done on the server as details of all routes (journeys) will need to be stored and for searching.
Has anyone ever worked on a similar hitch hiking project and how would you check if a hitch hicker's route matches with a Driver's route. Surely this mapping must be done on the server and is there any API for Laravel that supports this?
My interpretation to how your service will work is that both hitch hikers and drivers will state their current location and their intended destination, and hitch hikers will be able to request rides based on matching routes/destinations (which is a pretty cool idea actually).
Based on that interpretation, here's how I might go about implementing it.
1. Create a Journey
A Journey model would be a the journey the user wishes to make. It would be comprised of many Waypoint models (at least 2, the minimum being the start and end points).
There would be a one-to-many relationship between a Journey and Waypoint.
A user creates a Journey and you use the Google Maps Directions API to store the Waypoints for it.
2. Periodically update a user's location
A user will eventually move between waypoints. When they do, you want to know where they are so you can update their position so that they're able to be accurately represented on a map of active users (I imagine you'll have one, displaying the locations of various Drivers and Hitchhikers, similar to Uber).
3. Match users based on similar waypoints
Use the waypoint data you have stored against a driver and hitchhiker's routes to find similar routes/journeys and make suggestions as to which hitchhikers a driver may pick up. You can even use the API data to give estimated times of pickup based on the distance between the driver and the hitchhiker.
There's more to consider, but that'd be a pretty decent starting point.
You would want to think about re-routing (what if a user can't go between certain waypoints due to roadworks, or perhaps they take a wrong turn - think about how your SatNav might handle it), perhaps the ability to plan trips in advance, etc.
To actually answer your questions, yes, if you wanted to use Laravel for this you'd map the routes and match the waypoints server-side.
Let's take the scenario where I am a hitchhiker.
I want to get from A to G.
I'm currently at waypoint C
Driver X is on another route which happens to have my waypoints C, D, and E in it. To find Driver X, you could do something like (pseudocode):
// Find a driver with similar waypoints
Driver::withSimilarWaypoints($myJourney->remainingWaypoints())->all();
// withSimilarWaypoints scope
function scopeWithSimilarWaypoints($waypointsCollection)
{
$query->whereHas('waypoints', function ($query) use ($waypointsCollection) {
$query->where('passed', 0)->whereIn('waypoint_identifier', $waypointsCollection->pluck('waypoint_identifier'));
}
}
In this case waypoint_identifier would have to be the same for me and Driver X, so perhaps a hash of the waypoint object or you could use place_id as returned by the API.
You'd also want to make sure you're not matching against waypoints you've both already passed (hence remainingWaypoints() and where('passed', 0).
Driver X is estimated to arrive at waypoint C in 8 minutes, so I decide to wait for them (or I can request a lift via the app)
All that should be a pretty decent jumping off point for your service. I quite like the idea – good luck!
Related
I'm using the MapBox directions API to show and calculate the distance between several waypoints. The thing is, this routes are for big trucks, and MapBox generates a route where big trucks can't go through (A tiny one way bridge). Legally, only cars can go through. Is there a way to tell the direction's API to skip that bridge and generate an alternative, longer route?
The only exclusion options currently available in the Mapbox Directions API are for ferries, tolls, and motorways. You can not exclude with waypoints or areas at this time. Where available, Alternative routes may be requested by passing the alternatives=true parameter. If you wish to create custom routes, use the Map Matching API to make a request that will snap your desired coordinates to parts of the network you wish to route on.
I'm creating a trip planner application using rails 4, coffeescript, the Google Maps API, and jquery. On our trip planner page, we let users link multiple destinations together on a Google map, and save the trip to their account if they want.
We have 3 main models we are working with:
Trips - contains the name of the trip, start and end dates
Destinations - locations on the map, identified by a name and geo coordinates (lat/long). Destinations are not directly linked to a trip.
DestinationOrders - this is the table contains the order of destinations in a trip (like a linked list). The columns are trip_id, destination_id, and order_authority. Order_authority will be a number we use to sort the order of destinations using the method described here.
A typical set of actions on the page are:
Load the google map
Select the first destination using Google's places autocomplete functionality (javascript). Add a marker to the Google Map for the first destination
Add a second destination, place the marker, link the two destinations with a path
Add a third destination, place the marker, link destinations 2 and destination 3 with a path
User clicks 'Save' to store the trip in his account
We are fairly new to rails and I'm wondering the best way to approach this given the back and forth between javascript, the controller, and the model. We don't want to associate the trip to his account until he click save.
Possible approaches we've thought of:
Do we create new instances of the models, then when the user clicks save, save all of the instances to the database? The problem here is when trying to create the DestinationOrder, as it requires a trip id and a destination id which have not been created yet. Using our steps above, this would be something like:
trip = Trip.new
Send location information (place) to controller via Ajax, then:
firstDestination = Destination.new (name: place.name, lat: place.geometry.location.lat, long: place.geometry.location.long)
firstDestOrder = DestinationOrder.new
Another possible (naive) solution would be to keep everything stored in javascript variables until the user clicks save, then send an ajax request with all of the destinations in order and create the models.
Finally, we thought of the possibility of creating and saving trips and destinations as the user goes along. That is, when a user first gets to the page, a trip would be created and saved. When the user adds a destination, that destination would be saved as well. This allows us to pass DestinationOrder those id, and if the user clicks save, we would associate the trip_id with his account. However, if the user left the site mid-creation, this would create a zombie trip with no associated user, and would require some process to clean these up every-so-often.
What is the most efficient way to approach a situation like this? I hope my explanation makes sense - please let me know if I need to clarify. Any help is appreciated!
I think your schema is a bit weird. Seems like what you really want to do is create Trips that are associated with destinations and each one of those destinations has and order. What you are really looking for is a has many through associations, this will give you the flexibility of adding the order attribute on the join table.
A Trip has many Destinations through DestinationOrder, that way DestinationOrder serves as the glue (join model) between the Destination Model ad the Trip model. It seems like that is what you are trying to do but you never quite said the name of the association so I thought i'd clarify that.
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
Now to the order of operation.
As the user creates a trip, I would save that trip.
Once that trip is created you can start adding destinations to it.
Yes tou could potentially create trips without destinations but that gives the user the ability to come back and keep filling out the trip. Trips are something that take a long time to plan, so I thin it is fine to create the trip even if it does not have any destinations and then add destinations as they are created.
See this for reference How to save data with has_many :through
Hope that helps some.
I'm building a custom admin dashboard for users on our site who create posts. I want to show them the active amount of visitors on their posts only (not on the entire site).
I want it to act exactly like GA does it:
I was originally thinking of building this from scratch, but in retrospect it might be easier to use the GA API?
I've stared at the docs for forever and I'm just not groking it, so I'm coming here for help.
We have ~5,000 posts total, and I some people on our site have authored over 1000 posts, so the 'input' to GA will be anywhere from 1 to 1000+ slugs (for only their posts).
I want a combined amount of on-site traffic for their posts only.
Optionally, maybe it would have to be reversed... I'm not sure if GA can show it, but even better probably would be to get a content breakdown of the realtime visitors from the API, with 5000 max results. From there I can filter through the result set slugs (along with then number of users on each), and compare those results to each slug which belongs to that user, then just sum the totals on my end.
Is this something the Google API could help me with? which API endpoint would I need to use? Is it possible to have 5000+ max results for URLs with traffic on them from the API?
Thanks!
Yes, it is possible.
It seems that you should utilize Real Time Data: get endpoint.
Additionally, to limit results for specific pages (posts) only, you should use dimension filters (filters which will select only specific page views before calculating aggregated result), and 'ga:pagePath' looks like the one you need:
ga:pagePath
UI Name: Page
A page on your website specified by path and/or query parameters. Use in conjunction with hostname to get the full URL of the page.
Source
You might prefer using ga:pageTitle instead, if you have similar title for posts of a single author, and you haven't got common path elements in posts of the same author.
So you do something like:
GET https://www.googleapis.com/analytics/v3/data/realtime
ids=ga:<your_analytics_id>
metrics=rt:activeUsers
dimensions=rt:pagePath
filters=rt:pagePath=~/authors/123/*
Please notice that there maybe slight difference in real time and non-realtime API (e.g. use of 'rt' instead of 'ga' above), and generally realtime-API is still in beta.
Generally speaking, you should go here: Real Time Reporting API - Developer Guide and look through the links in the table of contents (left part of the page).
What about 'building from scratch' idea: it's rather simple from the developer's perspective, but it could be complex from the dev-ops perspective. I.e., it's not a problem to write code which would aggregate such metrics. But it could be a problem to make a system which will sustain required for that task amount of requests per second.
I think you will want to apply your second approach: pull down realtime visitors for all slugs and then aggregate by author on your own server.
There is a quota of 10,000 queries per profile per day. Using your first approach, it sounds like you would be performing a query for each author. Say you have 50 authors. This would leave you only 20 queries/day/author (10,000/50). Factoring in the time dimension, this would allow you only 8.33 (200/24) queries per hour for each author. Not very "realtime like".
If you have problems getting it going, check out http://www.embeddedanalytics.com - we have done many implementations such as this. In fact, we even have hat "Right Now" realtime widget.
Is there a way to determine the author based on the slug title?
Using the Nokia Here (Javascript) API, is it possible to have a Polyline - defined by a relatively sparse but potentially large set of coordinates - snap to roads without making a route query?
If you are unable to positively surprise me, and this is not possible as I assume, any additional suggestions for achieving the same result with a minimum amount of routing queries (or other approach you find 'optimal')? Thus far I am thinking of dividing the coordinate sets into smaller sets if required, getting the route for them separately, then combining the data of the resulting Shapes (Strips) and caching it all in a database for later display..
If you are using the Enterprise Routing API you could do the following:
1) Make a series of routing requests to HERE from your point A to your point B using the manueverattribute=none&routeattributes=none parameters in the request which suppresses unwanted information. Store the routeId in your database:
http://route.st.nlp.nokia.com/routing/6.2/calculateroute.json?...&manueverattribute=none&routeattributes=none&app_id=YOUR_APP_ID&app_code=YOUR_APP_CODE .
2) When a user queries your sparse database from from your point A to your point B , retrieve the routeId from your database and make a query to HERE using the getroute endpoint passing in the id from previous request as shown:
http://route.st.nlp.nokia.com/routing/6.2/getroute.json?routeid=your_route_id&app_id=your_app_id&app_code=your_app_code&manueverattribute=none&routeattributes=shape
This way you can get away with storing the minimal amount of information yourself - i.e. a matrix of all possible start points against all possible end points, and use the RESTful routing API to do all the intermediate calculations.
Im working with the google-mapquest mapping API. I need to add some Points of Interest near a certain area from a given latitude-longitude location.
I search the google and mapquest documentation to figure out if there is a method to get all zip-codes in that area but i didnt find anything that does that.
I tried the harvesine implementation to calculate the nearest point given in that radiuos/latitude-longitude and it works fine. The problem with this approach is that i need to update constatntly the database, so i dont like it much.
The question is: Is there a service (google-mapquest or another) that gives you this information?.
No, there is no API for either service that I am aware of. Your best bet is to just get a ZIP Code database and use that. Some really good inexpensive ones are out there. I prefer http://www.zip-codes.com/zip-code-database.asp. Their $40 package is very accurate, updated monthly, and licensed by the USPS (so you know it's quality data).
UPDATE:
I found a WebService that does exactly what i need. You could provide only a simple ZipCode and a country or perhaps a full address and in the response you get the longitude/latitude. Then i send the Latitude and Longitude returned to get a list of all the ZipCodes near the provided coordinates and a given Radius that also can be customized.
You can filter the total rows you want the service to return, or even if you are gonna use miles or kilometers as the measure unit.
So, basically with the returned information, i feed those coordinates for each of the nearest ZipCodes obtained to the google API and render those points of interest into the map that you need to show.
The services are provided by GeoNames. Its an organization dedicated to Geolocalization services. They offer also premium data, but in particular these services are free of use, obviously the information is not as accurate as the premium one, but actually in my tests i found that that is trustful and the response also is very fast.
Another good advantage is that the process to get a Key for use Geonames services it's quite simple.
I left you the link of the services that i'm talking about.
List of available services:
http://www.geonames.org/export/web-services.html
Hope it helps many people.
Regards!