How to get a reference to the modified feature in openlayers 3 - gis

Using OpenLayers 3 to modify features, how do I get the modified feature?
var features = new ol.Collection(editableLayer.getSource().getFeatures());
var modifyInteraction = new ol.interaction.Modify({
features: features
})
map.addInteraction(modifyInteraction);
modifyInteraction.on("modifyend", modifyFeature, this);
When I go to get the feature:
function modifyFeature(event)
{
var feature1 = event.features.getArray()[0]; //this brings back all features
//I want to know which specific
//features was modified
var feature2 = modifyInteraction.getFeatures(); //this did not work at all
}
My question is how do I get a reference the actual feature that was modified?

According to the api docs ol.interaction.Modify doens't provide a get Featueres Option. One approach is to add a common change event - .on('change:'... - on each feature, and after the event is fired you should get the target Feature.
Otherwise you can check the revision counter which is increased by one on every feature after a change (but i wouldn't recommend this)

Related

I Want To add FileFilter ("*.doc") to save automatic file without type extension

I want to add my FileFilter in as3. Because there is the main problem of extension typing. I already use this option
(saveFile.save(bytes,_dbookNameFill+".doc"));
but I want to automatically generate this extension when I save my file any names. Please Help Me I am Mini Programmer.
var bytes:ByteArray = document.save(Method.LOCAL);
var saveFile:FileReference = new FileReference()
var _dbookNameFill:String =
QSTPreviwForStudentMC._bookNameMc.bookNtxt.text;
var fileFilter:FileFilter=new FileFilter("*.doc","*.text;*.RTF;");
saveFile.save(bytes,_dbookNameFill+".doc");
I'm afraid this won't work. Using AS3's FileFilter class you're just able to limit
what's being displayed on a file dialog you've opened using Filereference.browse().
FileReference.save() isn't affected by a FileFilter and as far as I know there is
no way to force a particular file extension - perhaps due to security reasons.

How to update $rootScope in Angular 1 inside an async callback?

I'm sure this is a very common issue but for some reason I can't find a solution that works.
I have a very simple setup with Firebase Realtime Database and Angular 1. I have this directive in my html
<div id="usersListWrapper" ng-controller="UsersListController" ng-init="loadUsersList()">
Then inside my loadUsersList() method, I make a call to Firebase Database to fetch the data
$rootScope.users = [];
var usersRef = firebase.database().ref('/users');
usersRef.on('value', function(snapshot) {
console.log("loaded users list");
var users = snapshot.val();
updateUsersTable(users);
});
Then finally, inside updateUsersTable(users), I update my $rootScope.users variable
var updateUsersTable = function(users) {
$.each(users, function(key, value) {
var user = {
username: key,
...
}
$rootScope.users.push(user);
}
}
However, even though the $rootScope.users variable updates correctly (I verified using the devtools inside Chrome), the html doesn't update :/
Apologies in advance if this is a duplicate question. Help would be appreciated.
$rootScope is not an appropriate place for you to be storing your user objects. Generally speaking, modifying $rootScope should be considered something you do when there are no other options.
What you should be doing is creating a userService and injecting it whereever you need access to user data.
The same advice is generally true for using ng-init as well. I'm guessing you're just getting started with Angularjs. I'd highly recommend you familiarize yourself with John Papa's Angularjs style guide: https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md. It's a bit dated in that it doesn't cover components, which are EVERYTHING, but following the style guide makes migration to components super easy.
The solution here seems to work: Firebase callbacks and AngularJS
Kinda hacky but it works I guess. Thank you for those who answered.
As I mentioned in a comment above I would put the scope.$apply on the event listener b/c AngularJS doesn't know when the event is fired since it's not managing it. ie:
usersRef.on('value', scope.$apply(function () {
console.log("loaded users list");
var users = snapshot.val();
updateUsersTable(users);
}));
Or you could look into $evalAsync. From the AngularJS docs:
$evalAsync([expression], [locals]); Executes the expression on the
current scope at a later point in time.
The $evalAsync makes no guarantees as to when the expression will be
executed, only that:
it will execute after the function that scheduled the evaluation
(preferably before DOM rendering). at least one $digest cycle will be
performed after expression execution.

How to change data in data layer before sending to Google Analytics?

I tried to change some values in the data layer before it reach my Google analytics account.
I used a custom HTML tag to manipulate the data Layer. Say I wanted to multiply my room count variable by 3,
<script type="text/javascript">
(function() {
var var7 = ({{DL_roomcount}})
var7 = 3*var7
dataLayer.push({
'roomcount' : var7
});
})();
</script>
Apparently, even though it shows the new values in the data Layer in preview mode, the new values never reached the analytics account.
The trigger type I used was - custom event & event name was 'gtm.load'. In preview mode datalayer shows roomcount as 3 but in analytics account its still 1.
My GA-debug console also shows 1 instead of 3.
Any help regarding this would be highly appreciated.
Thank you
You should push an event into the dataLayer at the same time that you are pushing the new value for roomcount so that you can access that new value:
// your other code
dataLayer.push({
'event': 'update roomcount',
'roomcount': var7
})
You can now access the new roomcount value if you trigger your tag to fire on the update roomcount event.
You need to look at when it is that those values are read; let me give you an example.
You click on the page.
This causes a data layer push.
That push causes a google analytics to fire off an event.
You use your custom tag to edit the data layer variable.
In this situation, it's too late. You've already missed the point at which Google Analytics recieves the information.
I recommend either editing the data layer push, the data layer variable, or the tag that sends the information to Google Analytics. Adding in a 4th party just makes it more complicated.

Call Gnome Shell Shortcuts programmatically

Gnome Shell has great shortcuts, however, I don't find a way to call them programmingly
Assume that I want to use a GJS script to start Google Chrome, move it to workspace 1, and maximize it, then start Emacs, move it to workspace 2, and maximize it.
This could be done using wm.keybindings: move-to-workspace-1, move-to-workspace-2 and maximize. However, how to call them programmingly?
I notice that in GJS, Meta.prefs_get_keybinding_action('move-to-workspace-1') will return the guint of action move-to-workspace-1, but I did not find any function to call the action.
In https://github.com/GNOME/mutter/blob/master/src/core/keybindings.c, I found a function meta_display_accelerator_activate, but I could not find a GJS binding for this function.
So, is there any way to call gnome shell shortcuts programmatically?
The best bet to move an application is to grab its Meta.Window object, which is created after it's started.
This would be done through getting the active workspace, starting the application, then getting the application from the active workspace and moving it.
Sample code for a quick implementation:
const workspace = global.screen.get_active_workspace();
const Gio = imports.gi.Gio;
//CLIname: Name used to open app from a terminal
//wsIndex: Workspace you want it on
function openApp(CLIname, wsIndex) {
let context = new Gio.AppLaunchContext;
//use 2 to indicate URI support
//0 is no flags, 1 for terminal window,
//No 3, 4 for notification support
//null because setting a name has no use
Gio.AppInfo.create_from_commandline(CLIname, null, 2).launch([], context);
//Unfortunately, there is no way I know to grab a specific window if you don't know the index.
for(let w of workspace.list_windows()) {
//check if the window title or window manager class match the CLIname. Haven't found any that don't match either yet.
if(w.title.toLowerCase().includes(CLIname.toLowerCase() || w.get_wm_class().toLowerCase.includes(CLIname.toLowerCase()) {
//Found a match? Move it!
w.change_workspace(global.screen.get_workspace_by_index(wsIndex));
}
{
}
/*init(), enable() and disable() aren't relevant here*/
To answer the actual question way at the end, it might be possible by forcing the GNOME on-screen keyboard to emit those keys, but that would require matching the right keys and I/O emulation for every keybinding you wish to execute, which can change whenever a user wants it to, from an extension.

IndexedDB onversionchange event not fired in Chrome

I'm playing with the IndexedDB API from html5 spec in both Firefox and Chrome.
There something that's not working as expected I and want to share it here because I don't know if it's my fault or a browser bug.
According to the API, there's an event called onversionchange that's fired when you open a connection to a local database and the version number used is greater than the databases one.
My problem is that this event is being fired in Firefox but not in Chrome.
Some sample code trying several modes:
var db;
var DB_VERSION = 5;
var openRequest = indexedDB.open("test_db", DB_VERSION);
openRequest.onsuccess = function(event) {
db = openRequest.result;
};
openRequest.onversionchange = function(event) {
console.log("This is the place where I can change db structure");
};
openRequest.onupgradeneeded = function(event) {
console.log("This is the place where I can change db structure");
};
onversionchage event is not being fired even when I change the version number.
UPDATE
As ebidel has answered, Chrome implementation does not follow the currently specification so, in order to have a cross browser client code, we need to handle two situations: onversionchange event and database.version manual comparison.
Here are a couple on links with code example:
Chromium google group and
HTML5 Rocks!
Chrome's IndexedDB implementation is based off an older version of the spec which uses the older setVersion call rather than onversionchange/onupgradeneeded. Please star this issue: http://crbug.com/108223