Fusion table stopped appearing via Maps API (fusiontablelayer) - google-fusion-tables

A fusion table has stopped being shown via the Maps API. It was working the other day (Monday or last Friday).
It works fine inside the Fusion Tables website.
Other fusion tables continue to work fine via the Maps API.
Here's a site I made showing the (actually not showing the) layer in question.
http://dl.dropboxusercontent.com/u/14878119/map/sewerlayernotshowing.html
View the source of that site for the entire code, but here's how this layer (and all the others we use) are being called:
<script>
//initializing Google Maps
map = new google.maps.Map(document.getElementById('divMap'), {
zoom: 14,
center: {lat:33.040171488300871,lng:-97.022509084376622}
});
//Fusion Table (Sewer Lines) *****NOT WORKING!*****
var _ftId = "140ge-x0HKkzrlZYOdrCxYBNlu4ta15vpHetZh_s";
var _ft = new google.maps.FusionTablesLayer(_ftId,{query: "SELECT * FROM " + _ftId});
_ft.setMap(map);
//Fusion Table (Sewer Points) *****WORKING*****
var _ftId2 = "1NsByxnFPfr20fL1MAr_zYoPdtocKqCXJg9tqLoA";
var _ft2 = new google.maps.FusionTablesLayer(_ftId2,{query: "SELECT * FROM " + _ftId2});
_ft2.setMap(map);
</script>
Any ideas why the one with id 140ge-x0HKkzrlZYOdrCxYBNlu4ta15vpHetZh_s would stop working?

You are using the "old" (now undocumented) syntax for FusionTableLayer constructors. Use the new syntax and it works.
//Fusion Table (Sewer Lines)
var _ftId = "140ge-x0HKkzrlZYOdrCxYBNlu4ta15vpHetZh_s";
var _ft = new google.maps.FusionTablesLayer({
query: {
select: "Shape",
from: _ftId,
where: ""
},
options: {
styleId: 6,
templateId: 2
}
});
_ft.setMap(map);
working fiddle

Related

IMPORTRANGE: multiple hyperlinks within one cell, importing this cell data into another sheet and retaining separate clickable links

