Is there a way to use geokit in rails to get the estimated travel time between two locations? Right now, I'm simply showing the distance away but I think a better approach would be to show '15 minutes away' -- gives it a more practical approach to distance (sometimes 2 miles is 10 minutes and sometimes its 3)
A better solution would be to use the Google Maps Directions API using the API is as simple as calling the following URL http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false.
Which returns this JSON:
{
"status": "OK",
"routes": [ {
"summary": "I-40 W",
"legs": [ {
"steps": [ {
"travel_mode": "DRIVING",
"start_location": {
"lat": 41.8507300,
"lng": -87.6512600
},
"end_location": {
"lat": 41.8525800,
"lng": -87.6514100
},
"polyline": {
"points": "a~l~Fjk~uOwHJy#P",
"levels": "B?B"
},
"duration": {
"value": 19,
"text": "1 min"
},
"html_instructions": "Head \u003cb\u003enorth\u003c/b\u003e on \u003cb\u003eS Morgan St\u003c/b\u003e toward \u003cb\u003eW Cermak Rd\u003c/b\u003e",
"distance": {
"value": 207,
"text": "0.1 mi"
}
},
...
... additional steps of this leg
...
... additional legs of this route
"duration": {
"value": 74384,
"text": "20 hours 40 mins"
},
"distance": {
"value": 2137146,
"text": "1,328 mi"
},
"start_location": {
"lat": 35.4675602,
"lng": -97.5164276
},
"end_location": {
"lat": 34.0522342,
"lng": -118.2436849
},
"start_address": "Oklahoma City, OK, USA",
"end_address": "Los Angeles, CA, USA"
} ],
"copyrights": "Map data ©2010 Google, Sanborn",
"overview_polyline": {
"points": "a~l~Fjk~uOnzh#vlbBtc~#tsE`vnApw{A`dw#~w\\|tNtqf#l{Yd_Fblh#rxo#b}#xxSfytAblk#xxaBeJxlcBb~t#zbh#jc|Bx}C`rv#rw|#rlhA~dVzeo#vrSnc}Axf]fjz#xfFbw~#dz{A~d{A|zOxbrBbdUvpo#`cFp~xBc`Hk#nurDznmFfwMbwz#bbl#lq~#loPpxq#bw_#v|{CbtY~jGqeMb{iF|n\\~mbDzeVh_Wr|Efc\\x`Ij{kE}mAb~uF{cNd}xBjp]fulBiwJpgg#|kHntyArpb#bijCk_Kv~eGyqTj_|#`uV`k|DcsNdwxAott#r}q#_gc#nu`CnvHx`k#dse#j|p#zpiAp|gEicy#`omFvaErfo#igQxnlApqGze~AsyRzrjAb__#ftyB}pIlo_BflmA~yQftNboWzoAlzp#mz`#|}_#fda#jakEitAn{fB_a]lexClshBtmqAdmY_hLxiZd~XtaBndgC",
"levels": "BBBAAAAABAABAAAAAABBAAABBAAAABBAAABABAAABABBAABAABAAAABABABABBABAABB"
},
"warnings": [ ],
"waypoint_order": [ 0, 1 ],
"bounds": {
"southwest": {
"lat": 34.0523600,
"lng": -118.2435600
},
"northeast": {
"lat": 41.8781100,
"lng": -87.6297900
}
}
} ]
}
Then parse the JSON returned to grab the duration.text and display it on your page.
You may have to comply with terms of service in order to use this API so make sure you read up on googles requirements and how they affect the use of the service.
Related
I have a Google Sheet with a list of image URLs.
First column : image URLs.
Second column : tags describing the image (for example: "landscape, mountain, field, sunset, lake" for a landscape image with a mountain, field, sunset, etc...)
I would like to fill automatically my column 2 with a formula like "ImageTags(ImageUrl)".
Are there any formula, extension or script (already available :) ) for that?
Thanks !
An option is to use Google Cloud Vision API to label your images. You can test the API to decide whether it suits your needs or not here.
There are two tutorials using Google Apps Script to call the API that can help you develop the exact code that you need:
Using a service account to authenticate, detect labels and send a GMail message
Using oAuth2 to authenticate and label images
As an example, using the following image:
And calling the API with the following parameters:
HTTP Request
POST https://vision.googleapis.com/v1/images:annotate
Body
{
"requests": [
{
"image": {
"source": {
"imageUri": "https://i.stack.imgur.com/4vwKt.jpg"
}
},
"features": [
{
"type": "LABEL_DETECTION"
}
]
}
]
}
You obtain the following result (5 Nov 2019):
{
"responses": [
{
"labelAnnotations": [
{
"mid": "/m/09j06",
"description": "Hot air balloon",
"score": 0.9889263,
"topicality": 0.9889263
},
{
"mid": "/m/01j51",
"description": "Balloon",
"score": 0.95322704,
"topicality": 0.95322704
},
{
"mid": "/m/02p81ht",
"description": "Hot air ballooning",
"score": 0.9223063,
"topicality": 0.9223063
},
{
"mid": "/m/0cmqr_4",
"description": "Party supply",
"score": 0.9016293,
"topicality": 0.9016293
},
{
"mid": "/m/01d40f",
"description": "Dress",
"score": 0.86037284,
"topicality": 0.86037284
},
{
"mid": "/m/07yv9",
"description": "Vehicle",
"score": 0.7725018,
"topicality": 0.7725018
},
{
"mid": "/m/01bqvp",
"description": "Sky",
"score": 0.7326111,
"topicality": 0.7326111
},
{
"mid": "/m/0ds99lh",
"description": "Fun",
"score": 0.7039424,
"topicality": 0.7039424
},
{
"mid": "/m/016pp7",
"description": "Happy",
"score": 0.6789371,
"topicality": 0.6789371
},
{
"mid": "/m/06bm2",
"description": "Recreation",
"score": 0.6695586,
"topicality": 0.6695586
}
]
}
]
}
Microsoft Graph API
Findmeeting times api
what happens when meeting time is less than 30mins(like 10mins)?Because Findmeeting Times search only for every 30 mins. It does not search times in between. For example I want for 10 mins meeting with someone 8 to 10. It returns 8.00 t0 8.10 and 8.30 to 8.40.Why can't it return 8.10 t0 8.20 and 8.20 to 8.30 ?Here is the inputs and outputs
Input
{
"attendees": [
{
"type": "required",
"emailAddress": {
"address": "kumar.muthu#mic123.com",
"name": "kumar muthu"
},
}
],
"timeConstraint": {
"activityDomain": "unrestricted",
"timeslots": [
{
"start": {
"dateTime": "2018-03-27T18:00:00",
"timeZone": "India Standard Time"
},
"end": {
"dateTime": "2018-03-27T18:30:00",
"timeZone": "India Standard Time"
}
}
]
},
"meetingDuration": "PT0H10M"
}
Output
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.meetingTimeSuggestionsResult",
"emptySuggestionsReason": "",
"meetingTimeSuggestions": [
{
"confidence": 100,
"organizerAvailability": "free",
"meetingTimeSlot": {
"start": {
"dateTime": "2018-03-27T18:00:00.0000000",
"timeZone": "India Standard Time"
},
"end": {
"dateTime": "2018-03-27T18:10:00.0000000",
"timeZone": "India Standard Time"
}
},
"attendeeAvailability": [
{
"availability": "free",
"attendee": {
"type": "required",
"emailAddress": {
"address": "kumar.muthu#mic123.com"
}
}
}
],
"locations": [
{
"displayName": "RM-CHN-Training-Room1",
"locationEmailAddress": "RM-Chennai.Trainning-Room1#mic123.com"
},
{
"displayName": "DEV BAY",
"locationEmailAddress": ""
},
{
"displayName": "Conference room near Security",
"locationEmailAddress": ""
},
{
"displayName": "Any Phone Booth or WebEx",
"locationEmailAddress": ""
},
{
"displayName": "Austin",
"locationEmailAddress": ""
}
]
}
]
}
why it doesn't send timings between 8.10 to 8.30
I can't tell you why the limitation is there. It's not documented in the Find meeting times API documentation. But Outlook, which presumably uses the same or a similar API, has the limitation in the UI as well:
I can see that your filter for 10minutes worked, now the results appear limited due to some default filters applied, try adding these params and play with the results.
"isOrganizerOptional": "true",
"returnSuggestionReasons": "true",
"minimumAttendeePercentage": "100"
Hope it helped.
All Measurements came with a time-stamp (event time) of when the measurement was created. Some of these measurements are artificial ones, meaning that they are not created by the device itself, but by a CEP rule running inside the CoT.
The "normal" measurements have the time format coded as UTC
[{
"id": "12704547",
"data": {
"data": {
"time": "2016-07-25T15:24:11.000Z",
"id": "1152930",
"self": "http://testTenant.c8y.com/measurement/measurements/1152930",
"source": {
"id": "222812",
"self": "http://testTenant.c8y.com/inventory/managedObjects/222812"
},
"type": "tsystems_cumulocity_energymeter_digital_ping",
"Energieverbrauch": {
"Ping": {
"unit": "Wh",
"value": 1
}
}
},
"realtimeAction": "CREATE"
},
"channel": "/measurements/222812"
}, {
"successful": true,
"channel": "/meta/connect"
}]
But the "artificial" measurements (created by the CEP rule) use a timestamp with local time
[{
"id": "12704578",
"data": {
"data": {
"time": "2016-07-25T17:24:00.952+02:00",
"id": "1152931",
"self": "http://testTenant.c8y.com/measurement/measurements/1152931",
"source": {
"id": "222812",
"self": "http://testTenant.c8y.com/inventory/managedObjects/222812"
},
"type": "tsystems_cumulocity_energymeter_power_consumption",
"Leistung": {
"Aggregation_1min": {
"unit": "W",
"value": 900
}
}
},
"realtimeAction": "CREATE"
},
"channel": "/measurements/222812"
}]
The measurements from one device should always be encoded with the same timezone (UTC preferred) as different timezone can create problems in clients using that data.
I create the 'time' in the CEP with
current_timestamp().toDate() as time
please use:
com.cumulocity.model.util.DateTimeUtils.newUTC(current_timestamp().toDate()) as dateTime,
instead of
current_timestamp().toDate() as time
in your cep rule.
Best regards,
Arkadiusz
Cumulocity Support Team
I created a bill through the QuickBooks Online (QBO) web UI. Then I queried using the API (v3, documented here). The response:
{
"SyncToken": "16",
"domain": "QBO",
"VendorRef": {
"name": "MyVendor",
"value": "237"
},
"TxnDate": "2014-12-07",
"TotalAmt": 1.83,
"CurrencyRef": {
"name": "United States Dollar",
"value": "USD"
},
"PayType": "Check",
"PrivateNote": "test billpayment description (mod)",
"sparse": false,
"Line": [
{
"Amount": 1.22,
"LinkedTxn": [
{
"TxnId": "1412",
"TxnType": "Bill"
}
]
}
],
"Id": "1413",
"CheckPayment": {
"PrintStatus": "NeedToPrint",
"BankAccountRef": {
"name": "MyBankAcct#1234",
"value": "137"
}
},
"MetaData": {
"CreateTime": "2014-12-07T18:44:51-08:00",
"LastUpdatedTime": "2014-12-10T20:20:28-08:00"
}
}
As you can see, it has $0.61 of the TotalAmt unapplied to any Bills. (The other $1.22 is applied to Bill 1412.) Now, when I try to update this bill to change JUST the amount applied to the linked transaction, I get unexpected results.
Here's the update request body:
{
"SyncToken": "16",
"domain": "QBO",
"VendorRef": {
"name": "MyVendor",
"value": "237"
},
"TxnDate": "2014-12-07",
"TotalAmt": 1.83,
"CurrencyRef": {
"name": "United States Dollar",
"value": "USD"
},
"PayType": "Check",
"PrivateNote": "test billpayment description (mod)",
"sparse": false,
"Line": [
{
"Amount": 1.21,
"LinkedTxn": [
{
"TxnId": "1412",
"TxnType": "Bill"
}
]
}
],
"Id": "1413",
"CheckPayment": {
"PrintStatus": "NeedToPrint",
"BankAccountRef": {
"name": "MyBankAcct#1234",
"value": "137"
}
},
"MetaData": {
"CreateTime": "2014-12-07T18:44:51-08:00",
"LastUpdatedTime": "2014-12-10T20:20:28-08:00"
}
}
In the response, it appears that the API just basically can't handle the situation (even though it clearly existed when I created it in the web UI). Look what happens to the TotalAmt attribute! It's reduced to whatever the payment was in the LinkedTxn:
{
"BillPayment": {
"VendorRef": {
"value": "237",
"name": "MyVendor"
},
"PayType": "Check",
"CheckPayment": {
"BankAccountRef": {
"value": "137",
"name": "MyBankAcct#1234"
},
"PrintStatus": "NeedToPrint"
},
"TotalAmt": 1.21,
"domain": "QBO",
"sparse": false,
"Id": "1413",
"SyncToken": "17",
"MetaData": {
"CreateTime": "2014-12-07T18:44:51-08:00",
"LastUpdatedTime": "2014-12-10T20:25:02-08:00"
},
"TxnDate": "2014-12-07",
"CurrencyRef": {
"value": "USD",
"name": "United States Dollar"
},
"PrivateNote": "test billpayment description (mod)",
"Line": [
{
"Amount": 1.21,
"LinkedTxn": [
{
"TxnId": "1412",
"TxnType": "Bill"
}
]
}
]
},
"time": "2014-12-10T20:25:01.91-08:00"
}
I don't see discussion of this on the known issues page, so I'm pretty confused.
If you have any suggestions as to how to get this to do what I want it to, I thank you for your thoughts!
I'm having problems extracting values in a response hash from a call to google image search API.
I only want the value from the url key from each result.
I figured i'd call deep_symbolize_keys on the response and do something like hash.results.url , which doesn't work. I feel like i'm doing something stupid, so any pointers are welcome.
CONTROLLER CODE
_url = 'http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=fuzzy%20monkey'
_response = Net::HTTP.get_response(URI.parse(_url))
#response_hash = JSON.parse _response.body
RESPONSE HASH BEFORE KEYED STORED IN #response_hash
"responseData": {
"results": [
{
"GsearchResultClass": "GimageSearch",
"width": "1152",
"height": "864",
"imageId": "ANd9GcQQigy-U6KTXke82n5hma5qvFM2UyVnkGtJme6pkZgl_1GYM--Yb90oqnOJ",
"tbWidth": "150",
"tbHeight": "113",
"unescapedUrl": "http://www.blirk.net/wallpapers/1152x864/fuzzy-monkey-1.jpg",
"url": "http://www.blirk.net/wallpapers/1152x864/fuzzy-monkey-1.jpg",
"visibleUrl": "www.blirk.net",
"title": "<b>Fuzzy Monkey</b> Normal 1152x864",
"titleNoFormatting": "Fuzzy Monkey Normal 1152x864",
"originalContextUrl": "http://www.blirk.net/fuzzy-monkey/1/1152x864/",
"content": "<b>Fuzzy Monkey</b> Normal 1152x864",
"contentNoFormatting": "Fuzzy Monkey Normal 1152x864",
"tbUrl": "http://t1.gstatic.com/images?q=tbn:ANd9GcQQigy-U6KTXke82n5hma5qvFM2UyVnkGtJme6pkZgl_1GYM--Yb90oqnOJ"
},
{
"GsearchResultClass": "GimageSearch",
"width": "600",
"height": "397",
"imageId": "ANd9GcRpZyXXWBk0TJuU6PCdvrgrU7QckCJQ5DP96iyLc6uLx1bQn4EvBZDFLCk",
"tbWidth": "135",
"tbHeight": "89",
"unescapedUrl": "http://www.acuteaday.com/blog/wp-content/uploads/2011/05/fuzzy-snub-nosed-monkey.jpg",
"url": "http://www.acuteaday.com/blog/wp-content/uploads/2011/05/fuzzy-snub-nosed-monkey.jpg",
"visibleUrl": "www.acuteaday.com",
"title": "<b>Monkeys</b> » A Cute A Day",
"titleNoFormatting": "Monkeys » A Cute A Day",
"originalContextUrl": "http://www.acuteaday.com/blog/category/monkeys/",
"content": "<b>Monkeys</b> » A Cute A Day",
"contentNoFormatting": "Monkeys » A Cute A Day",
"tbUrl": "http://t1.gstatic.com/images?q=tbn:ANd9GcRpZyXXWBk0TJuU6PCdvrgrU7QckCJQ5DP96iyLc6uLx1bQn4EvBZDFLCk"
},
{
"GsearchResultClass": "GimageSearch",
"width": "800",
"height": "600",
"imageId": "ANd9GcQGs5BxeWNBIqhM5vL6dVaPcqkopWN8HrqXNdBiuq54HFOXzHBbtgu2wpE",
"tbWidth": "143",
"tbHeight": "107",
"unescapedUrl": "http://wild-facts.com/wp-content/uploads/2010/09/woolly_monkey1.jpg",
"url": "http://wild-facts.com/wp-content/uploads/2010/09/woolly_monkey1.jpg",
"visibleUrl": "www.wild-facts.com",
"title": "Facts about the Woolly <b>Monkey</b> | Wild Facts",
"titleNoFormatting": "Facts about the Woolly Monkey | Wild Facts",
"originalContextUrl": "http://www.wild-facts.com/2010/wild-fact-723-it-is-not-a-fuzzy-monkey-woolly-monkey/",
"content": "Facts about the Woolly <b>Monkey</b> | Wild Facts",
"contentNoFormatting": "Facts about the Woolly Monkey | Wild Facts",
"tbUrl": "http://t1.gstatic.com/images?q=tbn:ANd9GcQGs5BxeWNBIqhM5vL6dVaPcqkopWN8HrqXNdBiuq54HFOXzHBbtgu2wpE"
},
{
"GsearchResultClass": "GimageSearch",
"width": "1200",
"height": "1600",
"imageId": "ANd9GcQvIhN2ozrnr6ujdQSbknSV2hexAuA-lP5X22UsDCYzmTsolC97nfjXAVAB",
"tbWidth": "113",
"tbHeight": "150",
"unescapedUrl": "http://4.bp.blogspot.com/_Q6jkicsZAr0/TN1A8bLuGVI/AAAAAAAADoA/NyC1Xl8bNOc/s1600/Fuzzy+Monkey+017.JPG",
"url": "http://4.bp.blogspot.com/_Q6jkicsZAr0/TN1A8bLuGVI/AAAAAAAADoA/NyC1Xl8bNOc/s1600/Fuzzy%2BMonkey%2B017.JPG",
"visibleUrl": "www.inkingpink.com",
"title": "inkingpink: <b>Fuzzy Monkey</b>",
"titleNoFormatting": "inkingpink: Fuzzy Monkey",
"originalContextUrl": "http://www.inkingpink.com/2010/11/fuzzy-monkey.html",
"content": "inkingpink: <b>Fuzzy Monkey</b>",
"contentNoFormatting": "inkingpink: Fuzzy Monkey",
"tbUrl": "http://t0.gstatic.com/images?q=tbn:ANd9GcQvIhN2ozrnr6ujdQSbknSV2hexAuA-lP5X22UsDCYzmTsolC97nfjXAVAB"
}
],
"cursor": {
"resultCount": "2,990,000",
"pages": [
{
"start": "0",
"label": 1
},
{
"start": "4",
"label": 2
},
{
"start": "8",
"label": 3
},
{
"start": "12",
"label": 4
},
{
"start": "16",
"label": 5
},
{
"start": "20",
"label": 6
},
{
"start": "24",
"label": 7
},
{
"start": "28",
"label": 8
}
],
"estimatedResultCount": "2990000",
"currentPageIndex": 0,
"moreResultsUrl": "http://www.google.com/images?oe=utf8&ie=utf8&source=uds&start=0&hl=en&q=fuzzy+monkey",
"searchResultTime": "0.21"
}
},
"responseDetails": null,
"responseStatus": 200
}
are you looking for something like this?
urls = _response["responseData"]["results"].map { |result| result["url"] }