need to export individual features to shapefiles using geopandas - javascript

I'm using geopandas to read a geojson file and output shapefiles. The issue is I cannot figure out how to export single features within that shapefile - only the entire shapefile. Just for ref, I'm using google colab.
here's what I have so far
os.makedirs('/content/drive/MyDrive/shapes')
gdf = gpd.read_file('/content/sample_data/countries.geojson')
for num, row in gdf.iterrows():
key = row.city
fileName = key+".shp"
path = '/content/drive/MyDrive/shapes/'+fileName
os.makedirs('/content/drive/MyDrive/shapes/'+fileName)
os.chdir('/content/drive/MyDrive/shapes/'+fileName)
gdf.to_file(fileName) # need to do something like row to file here
this code will export a bunch of shapefiles of the original geojson file & name them by a certain key. I can't figure out how to loop through the individual features and make a shapefile for each.

Since I didn't have your shapefile, I am going to answer your question based on what you have told in your question. First of all, you should not save the gdf dataframe every time because you want to save the row into a file(I think each row represents a city and you want to have this city in a different shapefile that is named after the city name). So, what I suggest is:
os.makedirs('/content/drive/MyDrive/shapes')
gdf = gpd.read_file('/content/sample_data/countries.geojson')
for num, row in gdf.iterrows():
key = row.city
fileName = key+".shp"
path = '/content/drive/MyDrive/shapes/'+fileName
os.makedirs(path)
os.chdir('/content/drive/MyDrive/shapes/'+fileName)
gdf.iloc[num:num+1,:].to_file(path)
Note that, instead of saving in filename I saved the file into path because if it wasn't the case, the last few lines in your code would be for nothing!

Related

How to create multiple random Google forms with a fixed number of Multiple Choice Questions with a single script

