Why do I get very inconsistent Google Geocode API results? - google-api

I have a list of a few thousand locations for which I need to find the coordinates. I'm using Google Geocode API for this.
The information I have is something like "USA, California, Napa Valley"
So my Geocode call would look something like this:
https://maps.googleapis.com/maps/api/geocode/json?address=Napa+Valley,California,USA&key=<apikey>
(I put them in reverse order and replace spaces with "+" characters)
I'm of course mostly interested in the values found under ['results'][0]['geometry']['location'] key (where latitude and longitude will be found).
Now in a lot of cases I get very different results by simply waiting a few hours or 1 day and making the call again. And I make those calls using the exact same data, same parameters, same everything
Usually the coordinates are different by a fraction of a degree or at most 1.0 - 1.5 degrees. For example 39.8 latitude yesterday becomes 40.4 latitude today. And then it becomes 40.1. And then a day after it comes back to 39.8. And then it's 40.25. And so on...
However in some extreme cases the differences are massive.
Actual concrete example:
https://maps.googleapis.com/maps/api/geocode/json?address=Côtes+du+Rhône-Brézème,Northern+Rhône,Rhône,France&key=<apikey>
The result will be something like:
{
"results": [
{
.....
"formatted_address": "Rhône",
"geometry": {
.........
"location": {
"lat": 44.952398,
"lng": 6.4840823
}
},
"partial_match": true,
......
}
],
"status": "OK"
}
So it's somewhat correctly identified as the Rhone region in France.
However if I wait just a few minutes and make the call again, I get this:
{
"results" : [
{
......
"formatted_address" : "148 Chambers St A, New York, NY 10007, USA",
"geometry" : {
"location" : {
"lat" : 40.715666,
"lng" : -74.009906
},
......
},
.....
}
],
"status" : "OK"
}
Since when is Rhone/France even close to New-York ?
And this is the annoying part: I don't change anything about the URL. I simply make the EXACT same call a few minutes apart.
My thinking was that it was caused by me not properly encoding the URL.
However, while this may be true, I found it happens for queries that use NO special characters at all, for example something like Clarksburg,California,USA. In this case though I get 2 different results (coordinates), both in California, about 200 miles from each other.
Why does this happen? I need consistent results by this API. I don't need extreme precision or something like that. But at least some strong consistency.
I can't just go through a few thousand locations and put them manually in Google-Maps website to find their coordinates. It would take me 1 week of non-stop work...

This looks like a bug that would be best reported in the Google Maps APIs public issue tracker at https://issuetracker.google.com/code/p/gmaps-api-issues/

Related

Unexpected pageInfo from YouTube Data API v3

I've tried to search videos using YouTube Data API v3 (https://developers.google.com/youtube/v3/docs/search/list).
I successfully got some information, but I figured out the result of pageInfo wasn't something I expected.
Here is the query and the response I got:
https://www.googleapis.com/youtube/v3/search?part=id&channelId=UC5fslQUCCo3OE1EaA1n5ZmQ&key=...&publishedAfter=2019-01-15T08:09:38Z&publishedBefore=2019-01-15T10:09:38Z&order=date .
{
"kind": "youtube#searchListResponse",
"etag": "iLvO2LgGDksqADNU-_xPwG4QMCU",
"nextPageToken": "CAUQAA",
"regionCode": "JP",
"pageInfo": {
"totalResults": 49,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "Adtll-9lbQDiKGJEkBb2IEjPfjw",
"id": {
"kind": "youtube#video",
"videoId": "d4Z7MZo3-Ac"
}
}
]
}
I specified date strings to publishAfter and publishBefore so that the result include single video information only.
I guessed both pageInfo.totalResult and pageInfo.resultPerPage were 1.
Contrary to my anticipation, pageInfo.totalResult was 49 and pageInfo.resultsPerPage was 5.
What describes pageInfo? Is my understanding incorrect?
Here are the answers to your two questions:
1. Why pageInfo.resultsPerPage is 5?
The specification of this property is the following:
pageInfo.resultsPerPage (integer)
The number of results included in the API response.
One may read this specification as (am rephrasing the text above): the number of items in the result set obtained from the API, i.e the number of elements of the JSON array items.
Unfortunately, this does not correspond to reality. In my experience, pageInfo.resultsPerPage is simply the value of the request parameter maxResults:
maxResults (unsigned integer)
The maxResults parameter specifies the maximum number of items that should be returned in the result set. Acceptable values are 0 to 50, inclusive. The default value is 5.
Since your API invoking URL above does not specify maxResults, this parameter is taken as having the default value; hence pageInfo.resultsPerPage gets to be 5.
One more remark: indeed the official specification of this property is misleading; this issue may well be reported to Google (via its own issue tracker site) as a documentation bug.
2. Why pageInfo.totalResults is 49 and is not 1?
The specification of this property is the following (the emphasis below is mine):
pageInfo.totalResults (integer)
The total number of results in the result set. Please note that the value is an approximation and may not represent an exact value. In addition, the maximum value is 1,000,000.
You should not use this value to create pagination links. Instead, use the nextPageToken and prevPageToken property values to determine whether to show pagination links.
According to this specification, pageInfo.totalResults is not to be taken as a precise quantity that the user can rely upon. This peculiarity is also confirmed officially by Google's staff.
Moreover, if experimenting a bit with your URL, eliminating the two date request parameters publishedAfter and publishedBefore, you'll see that the value of pageInfo.totalResults becomes unstable: repeating the same API call several times in a row (only seconds apart one from another), I never got the same value of out of the API, but, alternating, 1374 and 1375.

