Is it possible to refresh a single feature of a vector layer with Openlayers 3? I don't want to refresh all the layer.
If you have a reference to the feature, you can update aspects of the feature like it's geometry or properties and that will be updated in the map.
setGeomtry and setProperties both fire events that make the map update:
http://openlayers.org/en/latest/apidoc/ol.Feature.html
As long as you have set things up so that you can find or keep a direct reference to the feature, you can use the methods detailed in http://openlayers.org/en/latest/apidoc/ol.Feature.html to update a feature
If you are using the ol vector source, you can try to remove the feature and add it again. The Add Feature function triggers a change event (for the whole source, but this shouldn't update already drawed features).
ol.source.Vector.prototype.addFeature = function(feature) {
this.addFeatureInternal(feature);
this.changed();
};
Related
when using new beta feature LocalContextMapView from Google map, as described in https://developers.google.com/maps/documentation/javascript/local-context
How does one refresh the localContext when the map is panned/zoomed ?
LocalContextMapView place search is strictly bound by the map viewport by default. You can use the locationRestriction parameter to set a bounds to be much larger than the map's initial viewport.
You can find the sample implementation here: https://developers.google.com/maps/documentation/javascript/local-context/samples/location-restriction
And, since Local Context Search is still in beta, I highly suggest that you file a feature request for having a function to set locationRestriction programatically/dynamically.
For example, having a localContextMapView.setLocationRestriction() property would be a great addition to the Local Context Library. You can use Google Public Issue Tracker to file a feature request.
Why it uses d->eventFilters.prepend(obj) not append(obj) in function(QObject::installEventFilter),i want to know why design it in such way.I just curious about it.
void QObject::installEventFilter(QObject *obj)
{
Q_D(QObject);
if (!obj)
return;
if (d->threadData != obj->d_func()->threadData) {
qWarning("QObject::installEventFilter(): Cannot filter events for objects in a different thread.");
return;
}
// clean up unused items in the list
d->eventFilters.removeAll((QObject*)0);
d->eventFilters.removeAll(obj);
d->eventFilters.prepend(obj);
}
It's done that way because the most recently installed event filter is to be processed first, i.e. it needs to be at the beginning of the filter list. The filters are invoked by traversing the list in sequential order from begin() to end().
The most recently installed filter is to be processed first because the only two simple choices are to either process it first or last. And the second choice is not useful: when you filter events, you want to decide what happens before anyone else does. Well, but then some new user's filter will go before yours, so how that can be? As follows: event filters are used to amend functionality - functionality that already exists. If you added a filter somewhere inside the existing functionality, you'd effectively be interfacing to a partially defined system, with unknown behavior. After all, even Qt's implementation uses event filters. They provide the documented behavior. By inserting your event filter last, you couldn't be sure at all what events it will see - it'd all depend on implementation details of every layer of functionality above your filter.
A system with some event filter installed is like a layer of skin on the onion - the user of that system only sees the skin, not what's inside, not the implementation. But they can add their own skin on top if they wish so, and implement new functionality that way. They can't dig into the onion, because they don't know what's in it. Of course that's a generalization: they don't know because it doesn't form an API, a contract between them and the implementation of the system. They are free to read the source code and/or reverse engineer the system, and then insert the event filter anywhere in the list they wish. After all, once you get access to QObjectPrivate, you can modify the event filter list as you wish. But then you're responsible for the behavior of not only what you added on top of the public API, but of many of the underlying layers too - and your responsibility broadens. Updating the toolkit becomes next to impossible, because you'd have to audit the code and/or verify test coverage to make sure that something somewhere in the internals didn't get broken.
I am trying to render a whole heap of vectors in the google earth plugin. I use the parseKml method to create my Kml Feature object and store it in an array. The code looks something like below. I loop over a list of 10,000 kml objects that I return from a database and draw it in the plugin.
// 'currentKml' is a kml string returned from my DB.
// I iterate over 10,000 of these
currentKmlObject = ge.parseKml(currentKml);
currentKmlObject.setStyleSelector(gex.dom.buildStyle({
line: { width: 8, color: '7fff0000' }
}));
ge.getFeatures().appendChild(currentKmlObject);
// After this, I store teh currentKml object in an array so
// I can manipulate the individual features.
This seems to work fine. But when I want to turn the visibility of all these features on or off at once, I have to iterate over all of these kml objects in my array and set their individual visibilities on or off. This is a bit slow. If I am zoomed out, I can slowly see each of the lines disappearing and it takes about 5 - 10 seconds for all of them to disappear or come back.
I was wondering if I could speed up this process by adding a layer and adding all my objects as children of this layer. This way I set the visibility of the whole layer on or off.
I have been unable to find out how to create a new layer in code though. If someone can point the appropriate methods, it would be great. I am not sure if a layer is the right approach to speed up the process either. If you also have any other suggestions on how I can speed up the process of turning on/off all these objects in the map at once, that would be very helpful as well.
Thanks in advance for you help.
Ok, found out how to do this by myself.
In the google earth extensions libarary I use the 'buildFolder' method.
var folder = gex.dom.buildFolder({ name: folderName });
ge.getFeatures().appendChild(folder);
Now, when I iterate over my object array, I add them to the folder instead using the following
folder.getFeatures().appendChild(currentKmlObject);
This way, later on I can turn the visibility on and off at the folder level using
folder.setVisibility(false); // or true
And this works quite well as well. IThere is no delay, I can see all the objects turning on and off at once. It is quite quick and performant.
How can I refresh view after a certain event?
I have a view which contains multiple groups. I want to show or hide some groups.
onCreationComplete() or initialize() method works only at the beginning of the view creation.
Try invalidateDisplayList() on the view
Let me know if that doesn't do the trick and we'll try some other tricks.
I personally don't like the answer that says to call invalidateDisplayList (sorry no offense Nate nothing personal). I feel it's too vague and doesn't explain what this does under the hood and furthermore you shouldn't have to call it directly in cases such as the one explained in the OPs question. You can simply create booleans that are bindable for each of the groups you'd like to show/hide then in the event handler set those booleans to the appropriate value and if they are bound to the visible and include in layout properties of the containers those containers will internally call invalidateDisplayList after calling set visible and consequently commitProperties.
This is basically what happens under the hood as I understand it: The way this works is values aren't committed or used to update the display until the next frame this way it doesn't get bogged down doing unnecessary layout calculations. So you update the bindable property which fires an event which triggers a notification in the listener (in this case a function that sets the property on your control), that in turn passes along the value to the control which sets an internal flag to update the property and calls invalidateProperties. When it hits the next frame redraw it sees that the properties flag is dirty (true) and then calls commitProperties, this computes/sets the appropriate values (possibly also invalidating then "fixing" the size using invalidateSize() and measure()) and calls invalidateDisplayList, then during the same frame it sees that the display list flag is dirty so it calls updateDisplayList, here it uses the values of the properties to draw appropriately.
You should also be able to achieve this using states, which add or remove children from the display list based on an array of "actions" for each state.
In the Flash authoring environment I can edit a library symbol and all on-stage instances based upon it reflect the changes. How can I do the same thing in ActionScript? There seems to be no way to address a library symbol.
For example:
Inside Flash CS3, I have created a Square.swf file that has 100 instances of the library symbol Square.
Now, Square.swf is loaded into another file BlueSquare.swf and I want to change the Square symbol into a blue square so that all instances of Square become blue.
How do I do this using Actionscript?
Thanks for the help.
What's in a clip's library symbol is the author-time definition of that object - you can't change it at runtime. Instead the normal approach would be to dynamically change the contents (not definitions) of the clips you want to change, which can be done in various ways, but all the good ways of doing that involve making the dynamically-changing clip understand how to update its appearance. So you need to be able to re-author the changing clips to suit your needs.
If you're loading in an animation that somebody else made, and trying to go through and replace all instances of object A with object B, the only way to achieve that is to traverse through the content's display list looking for A, and when you find one, remove its children and replace them with the the contents of a B. Mind you, for animations that may not really solve your problem, since animations normally add and remove clips frequently, so at any given point you could replace all the "hand" clips with "hand2", but then a frame later new "hand" clips might come into existence. But short of opening up the SWF and changing the binary data inside, there's no other way to dynamically change all of a given object to something else unless the object knows how to change its contents.
If it is only about making sure that the square you are attaching is blue you could use the colorTransform to change its appearance:
var someSquare:Square = new Square();
someSquare.transform.colorTransform = new ColorTransform(0,0,0,1,0x00,0x00,0xff,0x00 );
addChild( someSquare );
Of course this does not change the color of all instances that you have already attached.
If you really wanted to change the actual SWF symbol in Actionscript the only way I see is to parse the swf with as3swf ( https://github.com/claus/as3swf/wiki ), find the shape tag of the symbol, change it and then load the ByteArray that contains the swf via loader.loadBytes() - but that's admittedly quite a complicated way and you can achieve the same result by simply putting some colorizing code into the shape symbol itself and then trigger the color change via an Event that is broadcasted by your main app.
Of course, if you make custom component, when you change it changes will appear on all instances of that component/class. Here's the example: http://livedocs.adobe.com/flex/3/html/intro_3.html
On the other hand, if you use modules whey pretty much do the same as swf-s you used in Flash, when you rebuild-recompile them changes will reflect on your main application which uses them. Here's th eexample for modules: http://blog.flexexamples.com/2007/08/06/building-a-simple-flex-module/
So MXML/AS component/class are your "symbols" which you can create or drop on stage on fly.
Modules are "movies" you can load and they run on their own with possibility to communicate to main movie.
The closest way of achieving this is to use Bitmaps. If you update the bitmapData they display, they will all update automatically.
However this approach is not good at all. You should maintain application state separately in an object model, and have the visualisation update, if the state changes.
What you want to do, is to misuse a feature for changing graphic appearence at design time, to change application state at runtime. In generally, ideas like these can be thought off as bad.
For example if you take the time to separate the state model and the visualisation layer, it will become fairly easy to save the game state on a server or to synchronize it with other clients to achieve multiuser features.
greetz
back2dos
If you are trying to build an Avatar and user can customize your Avatar parts e.g. hands, legs, face etc. and you want all these assets to be kept in separate swf file, that is pretty straightforward. You keep all the assets, in separate swf or one large swf file and load them at runtime. Now, maintain your Avatar object instance and place the child objects, which are chosen by the user.
You can create inside your class a static List with references all the created instances and then apply a change with static methods. For example:
package
{
import flash.display.MovieClip;
import flash.geom.ColorTransform;
public class Square extends MovieClip
{
public static var instances:Array = new Array();
public function Square():void
{
Square.instances.push(this); // This is the trick. Every time a square is created, it's inserted in the static list.
}
// This property gets the color of the current object (that will be the same of all others because the setter defined below).
public function get color():ColorTransform
{
return this.transform.colorTransform;
}
public function set color(arg:ColorTransform):void
{
// Sets the color transform of all Square instances created.
for each(var sqr:Square in Square.instances)
{
sqr.transform.colorTransform = arg;
}
}
}
}