Disclaimer: I just started with JavaScripts/GoogleForms
I want to validate some data with a GoogleForm that I've created. Each section contains 5 multiple choice questions. In the example below I've shown how I add one question to the section.
// Sentence 1
sentence = form.addMultipleChoiceItem();
choices = [
sentence.createChoice('Answer I'),
sentence.createChoice('Answer II'),
sentence.createChoice('Answer III'),
]
sentence.setTitle(pred_1) // pred_1 -> Variable extracted from the dataset
.setChoices(choices);
In the end, I can build an excellent-looking form that contains 20 sections with five questions each based one a single dataset in my Google Drive Folder.
However, I want to extend this. I have ten different datasets that I want to have evaluated. A straightforward approach is copying the script ten times and pointing the script towards a different dataset. However, with this approach, I have to run the script ten times, and every time I adjust something (e.g. in the Title/HelpText), I have to rerun all the scripts.
I was thinking there should be a solution where I just read all the file inside my Drive folder and run my main scripts that produces the forms for multiple dataset. I was thinking something like this:
function createForms() {
// Folder with data
var folder = DriveApp.getFolderById('FOLDERID')
// List files
var files = folder.getFiles()
for (var i = 1; i < 11; i++) {
createMultipleChoiceForm(files[i]) // Function that creates a single form
}
}
This does unfortunately does not work at all (it does not give any errors, but does not produce anything).
EDIT:
This does actually work, but it creates a new form every time without saving it (it overruns the previous version).
I final approach is of course concatenating all the 10 datasets, and sample them from within the Google Script editor. But I still want to end up with ten different form (so I can send them to different people.
I hope anyone can give me some pointers in the right direction.
Thanks!
The Folder.getFiles() method returns a FileIterator object rather than an array. The code in the question ends up calling createMultipleChoiceForm() with an undefined parameter every time.
To make it work, replace the for loop with this pattern:
const files = folder.getFiles();
while (files.hasNext()) {
createMultipleChoiceForm(files.next());
}

Replacing items skips values

I have a file that includes Database Name and Label - these labels correspond to sectors. My script goes as follows:
I read an excel file that has sector names on it, I then use this to get an allocation of calcrt_field and sector:
es_score_fields['esg_es_score_peers']= es_score_fields.iloc[:,10:100].apply(lambda x: '|'.join(x.dropna().astype(str)), axis=1)
once I have each calcrt_field aligned to the relevant peers (sectors), I read another file that has 2 columns: Database Name and Label. The end goal is to map the score peer sectors to each of these Database Names, examples:
Database Name1: Chemicals (123456)
Label1: Chemicals
Database Name 2: Cement (654321)
Label2: Cement
Once I read the file i use the following (multiple rows) to remove any symbol, space, comma:
score_peers_mapping.Label= BECS_mapping.Label.str.replace('&', '')
this gives me a list with both Database Name (no changes) and Label (all words combined into a single string)
I then map these based on string length as follows:
score_peers_mapping['length'] = score_peers_mapping.Label.str.len()
score_peers_mapping= score_peers_mapping.sort_values('length', ascending=False)
score_peers_mapping
peers_d = score_peers_mapping.to_dict('split')
peers_d = becs_d['data']
peers_d
finally, I do the following:
for item in peers_d:
esg_es_score_peers[['esg_es_score_peers']]= esg_es_score_peers[['esg_es_score_peers']].replace(item[1],item[0],regex=True)
I exported to csv at this stage to see if the mapping was being done correctly but I can see that only some of the fields are correctly being mapped. I think the problem is this replace step
Things I have checked (that might be useless but thought were a good start):
All Labels are already the same as the esg_es_score_peers - no need to substitute labels like i did to remove "&" and so on
Multiple rows have the same string length but the error does not necessarily apply to those ones (my initial thought was that maybe when sorting them by string length something was going wrong whenever there were multiple outputs with the same string length)
Any help will be welcome
thanks so much

AngularJS/JavaScript - How to rename an array key name

I have an application that reads an excel file, and displays its contents in an html table.
These elements are in an array called "AgendaItems".
There are 2 files the user can read, each is formatted with some differences.
Both have 3 columns.
File 1: AgendaItem, LegistarId, Title
File 2: Agenda #, File #, Title
I am able to read the file and populate the array $scope.AgendaItens with the contents of either file, depending what the user selects.
My problem is that before making these modifications to accept a second file with a different format, I used:
<td scope="row">{{ai.AgendaItem}}</td>
<td>{{ai.LegistarID}}</td>
When processing the new file, now the array contains: Agenda #, and File #, which are equivalent to AgendaItem, and LegistarID respectively.
Is there a way to, in the HTML choose which value to display? for example, if array has AgendaItem, display AgendaItem, if array has Agenda #, display Agenda #?
Or, is it possible to rename a the name of a key, from Agenda # to AgendaItem and from File # to LegistarID?
Please let me know if I need to post more details, more code in order for me to be able to get help.
Thank you in advance,
Erasmo
You can use javascript array.map extension ? May be better for later reading the code.
Source data
var source = [{"Agenda #":"1","File #":"file1.xls"}]
Map it for cleaner usage
var maped = source.map(function(p) {
return {"AgendaItem":p["Agenda #"], "LegistarID":p["File #"]}
})
Other wise you have to use Object[fieldName] usage in html.(not suggesting to do so) like; ng-if="expression"
< ... ng-if='data["Agenda #"]' > {{data["Agenda #"]}}
...

Using Google Apps Script, how can I replace text in a Google Sheets template to make a new Sheet?

I have a Google Sheet which is being populated by a Google Form. I am using Google Apps Script to add some extra functionality. Please feel free to access and modify these as needed in order to help.
My goal is to be able to take responses from a Google Form, have that come into a Google Sheet, and then, using a template file, populate the template with the responses and have that sent out as an email attachment to whomever I specify.
This is a dumbed down version of my ultimate project, but the process should remain the same so that I can transpose from this small scale example to that bigger one.
Currently, in my Apps Script, I have code which is successfully able to make a copy of the template file and name it accordingly:
//Enter collected info into Requirements Template
const googleSheetTemplate = DriveApp.getFileById('1wqCwMhpuDLReU1hE1CbcDL-Vdw_4zge1xM6oOl34Ohg');
const destinationFolder = DriveApp.getFolderById('1GxNZQmP8mxHBhVl5AMoqBFs8sAIYzcm3');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 2');
const copy = googleSheetTemplate.makeCopy(`${row[3]}, ${row[0]} Vehicle Order` , destinationFolder);
const newSheet = SpreadsheetApp.openById(copy.getId());
const A1 = newSheet.getActiveRange();
But the next few lines which are meant to be able to find and replace certain strings within the newly copied Sheet does not seem to function properly.
A1.createTextFinder("{{Customer}}").replaceAllWith(row[3]);
A1.createTextFinder("{{Car}}").replaceAllWith(row[1]);
A1.createTextFinder("{{Color}}").replaceAllWith(row[2]);
A1.createTextFinder("{{Delivery}}").replaceAllWith(row[5]);
I just get the same dummy lines back in the new copy.
I was following another post which I found on a different issue but with the same goal. The majority of the concept I was looking to copy came from this blog post, but where they used a Google Doc, I was hoping to use a Google Sheet. Ultimately, the person that receives this new sheet will need to do some calculations and things with the provided information, so it still needs to be in Sheet form.
What modifications do I need to make in order to successfully replace the text in the template with the answers provided from the Google Form responses?
As far as I can tell, this line means some cells on the sheet were selected:
const A1 = newSheet.getActiveRange();
And script will search and replace within these cells only.
Probably you need to define the range with no reference on active range. Something like this:
const A1 = newSheet.getRange("A1:A"); // or "A1:Z", or .getDataRange()
I don't know what the range you need.
From the documentation, createTextFinder(findText) only works on a Sheet class, this means you need to define a Sheet variable before replacing text:
const copy = googleSheetTemplate.makeCopy(`${row[3]}, ${row[0]} Vehicle Order` , destinationFolder);
const newSheet = SpreadsheetApp.openById(copy.getId()).getSheets()[0];
newSheet.createTextFinder("{{Customer}}").replaceAllWith(row[3]);
newSheet.createTextFinder("{{Car}}").replaceAllWith(row[1]);
newSheet.createTextFinder("{{Color}}").replaceAllWith(row[2]);
newSheet.createTextFinder("{{Delivery}}").replaceAllWith(row[5]);

Read back chart details from highchart in json

I need to read back the chart details like styles, type, and all the attributes which are used to display any chart by Highchart, i.e. similar to chart.getSVG(). I need something like chart.getJSON() to save the entire JSON template with user chosen colors, fonts, series location etc in the DB, except the "data".
When we do the automatic distribution of the above mentioned chart using HighChart server, we need to read the above template with all the user specific attributes, but insert new data values for X and Y which we have, i.e only values will be new here, not the style. What is the best way to do it?, i.e. read the user template on the chart, but generate pdf with the new values. Your help is appreciated.
You can get all non-default options set for chart from:
var userOptions = $("#container").highcharts().userOptions
So options used when creating chart are stored there. Now you can use that object (without userOptions.series array of course) to store in your DB.
To remove series array use this snippet:
delete userOptions.series
And now you can create object using:
var myJSON = JSON.stringify(userOptions);
And send myJSON to you DB and store it.

Categories

Resources