I currently use a Google sheet to hold data x1 row per item. I use one particular cell to hold two separate hyperlinks within (x2 website addresses), both links are relevant/in relation to this item.
I want to keep the structure of having two separate clickable hyperlinks in one cell, but I also need to import this cell data (these two links) into another Google sheet, is there a way of using IMPORTRANGE and retaining these two separate hyperlinks (ensuring clickable & still x2 separate links within one cell), or converting them into hyperlinks when importing into another sheet?
Thank you in advance
I've created two dummy sheets with data for testing & to help visualise
Sheet Name: "Static" & Sheet URL: https://docs.google.com/spreadsheets/d/1JS40eNGUAmBqQJqmdX4PhWtm6GEVQP64CoxO_DooZYM/edit#gid=0
Sheet Name: "Imported" & Sheet URL: https://docs.google.com/spreadsheets/d/1rhnULIcbkSMCp8AONa7UwTQz77uHn443VuwYjty2xFs/edit#gid=0
I've used =IMPORTRANGE("1JS40eNGUAmBqQJqmdX4PhWtm6GEVQP64CoxO_DooZYM","Static1!A1:D")
To pull data from 'Static' sheet (tab: 'Static1') into 'Imported' (tab: 'Imported1')
I'm hoping to get clickable links in column 'D' of the 'Imported' sheet
I've added different variations i.e. the hyperlinks are renamed in 'Static' sheet as "Link 1" & "Link 2", I've added a few rows with full URLs addresses (no re-naming), and a couple with full URLs and with an empty line in between - I'm not too fussed with how they look to be honest (ideally it would be nice to have 'Link 1' & 'Link 2') but mainly just looking to have x2 imported URLs within same cell that remain/become clickable after importing
This is because I'll also be iframe/embedding the 'Imported' sheet afterwards.
Thank you
You can extract the urls by a custom function in addition of the IMPORTRANGE
function extractUrls(range) {
var activeRg = SpreadsheetApp.getActiveRange();
var activeSht = SpreadsheetApp.getActiveSheet();
var activeformula = activeRg.getFormula();
var rngAddress = activeformula.match(/\((.*)\)/).pop().trim();
var urls = activeSht
.getRange(rngAddress)
.getRichTextValue()
.getRuns()
.reduce((array, e) => {
var url = e.getLinkUrl();
if (url) array.push(url);
return array;
}, []);
return ([urls])
}
edit
in your situation
function createCopy() {
var id = "1JS40eNGUAmBqQJqmdX4PhWtm6GEVQP64CoxO_DooZYM"
var source = SpreadsheetApp.openById(id).getSheets()[0]
var values = source.getRange(2,1,source.getLastRow()-1,3).getValues()
var richTxt = source.getRange(2,4,source.getLastRow()-1,1).getRichTextValues()
var output = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('output_v2')
output.getRange(2, 1, values.length, values[0].length).setValues(values)
output.getRange(2, 4, richTxt.length, richTxt[0].length).setRichTextValues(richTxt)
}
UPDATE:
Option 1:
This is fairly straightforward. It just copies the Static1 sheet unto a destination sheet and names it Imported.
function createCopy2() {
var ss = SpreadsheetApp.openById("1vM-0nBBlhVvRQ3vvXwkWlecENM7CVuv8iei3cl0uRQI");
var ds = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Static1');
sheet.copyTo(ds).setName('Imported');
}
Option 2 (incomplete):
This is what I have done so far, but this still throws an error Exception: Illegal Argument at this line var text = SpreadsheetApp.newRichTextValue().setText(linkval[i]).setLinkUrl(0,7,urls1[i]).setLinkUrl(7,13,urls2[i]).build();.
(P.S: Just wanted to throw this out here if in case someone would find this logic useful/not to waste my efforts practicing JS lol).
Kudos to Mike Steelson for providing a working answer.
function createCopy() {
//Creates a full copy of the source sheet without Hyperlinks (AKA importrange in script form)
var ss = SpreadsheetApp.openById("1vM-0nBBlhVvRQ3vvXwkWlecENM7CVuv8iei3cl0uRQI");
var sheet = ss.getSheets()[0].getSheetValues(1,1, ss.getLastRow(), ss.getLastColumn());
var ds = SpreadsheetApp.getActiveSheet();
ds.getRange(1,1, ss.getLastRow(), ss.getLastColumn()).setValues(sheet);
Logger.log(sheet);
var link = ds.getRange(2,4, ss.getLastRow(), 1);
var linkval = link.getValues();
var urls1 = ds.getRange(2,5, ss.getLastRow(), 1).getValues();
var urls2 = ds.getRange(2,6, ss.getLastRow(), 1).getValues();
for(i=0; i < ss.getLastRow(); i++){
var text = SpreadsheetApp.newRichTextValue().setText(linkval[i]).setLinkUrl(0,7,urls1[i]).setLinkUrl(7,13,urls2[i]).build();
}
}

Importing Url's of sheets shared with me into google sheets automatically whenever one is shared

