Issue when trying to run query on Fusion Tables with Google Maps - google-fusion-tables

http://zoofinder.us/map2.html
https://www.google.com/fusiontables/DataSource?docid=1EawtHPl3kbnsXqzPPxQWPZOJeHX3i0XUOffz884
Trying to create buttons to load certain categories.
Would eventually like it to load with all Categories and have the ability to turn them on and off via buttons on the left.
My queries do not seem to be working. For testing, I was trying to load all Farms and then toggle on the Zoos (and eventually toggle back off Zoos).
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Location',
from: '3092255',
where: 'Category contains Farm',
function updateMapZoosOn() {
layer.setOption("SELECT Location FROM 3092255 WHERE Category CONTAINS Zoo");
}
Any help please?
THANKS!

CONTAINS is a string operator and your search values must be quoted e.g.
where: "Category CONTAINS 'Farm'",
Plus your layer.setOptions() syntax is incorrect. You need the same type of {query: ....} options as you used when creating your layer
The GMap FT Query Reference explains this.

Related

Avoid calculating startIndex and endIndex when creating a document using Google Docs API

I have proven to myself that I can insert text into a Google Docs document using this code:
function appendToDocument() {
let offset = 12;
let updateObject = {
documentId: 'xxxxxxx',
resource: {
requests: [{
"insertText": {
"text": "John Doe",
"location": {
"index": offset,
},
},
}],
},
};
gapi.client.docs.documents.batchUpdate(updateObject).then(function(response) {
appendPre('response = ' + JSON.stringify(response));
}, function(response) {
appendPre('Error: ' + response.result.error.message);
});
}
My next step is to create an entire, complex document using the api. I am stunned by what appears to be the fact that I need to maintain locations into the documents, like this
new Location().setIndex(25)
I am informing myself of that opinion by reading this https://developers.google.com/docs/api/how-tos/move-text
The document I am trying to create is very dynamic and very complex, and handing the coding challenge to keeping track of index values to the api user, rather than the api designer, seems odd.
Is there an approach, or a higher level api, that allows me construct a document without this kind of house keeping?
Unfortunately, the short answer is no, there's no API that lets you bypass the index-tracking required of the base Google Docs API - at least when it comes to building tables.
I recently had to tackle this issue myself - a combination of template updating and document construction - and I basically ended up writing an intermediate API with helper functions to search for and insert by character indices.
For example, one trick I've been using for table creation is to first create a table of a specified size at a given index, and put some text in the first cell. Then I can search the document object for the tableCells element that contains that text, and work back from there to get the table start index.
Another trick is that if you know how many specific kinds of objects (like tables) you have in your document, you can parse through the full document object and keep track of table counts, and stop when you get to the one you want to update/delete (you can use this approach for creating too but the target text approach is easier, I find).
From there with some JSON parsing and trial-and-error, you can figure out the start index of each cell in a table, and write functions to programmatically find and create/replace/delete. If there's an easier way to do all this, I haven't found it. There is one Github repo with a Google Docs API wrapper specifically for tables, and it does appear to be active, although I found it after I wrote everything on my own and I haven't used it.)
Here's a bit of code to get you started:
def get_target_table(doc, target_txt):
""" Given a target string to be matched in the upper left column of a table
of a Google Docs JSON object, return JSON representing that table. """
body = doc["body"]["content"]
for element in body:
el_type = list(element.keys())[-1]
if el_type == "table":
header_txt = get_header_cell_text(element['table']).lower().strip()
if target_txt.lower() in header_txt:
return element
return None
def get_header_cell_text(table):
""" Given a table element in Google Docs API JSON, find the text of
the first cell in the first row, which should be a column header. """
return table['tableRows'][0]\
['tableCells'][0]\
['content'][0]\
['paragraph']['elements'][0]\
['textRun']['content']
Assuming you've already created a table with the target text in it: now, start by pulling the document JSON object from the API, and then use get_target_table() to find the chunk of JSON related to the table.
doc = build("docs", "v1", credentials=creds).documents().get(documentId=doc_id).execute()
table = get_target_table(doc, "my target")
From there you'll see the nested tableRows and tableCells objects, and the content inside each cell has a startIndex. Construct a matrix of table cell start indices, and then, for populating them, work backwards from the bottom right cell to the upper left, to avoid displacing your stored indices (as suggested in the docs and in one of the comments).
It's definitely a bit of a slog. And styling table cells is a whole 'nother beast, which is a dizzying maze of JSON options. The interactive JSON constructor tool on the Docs API site is useful to get the syntax write.
Hope this helps, good luck!
The answer I arrived at: You can create Docs without using their JSON schema.
https://developers.google.com/drive/api/v3/manage-uploads#node.js_1
So, create the document in your format of choice (HTML, DocX, MD (you'd use pandoc to convert MD to another format)), and then upload that.

Prevent users from creating new sheets in a shared google spreadsheet

I have created a spreadsheet with all sheets protected from editing except for a single cell, where the user is supposed to enter a search value, which filters the sheet. I shared the spreadsheet with enabled editing to allow for that, but that also enables users to create new sheets, which I'd like to prevent.
Perhaps I'm using not the most optimal way of achieving what I want, so suggestions are welcome. I saw people advising to use forms in similar use cases, but I don't see how to apply their survey capabilities to my needs.
EDIt: here is the shared spreadsheet: https://docs.google.com/spreadsheets/d/1C4mrBWJxPLrFQ4bp82UA2ICOr1e6ER47wF7YuElyoZg/edit?usp=sharing
You can use a script to delete every newly created (not by the owner) sheet. Here is an example of such a script :
// Deletes any tab named "SheetN" where N is a number
function DeleteNewSheets() {
var newSheetName = /^Sheet[\d]+$/
var ssdoc = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ssdoc.getSheets();
// is the change made by the owner ?
if (Session.getActiveUser().getEmail() == ssdoc.getOwner().getEmail()) {
return;
}
// if not the owner, delete all unauthorised sheets
for (var i = 0; i < sheets.length; i++) {
if (newSheetName.test(sheets[i].getName())) {
ssdoc.deleteSheet(sheets[i])
}
}
}
Then set a trigger that runs this function DeleteNewSheets when a change (like sheet creation) happens.
Note : If english is not the document language you should change the regular expression /^Sheet[\d]+$/, for example for french it should be /^Feuille [\d]+$/.
Without seeing your existing spreadsheet, Seedmanc, Google's "Filter views" option under the "Data" menu of your Sheet could be helpful, because it lets owners/editors create and save filters that are accessible to view-only users too.
What's more, view-only users can create filter views unique to them. Once they enter a filter range, menu arrows appear...
...allowing them to filter either by condition (including custom formulas!) or by values. So, depending on how elaborate your filter is and how spreadsheet-savvy your users are, filter views can provide a more flexible filter while still protecting your sheets.
(Read more about Google Sheets filter views here.)

Breezejs projection not working for referencing one to many navigators

I have the following model:
1 Person to many Participant ('enrollments' is the navigator)
If I just want the name of the person, and the date of all enrollments, this doesn't work:
EntityQuery.from('Person').where('id','eq',id)
.select('firstName, lastName, enrollments.dateEnrolled')
.execute()
I get an error:
Unable to locate property 'DateEnrolled' on type
'System.Collections.Generic.ICollection`1[EntityClasses.Participant]'
What is the proper syntax for projections of fields on one-to-many relationships?
There is no really good way to express this in a single query. You can get all of the "enrollments" but you will need to select out the "dateEnrolled" on the client.
EntityQuery.from('Person').where('id','eq',id)
.select('firstName, lastName, enrollments').expand("enrollments")
.execute().then(function(data) {
// extract "dateEnrolled" from data.results
});
Alternatively, you can use a 'named query" on the server that performs the projection there and simply query the projection from the client.
Or perhaps better would be to invert your query. Something like this: ( assuming you have a scalar property named 'Person' on your 'Enrollment' type).
EntityQuery.from('Enrollments').where('person.id','eq',id)
.select('person.firstName, person.lastName, dateEnrolled').expand("person")
.execute().then(...);
I got this working on my fork of breeze.server.net: https://github.com/eggers/breeze.server.net/tree/property-of-collection-25

Grails: query or criteria against a string/value pairs map property

Grails gives the possibility of creating simple string/value map properties section "Maps of Objects", first paragraph.
I was wondering, is there a way to later query the domain class (using Gorm dynamic finders, criterias or HQL) using the map property as part of the query (i.e adding a condition for the key X to have the value Y)?
After playing with it a bit and almost give up, I discovered the map syntax to (surprisingly) work in HQL. Assuming the class looks like:
class SomeClass {
Map pairKeyProperty
}
You can build queries that look like the following:
select * from SomeClass sc where sc.pairKeyProperty['someKey'] = 'someValue' and sc.pairKeyProperty['someOtherKey'] = 'someOtherValue'
Pretty neat! I still would prefer to use criterias as they are much cleaner to compose, but they seem to not support the same syntax (or I couldn't find it).
I created a sample app in GitHub:
https://github.com/deigote/grails-simple-map-of-string-value-pairs
It can be visisted at:
http://grails-map-of-string-pairs.herokuapp.com/
The form above uses a cross join. To enforce an inner join use
join sc.pairKeyProperty pk1 on index(pk1) = 'someKey'
where 'someValue' in elements(pk1)

GORM/Grails :: possible to query based on contents of a List within the model?

Assume the following:
class Thing {
String name
List<String> tags
static constraints = {
name(nullable: false)
tags(nullable: false)
}
}
I want to know if its possible, using GORM, to run a query for domain instances based on values in their respective lists
For instance: Are there dynamic GORM finders to query things like 'Find all Things that have the tag "Video" ', or 'Find all things with name = "Product1" that have the tag "Image" '
Just want to know if there's a nice concise way of doing this with Grails&Gorm, as opposed to retrieving a list of Things and iterating through it, finding the ones that have the appropriate tags and adding them to a results list.
Thanks!
One way (although not necessarily the most efficient!) would be to return the whole list of Things eg Thing.list() and then filter the resulting list using findAll.
List results = Thing.list().findAll{it.tags.contains("Image")}
How big is your list of Things and associated Tags likely to be?

Resources