Using a Power Automate flow, how do I convert JSON array to a delimited string?

In Power Automate I am calling an API which returns this JSON:
{
"status":"200",
"Suburbs":[
{
"ID":"1000",
"Name":"CONCORD WEST",
"Postcode":"2138"
},
{
"ID":"1001",
"Name":"LIBERTY GROVE",
"Postcode":"2138"
},
{
"ID":"1002",
"Name":"RHODES",
"Postcode":"2138"
},
{
"ID":"3891",
"Name":"UHRS POINT",
"Postcode":"2138"
},
{
"ID":"1003",
"Name":"YARALLA",
"Postcode":"2138"
}
]
}
Using PA actions, how do I convert this JSON to a String variable that looks like this?:
"CONCORD WEST, LIBERTY GROVE, RHODES, UHRS POINT, YARALLA"
I figured out how to do this. I prefer not to use complex code-style expressions in Power Automate flows as I think they are hard to understand and hard to maintain so used standard PA actions where I could.
I parsed the JSON, then used "Select" to pick out the suburb names, then used concat() within a "for each" loop through the Suburbs array. I think that Compose could probably be used in the place of the concat() but stopped investigating once I'd found this solution.

An error with opening Multi-Series Line Chart from Mike Bosktok

I'm practicing d3 with Mike Bostok's example: https://bl.ocks.org/mbostock/3884955
I'd like to see how the series that he made - cities - looks like.
I opened the html file using Python local server and in the console, I wrote 'console.log(cities);' but it didn't work. 'console.log(data);' also didn't work. They all showed this error message:
VM100:1 Uncaught ReferenceError: cities is not defined
at <anonymous>:1:13
I didn't make any modification in his code. So I don't think there is an error in the code. I assume perhaps the problem is in line with d3 setting?
So, I've tried to open the file in Firefox and I've also downloaded d3 but those two ways also didn't work.
Does anyone happen to know what is the cause of the problem?
If someone can explain how the 'cities' in his code looks like, then you are the most welcome!
Thanks a lot,
At a guess, the reason cities is undefined is because your console.log statement is somewhere outside of the callback function provided to d3.tsv. If you look closely at Mike's code, you'll notice that the third argument to d3.tsv is a function that receives as an argument an error object and the processed data. Inside that function, he defines the cities variable, so if you put console.log(cities) anywhere outside of that function, cities will be undefined.
Now, on to the format of the data. If you look further down that block, there's another file: data.tsv. It has four columns: date, New York, San Francisco, Austin. d3.tsv will create an array where each element in the array corresponds to one row in the TSV (except for the header row). Each row is converted to a plain JavaScript Object with properties that correspond to the columns of the file. That array is passed into the callback as the data variable in this block. So data[0] will be
{
"date": "20111001",
"New York": "63.4",
"San Francisco": "62.7",
"Austin": "72.2"
}
When the cities variable is defined, that array is transformed into an array that contains one item per city, and each object representing the city contains the time-series data of temperature for that city. So the cities variable will look like:
[
{
"id": "New York",
"values": [
{"date": Date 2011-10-01T00:00:00, "temperature": 63.4},
{"date": Date 2011-10-02T00:00:00, "temperature": 48.0},
...
]
},
{
"id": "San Francisco",
"values": [...]
},
{
"id": "Austin",
"values": [...]
}
]
It's probably worth pointing here the second argument to d3.tsv in this example: the type function. This is where all the strings are converted into Date or Number objects. Without this argument, all of the property values in data would be strings.
For more information on how d3.tsv works, you can check the docs for d3-request.
CAVEAT: that block is for d3v4, the latest version of d3 is v5. In v5, d3-request is deprecated in favor of d3-fetch. d3-fetch provides pretty much the same set of utilities for fetching data, but instead of using callback functions, they return Promises.