I'm pretty new to excel or google sheets. The work place, that I work at does not have anything stream lined.
I'm trying to create my own work book that I can refresh everyday I log in so that I can have a list of things that I need to work on for that day.
One of the functions that I would like to have is, whenever a new sheet is shared with me on Google Sheets, I want the URL for that sheet to populate in one of the cells in my workbook automatically and arranged based on timestamp.
I was trying to search for this on Google, but I read that: shared with me docs are not stored anywhere specifically.
Any help or pointing me in the right direction is highly appreciated.
It is easy to fetch the files that have been shared with you. For that, you can simply call the Drive API's Files: list method specifying in the q parameter the sharedWithMe attribute.
Afterwards, you can use the SpreadsheetApp class to gather a spreadsheet and insert data into it. In this case, you can simply make several calls of apendRow() to insert the results.
Finally, properties can be used to store the status of the script (last date checked), so that it can know where to resume from. In this case below, we'll be saving the date in the LAST_DATE property.
Code.gs
var SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID';
var SHEET_NAME = 'YOUR_SHEET_NAME';
function myFunction() {
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
var lastDate = new Date(PropertiesService.getScriptProperties().getProperty('LAST_DATE'));
var currentDate = new Date();
var files = getFiles(lastDate);
for (var i=0; i<files.length; i++) {
var row = [
new Date(files[i].sharedWithMeDate),
files[i].title,
files[i].alternateLink,
files[i].sharingUser.emailAddress,
files[i].owners.map(getEmail).join(', ')];
sheet.appendRow(row);
}
console.log('lastDate: %s, currentDate: %s, events added: %d', lastDate, currentDate, files.length);
PropertiesService.getScriptProperties().setProperty('LAST_DATE', currentDate.toISOString());
}
function getEmail(user) {
return user.emailAddress;
}
function getFiles(lastSharedDate) {
var query = "sharedWithMe and mimeType = 'application/vnd.google-apps.spreadsheet'";
var res = Drive.Files.list({
q: query,
orderBy: "sharedWithMeDate desc",
fields: "*",
pageSize: 1000
});
// `query` parameter cannot compare sharedWithMeDate, so we do it afterwards
return res.items.filter(function (i) {
return (new Date(i.sharedWithMeDate) > lastSharedDate);
}).reverse();
}
You can set up the script to be ran periodically (i.e once a day, or more in case you'd need it) using Time-driven triggers.

Partial CellFeed load

Happy new year, folks,
Currently, I'm accessing and loading a Google Sheets worksheet using the following, default way:
URL metafeedUrl = new URL(SPREADSHEET_URL);
SpreadsheetEntry spreadsheet = service.getEntry(metafeedUrl, SpreadsheetEntry.class);
URL cellFeedUrl = ((WorksheetEntry) spreadsheet.getWorksheets().get(0)).getCellFeedUrl();
// Get entries as cells
feed = (CellFeed) service.getFeed(cellFeedUrl, CellFeed.class);
Then I work with it, etc. Everyting works just fine.
The problem:
I'm about to deploy the application and have it work with a Worksheet that has several hundred, if not thousand rows of cells. To me, the only relevant rows are usually the 100-200 bottom ones.
Is there a way to partially load a CellFeed, preferrably from the bottom up? Does the API provide such a way?
Looking at the API itself, you can do it with cell feed or list feed.
in cell feed, look at https://developers.google.com/google-apps/spreadsheets/#fetching_specific_rows_or_columns
you can specify there the minimum/maximum row/columns to get, and there is also a java example in there.
a more efficient way to get your data, is the row feed as it sends less bytes in return:https://spreadsheets.google.com/feeds/list/
with the undocumented "start-index' parameter so it only reads starting at that row.
I use this and works for the "old" and "new" sheets.
The first time you will need to get all rows (or attempt some sort of binary lookup to find the last spreadsheet row).
I have not used the java api library, it probably does not allow for that undocumented parameter. You can always do a url "get" directly from java or any language and use the spreadsheet api directly by https.
I got this tip a long time ago from here:
https://groups.google.com/forum/#!topic/google-spreadsheets-api/dSniiF18xnM
and use it on this github project (javascript ajax call example)
https://github.com/zmandel/Plus-for-Trello/blob/master/source/sql.js
I don't know any CellFeed, but you can create an HTML feed that retrieves a number of ROWS from any Spreadsheet, then treat that HTML, would that work for you? What are the goals when retrieving the information?
Eg.
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile("form").evaluate().setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function getLastLines( numLines, ssId, sheetName ){
var sheet = SpreadsheetApp.openById(ssId).getSheetByName(sheetName);
return JSON.stringify(sheet.getRange(sheet.getLastRow() - numLines, 1, numLines, sheet.getLastColumn()).getValues());
}
in form.html
<div id="arrayPlace"></div>
<script>
function changeDiv( res ){
document.getElementById("arrayPlace").innerHTML = res;
}
function getUrlParameter(sParam)
{
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++)
{
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam)
{
return sParameterName[1];
}
}
}
var numLines = getUrlParameter("numLines");
var ssId = getUrlParameter("ssId");
var sheetName = getUrlParameter("sheetName");
google.script.run.withSuccessHandler( changeDiv ).getLastLines( numLines, ssId, sheetName );
</script>
And the URL would have the additional parameters:
https://script.google.com/macros/s/AKfycbwFLN-qqTcXXAVgR-aDa9h61yTa39kVhE2MwX9htRbIm2NN5I4/exec?numLines=5&ssId=1dJlNmtvcsWixEDnUz7GxnyLMZKXHwA-9uopYPUC8I4E&sheetName=Sheet1