New Teams Who Bot Actionable Messages Syntax? Undocumented O365ConnectorCard functionality?

I'm working with the O365ConnectorCard capabilities in Teams for bots and I'm trying to recreate the scrolling list of people the new Who bot can produce when you say something like who works with jim#contoso.com?.
You can see what it looks like here.
If it is using the connector card functionality, I'm assuming that is a Section but maybe using undocumented syntax? Additionally, the sections are clickable from the Who bot, but no matter what combination of PotentialAction added, I cannot get the row to have a hover and click of type imBack.
The MessageCard Playground as well doesn't have any examples that match what that Who bot can produce.
Anyone know how this was done? Any MS folks want to post some sample JSON of what's possible but not available yet from the Microsoft.Bot.Connector.Teams NuGet package :)? I'm currently up to v0.8.0.
Thanks!
I believe the Who bot is using the List Layout. The list layout is used to display a collection of cards in a stacked list.
We haven't documented these new card formats yet - we were waiting for Who bot to ship, but there are actually two new card formats, PersonCard and ListCard. You can see some commented-out examples of how to use them here: https://github.com/OfficeDev/BotBuilder-MicrosoftTeams/blob/3c6f07b7600bb20713626cbf79acf5e114e57d0d/CSharp/Tests/Microsoft.Bot.Connector.Teams.Tests.Shared/CardTests.cs.
ListCard is different from List, and there are supports for three kinds of objects in a list: Person, File, and a generic one called "resultitem" - that latter one may not render properly on Android. There's also a way to add a separator line.
This may or may not be enough to get you going, but in case you find it useful:
{
"content":{
"title":"Test List Card",
"items":[
{
"type":"section",
"title":"List Card section"
},
{
"type":"person",
"id":"shmayura#microsoft.com",
"title":"Shanmathi Mayuram Krithivasan",
"subtitle":"SOFTWARE ENGINEER",
"tap":{
"type":"invoke",
"title":"Details?",
"value":"{\"intentName\":\"WhoIs\",\"employeeName\":null,\"employeeEmail\":\"shmayura#microsoft.com\",\"topic\":null}"
}
},
{
"type":"file",
"id":"https://microsoft.sharepoint.com/teams/skypespacesteamnew/Shared%20Documents/Design/FinancialReport.xlsx",
"title":"FinancialReport",
"subtitle":"teams > skypespacesteamnew > design",
"tap":{
"type":"openUrl",
"title":"Open url",
"value":"https://microsoft.sharepoint.com/teams/skypespacesteamnew/Shared%20Documents/Design/FinancialReport.xlsx"
}
},
{
"type":"resultItem",
"title":"Seattle to Chicago",
"subtitle":"$500 July 4 - July 8",
"icon":"https://skypeteamsbotstorage.blob.core.windows.net/bottestartifacts/sandwich_thumbnail.png",
"tap":{
"type":"imBack",
"title":"Reply",
"value":"flightto Chicago"
}
}
],
"buttons":[
{
"type":"imBack",
"title":"Open Online",
"value":"editOnline"
}
]
},
"contentType":"application/vnd.microsoft.teams.card.list"
}

zingchart setseriesdata visibility issue

Pretty straight forward question, as soon as i use setseries data the visibility my pie chart is no longer visible. I have checked the plot object and the series were updated correctly, however since I do not find a visibility attribute anywhere in the plot object, i am at a loss.
The lack of zingcharts documentation and proper examples does not aid either. Im fairly certain this is a simple scenario to solve, but I've been unable to do so.
zingchart.exec('organismplot', 'setseriesdata', {
"data": [
{
"values":data_update.organisms,
"text":"active",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":1
},
{
"values":(data_update.totalorganism-data_update.organisms),
"text":"passive",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":0
}]
I'm a member of the ZingChart team, and I'm happy to help you out!
What is the type of data_update.organisms and data_update.totalorganism-data_update.organisms? Make sure that you are passing a single element array, or if those are simply single values, wrap the variables in brackets to create a single value array for the "values" attribute. E.G.:
"data": [
{
"values":[data_update.organisms], // If data_update.organisms is a single value.
"text":"active",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":1
},
{
"values":[data_update.totalorganism-data_update.organisms], // Again, single value array.
"text":"passive",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":0
}
]
I've created a demo using your exact method call, except I've changed the "values" attributes to use a single value array, which are needed for pie charts. Check out the demo here.
I hope that helps. Let me know if you need some more help!

Resources