Fusion Tables numeric ID

I'm working on a multiple query with Fusion Table. Till yesterday I used numericID but today creating a new Table, FT shows no numeric ID in the about menu. I tried to change NUmeric ID with Ecrypted one, but it doesn't work. This is the page:
http://siti-torino.hostei.com/test/test_09_02.html ( numeric ID)
http://siti-torino.hostei.com/test/test_09_03.html ( Encrypted ID)
It's quite clear that the query works correctly (the counter show the right result), but the script can't update the map. So I suppose the problem is at line 94-95
searchTracks = new google.maps.FusionTablesLayer(fusionTableId, { query: searchStr});
What am I doing wrong here?
You are using the "old syntax", that doesn't work with encrypted ids.
new google.maps.FusionTablesLayer(fusionTableId, { query: searchStr});
Use the documented syntax
new google.maps.FusionTablesLayer({ query: {[FusionTablesQuery object](https://developers.google.com/maps/documentation/javascript/reference#FusionTablesQuery)}});
Example of your page
Hey Guys I'm trying to pick up the piece after a coworker left. I'm not a programmer.
We beleive the site might be having a problem not recognizing the new I'ds as a String compared to the old numeric Values
//Setting the lat lng
var latlng = new google.maps.LatLng(lati, long);
var myOptions = {
zoom: zoomLevel,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
layer = new google.maps.FusionTablesLayer "1QzYXB7nkb7drbz66HMmq3_d7Dut_Gulx2aZEC2Q";
layer.setMap(map);
if(addressMarker)
addressMarker.setMap(null);
addressMarker = new google.maps.Marker({
map: map,
position: latlng
});
infowindow.open(map,addressMarker);
google.maps.event.addListener(addressMarker, 'click', function()
{
infowindow.open(map,addressMarker);
});
}
}

Type error when drawing chart - Google Charts & Fusion Tables

I've been bashing my head against this for a little too long now - probably to the point of missing something completely obvious.
I am trying to generate a bar chart showing the number of public toilets per state from this Fusion Table - https://www.google.com/fusiontables/DataSource?docid=1Acf5-fZ1fbRrbsCthOSu2q5s0PmMFBVFI8tuCg - obviously there isn't anything that easily counts this for me so I'm having to do it through the query.
This is the code I have so far...
var dataURL = 'http://www.google.com/fusiontables/gvizdata?tq=';
var query = "SELECT state, COUNT() " +
"FROM 1Acf5-fZ1fbRrbsCthOSu2q5s0PmMFBVFI8tuCg GROUP BY state";
var queryText = encodeURIComponent(query);
var gvizQuery = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
gvizQuery.send(function(response) {
if(response.isError()){
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
data = response.getDataTable();
//This bit below is to see what I'm getting in the data table
for(i in data){
document.getElementById('visualization').innerHTML += data[i];
}
var chart = google.visualization.BarChart(document.getElementById('visualization'));
var options = {
title: 'Toilets by State',
vAxis: {title: 'State', titleTextStyle: {color: 'red'}},
};
chart.draw(data, options);
});
When I try to run it, I get "TypeError: 'undefined' is not a function (evaluating 'thispc')" from format+en,default,corechart.I.js:824 - which I cannot pin down. When I pump out the data table to the page, I get the usual series of [object Object] with a chunk of Javascript after it - which looks odd to me.
Any suggestions - or glaring errors that anyone can see?
Fusion Tables can do the aggregation for you, like so:
https://www.google.com/fusiontables/DataSource?snapid=S568510O6Lf
Then Visualize > Bar and "Get embeddable link" for:
Or, use the aggregation (GROUP BY) query via the gviz API (sample code) for more control.
-Rebecca

Resources